直立平衡车的姿态测量卡尔曼滤波算法原理与应用(附代码及调试截图)

2023-05-16

        鄙人最近测量调试直立平衡车的姿态角度时,用到了卡尔曼滤波算法。本着知其然还需知其所以然的学习精神,在网上阅览了很多关于滤波原理及算法应用的文章,加上自己的调试经验,有了一点小小的心得,现在分享给大家。疑惑不当之处,欢迎讨论批评。首发于CSDN:http://blog.csdn.net/qq_32666555。转载请注明作者及出处,谢谢!


        首先介绍我的方案背景。我用了惯性测量组合元件(Inertial Measurement Uint,IMU),两轴ENC-03MB陀螺仪及两轴MMA7361加速度计,其中一轴陀螺仪应用在方向测量上,所以不在讨论范围内,测量零点等拓展内容也不在本次讨论范围内。而另一轴陀螺仪测得的角速度作为卡尔曼滤波函数的一个输入变量,两轴加速度计测得的角度之差乘上角度量比例作为卡尔曼滤波函数的另一输入变量。


        下面,我们以“是什么,为何用,怎么用”的顺序来介绍直立平衡车的姿态测量滤波算法原理与应用。因此,先介绍滤波算法的原理。在介绍卡尔曼滤波之前,我们可以先以互补滤波作为敲门石。而介绍互补滤波,就不得不提大名鼎鼎的MIT经典PPT《The Balance Filter》。鄙人亲自翻译了这个牛文,在此附上链接:

        《The Balance Filter》互补滤波器--MIT著名牛文翻译(上)

        《The Balance Filter》互补滤波器--MIT著名牛文翻译(下)

        简单浏览这篇文章,在初步了解了两种传感器工作原理、权重分配、误差漂移、互补滤波等后,我们理解卡尔曼滤波会简单些。


        卡尔曼滤波,于我理解,是只需要k-1时刻两参数的协方差估算出k时刻最优解,并算出k时刻协方差进行递归,算出k+1,k+2…时刻的最优解。因此它是个快速而智慧的算法。知乎上有很多通俗科学的解释,我贴出一个问题链接,里面那些高赞同回答个人觉得都不错:https://www.zhihu.com/question/23971601


        那为何用卡尔曼滤波算法呢?

        首先解释为什么用2种传感器。陀螺仪具精确但有零点漂移特性,其测量误差会随着时间的累加而不断的累积,从而影响测量精度。因此,短时间测量应信任陀螺仪。加速度计一直受到平衡车振动的影响,混叠额外的高频振动量干扰,但是漂移小。因此,长时间测量应信任加速度计。所以单一的传感器测量难以得到精确的姿态角度。需采用多传感器信号融合的方法,来获得准确的姿态角度量。

        而卡尔曼滤波,可以设置分配信任权重,解决陀螺仪零漂、滤除加速度计高频振动,递归自学习,滤波平滑、跟随快。虽然算法较复杂,占用较多线程时间,但是我们选用的freescale K60处理器完全可以承担这样的计算,所以决定使用该滤波算法。



最后,就是卡尔曼滤波算法的应用了。Show you the code.

float Kal_Gyro;
float gyro;
int16_t mmax, mmaz;
float angle, angleSpeed;
float Angle_Kalman;
int16_t Pre_Angle_Kalman;
float angleSpeedIntegral;

float Q_bias, Angle_err;
float PCt_0, PCt_1, E;
float K_0, K_1, t_0, t_1;
float Pdot[4] ={0,0,0,0};
float PP[2][2] = { { 1, 0 },{ 0, 1 } };

/**
 * @brief  卡尔曼滤波, 输入带有噪声的参数组, 返回可靠的参数组, 此处用于获得变化较稳定的角度值
 * @param[in]  Accel 由加速度计得到的角度参量
 * \param[in]  Gyro 由陀螺仪得到的角速度参量
 * @retval 稳定可靠的角度值, 用于直立控制
 */

