struct mola::LidarOdometry::Parameters::IMUGravityCorrection::OdometryAttitude

Overview

Take the verticality reading from an odometry source’s ABSOLUTE attitude instead of from the accelerometer.

Only the “up” axis is taken, never the position or the heading. The source’s reference frame differs from the map frame by an unknown yaw and translation, and neither of those touches the direction of gravity, so the vertical transfers between the two frames exactly while nothing else does.

The motivation is that an accelerometer only measures gravity while the platform is quasi-static, so on a legged or otherwise continuously-accelerating platform adaptive_sigma correctly stands the constraint down almost all of the time, leaving the vertical unconstrained for the whole run. A kinematic-inertial state estimator on the platform itself does not have that limitation and publishes an attitude that stays gravity-referenced while walking.

The map-origin reference is then captured from the same source (see captureMapOriginVerticality), because mixing a reading from one source with a reference from another injects the constant offset between them as a permanent map tilt.

Only honored by the rank-2 prior path; use_rank2_prior: false ignores it, with a warning at initialization.

#include <LidarOdometry.h>

struct OdometryAttitude
{
    // fields

    bool enabled = false;
    std::string sensor_label = "odom_wheels";
    double sigma_deg = 1.0;
    double max_age_seconds = 0.5;

    // methods

    void initialize(const Yaml& c);
};

Fields

std::string sensor_label = "odom_wheels"

Sensor label of the odometry observation to read. It must carry a full 3D attitude, i.e. arrive as mrpt::obs::CObservationRobotPose; planar CObservationOdometry has no pitch or roll to offer and is ignored.

double sigma_deg = 1.0

Sigma [degrees] of the verticality constraint when the reading comes from this source. adaptive_sigma does not apply here: it widens by accelerometer dispersion, which says nothing about an external attitude estimate.

double max_age_seconds = 0.5

Maximum age [s] of the reading, measured against the newest observation timestamp seen by the system. Older readings are ignored and the accelerometer is used instead, so a source that stops publishing degrades to the previous behavior rather than freezing the vertical. 0 = no age limit.