Google Cardboard的九轴融合算法——基于李群的扩展卡尔曼滤波
Google Cardboard的九轴融合算法
——基于李群的扩展卡尔曼滤波
极品巧克力
前言
九轴融合算法是指通过融合IMU中的加速度计(三轴)、陀螺仪(三轴)、磁场计(三轴),来获取物体姿态的方法。它是开发VR头显中的一个至关重要的部分。VR头显必须要实时准确地获取用户头部的姿态,然后在屏幕上渲染出在对应的姿态所应该要看到的画面,才能让用户在VR世界里获得沉浸感。
因为人眼是非常精密的器官,如果渲染出来的画面稍微有一点点的延时或者偏差,人眼都能察觉出来,导致用户头晕想吐,再也不相信VR了。所以,VR头显对九轴融合算法的实时性和精度提出了非常高的要求。
而另一方面,公开的九轴融合方法又少之又少,常见的就是互补滤波算法和Madgwick算法,但是这两个方法的精度都不能达到VR头显的要求。而精度高的九轴融合算法都掌握在一些算法公司手里,需要向他们支付高昂的算法使用费,源码的价格更是天价。

Cardboard是谷歌在2014年发布的VR盒子,虽然它不是开源的,但是在GitHub上有很多Cardboard的反编译工程,比如https://github.com/rsanchezsaez/cardboard-java。Cardboard的VR体验,可以在一定程度上,证明它的九轴融合算法是满足VR要求的。所以,我对Cardboard反编译工程中的九轴融合部分的程序进行了研读,这部分的程序大概有5000行左右。我在通读完程序之后,结合文献[1],把程序背后的算法理论公式全部都反推出来,总结成了本文,与各位分享。
虽然早在2014年,Cardboard就已经在GitHub上被反编译了,但是这么多年过去了,有关它的代码原理分析的文章却是几乎没有。能结合源代码,把它背后的算法理论基础详细推导出来的,本文应该算是第一篇。如有推导错误的地方,还请各位不吝赐教。
本文目标读者:传感器融合算法工程师。
一.预测
基于陀螺仪积分来预测出下一个姿态。
假设在
时刻的状态的SO3形式
的概率
满足高斯分布,



其中
为归一化常数。为方便起见,把满足上面条件的
表示成,
。
在
时刻,陀螺仪的测量值为
,如果没有噪声的话,则对下一个时刻
的状态均值的预测
为,

其中,
为时刻
到时刻
的时间间隔,
。
而如果考虑噪声的影响的话,则对时刻
的预测的状态分布
要满足,

其中,
表示陀螺仪数据的噪声,协方差
可以通过采集一段时间的数据
,计算得到
。

所以,新的均值
附近的扰动
要满足这样的分布,

又因为有SO3上的性质,
,所以,上式中的
。所以,原式可以转换如下,

这时候,又因为有SO3上的伴随性质,

原式就可以转换为,

所以,就可以得到,

所以,新的扰动
的均值
,

新的扰动
的协方差,
,

所以,最终得到,

二.更新
设在世界坐标系下,加速度计所测的重力向量为
,磁场计所测的磁场向量为
。则在时刻
时,加速度计所测的重力向量为
,磁场计所测的磁场向量为
。加速度计上面的测量噪声
满足
。磁场计上面的测量噪声
。
2.1加速度计测量更新
把第一部分预测出来的姿态
,作为预测的测量姿态,可以预测出当前加速度计的测量值
,其计算过程如下,

而根据实际测量值
,可以反过来计算出姿态
,作为实际的测量姿态。以之前的预测姿态
为初值,则把两者的关系表示为,

可以把
优化出来,或者直接叉乘出来。

根据李代数与向量叉乘的转换关系。不考虑测量噪声
,则可以得到
的均值
。

设
上的噪声为
,则关系满足如下,

进一步得到,

要获得
与
之间的关系,

这两者间的关系不是线性化的,那么就只能进行线性化,一阶泰勒展开,

其中,
的计算,采用数值扰动的方法。
从而,可以得到
。

最终得到,
的分布,

再进行转换,用跟第一部分同样的方法,转换出扰动
。


用
来表示。


所以,根据第一部分,可以得到
,现在又得到了
。综合这两者的信息,可以得到,
。就是要求一个
,使得
最大,用公式表达如下。

其中,
是个未知数,用
,转换成用未知数
来表示。然后,上式就可以转换为,

但这样子也解不出来。对上式中的部分,在
处进行线性化,一阶泰勒展开。则可以转换为,