static float KalmanFilter(float Accel,float Gyro)		
{
    static float Angle = 0, Gyro_y = 0;
	Angle+=(Gyro - Q_bias) * dt; //先验估计

	Pdot[0]=Q_angle - PP[0][1] - PP[1][0]; // Pk-先验估计误差协方差的微分

	Pdot[1] = -PP[1][1];
	Pdot[2] = -PP[1][1];
	Pdot[3]= Q_gyro;
	
	PP[0][0] += Pdot[0] * dt;   // Pk-先验估计误差协方差微分的积分
	PP[0][1] += Pdot[1] * dt;   // =先验估计误差协方差
	PP[1][0] += Pdot[2] * dt;
	PP[1][1] += Pdot[3] * dt;
		
	Angle_err = Accel - Angle;	//zk-先验估计
	
	PCt_0 = C_0 * PP[0][0];
	PCt_1 = C_0 * PP[1][0];
	
	E = R_angle + C_0 * PCt_0;
	
	K_0 = PCt_0 / E;
	K_1 = PCt_1 / E;
	
	t_0 = PCt_0;
	t_1 = C_0 * PP[0][1];

	PP[0][0] -= K_0 * t_0;		 //后验估计误差协方差
	PP[0][1] -= K_0 * t_1;
	PP[1][0] -= K_1 * t_0;
	PP[1][1] -= K_1 * t_1;
		
	Angle	+= K_0 * Angle_err;	 //后验估计
	Q_bias	+= K_1 * Angle_err;	 //后验估计
	Gyro_y   = Gyro - Q_bias;	 //输出值(后验估计)的微分=角速度
	return Angle;
}


因为我是按The balance filter里的坐标系修改的,所以

@param[in] angle_kal 由加速度计得到的角度参量,是两轴加速度计测得的角度之差乘上角度量比例再乘初始所占权重;

\param[in] angle_speed_kal 由陀螺仪得到的角速度参量,是陀螺仪测得的角速度的相反值;

@retval 稳定可靠的角度值, 用于直立控制,是送入角度调节中的当前量。


而卡尔曼滤波的5个方程 

X(k|k-1)=A X(k-1|k-1)+B U(k) ………(1)//先验估计
P(k|k-1)=A P(k-1|k-1) A’+Q ………(2)//协方差矩阵的预测
Kg(k)= P(k|k-1) H’ / (HP(k|k-1) H’ + R) ………(3)//计算卡尔曼增益
X(k|k)= X(k|k-1)+Kg(k) (Z(k) - H X(k|k-1)) ………(4)//通过卡尔曼增益进行修正
P(k|k)=(I-Kg(k) H)P(k|k-1) ………(5)//更新协方差阵


(1)根据角度微分等于时间的微分乘以角速度,k时刻角度可近似认为是k-1时刻的角度值加上k-1时刻陀螺仪测得的角加速度值乘以时间,同时要减去陀螺仪的静态漂移。

angle_kalman += (angle_speed_kal - Kal_Gyro_Zero) * Kalman_Sample_Time;// Kalman_Sample_Time 是卡尔曼滤波采样时间参量,应调节到使滤波平滑,跟随快滞后少,此处为0.0055.


结合其余定义式,写成矩阵形式


对应卡尔曼滤波第一个方程
X(k|k-1)=A X(k-1|k-1)+B U(k) ………(1)//先验估计



(2)预测方差阵的预测值,噪声就是数据的方差值


#define Q_angle     0.001 //角度噪声
#define Q_gyro      0.0005//漂移噪声



Pdot[0] = Q_angle - Pk[0][1] - Pk[1][0];

Pdot[1] = -Pk[1][1];

Pdot[2] = -Pk[1][1];

Pdot[3] = Q_gyro;

Pk[0][0] += Pdot[0] * Kalman_Sample_Time;

Pk[0][1] += Pdot[1] * Kalman_Sample_Time;

Pk[1][0] += Pdot[2] * Kalman_Sample_Time;

Pk[1][1] += Pdot[3] * Kalman_Sample_Time;

对应卡尔曼滤波第二个方程
P(k|k-1)=A P(k-1|k-1) A’+Q ………(2)//协方差矩阵的预测


(3)计算卡尔曼增益K_0,K_1
#define R_angle     0.05  //角度测量噪声值 


angle_err = angle_kal - angle_kalman;

PCt_0 = C_0 * Pk[0][0];

PCt_1 = C_0 * Pk[1][0];

E = R_angle + C_0 * PCt_0;

K_0 = PCt_0 / E;

K_1 = PCt_1 / E;

对应卡尔曼滤波第三个方程

Kg(k)= P(k|k-1) H’ / (HP(k|k-1) H’ + R) ………(3)//计算卡尔曼增益




(4)对矩阵Pk进行更新
t_0 = PCt_0;

t_1 = C_0 * Pk[0][1];

Pk[0][0] -= K_0 * t_0;

Pk[0][1] -= K_0 * t_1;

Pk[1][0] -= K_1 * t_0;

Pk[1][1] -= K_1 * t_1;

对应卡尔曼滤波第五个方程

