cartographer/mapping/internal/3d/scan_matching/ceres_scan_matcher_3d.h¶
Overview¶
CeresScanMatcher3D aligns scans with an existing 3D map using Ceres nonlinear least-squares optimization. It is the refinement stage of 3D scan matching: given an initial pose estimate, it optimizes a full Rigid3d pose against one or more HybridGrid maps (high-resolution, low-resolution, and optionally intensity) using auto-differentiable cost functions.
Class: cartographer::mapping::scan_matching::CeresScanMatcher3D¶
Construction¶
explicit CeresScanMatcher3D(const proto::CeresScanMatcherOptions3D& options);
Builds the Ceres solver options from the proto and forces ceres::DENSE_QR as the linear solver.
PointCloudAndHybridGridsPointers¶
struct PointCloudAndHybridGridsPointers {
const sensor::PointCloud* point_cloud;
const HybridGrid* hybrid_grid;
const IntensityHybridGrid* intensity_hybrid_grid; // optional
};
Describes one point cloud matched against one (or optionally two) grids. In LocalTrajectoryBuilder3D two of these are passed: the high-resolution cloud against the high-resolution grid (with the intensity grid when use_intensities), and the low-resolution cloud against the low-resolution grid.
Match¶
void Match(const Eigen::Vector3d& target_translation,
const transform::Rigid3d& initial_pose_estimate,
const std::vector<PointCloudAndHybridGridsPointers>&
point_clouds_and_hybrid_grids,
transform::Rigid3d* pose_estimate,
ceres::Solver::Summary* summary) const;
The state is a CeresPose (translation + quaternion rotation). The rotation parameterization is chosen by only_optimize_yaw:
true—YawOnlyQuaternionOperations/YawOnlyQuaternionPlusmanifold, which fixes roll and pitch.false— a full quaternion manifold.
Residual blocks:
Occupied-space term per cloud —
OccupiedSpaceCostFunction3Dfor each entry, weighted byoccupied_space_weight(i) / sqrt(point_cloud.size()). There must be exactly as manyoccupied_space_weightentries as clouds.Intensity term (optional per cloud) —
IntensityCostFunction3Dweighted byintensity_cost_function_options(i).weight / sqrt(size)withintensity_thresholdand aceres::HuberLosswithhuber_scale. Only added whenintensity_hybrid_gridis present.Translation prior —
TranslationDeltaCostFunctor3Dweighted bytranslation_weightagainsttarget_translation.Rotation prior —
RotationDeltaCostFunctor3Dweighted byrotation_weightagainst the initial rotation.
ceres::Solve produces the optimized pose, which is returned via pose_estimate (a Rigid3d).
Options¶
proto::CeresScanMatcherOptions3D:
Field |
Type |
Meaning |
|---|---|---|
|
repeated double |
One weight per matched point cloud |
|
repeated |
Per-cloud |
|
double |
Penalty on translation from the target |
|
double |
Penalty on rotation from the initial estimate |
|
bool |
Fix roll/pitch (yaw-only manifold) |
|
CommonSolverOptions |
Ceres solver configuration |
Configuration¶
From trajectory_builder_3d.lua:
ceres_scan_matcher = {
occupied_space_weight_0 = 1.,
occupied_space_weight_1 = 1.,
translation_weight = 10.,
rotation_weight = 1.,
only_optimize_yaw = false,
ceres_solver_options = { ... },
}
CreateCeresScanMatcherOptions3D() reads an arbitrary number of occupied_space_weight_<i> and intensity_cost_function_options_<i> keys (until a missing index), then the scalar weights and solver options.
Role in the SLAM Pipeline¶
LocalTrajectoryBuilder3D::ScanMatch calls this matcher after the optional online correlative stage to refine the pose in the submap frame. The same matcher is reused by the 3D constraint builder for loop closure refinement.
See Also¶
RealTimeCorrelativeScanMatcher3D— Coarse matcher before Ceres (3D variant of the 2D real-time matcher)FastCorrelativeScanMatcher3D — Loop-closure candidate matcher
LocalTrajectoryBuilder3D — Online caller
CeresScanMatcher2D — 2D counterpart