Files
I150/docs/CartographerSharp/CERES_INTEGRATION_TASKS.md
2026-07-03 16:37:12 +07:00

347 lines
13 KiB
Markdown

# 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
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>preview</LangVersion>
</PropertyGroup>
<ItemGroup>
<!-- Reference to CeresSharp -->
<ProjectReference Include="../CeresSharp/CeresSharp.csproj" />
<!-- Existing dependencies -->
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.4.0" />
<PackageReference Include="SkiaSharp" Version="2.88.9" />
</ItemGroup>
</Project>
```
### 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``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<TranslationDeltaCostFunctor2D, 2, 3>(
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``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<RotationDeltaCostFunctor2D, 1, 3>(
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``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``_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/)