imu预积分代码解析
LIOSAM一共四个src文件,本节我们要讨论的文件为imuPreintegration.cpp
,
函数入口
1 | int main(int argc, char** argv) |
函数首先进入的是IMUPreintegration的默认构造函数
IMUPreintegration构造函数
该构造函数订阅了两条消息
- IMU 的topic:回调函数为IMUPreintegration::imuHandler
- Odometry:回调函数为IMUPreintegration::odometryHandler。 该Odom来自于mapping模块
1 | IMUPreintegration() |
imuHandler
该回调函数会把接收到的imu数据全部转换到lidar坐标系上,并且把收到的消息传入到两个队列中,一个用于预积分和位姿的优化,一个用于更新最新imu状态。
只有在odometry 的回调函数处理过后doneFirstOpt才会true。下面先看,在设置为true之前会发生什么
1 | void imuHandler(const sensor_msgs::Imu::ConstPtr& imu_raw) |
odometryHandler
流程
odometry的回调函数是最重要的回调函数,步骤为
取出里程计的位置和方向
判断里程计是否退化,这个会在后端中说明,什么时候会退化,退化的精度会下降
这帧雷达的pose转为gtsam
第一次进入,初始化系统:
4.1 GTSAM初始化
4.2 添加先验约束
4.3 添加实际的状态量
4.4 更新isam优化器
4.5 预积分接口重置
加入imu数据,自动实现预积分量的更新以及协方差矩阵的更新
添加ImuFactor,零偏约束
添加雷达的位姿约束
失败检测(速度大于30,零偏太大)
根据最新的imu状态进行传播
代码
- 取出里程计的位置和方向
1 | float p_x = odomMsg->pose.pose.position.x; |
- 判断里程计是否退化,这个会在后端中说明,什么时候会退化,退化的精度会下降
1 | bool degenerate = (int)odomMsg->pose.covariance[0] == 1 ? true : false; |
- 这帧雷达的pose转为gtsam
1 | gtsam::Pose3 lidarPose = gtsam::Pose3(gtsam::Rot3::Quaternion(r_w, r_x, r_y, r_z), gtsam::Point3(p_x, p_y, p_z)); |
- 初始化系统
1 | // 0. initialize system |
下面的内容为,添加因子图的信息
gtsam::NonlinearFactorGraph graphFactor: 类别为:gtsam::PriorFactor
- 添加先验速度约束
- 添加先验零偏约束
- 添加先验位置约束
gtsam::Values graphValue
- 插入位置
- 插入速度
- 插入零偏
1 | // initial pose |
- 加入imu数据
imuIntegratorOpt_->integrateMeasurement
1 | while (!imuQueOpt.empty()) |
- 加ImuFactor,零偏约束
graphFactors 因子图因子添加
1 | // add imu factor to graph |
- 添加雷达的位姿约束,设定因子图的初值
1 | // add pose factor |
- 失败检测
1 | // check optimization |
- 根据最新的imu状态进行传播
1 | // repropogate |
Comments