0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

RT-Thread 互补滤波器 (STM32 + 6 轴 IMU)

RTThread物联网操作系统 来源:未知 2023-07-11 20:20 次阅读
作者:wuhanstudio 原文链接:https://zhuanlan.zhihu.com/p/611568999最近在看无人驾驶的 Prediction 部分,可以利用EKF (Extended Kalman Filter)融合不同传感器的数据,例如 IMU, Lidar 和 GNSS,从而给出更加准确的状态预测。刚好手边开发板有一个 6 轴的 IMU,本来打算试一下卡尔曼滤波器 (Kalman Filter),然而 Kalman Filter 更适合 9 轴的传感器,也就是在 6 轴的基础上(3-axis Accel + 3-axis Gyro)融合 3 轴的磁力计。对于一个只有 6 轴 IMU 的 MCU,轻量级的互补滤波器 (Complementary Filter)更加合适,利用 3 轴陀螺仪和 3 轴加速度计来估计开发板的姿态 (Pitch, Roll, Yaw)。

大致流程:首先用 RT-Thread 的 icm20608 软件包读取 陀螺仪 (Gyroscope) 和 加速度计 (Accelerometer) 的数据,分别计算出估计的角度,再用互补滤波器 (Complementary Filter) 融合两个角度估计、进行校正,其实核心算法的代码就 7 行。最后串口把数据发到电脑上,用 Python + OpenGL 可视化。

Github - STM32 IMU 互补滤波器 (RT-Thread):https://github.com/wuhanstudio/stm32-imu-filter

IMU 传感器 (Inertial Measurement Unit)

我们先介绍下从 I2C 总线读取出传感器原始数值后,如何处理得到加速度和旋转角速度。一个六轴的 IMU 可以测量 x, y, z 三个方向的重力加速度,和绕三个轴的旋转角速度。比如,开发板如果静止放置在桌面上,会测量到 z 方向的重力加速度。

a0b23718-1fe4-11ee-962d-dac502259ad0.png

三个轴的加速度

当然,如果开发板静止不动,绕三个轴的旋转速度都是 0。

a0caa618-1fe4-11ee-962d-dac502259ad0.png

三个轴的旋转角速度

由于传感器的输出实际上是来自 ADC 的 16 位数字信号,我们需要把它的单位转换成重力加速度 g。例如,我们可以选择测量范围

a0f4ea4a-1fe4-11ee-962d-dac502259ad0.png

,默认是

a10d4112-1fe4-11ee-962d-dac502259ad0.png

也就是把传感器的 16 位输出

a12c7dca-1fe4-11ee-962d-dac502259ad0.png

映射到 [-2g, 2g),于是

a1435c34-1fe4-11ee-962d-dac502259ad0.png

也就是下面 icm20608 芯片手册的 Sensitivity Scale Factor。

a1591268-1fe4-11ee-962d-dac502259ad0.jpg

于是在代码里面,将原始的 int16 加速度数据除以 16384。

double aSensitivity = 16384;

accel_x = accel_x / aSensitivity;
accel_y = accel_y / aSensitivity;
accel_z = accel_z / aSensitivity;

同样,我们可以换算出角速度

a17897fa-1fe4-11ee-962d-dac502259ad0.png

a18eef6e-1fe4-11ee-962d-dac502259ad0.png

于是在代码里面,将原始的 int16 角速度数据除以 131。

double gSensitivity = 131;

gyrX = gyro_x / gSensitivity;
gyrY = gyro_y / gSensitivity;
gyrZ = gyro_z / gSensitivity;

这样我们就把 ADC 输出的 int16 原始数据分布转换成了加速度单位 g,和旋转角速度单位 °/s.

互补滤波器 (Complementary Filter)

我们可以用 互补滤波器 结合 加速度 和 旋转速度 的测量值,得到更准确的姿态预测。

我们使用下面的图中的坐标系,绕 x 轴旋转的角度为 roll,绕 y 轴的旋转方向为 pitch,绕 z 轴旋转方向为 yaw。逆时针旋转为正,顺时针旋转为负。

a1c9396c-1fe4-11ee-962d-dac502259ad0.png

陀螺仪估计姿态

