cartographer/mapping/internal/imu_based_pose_extrapolator.h¶
Overview¶
ImuBasedPoseExtrapolator is a PoseExtrapolatorInterface implementation that estimates pose using the IMU’s linear acceleration and angular velocity, instead of assuming constant velocity. It solves a small Ceres optimization problem over the recent pose queue, integrating IMU measurements between poses, to predict the tracking frame pose at arbitrary times and to estimate gravity alignment. It is used by 3D local SLAM when use_imu_based is set.
Class: cartographer::mapping::ImuBasedPoseExtrapolator¶
Interface¶
Implements PoseExtrapolatorInterface:
common::Time GetLastPoseTime() const override;
common::Time GetLastExtrapolatedTime() const override;
void AddPose(common::Time time, const transform::Rigid3d& pose) override;
void AddImuData(const sensor::ImuData& imu_data) override;
void AddOdometryData(const sensor::OdometryData& odometry_data) override;
transform::Rigid3d ExtrapolatePose(common::Time time) override;
ExtrapolationResult ExtrapolatePosesWithGravity(
const std::vector<common::Time>& times) override;
Eigen::Quaterniond EstimateGravityOrientation(common::Time time) override;
Factory¶
static std::unique_ptr<PoseExtrapolatorInterface> InitializeWithImu(
const proto::ImuBasedPoseExtrapolatorOptions& options,
const std::vector<sensor::ImuData>& imu_data,
const std::vector<transform::TimestampedTransform>& initial_poses);
Seeds the extrapolator with buffered IMU data and optional initial poses. If no initial poses are given, the first pose is built by aligning the last linear acceleration measurement with the world z-axis (gravity) via FromTwoVectors.
ExtrapolationResult¶
Defined in PoseExtrapolatorInterface:
struct ExtrapolationResult {
std::vector<transform::Rigid3f> previous_poses; // times[0..N-1]
transform::Rigid3d current_pose; // times[N]
Eigen::Vector3d current_velocity;
Eigen::Quaterniond gravity_from_tracking;
};
Extrapolation with Gravity¶
ExtrapolatePosesWithGravity(times):
Requires at least 3 poses in the queue and a positive time span; otherwise returns the last known pose for all requested times.
Builds a Ceres problem with a
gravity_from_localpose (the slowly varying gravity alignment), one node per queued pose, plus an extra node for the requested extrapolation time seeded byExtrapolatePoseWithImu.Adds residual blocks:
SpaCostFunction3Dper queued pose (weighted bypose_translation_weight/pose_rotation_weight) keeping nodes near their scan-match poses.AccelerationCostFunction3Dbetween consecutive triples of nodes, constraining acceleration computed from node translations against the IMU-integrateddelta_velocity(weightimu_acceleration_weight).RotationCostFunction3Dbetween consecutive nodes, constraining relative rotation against the IMUdelta_rotation(weightimu_rotation_weight).SpaCostFunction3Dbetween consecutive nodes when odometry is available, constraining relative motion to the interpolated odometry delta (weighted byodometry_translation_weight/odometry_rotation_weight).
The
gravity_constant(default 9.8) is optimized unless a positivegravity_constantoption fixes it; the IMU calibration quaternion is added as a constant parameter block.After
ceres::Solve, the extrapolated pose is expressed relative to the last known scan-match pose, poses are interpolated to the requested times, the current velocity is computed, andgravity_from_localplus the solution are cached for reuse.
Estimation of Gravity¶
EstimateGravityOrientation(time) returns ExtrapolatePosesWithGravity({time}).gravity_from_tracking, the rotation from the tracking frame into the gravity-aligned frame at the requested time.
Data Management¶
AddPosepushes intotimed_pose_queue_, trimming entries older thanpose_queue_durationand dropping them fromprevious_solution_.AddImuData/AddOdometryDataappend to their deques (timestamps must not go backwards) andTrimImuData/TrimOdometryDatadrop data older than the front of the pose queue.InterpolateOdometrylinearly interpolates odometry poses within the buffered odometry range;CalculateOdometryBetweenNodescomputes the relative odometry between two node poses.
Options¶
proto::ImuBasedPoseExtrapolatorOptions:
Field |
Type |
Meaning |
|---|---|---|
|
double |
Keep poses within this time horizon (s) |
|
double |
Fix gravity (if > 0); otherwise estimated |
|
double |
Weight keeping nodes near scan-match poses |
|
double |
Rotation weight for scan-match poses |
|
double |
Weight of the acceleration residual |
|
double |
Weight of the rotation residual |
|
double |
Translation weight for odometry deltas |
|
double |
Rotation weight for odometry deltas |
|
CeresSolverOptions |
Ceres solver configuration |
Configuration¶
From trajectory_builder_3d.lua:
pose_extrapolator = {
use_imu_based = true,
imu_based = {
pose_queue_duration = 0.25,
gravity_constant = 9.8,
pose_translation_weight = 1.,
pose_rotation_weight = 1.,
imu_acceleration_weight = 1.,
imu_rotation_weight = 1.,
odometry_translation_weight = 1.,
odometry_rotation_weight = 1.,
solver_options = { ... },
},
}
Role in the SLAM Pipeline¶
LocalTrajectoryBuilder3D creates this extrapolator on the first IMU message (via InitializeWithImu) and uses ExtrapolatePosesWithGravity to obtain a pose for every point of an accumulated scan, plus the current pose and gravity alignment used to seed scan matching and submap insertion.
See Also¶
PoseExtrapolatorInterface— Abstract interface andExtrapolationResultLocalTrajectoryBuilder3D — Primary consumer
Sensor ImuData — IMU measurement type
Sensor OdometryData — Odometry input type