# CeresSharp Integration Tasks - Chi tiết Công việc ## 📋 Tổng quan Tài liệu này mô tả **cụ thể** những gì cần làm để tích hợp CeresSharp vào CartographerSharp, hoàn thiện các components còn thiếu. ## ✅ Trạng thái hiện tại - **CeresSharp**: ✅ Đã có sẵn (100% complete - 216+ APIs) - **Ceres Solver Version**: 2.2.0 - **CartographerSharp**: ⏳ Đang chờ CeresSharp integration ## 🎯 Nơi Triển Khai: **CartographerSharp** **Quan trọng**: Tất cả implementation sẽ được làm **trong CartographerSharp**, không phải CeresSharp. ### Lý do: - **CeresSharp** = Generic optimization library (cung cấp building blocks) - **CartographerSharp** = Application layer (sử dụng CeresSharp để implement Cartographer algorithms) - Các cost functions là **Cartographer-specific**, không phải generic Ceres functionality ### Cấu trúc Files: ``` CartographerSharp/ ├── Mapping/ │ ├── Internal/ │ │ ├── 2D/ │ │ │ └── ScanMatching/ │ │ │ ├── CeresScanMatcher2D.cs ✅ (skeleton) │ │ │ ├── OccupiedSpaceCostFunction2D.cs ⏳ (cần implement) │ │ │ ├── TranslationDeltaCostFunctor2D.cs ⏳ (cần implement) │ │ │ └── RotationDeltaCostFunctor2D.cs ⏳ (cần implement) │ │ └── Optimization/ │ │ ├── OptimizationProblem2D.cs ✅ (skeleton) │ │ └── SpaCostFunction2D.cs ⏳ (cần implement) │ └── ... └── CartographerSharp.csproj ⏳ (cần thêm ProjectReference đến CeresSharp) ``` ## 📦 Dependencies ### 1. Project Reference **File**: `CartographerSharp.csproj` Thêm reference đến CeresSharp: ```xml net10.0 enable enable preview ``` ### 2. Using Directives Thêm vào các files cần dùng CeresSharp: ```csharp using CeresSharp; using CeresSharp.Core; using CeresSharp.Enums; ``` --- ## 🎯 Các Components Cần Hoàn Thiện ### 1. CeresScanMatcher2D ⏳ **File**: `Mapping/Internal/2D/ScanMatching/CeresScanMatcher2D.cs` **Trạng thái hiện tại**: Skeleton implementation với TODOs **Cần implement**: #### 1.1. Cost Functions cho Scan Matching ##### a) OccupiedSpaceCostFunction2D **File mới**: `Mapping/Internal/2D/ScanMatching/OccupiedSpaceCostFunction2D.cs` **Mục đích**: Tính cost dựa trên occupied space trong grid **C++ Reference**: `refs/cartographer/cartographer/mapping/internal/2d/scan_matching/occupied_space_cost_function_2d.h/cc` **Cần làm**: 1. Tạo class `OccupiedSpaceCostFunction2D` implement `CeresSharp.CostFunction` 2. Sử dụng `CeresSharp.BiCubicInterpolator` để interpolate grid values 3. Transform point cloud points theo pose estimate 4. Tính residual = 1.0 - interpolated_probability cho mỗi point 5. Weight = `occupied_space_weight / sqrt(point_cloud.size())` **CeresSharp APIs cần dùng**: - `CeresSharp.BiCubicInterpolator` - Cho grid interpolation - `CeresSharp.AutoDiffCostFunction` - Cho automatic differentiation - `CeresSharp.Problem.AddResidualBlock()` - Thêm cost function vào problem **Code structure**: ```csharp // File: Mapping/Internal/2D/ScanMatching/OccupiedSpaceCostFunction2D.cs using CeresSharp; using CeresSharp.Core; using CartographerSharp.Mapping.D2D; using CartographerSharp.Sensor; namespace CartographerSharp.Mapping.Internal.D2D.ScanMatching; public class OccupiedSpaceCostFunction2D : CostFunction { private readonly BiCubicInterpolator _interpolator; private readonly PointCloud _pointCloud; private readonly double _weight; // Implement Evaluate() method // Transform points, interpolate, compute residuals } ``` ##### b) TranslationDeltaCostFunctor2D **File mới**: `Mapping/Internal/2D/ScanMatching/TranslationDeltaCostFunctor2D.cs` **Mục đích**: Penalize translation deviation từ target translation **C++ Reference**: `refs/cartographer/cartographer/mapping/internal/2d/scan_matching/translation_delta_cost_functor_2d.h/cc` **Cần làm**: 1. Tạo functor class với `target_translation` và `weight` 2. Residual = `weight * (current_translation - target_translation)` 3. Sử dụng `AutoDiffCostFunction` với 3 parameters (x, y, theta) **Code structure**: ```csharp // File: Mapping/Internal/2D/ScanMatching/TranslationDeltaCostFunctor2D.cs using System.Numerics; using CeresSharp; using CeresSharp.Core; namespace CartographerSharp.Mapping.Internal.D2D.ScanMatching; public class TranslationDeltaCostFunctor2D { private readonly Vector2 _targetTranslation; private readonly double _weight; public static AutoDiffCostFunction CreateAutoDiffCostFunction( double scalingFactor, Vector2 targetTranslation) { return new AutoDiffCostFunction( new TranslationDeltaCostFunctor2D(scalingFactor, targetTranslation) ); } public void Evaluate(double[] parameters, double[] residuals, double[][] jacobians) { // parameters[0] = x, parameters[1] = y // residuals[0] = weight * (x - targetX) // residuals[1] = weight * (y - targetY) } } ``` ##### c) RotationDeltaCostFunctor2D **File mới**: `Mapping/Internal/2D/ScanMatching/RotationDeltaCostFunctor2D.cs` **Mục đích**: Penalize rotation deviation từ initial rotation **C++ Reference**: `refs/cartographer/cartographer/mapping/internal/2d/scan_matching/rotation_delta_cost_functor_2d.h/cc` **Cần làm**: 1. Tạo functor class với `initial_rotation` và `weight` 2. Residual = `weight * (current_rotation - initial_rotation)` 3. Sử dụng `AutoDiffCostFunction` với 1 parameter (theta) **Code structure**: ```csharp // File: Mapping/Internal/2D/ScanMatching/RotationDeltaCostFunctor2D.cs using CeresSharp; using CeresSharp.Core; namespace CartographerSharp.Mapping.Internal.D2D.ScanMatching; public class RotationDeltaCostFunctor2D { private readonly double _initialRotation; private readonly double _weight; public static AutoDiffCostFunction CreateAutoDiffCostFunction( double scalingFactor, double targetAngle) { return new AutoDiffCostFunction( new RotationDeltaCostFunctor2D(scalingFactor, targetAngle) ); } public void Evaluate(double[] parameters, double[] residuals, double[][] jacobians) { // parameters[0] = theta // residuals[0] = weight * (theta - initialRotation) } } ``` #### 1.2. CeresScanMatcher2D.Match() Implementation **File**: `Mapping/Internal/2D/ScanMatching/CeresScanMatcher2D.cs` **Cần làm**: 1. Khởi tạo `CeresSharp.Problem` 2. Setup `CeresSharp.SolverOptions`: - `LinearSolverType = LinearSolverType.DenseQr` (cho 2D scan matching) - Configure từ `CeresSolverOptions` proto 3. Tạo parameter block: `double[3]` = `[x, y, theta]` 4. Add cost functions: - OccupiedSpaceCostFunction2D (cho ProbabilityGrid hoặc TSDF2D) - TranslationDeltaCostFunctor2D - RotationDeltaCostFunctor2D 5. Solve: `CeresSharp.Solver.Solve(options, problem, out summary)` 6. Extract result: `poseEstimate = new Rigid2d(x, y, theta)` --- ### 2. OptimizationProblem2D ⏳ **File**: `Mapping/Internal/Optimization/OptimizationProblem2D.cs` **Trạng thái hiện tại**: Skeleton implementation với data structures **Cần implement**: #### 2.1. Cost Functions cho Pose Graph Optimization ##### a) SpaCostFunction2D **File mới**: `Mapping/Internal/Optimization/SpaCostFunction2D.cs` **Mục đích**: Sparse Pose Adjustment (SPA) cost function cho constraints **C++ Reference**: `refs/cartographer/cartographer/mapping/internal/optimization/cost_functions/spa_cost_function_2d.h/cc` **Cần làm**: 1. Tạo `SpaCostFunction2D` class 2. Residual = `relative_pose - (submap_pose^-1 * node_pose)` 3. Weight bằng `translation_weight` và `rotation_weight` từ constraint 4. Sử dụng `HuberLoss` cho loop closure constraints (robust với outliers) #### 2.2. OptimizationProblem2D.Solve() Implementation **File**: `Mapping/Internal/Optimization/OptimizationProblem2D.cs` **Cần làm**: 1. Khởi tạo `CeresSharp.Problem` 2. Setup `CeresSharp.SolverOptions`: - `LinearSolverType = LinearSolverType.SparseSchur` (cho large problems) - Configure từ `OptimizationProblemOptions` 3. Add parameter blocks: - Mỗi submap: `double[3]` = `[x, y, theta]` - Mỗi node: `double[3]` = `[x, y, theta]` 4. Set frozen trajectories: `problem.SetParameterBlockConstant(poseParams)` 5. Add constraints: - Loop closure constraints: Sử dụng `HuberLoss` - Intra-submap constraints: Không dùng loss function 6. Solve: `Solver.Solve(options, problem, out summary)` 7. Update poses: Extract từ parameter blocks và update `_submapData` và `_nodeData` --- ## 🔧 Migration Notes - Ceres 2.2.0 ### Deprecated APIs Cartographer C++ sử dụng Ceres cũ với các APIs đã deprecated: | API Cũ (Cartographer) | API Mới (Ceres 2.2.0) | Status trong CeresSharp | |----------------------|----------------------|------------------------| | `ceres::QuaternionParameterization` | `ceres::QuaternionManifold` | ✅ Có sẵn | | `ceres::LocalParameterization` | `ceres::Manifold` | ✅ Có sẵn | | `ceres::AutoDiffLocalParameterization` | `ceres::AutoDiffManifold` | ✅ Có sẵn | | `problem.SetParameterization()` | `problem.SetManifold()` | ✅ Có sẵn | **Lưu ý**: Khi implement, sử dụng **Manifold APIs** thay vì LocalParameterization (nếu cần cho 3D). --- ## 📝 Checklist Implementation ### Phase 1: Setup Dependencies ✅ - [x] Thêm `ProjectReference` đến CeresSharp trong `CartographerSharp.csproj` - [x] Verify build thành công với CeresSharp reference ### Phase 2: Cost Functions ✅ - [x] Implement `OccupiedSpaceCostFunction2D.cs` - Complete với BiCubicInterpolator integration - [x] Implement `TranslationDeltaCostFunctor2D.cs` - Complete với AutoDiffCostFunction - [x] Implement `RotationDeltaCostFunctor2D.cs` - Complete với AutoDiffCostFunction - [x] Implement `ProbabilityGridAdapter` cho BiCubicInterpolator - Complete với padding và grid data conversion - [ ] Tests cho cost functions (có thể làm sau khi integrate vào CeresScanMatcher2D) ### Phase 3: CeresScanMatcher2D ✅ - [x] Complete `CeresScanMatcher2D.Match()` method - Complete với Problem setup, cost functions integration, và Solver - [x] Initialize `SolverOptions` với DENSE_QR linear solver cho 2D scan matching - [x] Integrate với `LocalTrajectoryBuilder2D` - Đã có integration, signature đã match - [ ] Tests cho scan matching (có thể làm sau) ### Phase 4: OptimizationProblem2D ✅ - [x] Implement `SpaCostFunction2D.cs` - Complete với AutoDiffCostFunction, ComputeUnscaledError, ScaleError - [x] Complete `OptimizationProblem2D.Solve()` method - Complete với Problem setup, parameter blocks, constraints, frozen trajectories - [x] Handle frozen trajectories - Complete với SetParameterBlockConstant - [x] Integrate với `PoseGraph2D.RunFinalOptimization()` - Complete với data sync - [ ] Tests cho pose graph optimization (có thể làm sau) ### Phase 5: Integration ✅ - [x] Update `PoseGraph2D.RunFinalOptimization()` để gọi `OptimizationProblem2D.Solve()` - Complete với data sync và pose updates - [ ] End-to-end tests (optional - có thể làm sau) - [ ] Performance benchmarks (optional - có thể làm sau) --- ## 🎯 Kết quả Mong đợi Sau khi hoàn thành: 1. ✅ **CeresScanMatcher2D**: Fine alignment của scans với submap grids 2. ✅ **OptimizationProblem2D**: Global pose graph optimization với loop closure 3. ✅ **CartographerSharp**: Hoàn thiện Phase 3 (100%) --- ## 📚 Tài liệu Tham khảo - `CERES_USAGE.md` - Chi tiết cách Ceres được sử dụng trong Cartographer - `CERES_READINESS_EVALUATION.md` - Đánh giá mức độ sẵn sàng của CeresSharp - `refs/cartographer/` - C++ source code reference - [Ceres Solver Documentation](http://ceres-solver.org/)