陀螺仪测量的是瞬间的旋转角速度,所以位置的估计其实就是时间的积分。例如,每过 100ms 测量一次旋转速度,旋转速度 x 时间 = 旋转角度。
// angles based on gyro (deg/s)
gx = gx + gyrX * TIME_STEP_MS / 1000;
gy = gy + gyrY * TIME_STEP_MS / 1000;
gz = gz + gyrZ * TIME_STEP_MS / 1000;
当然,由于环境存在大量噪声,陀螺仪测量数据会存在随机的波动,这些噪声经过积分累积,最后会造成位置的漂移。比如下面这张图,过了很长时间后,虽然开发板是静止的,但是右边的陀螺仪估计的位置,就无法回到原点,这就是长时间的累计误差造成的。a1e1d1ca-1fe4-11ee-962d-dac502259ad0.jpg

加速度计估计姿态

加速度计不需要积分,我们可以直接对当前加速度角度求 arctan 得到角度:

a203908a-1fe4-11ee-962d-dac502259ad0.jpg
// angles based on accelerometer
ax = atan2(accelY, accelZ) * 180 / M_PI;                                     // roll
ay = atan2(-accelX, sqrt( pow(accelY, 2) + pow(accelZ, 2))) * 180 / M_PI;    // pitch

不管我们的开发板绕 z 轴旋转多少度,重力加速度始终朝向地面。因此开发板静止状态,我们无法利用重力加速度知道 z 轴的旋转角度 (yaw),所以上面只计算 roll 和 pitch,最终 z 轴的旋转角度 yaw 会出现累计积分误差

互补滤波器

我们需要结合2个测量值是因为:旋转速度短时间内比较准确,但是由于环境的噪声会产生一些随机运动,时间长了就会漂移,而加速度短时间内不一定准确,但是最终会维持稳定。

于是我们就可以取长补短,线性叠加2个测量值的估计,给出更准确的估计。

// complementary filter
gx = gx * 0.96 + ax * 0.04;
gy = gy * 0.96 + ay * 0.04;

短时间内,我们相信陀螺仪测量的旋转角速度 (权值: 0.96);长时间内,环境噪声逐渐造成的漂移,由加速度计慢慢进行矫正 (权值: 0.04)。

总结

最后总结一下,其实核心代码一共就 7 行。我们先利用加速度求解姿态,再利用旋转角速度求解姿态,最后用互补滤波器进行一个线性叠加。

// angles based on gyro (deg/s)
gx = gx + gyrX * TIME_STEP_MS / 1000;
gy = gy + gyrY * TIME_STEP_MS / 1000;
gz = gz + gyrZ * TIME_STEP_MS / 1000;

// angles based on accelerometer
ax = atan2(accelY, accelZ) * 180 / M_PI;                                     // roll
ay = atan2(-accelX, sqrt( pow(accelY, 2) + pow(accelZ, 2))) * 180 / M_PI;    // pitch

// complementary filter
gx = gx * 0.96 + ax * 0.04;
gy = gy * 0.96 + ay * 0.04;

References

  • https://github.com/mattzzw/Arduino-mpu6050

  • https://github.com/RT-Thread-pa




点击阅读原文查看近期赛事


原文标题:RT-Thread 互补滤波器 (STM32 + 6 轴 IMU)

文章出处:【微信公众号:RTThread物联网操作系统】欢迎添加关注!文章转载请注明出处。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • RT-Thread
    +关注

    关注

    31

    文章

    1148

    浏览量

    38877

原文标题:RT-Thread 互补滤波器 (STM32 + 6 轴 IMU)

