ImuTracker 的主要作用是根据 IMU的角速度和线性加速度进行位姿的预测,IMU原本给出的位姿是通过积分得出的,不准确的
头文件 ImuTracker 的主要作用是根据 IMU的角速度和线性加速度进行位姿的预测,IMU原本给出的位姿是通过积分得出的,不准确的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class ImuTracker { public : ImuTracker (double imu_gravity_time_constant, common::Time time); void Advance (common::Time time) ; void AddImuLinearAccelerationObservation ( const Eigen::Vector3d& imu_linear_acceleration) ; void AddImuAngularVelocityObservation ( const Eigen::Vector3d& imu_angular_velocity) ; common::Time time () const { return time_; } Eigen::Quaterniond orientation () const { return orientation_; } private : const double imu_gravity_time_constant_; common::Time time_; common::Time last_linear_acceleration_time_; Eigen::Quaterniond orientation_; Eigen::Vector3d gravity_vector_; Eigen::Vector3d imu_angular_velocity_; };
构造函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ImuTracker::ImuTracker (const double imu_gravity_time_constant, const common::Time time) : imu_gravity_time_constant_ (imu_gravity_time_constant), time_ (time), last_linear_acceleration_time_ (common::Time::min ()), orientation_ (Eigen::Quaterniond::Identity ()), gravity_vector_ (Eigen::Vector3d::UnitZ ()), imu_angular_velocity_ (Eigen::Vector3d::Zero ()) {}
orientation_ 在最开始时,在欧拉角表示则为(0,0,0)的。
AddImuAngularVelocityObservation 角速度的校准
1 2 3 4 5 void ImuTracker::AddImuAngularVelocityObservation ( const Eigen::Vector3d& imu_angular_velocity) { imu_angular_velocity_ = imu_angular_velocity; }
AddImuLinearAccelerationObservation 此函数最主要的作用是计算出当前加速度下的位姿orientation_ 。
在这期间,还做了以下操作
更新目前时刻的线性加速度(和上一帧的加权平均),gravityvector 。gravityvector 就是 imu_linear_acceleration
1 2 3 const double alpha = 1. - std::exp (-delta_t / imu_gravity_time_constant_); gravity_vector_ = (1. - alpha) * gravity_vector_ + alpha * imu_linear_acceleration;
理解 :如果imu时间间隔很小,那么就直接约等于上一帧的gravityvector ,第一帧的时候,gravityvector 直接赋值为imu_linear_acceleration。
时间差约大就越相信当前传入的值,时间约小,就越相信之前的值
预测目前时刻的位姿
1 2 orientation_ = (orientation_ * rotation).normalized ();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 void ImuTracker::AddImuLinearAccelerationObservation ( const Eigen::Vector3d& imu_linear_acceleration) { const double delta_t = last_linear_acceleration_time_ > common::Time::min () ? common::ToSeconds (time_ - last_linear_acceleration_time_) : std::numeric_limits<double >::infinity (); last_linear_acceleration_time_ = time_; const double alpha = 1. - std::exp (-delta_t / imu_gravity_time_constant_); gravity_vector_ = (1. - alpha) * gravity_vector_ + alpha * imu_linear_acceleration; const Eigen::Quaterniond rotation = FromTwoVectors ( gravity_vector_, orientation_.conjugate () * Eigen::Vector3d::UnitZ ()); orientation_ = (orientation_ * rotation).normalized (); CHECK_GT ((orientation_ * gravity_vector_).z (), 0. ); CHECK_GT ((orientation_ * gravity_vector_).normalized ().z (), 0.99 ); }
根据现在的线性加速度和之前的线性加速度不一样,就会产生一个旋转,此旋转可以根据当前的线性加速度对之前的线性加速度做一个矫正,矫正量就是rotation,把这个rotation作用于之前的orientation 上就可以得到现在的 orientation 。
Advance 此函数 预测出time时刻的姿态与重力方向
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 void ImuTracker::Advance (const common::Time time) { CHECK_LE (time_, time); const double delta_t = common::ToSeconds (time - time_); const Eigen::Quaterniond rotation = transform::AngleAxisVectorToRotationQuaternion ( Eigen::Vector3d (imu_angular_velocity_ * delta_t )); orientation_ = (orientation_ * rotation).normalized (); gravity_vector_ = rotation.conjugate () * gravity_vector_; time_ = time; }