22.IMU和里程计融合

1. 概述

实际使用中会出现轮子打滑和累计误差的情况,这里单单使用编码器得到里程计会出现一定的偏差,虽然激光雷达会纠正,但一个准确的里程对这个系统还是较为重要

2. IMU数据获取

IMU即为 惯性测量单元,一般包含了三个单轴的加速度计和三个单轴的陀螺仪,简单理解通过加速度二次积分就可以得到位移信息、通过角速度积分就可以得到三个角度,实时要比这个复杂许多

2.1 PIBOT IMU

PIBOT在嵌入式程序提供出原始的数据接口,通过配置可以输出原始raw_imu topic
raw_imu
topic类型为自定义具体如下,即为三轴加速度三轴陀螺仪和三轴磁力计的原始数据
raw_imu
raw_imu

通过对原始数据处理得到一个/imu/data_raw数据类型为sensor_msgs/Imu

通过ROS提供的相关包imu_tools进行滤波
可以看到complementary_filter_gain_node会订阅该topic,即该topic作为输入滤波得到最终数据(发布/imu/data topic 类型同样为sensor_msgs/Imu)

输出该topic可以看到得到的值波动已经较小了,且静止的时候接近于0
/imu/data

3. 两种融合的方法

3.1 一种简单的方法

从imu得到的数据为一个相对角度(主要使用yawrollpitch 后面不会使用到),使用该角度来替代由编码器计算得到的角度。
这个方法较为简单,出现打滑时候因yaw不会受到影响,即使你抬起机器人转动一定的角度,得到的里程也能正确反映出来

3.2 扩展的卡尔曼滤波

官方提供了个扩展的卡尔曼滤波的包robot_pose_ekf,robot_pose_ekf开启扩展卡尔曼滤波器生成机器人姿态,支持

  • odom(编码器)
  • imu_data(IMU)
  • vo(视觉里程计)
    还可以支持GPS
    引用官方图片

    PR2从实际初始点(绿色)溜达一圈回到初始点(绿色),编码器的里程(蓝色)发生了漂移,而使用robot_pose_ekf融合出来的里程(红色)则跟实际位置基本重合(后面我们会针对这个测试下效果)

中间的圆是小圆放大的展示效果

再回去看下该包的输出

  • 发布一个topic, 类型需要注意下是PoseWithCovarianceStamped并非Odometry
    后面会用到这个作为显示,所以还需要一个转换

    查看该topic信息可以看到odom_ekf订阅了该topic
    再次查看该节点信息可以看到
    ,他会发出一个Odometrytopic

  • 发出一个tf

robot_pose_ekf配置时,做了些映射处理,这样可以保证导航层在使用和不用imu的时候无需修改就可以工作

bringup.lauch或者bringup_with_imu.launch 输出的tf都为odom → base_footprint ;发出的里程也都是odom
bringup_with_imu.launch轮子的里程topic 映射为wheel_odom

这里很重要,后面的对该包的验证会使用到

下2张图展示了未使用IMU和使用IMU时候的tf tree情况, 可以看到用了一致的frame
no imu
use imu

  • 36
    点赞
  • 483
    收藏
    觉得还不错? 一键收藏
  • 18
    评论
在Matlab中进行IMU里程数据融合通常涉及以下步骤: 1. 数据预处理:首先,你需要对IMU传感器数据进行预处理,包括去除噪声、校准传感器偏差和误差等。这可以通过使用滤波器(例如卡尔曼滤波器)和传感器校准算法来实现。 2. 姿态估:使用预处理的IMU数据来估车辆的姿态(如欧拉角或四元数)。常用的方法包括互补滤波器、扩展卡尔曼滤波器等。 3. 运动集成:通过对估的姿态进行运动集成,可以得到车辆的位移和速度信息。这可以通过积分加速度数据来算。 4. 修正和校正:使用其他传感器(如GPS、激光雷达等)来修正和校正IMU数据的误差。这通常涉及到姿态对齐、位置校正等步骤。 以下是一个简单示例,展示了如何使用卡尔曼滤波器进行IMU里程数据融合: ```matlab % 初始化卡尔曼滤波器参数 dt = 0.01; % 采样时间间隔 A = [1 dt; 0 1]; % 状态转移矩阵 B = [dt^2/2; dt]; % 输入矩阵 C = [1 0]; % 观测矩阵 Q = eye(2); % 状态噪声协方差矩阵 R = 1; % 观测噪声协方差 % 初始化状态向量和协方差矩阵 x = [0; 0]; % 初始状态向量 P = eye(2); % 初始协方差矩阵 % 读取IMU数据(加速度和陀螺仪) % 加速度数据存储在accel_data变量中 % 陀螺仪数据存储在gyro_data变量中 % 数据融合 for i = 1:length(accel_data) % 预测步骤 x = A * x + B * accel_data(i); P = A * P * A' + Q; % 更新步骤 K = P * C' / (C * P * C' + R); x = x + K * (gyro_data(i) - C * x); P = (eye(2) - K * C) * P; % 存储融合后的数据(位置和速度) position(i) = x(1); velocity(i) = x(2); end % 可视化结果 t = dt * (1:length(accel_data)); figure; subplot(2,1,1); plot(t, position); xlabel('Time'); ylabel('Position'); subplot(2,1,2); plot(t, velocity); xlabel('Time'); ylabel('Velocity'); ``` 这只是一个简单的示例,实际的IMU里程数据融合可能需要更复杂的算法和步骤。你可以根据你的应用需求对代码进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值