文章出处:【微信号:RTThread,微信公众号:RTThread物联网操作系统】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    4月25日北京站RT-Thread线下workshop,探索RT-Thread混合部署新模式

    4月25日,下午我们将在北京举办RT-Thread混合部署线下workshop,在瑞芯微RK3568平台上实现同时运行RT-Thread和linux,本次workshop邀请到RT-Thread资深
    的头像 发表于 04-16 08:35 89次阅读
    4月25日北京站<b class='flag-5'>RT-Thread</b>线下workshop,探索<b class='flag-5'>RT-Thread</b>混合部署新模式

    RT-thread源码移植到STM32F10x和STM32F4xx

    RT-thread源码移植到STM32F10x和STM32F4xx: 一、源码下载 点击入门->下载   在历史版本里边随便选取一个   会进入百度云盘的下载地址,里边有全部版本的源码。这里下载
    的头像 发表于 11-15 09:38 1018次阅读
    <b class='flag-5'>RT-thread</b>源码移植到<b class='flag-5'>STM32</b>F10x和<b class='flag-5'>STM32</b>F4xx

    基于rt-thread的socket通信设计

    最近再研究 rt-thread 的通信 ,想设计出 eps8266(多个) rt-thread(作为中控) 服务器的通信框架,使用的开发板是 潘多拉
    的头像 发表于 10-13 15:02 692次阅读
    基于<b class='flag-5'>rt-thread</b>的socket通信设计

    rt-thread studio新建stm32f407工程

    rt-thread studio新建stm32f407工程,使用的版本是:2.2.6,stm32f4的支持包版本为0.2.2。先不用0.2.3,因为使用0.2.3建立的模板编译会报错。
    的头像 发表于 10-12 17:42 680次阅读

    RT-Thread使用Soft RTC(软件模拟RTC)

    开发环境:野火的stm32f407,rt-thread studio版本是版本: 2.2.6,rt-thread 使用版本为4.0.3,stm32f4的资源包为0.2.2。
    的头像 发表于 10-12 17:39 353次阅读
    <b class='flag-5'>RT-Thread</b>使用Soft RTC(软件模拟RTC)

    RT-Thread在Lan8720a和 lwip基础上移植ntp流程

    开发环境:野火的stm32f407,rt-thread studio版本是版本: 2.2.6,stm32f4的资源包为0.2.2。以RT-Thread中Lan8720和lwip协议栈的
    的头像 发表于 10-12 16:59 873次阅读
    <b class='flag-5'>RT-Thread</b>在Lan8720a和 lwip基础上移植ntp流程

    RT-Thread移植使用webserver (lwip+httpd)

    开发环境:野火的stm32f407,rt-thread studio版本是版本: 2.2.6,stm32f4的资源包为0.2.2,rt-thread版本为4.0.3。
    的头像 发表于 10-12 12:49 560次阅读
    <b class='flag-5'>RT-Thread</b>移植使用webserver (lwip+httpd)

    试用RT-Thread Studio(VSCode)

    想尝试RT-Thread studio (VSCode),先下载安装VSCode,再搜索RT-Thread
    的头像 发表于 10-12 10:58 572次阅读
    试用<b class='flag-5'>RT-Thread</b> Studio(VSCode)

    RT-Thread中Agile Modbus软件包的使用方法

    开发环境:野火的stm32f407,rt-thread studio版本是版本: 2.2.6,stm32f4的资源包为0.2.2,Agile Modbus软件包版本为v1.1.2。工程使用上一篇
    的头像 发表于 10-11 15:37 654次阅读
    <b class='flag-5'>RT-Thread</b>中Agile Modbus软件包的使用方法

    RT-Thread使用cjson软件包发送64位长整型数据

    开发环境:野火的stm32f407,rt-thread studio版本是版本: 2.2.6,stm32f4的资源包为0.2.2,rt-thread版本为4.1.1,cjson软件包使
    的头像 发表于 10-11 15:09 401次阅读
    <b class='flag-5'>RT-Thread</b>使用cjson软件包发送64位长整型数据

    RT-Thread v5.0.2 发布

    RT-Thread 代码仓库地址: ●  https://github.com/RT-Thread/rt-thread RT-Thread 5.0.2 版本发布日志详情: ●  htt
    的头像 发表于 10-10 18:45 780次阅读
    <b class='flag-5'>RT-Thread</b> v5.0.2 发布

    新书上架|嵌入式系统原理及应用——基于STM32RT-Thread

    教程书籍编撰过程中的第一选择! 本次上新的书籍为胡永涛主编的《嵌入式系统原理及应用——基于STM32RT-Thread》。 本书以意法半导体(ST)的STM32L431系列微控制器为硬件核心,采用
    的头像 发表于 09-25 18:25 542次阅读
    新书上架|嵌入式系统原理及应用——基于<b class='flag-5'>STM32</b>和<b class='flag-5'>RT-Thread</b>

    教你手上没有开发板如何跑RT-THREAD STM32应用?

    首先打开 RT-Thread Studio,新建RT-Thread
    的头像 发表于 07-18 16:09 1052次阅读
    教你手上没有开发板如何跑<b class='flag-5'>RT-THREAD</b> <b class='flag-5'>STM32</b>应用?

    STM32L4 RT-Thread Studio解决lptimer不工作的问题

    使用RT-Thread Studio 生成的基于STM32L4 的工程,发现开启PM框架后,lptimer不能工作。
    的头像 发表于 06-07 14:29 670次阅读
    <b class='flag-5'>STM32</b>L4 <b class='flag-5'>RT-Thread</b> Studio解决lptimer不工作的问题

    基于RT-Thread Studio学习

    前期准备:从官网下载 RT-Thread Studio,弄个账号登陆,开启rt-thread学习之旅。
    的头像 发表于 05-15 11:00 2580次阅读
    基于<b class='flag-5'>RT-Thread</b> Studio学习