P(k|k)=(I-Kg(k) H)P(k|k-1)………(5)//更新协方差阵




(5)通过卡尔曼增益修正当前的角度、陀螺仪零点,算出当前角速度

angle_kalman += K_0 * angle_err;

Kal_Gyro_Zero += K_1 * angle_err;

Kal_Gyro = angle_speed_kal - Kal_Gyro_Zero;


对应卡尔曼滤波第四个方程

X(k|k)= X(k|k-1)+Kg(k) (Z(k) - H X(k|k-1)) ………(4)//通过卡尔曼增益进行修正




最后,附上本人的测试曲线图及实物效果图,谢谢大家!



(2018.1.28更新,上面贴的代码也更新了)

这个是刚能直立时的1.0哈哈,见笑了

这是比赛前一天试车的截图,2.5m/s左右吧。旁边赛道的脚是厦大的同学的。

我们试完车轮到中南大学的大佬,他们最后拿了直立组第一。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

直立平衡车的姿态测量卡尔曼滤波算法原理与应用(附代码及调试截图) 的相关文章

  • 远程 sshd提示:Server unexpectedly closed network connection

    远程sshd提示 xff1a Server unexpectedly closed network connection 重启后服务器效果也一样 xff0c 经过一段时间连接后 xff0c 终于连上远程了 之后新建一个远程连接 xff0c
  • ubuntu如何跑arm程序

    1 首先确定一间配置好arm linux 交叉编译器 xff0c 可以使用arm linux gcc 2 看示例代码hello c include lt stdio h gt int add int a int b int c 61 a 4
  • 事件引入和本质

    前言 继上一篇委托后 xff0c 我们继续来探讨事件 xff0c 因为委托和事件有着不可分割的关系 通过本文 xff0c 相信你会对事件有更深刻的认识和理解 xff0c 不信 xff0c 你看 xff01 概念 用event 关键字使您可以
  • onlstm时间复杂度_CNN-LSTM | 一种融合卫星-雨量站降水数据的时空深度融合模型

    1 xff0c 不同模型的降水融合性能 表2 2001 2005年全国796个气象站不同降水校正模型的RMSE RB MAE和CC 如表2所示 xff0c 将4种模型结果与原TRMM数据进行了定量比较 xff0c RMSE和MAE值越小表明
  • app 后端技术

    app 后端技术 一直以来工作的方向是web server xff0c 对app server没有什么了解 虽然没有接触过移动app开发 xff0c 但对app后端技术还是挺有探索欲望的 xff0c app应用和web应用在前端的用户习惯不
  • GSM Hacking:使用BladeRF、树莓派、YatesBTS搭建便携式GSM基站

    每次看到黑客在网上发布的那些GSM技术相关文章我都十分惊讶 然而在没有Software Defined Radios SDRs 之前 xff0c 玩GSM并不便宜 xff0c 除此之外想要好好玩你得下大功夫 拓展阅读 GSM BTS Hac
  • 开发新产品的三个验证阶段(EVT/DVT/PVT)

    1 EVT Engineering Validation Test 是针对工程原型机的验证 xff0c 对象很可能是一大块开发板 xff0c 或是很多块开发板 xff1b 关键是要有足够时间和样品 通常 xff0c 如果是新平台 xff0c
  • 大麦盒子显示服务器超时,大麦盒子卡顿怎么办?这几个方法可以快速解决

    原标题 xff1a 大麦盒子卡顿怎么办 xff1f 这几个方法可以快速解决 根据研究表明 xff0c 目前家庭当中电视的使用时间依然在缓慢上升 xff0c 很多家庭会选购一款电视盒子 xff0c 让看电视的体验得到提升 xff0c 但网上很
  • 【转载】跨域请求出现preflight request失败的问题的解决

    本文转载自 xff1a https developer aliyun com article 753657 简介 xff1a 问题出现 这两天在项目联调过程中突然前端同学报告出现CORS跨域问题无法访问 刚听到很奇怪 xff0c 因为已经在
  • 什么是FSK制式?什么是DTMF制式?

    目前国内来电显示制式有FSK DTMF xff08 双音频 xff09 两种 xff0c 普通推广的是FSK 来电显示 又称 主叫号码显示 xff08 Calling Identity Delivery xff09 分为两种 xff1a 一
  • 【IntelliJ IDEA】idea显示工具栏

    idea显示工具栏 在view gt 勾选对应按钮即可
  • Windows Server 2016 路由和远程访问

    本次实验是将Windows Server 2016 配置成一个路由器 xff0c 为此网络上的客户端和服务器启用多重协议LAN到LAN xff0c LAN到WAN xff0c 虚拟专用网络和网络地址转换路由服务 使用路由和远程访问需配置下列
  • 如何理解Apache License, Version 2.0(整理)

    如何理解Apache License Version 2 0 xff08 整理 xff09 问题 xff1a 最近看到apache发布了2 0版本的License 而且微软也以此发布了部分源代码 我对OpenSource不是特熟 xff0c
  • 网页视频流m3u8/ts视频下载

    现在很多视频网站播放流视频 xff0c 都不是采用mp4 xff0f flv文件直接播放 xff0c 而是采用m3u8 ts这种方式播放 简单说就是 xff0c 网站后台把视频切片成成百上千个xx ts文件 xff0c 一般10秒一个 xf
  • Windchill的JSP页面跳转到Ext页面的分析

    今天花了一天时间 xff0c 看了一块代码 xff0c 低效但是不得不看懂 具体内容是这样的 xff1a Windchill中按钮菜单栏嵌入了一个菜单项 xff0c 点击它会触发弹出一个新的浏览器页面 xff0c 相当于弹框 xff0c 让
  • C++类的定义和声明怎么写

    C 43 43 语言可以看成是C语言的扩展和改进 xff0c 相对于C语言 xff0c C 43 43 语言主要是增添了面向对象的特性 类 xff08 Class xff09 则是C 43 43 面向对象编程的实现方式 无论是何种编程语言
  • jmeter-常用性能指标分析

    概述 我们在用jmeter做性能测试的时候 xff0c 有一些关键性的性能指标需要去分析 但是由于开源工具本身的局限性 xff0c 这些指标在工具中的命名极易对我们造成混淆 所以我们需要对这些指标一一进行剖析 指标分析 响应时间 xff1a
  • 讨论76 怎么查一下我机器的内存?AIX环境

    oracle大型数据库系统在AIX unix上的实战详解 讨论76 怎么查一下我机器的内存 xff1f AIX环境 一个读者来信问勒令一个简单问题 xff1a 怎么查一下我机器的内存 xff1f AIX环境 问题 xff0c 我这里借用or
  • 数组

    数据类型 数组名 61 new 数据类型 元素个数或数组长度 数组中最小的索引是 0 xff0c 最大的索引是 数组的长度 1 获得数组的长度 xff0c 提供了一个 length属性 xff0c 在程序中可以通过 数组名 length 的
  • 静态方法不需要有对象,可以使用类名调用

    Public static void printData 表明此类方法为类方法 xff08 静态方法 xff09 静态方法不需要有对象 xff0c 可以使用类名调用 静态方法中不允许访问类的非静态成员 xff0c 包括成员的变量和方法 xf