其中,
的计算,程序里面是用数值扰动的方法。这里应该也可以用解析的方法,把公式都展开来推导。
接下来,为了转换成卡尔曼滤波的形式,用
来表示。
所以,原式就可以表示为,

参考《State Estimation for Robotics》的3.1.2和3.3.2,求
,则上式最终可以转换出卡尔曼滤波的形式了。

所以,

同时,

则融合后的姿态的均值
为,

设相对于姿态
的李代数扰动
。则
与
的关系要满足,

所以,得到扰动
的均值
,

得到扰动
的协方差
,

所以,
的分布满足,

2.2公式总结
2.1中的公式总结出来就是,

上面的方法跟《State Estimation for Robotics》的7.3.4和8.2.4很像,但是上面的方法,对协方差的处理更加精细。
要融合磁场计,也是同样的方法。
要融合视觉SLAM中送过来的姿态,也是同样的方法。
3.实际程序
在cardboard的实际程序中,还有很多细节的处理。比如,
增加了很多加权滤波的方法。
把加速度计的模的变化滤波出来,实时更新加速度计的协方差。这一步,相当于是madgwick里面的动态调整权重,但这一步更好,因为是直接算加速度计的协方差来调整权重,而不是通过陀螺仪的测量值来间接表示运动过快而调整权重。
在静止的时候,把陀螺仪的偏移滤波出来。
还有时间差平滑滤波的方法。
在融合磁场计的时候,把磁场计向量映射到水平面上,相当于只优化水平面上的旋转偏差。这个,在空间想象时,应该保持重力竖直方向(0,0,1)不变,以此作为参考,再看原来的模型,就容易理解了。

但是没有对磁场计进行修正。如果要对磁场计进行修正,简单的方法可以参考madgwick里面的方法。全面的方法,则要参考那些专门搞磁场计标定的论文了。
4.总结
Cardboard里面的九轴融合算法,效果比Madgwick方法和互补滤波方法都要好,对细节的处理也非常棒。以后再写一篇文章,详细比较基于李群的扩展卡尔曼滤波方法,Madgwick算法,互补滤波的异同。
根据参考文献[1],这套理论也同样可以使用在六自由度(位移+旋转)融合上面,只需要把SO3改成SE3就可以了。可以用同一套理论,把视觉SLAM的位姿与IMU位姿融合在一起,得到融合后的六自由度数据,应用在VR头显中。
希望有一天,VR头显的体验能做到像电影《头号玩家》里面那样。与仍然还在做VR的各位同行共勉。

5.求赞赏
您觉得,本文值多少?

6.有奖问答
给各位出一道思考题。
已知,一个IMU水平地放在桌面上不动。重力大小为
。陀螺仪和加速度计以相同的频率同时输出,输出的时间间隔为
。它的初始状态为
。陀螺仪数据的噪声为
,加速度计数据的噪声为
。

其中,
,
,
都为对角矩阵。则随着时间的增长,请问,
(1)这个IMU的后验状态协方差是否会收敛?
(2)如果收敛的话,会收敛到什么值?
请在下面评论区作答。第一名正确回答的,将可以获得哈士企公仔一只。

