IMU预积分
Related Reading:
1 |
|
- 数据读取:从CSV文件中加载AVP数据,具体包括欧拉角、速度、位置和时间间隔。
- 预积分与IMU因子:使用IMU数据进行预积分并创建IMU因子,这在因子图优化中非常重要,尤其是在处理时间序列数据时。
- 因子图优化:利用Levenberg-Marquardt优化器执行非线性优化,优化位姿、速度和IMU偏置。
- 结果保存:最终的优化结果被输出到日志文件和CSV文件,包含了优化后的轨迹信息。
这段代码的主要功能是使用IMU(惯性测量单元)数据,结合图优化技术(尤其是 GTSAM 库),来进行 机器人或设备的状态估计,包括位姿(位置和朝向)、速度以及IMU的偏置估计。代码的核心任务是利用IMU的数据进行 预积分(Preintegration),构建一个因子图(Factor Graph),并通过 图优化 来估计系统的状态。
我们可以逐步分析这段代码的工作流程,以便理解它的具体功能。
背景知识:
在 机器人学 或 传感器融合 中,IMU 是一种常见的传感器,能够测量加速度和角速度。常见的应用包括 定位、姿态估计、惯性导航系统(INS) 等。
IMU 提供的是积分数据,意味着我们通常得到的是增量变化,而不是绝对位置、速度或姿态。因此,IMU 的数据需要通过 预积分(Preintegration) 和 优化算法 来推算出更准确的全局状态。
GTSAM 是一个处理 图优化 的库,常用于 SLAM(Simultaneous Localization and Mapping)和其他优化问题。通过构建一个 因子图(Factor Graph),它能够将各种约束(例如,来自传感器的测量数据)合并到一起,并通过优化算法(如 Levenberg-Marquardt)求解出最优的状态估计。
代码功能概述:
- 读取IMU和位置数据:从CSV文件中读取IMU的角速度、加速度、位置、速度以及时间戳等信息。
- 设置IMU预积分参数:使用IMU数据进行预积分,即通过加速度和角速度的增量计算设备的位姿和速度的变化。
- 建立因子图:将IMU的预积分数据、设备的初始状态(位姿、速度、偏置)和噪声模型等添加到因子图中,构建一个非线性优化问题。
- 执行图优化:使用 Levenberg-Marquardt优化器 对因子图进行优化,得到设备的最优状态(位姿、速度和偏置)。
- 输出结果:将优化后的位姿、速度和其他信息保存到文件中,供后续分析使用。
具体步骤分析:
1. 数据读取(读取CSV文件中的IMU数据)
1 | ifstream file("avp_data.csv"); |
首先,代码尝试从 "avp_data.csv" 文件中读取数据。如果文件打开失败,程序会输出错误信息并终止。
1 | vector<Vector3> euler_angles; |
定义几个 vector 用来存储从CSV文件中读取的数据:
- euler_angles:每一行数据中的欧拉角(roll, pitch, yaw),表示物体的姿态。
- velocities:每一行数据中的速度(x, y, z)。
- positions:每一行数据中的位置(x, y, z)。
- time_intervals:时间间隔,假设为常量。
1 | while (getline(file, line)) { |
这里逐行读取CSV文件中的数据,并将每行数据转换成对应的 欧拉角、速度、位置 和 时间间隔,存入前面定义的 vector 中。CSV文件的每一行数据的顺序假设是:欧拉角(roll, pitch, yaw)、速度(velocity_x, velocity_y, velocity_z)、位置(pos_x, pos_y, pos_z)和 时间间隔。
2. IMU预积分参数设置
1 | Vector3 gravity(0, 0, -9.81); // 设置重力加速度 |
在这部分代码中,我们创建了一个 IMU预积分参数对象 params。这个对象将用于对IMU数据进行预积分,计算设备的状态(位姿和速度)的增量。
gravity设置了重力加速度,指向 z轴负方向。params对象初始化时使用了重力加速度,这对于IMU数据的处理至关重要。- 通过调整 加速度计、陀螺仪 和 积分 的协方差矩阵,我们能够控制优化的精度和噪声。
3. 初始估计和噪声模型设置
1 | Pose3 prior_pose(Rot3::RzRyRx(euler_angles[0]), Point3(positions[0].x(), positions[0].y(), positions[0].z())); |
- prior_pose:使用从CSV文件读取的第一个欧拉角和位置数据来设置设备的初始位姿。
- prior_velocity:使用从CSV文件读取的第一个速度数据来设置设备的初始速度。
- prior_state:封装位姿和速度信息,表示设备的初始状态。
1 | auto pose_noise_model = noiseModel::Diagonal::Sigmas((Vector(6) << 0.1, 0.1, 0.1, 0.3, 0.3, 0.3).finished()); // 位姿噪声模型 |
- pose_noise_model:为位姿(位置和朝向)设置噪声模型。
- velocity_noise_model:为速度设置噪声模型。
- bias_noise_model:为IMU的偏置设置噪声模型。
4. 因子图(Factor Graph)创建与初始化估计
1 | NonlinearFactorGraph graph; // 创建因子图 |
- graph:用于存储因子图中的所有因子(约束)。
- initialEstimate:存储所有优化变量的初始值。
1 | graph.add(PriorFactor<Pose3>(Symbol('x', 0), prior_pose, pose_noise_model)); |
这里,我们为 位姿、速度 和 IMU偏置 添加了先验因子(表示我们对初始状态的知识和不确定性)。
1 | initialEstimate.insert(Symbol('x', 0), prior_pose); |
这些代码为初始估计容器插入了初始的位姿、速度和偏置估计值。
5. IMU数据预积分与因子添加
在每次读取IMU数据时,使用预积分技术计算设备状态的增量,并将其添加到因子图中。
1 | PreintegratedImuMeasurements preintegrated(params, prior_bias); // 创建IMU预积分对象 |
preintegrated 是一个 IMU预积分对象,用于根据每个时间步的加
速度和角速度来计算状态的增量。
1 | for (size_t i = 1; i < euler_angles.size(); ++i) { |
每处理一个数据点,程序就将加速度和角速度(这里简化为速度和欧拉角)通过 preintegrated 进行预积分,从而更新当前的设备状态。
总结
这段代码实现了基于 IMU数据 和 图优化 的 状态估计。具体来说,它从CSV文件中读取设备的IMU数据(加速度、角速度、位置、速度等),并通过 预积分 和 图优化 技术来计算设备的最优状态(位置、速度和偏置)。优化过程使用 Levenberg-Marquardt算法 来最小化因子图中的误差,从而得到更精确的估计结果。
最终,优化后的结果被保存到文件中,供后续分析使用。
Reference:
因子图优化及GTSAM中IMU预积分接口
VINS-Mono+Fusion源码解析系列(八):IMU预积分的代码实现