随机推荐

  • matlab练习程序(曲面拟合)

    这里用到的还是最小二乘方法 xff0c 和上一次这篇文章原理差不多 就是首先构造最小二乘函数 xff0c 然后对每一个系数计算偏导 xff0c 构造矩阵乘法形式 xff0c 最后解方程组 比如有一个二次曲面 xff1a z 61 ax 2
  • 高铁在高速运行时的电力是如何提供的?

    高铁在高速运行时的电力是如何提供的 xff1f 铁路机车是个庞大的家族 xff0c 高铁只是这个大家庭的一个新成员 xff0c 如果要连篇累牍赘述其他车辆 xff0c 恐怕这个答案是写不下的 xff0c 故本文针对高速铁路进行讨论 一 高铁
  • RS232通信协议详解

    通信协议 所谓通信协议是指通信双方的一种约定 约定包括对数据格式 同步方式 传送速度 传送步骤 检纠错方式以及控制字符定义等问题做出统一规定 xff0c 通信双方必须共同遵守 因此 xff0c 也叫做通信控制规程 xff0c 或称传输控制规
  • 学习C/C++的电子书大全

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 在 学习C 43 43 的经典书籍 这篇文章中 xff0c 列出了C C 43 43 的经典书籍 xff1a C 43 43 Primer 第 5 版 中文版 英文版 Ef
  • 做Android开发的你还为找工作迷茫吗?通过直观的年薪来调准你的方向

    最近仍然有不少同学在找工作 xff0c 跳槽 现在跳槽不是一个好时机 可以看到现在的岗位明显减少了 很多公司都在赶今年的项目交付 xff0c 新的项目还没有规划好 xff0c 新一轮的融资也还没有到时间 很多在职的同学都在等到拿到年终奖再跳
  • 协议栈是什么

    1 协议栈是什么 简介 协议栈 xff0c 英语名称为Protocol stack xff0c 又称协议堆叠 xff0c 是计算机网络协议套件的一个具体的软件实现 协议套件中的一个协议通常是只为一个目的而设计的 xff0c 这样可以使得设计
  • 给linux杀杀毒吧

    linux是非常先进的 xff0c 但是没有绝对的安全 所以来杀杀毒吧 xff1a ClamAV是一个在命令行下查毒软件 xff0c 因为它不将杀毒作为主要功能 xff0c 默认只能查出您计算机内的病毒 xff0c 但是无法清除 xff0c
  • 服务器编程的语言,服务器编程语言的配置与CMS系统

    做过 1 服务器编程函数禁用找到 disable functions 61 该选项可以设置哪些服务器编程函数是禁止使用的 服务器编程中有一些函数的风险性还是相当大的 可以直接执行一些CentOS系统级脚本命令 如果允许这些函数执行 当服务器
  • Linux中断与进程切换,结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程...

    64 实验环境 OS Linux cj virtual machine 5 3 0 51 generic 虚拟机 QEMU 内核版本 5 3 4 调式方法 GDB PS xff1a 调试环境安装请看上一篇博客汇编级理解Linux系统调用 f
  • 【FreeRTOS】栈生长方向 portSTACK_GROWTH

    FreeRTOS新建任务时 xTaskCreate 函数有这样一段注释 span class token comment 代码已简化 span span class token comment If the stack grows down
  • 十大畅销【操作系统类】书籍,说说你看过哪本

    鸟哥的Linux 私房菜 深入理解计算机系统 Linux内核设计与实现 UNIX操作系统设计 操作系统是控制其他程序运行 xff0c 管理系统资源并为用户提供操作界面的系统软件的集合 操作系统 xff08 英语 xff1b Operatin
  • HP 阵列卡错误代码

    POST Error Messages The RAID Controller produces diagnostic error messages at reboot Many of these Power On Self Test PO
  • 我的2013 --那些划过生命线的人和事(大二.上)

    那些划过生命线的人和事 大二 上 又一次大清早被红马甲查赶出被窝 xff0c 让哥光着屁股就跑到隔壁宿舍去了 xff0c 真心恨死他们 这是一篇最早写于 2013 11 26 日的日志 xff0c 通过后来不断地增删改 xff0c 来总结
  • git提交到一半关闭时

    一 xff1a 出现问题 最近写东西 xff0c 在提交代码时 xff0c 突然出现一大推文件 忘记加 gitignore文件了 xff0c 导致所有的安装依赖也都上传了 所以 xff0c 点击了关闭按钮 xff0c 当下一次提交时 xff
  • 实录分享 | IBM马达:Kubernetes/Swarm on Mesos

    4月17日 xff0c Mesos爱好者在北京P2联合创业办公社迎来了第四次Mesos User Group约会 xff0c 下面是来自IBM马达的分享实录 作者介绍 xff1a 马达 xff0c IBM 高级软件工程师 xff0c Kub
  • 人工智能技术在呼叫中心的应用

    随着人工智能技术的不断发展 xff0c 研究成果被应用到各行各业 xff0c 今天我们主要分享一下人工智能技术在客户服务方面的应用 智能语音服务方面 xff1a 利用智能语音识别及分析技术 xff0c 在传统IVR基础上 xff0c 实时通
  • delphi开发回忆录——示例源码下载

    今天把最新的源码上传上来 xff0c 给有需要学习的朋友 xff0c 如果有朋友需要调试的话 xff0c 再向我要数据库 下载地址 xff1a http files cnblogs com edrp Demo rar
  • python异常继承树

    BaseException 43 SystemExit 43 KeyboardInterrupt 43
  • apk闪退 ncnn_README.md · benjaminwan/OcrLiteAndroidNcnn - Gitee.com

    ChOcrLiteAndroidOnnxToNcnn Demo APK下载 Gitee下载 https gitee com benjaminwan ocr lite android ncnn releases 介绍 Chineseocr L
  • 直立平衡车的姿态测量卡尔曼滤波算法原理与应用(附代码及调试截图)

    鄙人最近测量调试直立平衡车的姿态角度时 xff0c 用到了卡尔曼滤波算法 本着知其然还需知其所以然的学习精神 xff0c 在网上阅览了很多关于滤波原理及算法应用的文章 xff0c 加上自己的调试经验 xff0c 有了一点小小的心得 xff0