7.参考文献
- Bourmaud G, Megret R, Giremus A, et al. Discrete Extended Kalman Filter on Lie groups[C]// Signal Processing Conference. EURASIP, 2013:1-5.
- Timothy D. Barfoot. State Estimation for Robotics [M].Cambridge University Press, 2017.
Google Cardboard的九轴融合算法——基于李群的扩展卡尔曼滤波的更多相关文章
- [stm32] MPU6050 HMC5883 Kalman 融合算法移植
一.卡尔曼滤波九轴融合算法stm32尝试 1.Kalman滤波文件[.h已经封装为结构体] /* Copyright (C) 2012 Kristian Lauszus, TKJ Electronic ...
- SLAM+语音机器人DIY系列:(三)感知与大脑——2.带自校准九轴数据融合IMU惯性传感器
摘要 在我的想象中机器人首先应该能自由的走来走去,然后应该能流利的与主人对话.朝着这个理想,我准备设计一个能自由行走,并且可以与人语音对话的机器人.实现的关键是让机器人能通过传感器感知周围环境,并通过 ...
- 基于均值坐标(Mean-Value Coordinates)的图像融合算法的具体实现
目录 1. 概述 2. 实现 2.1. 准备 2.2. 核心 2.2.1. 均值坐标(Mean-Value Coordinates) 2.2.2. ROI边界栅格化 2.2.3. 核心实现 2.2.4 ...
- 基于均值坐标(Mean-Value Coordinates)的图像融合算法的优化实现
目录 1. 概述 2. 实现 2.1. 原理 2.2. 核心代码 2.3. 第二种优化 3. 结果 1. 概述 我在之前的文章<基于均值坐标(Mean-Value Coordinates)的图像 ...
- 九大排序算法Java实现
之前学习数据结构与算法时花了三天时间整理九大排序算法,并采用Java语言来实现,今天第一次写博客,刚好可以把这些东西从总结的文档中拿出来与大家分享一下,同时作为自己以后的备忘录. 1.排序算法时间复杂 ...
- Beaglebone Black – 连接 GY-91 MPU9250+BMP280 九轴传感器(2)
这次用 SPI.BBB 有两套 SPI 接口可用,两套都是默认 disable,需要用 overlay 方式启用,即: echo BB-SPIDEV0 > /sys/devices/bone_c ...
- [python] A*算法基于栅格地图的全局路径规划
# 所有节点的g值并没有初始化为无穷大 # 当两个子节点的f值一样时,程序选择最先搜索到的一个作为父节点加入closed # 对相同数值的不同对待,导致不同版本的A*算法找到等长的不同路径 # 最后c ...
- Beaglebone Black – 连接 GY-91 MPU9250+BMP280 九轴传感器(1)
本篇内容为,通过 I2C 配置 GY-91 MPU9250+BMP280 里面的 MPU9250 连接 AK8963 磁感应.两个办法,1)MPU9250 设置 Master Mode 通过 AUX ...
- 【Cardboard】 体验 - Google Cardboard DIY及完成后简单体验
体验 - Google Cardboard DIY及完成后简单体验 今年的Google I/O最让我感兴趣的除了Material Design以外就是这个Google Cardboard了.据说是Go ...
随机推荐
- Android Service 基础
启动方式 startService(Intent) 这种方式启动的Service可以在后台无限期的运行,与启动它的组件没有关系. bindService 绑定Service.它提供了一种类似C/S结构 ...
- 关于换了手机后,导致原来连的fiddler抓不到新手机上的包的解决方法
原来我们测试都是一台安卓机,一台ios机,由于机子不够,所以安卓机都是自己的手机,可以连内网,也可以连外网 但是最近这几天,不知道公司抽了什么风.把网都给限制了,只有公司的测试机,才能连内网测,结果我 ...
- python提示import XX 不存在,如何排查错误
1.如何确定文件夹是一个包, 检查包中是否有__init__.py 文件, 在python模块的每一个包中,都有一个__init__.py文件(这个文件定义了包的属性和方法)然后是一些模块文件和子目录 ...
- python IDLE中反斜杠显示为人民币符号¥的解决办法
改换英文字体即可
- VS2017调试器无法附加到IIS进程(w3wp.exe)
问题描述: 当使用VS2017-> 调试->附加到进程来调试IIS进程(w3wp.exe)时,报错"无法附加到进程,已附加了一个调试器" 为了解决这个问题花了不少时间, ...
- C语言第一次博客作业——输入输出格式
一.PTA实验作业 注意:本次PTA实验共有8个题目,在博客上只要贴:4个题目就可以,分别为: 题目1:7-3 温度转换 (1分) 题目2:7-4 将x的平方赋值给y (2分) 题目3:7-6 是不是 ...
- Beta No.1
一.今日任务 重新熟悉整体项目 对整个项目在未来的beta冲刺中进程有一个合理的规划 由于我们送出的是一个负责前端的成员,引入的也是一个负责前端工作的女生,(女生做起美工比起男生更加得心应手吧)所以我 ...
- 软件工程结对编程-2017282110264&2017282110249
0 小组成员 李世钰 / 2017202110264 王成科 / 2017282110249 1 项目 GitHub 地址 && 演示地址 GitHub: https://github ...
- transient 与 volatile 笔记
1. transient 词义:瞬间的,短暂的 首先说说"序列化",把一个对象的表示转化为字节流的过程称为串行化(也称为序列化,serialization),从字节流中把对象重建出 ...
- 使用 PuTTY 从 Windows 连接到 Linux 实例
启动您的实例之后,您可以连接到该实例,然后像使用您面前的计算机一样来使用它. Note 启动实例后,需要几分钟准备好实例,以便您能连接到实例.检查您的实例是否通过了状态检查 - 您可以在 Instan ...