class mola::GravityLeveler
Overview
Causal gravity leveling of a trajectory produced by an odometry or a state estimator, without touching the estimator itself.
The trajectory’s frame may slowly tilt with respect to gravity (e.g. where the scans barely constrain pitch and roll), which turns horizontal motion into a vertical drift. This class estimates that tilt and rotates the trajectory increments to undo it:
Measurement, every
epoch_periodseconds: the mean specific force over a trailing window, each reading rotated into the trajectory frame with the trajectory’s attitude at its own time, minus the trajectory’s own mean acceleration over the same interval. Normalized, its horizontal part is the frame tilttau(2 DoF, small angles), plus the effect of any body-fixed accelerometer error.Readings beyond
max_tilt, or with gravity not pointing up, are ignored: a frame tilt is small, and a large reading means the trajectory’s attitude itself is failing.A Kalman filter with state
[tau (2), b (3)]:taua random walk withtilt_random_walkdeg/sqrt(s),ba constant body-frame accelerometer error (bias plus IMU misalignment), observed through the mean attitude over the window. A body-fixed error turns with the platform and a frame tilt does not, which separates both while the platform turns. Readings beyond a chi-squared gate are ignored; aftermax_consecutive_rejectionsof them in a row the filter restarts from the current reading, so a wrong state cannot lock itself in.Output: the part of the estimated tilt beyond
deadbanddegrees is removed by rotating every increment of the trajectory, and its attitude, by the small rotation that levels the frame. The deadband leaves alone a frame that is already level within the reading’s own error.
Only past data are used. Positions are corrected incrementally, so the output is continuous even when the correction changes.
#include <GravityLeveler.h> class GravityLeveler { public: // structs struct ImuSample; struct Parameters; struct PoseSample; struct Stats; // construction GravityLeveler(); GravityLeveler(const Parameters& p); // methods const Parameters& parameters() const; const Stats& stats() const; void add_imu(double t, const mrpt::math::TVector3D& specific_force); mrpt::poses::CPose3D add_pose(double t, const mrpt::poses::CPose3D& pose); std::optional<mrpt::math::TVector2D> tilt() const; mrpt::math::TVector2D applied_tilt() const; };
Construction
GravityLeveler(const Parameters& p)
Parameters:
std::exception |
on invalid parameters |
Methods
void add_imu(double t, const mrpt::math::TVector3D& specific_force)
Adds one accelerometer reading (specific force, in the vehicle frame)
mrpt::poses::CPose3D add_pose(double t, const mrpt::poses::CPose3D& pose)
Adds the next pose of the trajectory and returns it leveled. IMU readings up to t should have been added before. A pose not newer than the previous one is leveled with the current correction but does not update the filter.
std::optional<mrpt::math::TVector2D> tilt() const
The current tilt estimate (x, y components, in radians), before the deadband. Empty until the first reading has been taken.
mrpt::math::TVector2D applied_tilt() const
The tilt being removed from the output (after the deadband) [rad]