自动驾驶融合定位系列教程四:惯性导航解算

自动驾驶融合定位系列教程四:惯性导航解算

一、概述

惯性导航的解算是一个实现起来非常简单,但是理解起来要费一番功夫的东西,所谓“实现”就是把公式变成代码,所谓“理解”,就是要弄明白几个公式是怎么推导出来的。

鉴于这种情况,我们先把本篇文章的核心思路捋清楚,然后再去搞细节,不然很容易稀里糊涂地陷入繁琐的公式推导当中去,相信各位以前应该都有过这种体会,每一个公式都看得懂,但是连在一起就不知道它为什么要这么干,对于“理解”,“为什么”可比“是什么”要重要的多了。

在这里,“理解”就包含以下三点:

1)做什么:惯性导航解算的目的是什么?

2)怎么做:惯性导航解算的方法是什么?

3)为什么:这个方法是怎么来的?

image

附赠自动驾驶学习资料和量产经验:链接

二、惯性导航解算的目的

目的当然很简单,从IMU原始的角速度(陀螺仪采集)和加速度(加速度计采集)数据得到它的导航结果(位置、速度、姿态)呗。但如果我们深入下去,好像就不是这一句话能回答的了的了,比如导航信息是怎么描述的,位置和速度好说,姿态就显得略微复杂一些,这是一个long story,喝口水慢慢讲。

1.姿态描述

在导航定位领域,描述一个物体的姿态,常用的描述有欧拉角、旋转矩阵、四元数,这三个概念的理解难度逐渐递增。另外,还有一种表示方式,是等效旋转矢量,它主要作为运算过程中的一个工具,而一般不用来对外作为姿态的描述输出。

1.1 欧拉角

1)欧拉角定义

欧拉角是一个非常直观的概念,一般使用中,它包括俯仰角、横滚角、航向角。

a. 俯仰角

俯仰角描述载体“抬头”的角度大小,一般以抬头(向上)为正,低头(向下)为负

image

b. 横滚角

横滚角描述载体“侧身”的角度大小,一般以绕着正前方逆时针旋转为正,顺时针旋转为负。

image

c. 航向角

航向描述载体的朝向,一般以逆时针旋转为正,顺时针旋转为负。(传统组合导航领域与此相反,在此暂时不过多提及,只是让大家看资料时别觉得奇怪就行)

image

2)欧拉角与坐标轴的对应关系

我们常常把一个xyz直角坐标系放在载体上,这样才方便进行数学描述嘛,如果用前后左右上下来对应载体的方向的话,常见的载体坐标系的对应关系有“右(x)-前(y)-上(z)”、“前(x)-右(y)-下(z)”、“前(x)-左(y)-上(z)”,其中前两种更多的在传统组合导航领域使用,而第三种在机器人、自动驾驶领域使用比较多,由于我们的文章是以后者为主要目标的,所以后面所有的推导就直接使用“前(x)-左(y)-上(z)”坐标系。

在这种坐标系下,我们可以看到,俯仰角是绕y轴的顺时针为正,逆时针为负,横滚角绕x轴的逆时针为正,顺时针为负,航向角绕z轴的逆时针为正,顺时针为负。需要注意的是,一般我们习惯的坐标系表示中,都是逆时针为正,顺时针为负,而俯仰角在这里与y轴的对应关系是反的,这是因为欧拉角有明确的物理意义(比如俯仰角抬头为正、低头为负),违反这种物理意义会对使用带来一些障碍,所以一般宁愿去改变与坐标轴的对应关系。当然,也有很多不愿意转变的,也是很常见,所以大家在使用时要擦亮眼睛,接触一个新的系统之前,要记得首先去核实对应关系。

1.2 旋转矩阵

1)旋转矩阵定义

旋转矩阵是一个非常常见的姿态描述和计算手段了,因为它可以很方便地对坐标系中的矢量进行计算。

假设旋转前,载体系(b系)的单位正交基为 (𝑒1,𝑒2,𝑒3) ,旋转后对应的单位正交基为 (𝑒1′,𝑒2′,𝑒3′) ,在世界坐标系(w系,不随载体的旋转而旋转)下有向量 𝑎 ,它在旋转前后两个坐标系中的坐标分别为 [𝑎1,𝑎2,𝑎3]T 和 [𝑎1′,𝑎2′,𝑎3′]T ,那么有

image

2)旋转矩阵性质

旋转矩阵的主要特性是单位正交矩阵,即

image

1.3 四元数

1)四元数定义

对很多接触过导航定位算法的同志们来讲,可能四元数是一个让人头疼的问题了,想把它彻底讲明白,要费很大力气,更何况我自己也不敢说完全把它搞透彻了,曾经尝试过,我记得有一本专门写四元数的书,有好几百页,直接把我劝退,后来退而求其次,觉得从物理意义上大致理解它就行。

先从复数开始讲起,可能更容易理解些。我们知道一个实数,可以对应一个坐标轴上的一个点,姑且写作 𝐴=𝑥 吧,后来又有了复数 𝐴=𝑎+𝑏𝑖 ,发现它不仅可以描述坐标,还可以描述方向了 𝜃=𝑎𝑟𝑐𝑡𝑎𝑛(𝑏𝑎) ,所以这种东西在信号处理里面经常用,这个角度就对应信号的相位。这里可能会自然而然产生一个疑问,我直接用向量描述不也是一样的吗,比如写作 𝐴=(𝑎,𝑏) ,不照样也能得到角度吗?这个问题的核心在于向量不可向复数那样运算,即复数有 𝑖2=−1 的性质,因此两个复数相乘,就有了

image

这种性质让它具有了向量不具有的优势,复数域的直接运算带来的便利性是无可比拟的。

后来,三维空间的运动描述越来越迫切的时候,复数已经不能满足需求,因为它只有一个角度嘛,不是三维的,汉密尔顿想(可自行百度下汉密尔顿与四元数),能不能再加一维来表示呢,比如 𝐴=𝑎+𝑏𝑖+𝑐𝑗,后来发现不行,那就再加一维 𝐴=𝑎+𝑏𝑖+𝑐𝑗+𝑑𝑘 ,发现行了,于是就有了四元数。哈哈,他发明四元数的过程当然没有那么简单,因为这个“再加一维”牵扯到的东西太多太多,也是理解四元数的关键,不是拍一下脑袋这么简单。

为了弄明白这个“再加一维”,我们可以换一个角度来看它,若另 𝐴=𝑎+𝑏𝑖 , 𝐵=𝑐+𝑑𝑖 ,会发现

image

在这里,另 𝑘=𝑖𝑗 ,那上式不就是四元数了嘛

image

因此,从 𝑄=𝐴+𝐵𝑗 可以看出,四元数可以理解为“复数的复数”。

明白了这一点,再回到复数的定义,就可以严格点讲,复数不是在实数上加一维,而是“实数的复数”,看起来好像一句废话,但这样描述是有必要的。更抽象一点,可以总结为,把一类东西(假设类别为X)在复数维度升维,应该写成 𝑋𝑎+𝑋𝑏𝑗 ,而不应该是 𝑋𝑎+𝑏𝑗 (这里的b是一个实数)。当X表示实数时,这两种理解方式并无差异,而当X已经是复数时,两种方式造成的结果就产生了差异。这就是刚才所提到的,为什么汉密尔顿一开始在描述三维空间的角度时,只在复数上加一维( 𝐴=𝑎+𝑏𝑖+𝑐𝑗 )会不行的原因。

由此扩展下去,四元数的复数是八元数,八元数的复数是十六元数,这不是我胡说八道,在数学领域确实是存在的,它们统称为超复数。由于每一次升维,都会损失一个性质(比如四元数没有了乘法交换性,而复数有),且在三维空间领域,四元数已经足够用来描述,因此其他超复数就没有用武之地了,大家也就见不到。

2)四元数性质

四元数的性质很多,我们挑一些后面能用到的说。首先把四元数按照常见的形式写成

image

a. 单位四元数

在姿态表示中,我们所用的四元数都是单位四元数,即

image

b. 共轭四元数与四元数的逆

共轭四元数指的是实部相同,虚部相反的四元数

image

对于单位四元数来讲,它的逆与它的共轭四元数相等

image

c. 四元数乘法

四元数乘法定义为

image

如果你把上面的式子展开,会发现四元数乘法可以表示成矩阵与向量相乘的形式

image

其中

image

image

这是两个很重要的性质,后面的推导中会多次用到

1.4 等效旋转矢量

等效旋转矢量,从物理意义上比较好理解,借用欧拉角的定义,它表示物体绕坐标轴分别按三个欧拉角旋转三次,就可以得到它现在所处的姿态。而等效旋转矢量的定义是,物体绕空间某一个轴旋转一次,就可以达到现在的姿态。二者的区别在于,欧拉角的旋转是绕xyz这样的直角坐标轴的,而等效旋转矢量的所绕的轴可能朝向空间任意一个方向,这个轴取决于载体的姿态。

等效旋转矢量可以用向量 𝜙 ,并用 单位向量𝑢表示它的朝向, 𝜙 表示它的大小,因此有

image

等效旋转矢量的指数形式,是推导中重要的推导过程,因此先在这里给出

image

由于带着无穷项,因此需要化简才能用。由于反对称矩阵具有如下性质

image

因此,指数形式可以化简为

image

1.5 各种表示方式之间的转换

既然各种方式之间是等价的,且实际使用中,各种形式都有可能出现,那么理清它们之间的转换关系就是必要的。不过由于很多推到过程过于复杂且无聊,这里就只能给出结论,对过程感兴趣的自己去查资料吧。

1)欧拉角与旋转矩阵

按照机器人前(x)-左(y)-上(z)的坐标系定义,并令横滚角为 𝛼 、俯仰角为 𝛽 、航向角为 𝛾 ,假设旋转矩阵是按照z-y-x的顺序旋转得来,那么旋转矩阵可以表示为

image

其中

image

2) 四元数与旋转矩阵

image

3)旋转矩阵与等效旋转矢量

image

4) 四元数与等效旋转矢量

image

这个也可以从一个比较奇特的角度来解释,大家看一下,一个四元数和一个矢量相乘(其实乘的是矢量对应的纯虚四元数,即实部为0,虚步三个值对应这个三维矢量),得到的是什么?已经忘记的可以网上翻去看一下四元数乘法。结论是乘出来的一个东西,实部不为0,这就尴尬了,一个三维矢量,乘出来变成了一个四维的东西(一个实部和三个虚部),为了解决这个问题,就写成了上面的形式,左乘一个,右乘一个,实际就是对应两次旋转,自然每次就只旋转一半,即每一个四元数对应的角度只是想要的旋转角度的一半,这样改变之后,惊奇地发现,实部永远为0,等于三维矢量先是被第一个四元数给旋转到四维空间,又被第二个四元数给拉回到三维空间了,完美!

三、惯性导航解算的方法

经过上面啰嗦一大堆,我们解决了“做什么”、“怎么做”、“为什么”三个问题中的第一个,接下来解决第二个。

“怎么做”在这里就是怎么去解算的问题了,而解算就是“角速度->姿态”、“加速度->速度”、“速度->位置”(当然由于有坐标系问题,这种描述并不十分严谨,但更容易理解)。看到这些,我们很容易想到,就是个积分问题嘛,把这个积分过程用数学公式表示出来,就等于知道了“怎么做”的问题。

积分公式的形式其实很简单,但它的推导过程比较繁琐,因此这里先给出结论,过程是“为什么”这个环节要解决的问题。另外,积分与微分本是一家,因此本小节会从微分方程引入,讲“为什么”的时候就只讲微分方程怎么来的就好了,这样这两节就可以无缝衔接在一起。

1.基于旋转矩阵的姿态更新

1) 积分形式介绍

image

可见,求旋转矩阵的问题,最终转化成了求等效旋转矢量的问题。咋求?接着用微分方程求呗。等效旋转矢量的微分方程为(方程怎么来的,同样放在“为什么”中去讲)

image

这个方程看起来还是比较复杂的,可以也应当化简。在方程右边第二项,可以看到是两个矢量的叉乘,根据叉乘的定义,当两个矢量方向重合时,叉乘的结果为0。一般 imu 的采样频率不会低于 100hz,即 k-1 时刻到 k 时刻的时间间隔不会大于10ms,而载体一般自动驾驶车或者机器人也不会发生过于高频的运动,因此可以近似认为满足叉乘为0的条件,因此可以直接把上式简化为

image

它对应的积分形式就很简单了

image

有了旋转矢量的积分形式,那么该旋转矩阵的形式就了然了,直接带进去就行。

但是,到这里会遇到一个问题,我们一直讨论的都是连续时间的,即 k-1 时刻到 k 时刻之间的所有值都是连续可测的,而实际数据都是离散的,只能得到 k-1 和 k 这两个时刻的值,那么必须把上面的连续时间形式高程离散形式,才能继续走下去了。

2)离散时间处理

这就牵扯到常见的三种方法:欧拉法、中值法、龙哥库塔法,三者按复杂程度逐渐递增,按精度也是逐渐递增。我们先从简单的开始说。

a.欧拉法

欧拉法很好理解,虽然我不知道 k-1 到 k 时刻的所有值,但是如果我假设 imu 在这个时间段内是匀速旋转的,那不就解决了吗,此时,对应的旋转矢量为

image

b.中值法

欧拉法固然简单,但是匀速的假设还是有些太强了,实际使用中会发现精度不够,于是就有了中值法。中值法假设 imu 是匀加速运动的,这就比匀速更高级了一些,此时离散时间形式为

image

c.龙哥库塔法

中值法假设的匀加速运动,在imu运动更加剧烈的情况下仍然不够,那就继续把模型复杂化呗,龙哥库塔法就是这种,把运动模型搞成一个高阶曲线。由于这部分略显复杂,而且实际使用中,中值法多数情况下已经够用,因此在此处就不对这种方法做过多介绍了。

2.基于四元数的姿态更新

1)积分形式介绍

image

image

2) 离散时间处理

image

3.速度更新

image

4.位置更新

image

三、解算方法的来源

这一部分就是要解决“为什么”的问题,其实就是推导刚才用到的那些微分方程怎么来的。由于速度、位置的微分方程过于简单,此处就不介绍了,只介绍旋转矩阵、四元数、旋转矢量的微分方程。

1.旋转矩阵微分方程

image

2.四元数微分方程

image

image

image

image

3.旋转矢量微分方程

旋转矢量微分方程的推导就显得更加复杂,这里就借用严恭敏老师《惯性导航与组合导航算法》中的一个中间结论吧,直接给出旋转矢量微分方程的完整形式

image

如果你愿意把它泰勒展开,那么去除高阶项会得到如下简化形式

image

这就是前面看到的结果啦。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/595651.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【driver5】调用堆栈函数,printk,动态打印,ftrace,proc,sysfs

文章目录 1.内核函数调用堆栈:4个函数2.printk:cat /proc/cmdline查看consolettyS03.动态打印:printk是全局的且只能设打印等级,动态打印可控制选择模块的打印,在内核配置打开CONFIG_DYNAMIC_DEBUG4.ftrace&#xff1a…

【考研数学】武忠祥「基础篇」如何衔接进入强化?

如果基础篇已经做完,并且讲义上的例题也都做完了, 那下一步就是该做题了 这个时候,不能盲目做题,做什么题很重要!我当初考研之前,基础也很差,所以考研的时候选了错误的题集,做起来就…

AI+客服行业落地应用

一、客服行业变迁 1.传统客服时代 (1)客服工作重复性高,技术含量低 (2)呼出效率低,客服水平参差不齐 (3)管理难度高,情绪不稳定 (4)服务质量…

偏微分方程算法之椭圆型方程差分格式编程示例

目录 一、示例1-五点菱形格式 1.1 C代码 1.2 计算结果 二、示例2-九点紧差分格式 2.1 C代码 2.2 计算结果 三、示例3-二阶混合边值 3.1 C代码 3.2 计算结果 本专栏对椭圆型偏微分方程的三种主要差分方法进行了介绍,并给出相应格式的理论推导过程。为加深对…

“全国首批EVO+ ICL(V5)临床应用专家”授牌仪式在铭依眼科举行

近日,“全国首批EVO ICL(V5)新技术临床应用专家”授牌仪式在上海铭依眼科门诊部举行。仪式现场,瑞金医院谢冰教授获得此项荣誉称号。铭依眼科连锁医疗机构创始人吴英、Staar Surgical代表出席仪式现场。 为让近视人群不出国门即可…

ECC 号码总结

1、问题背景 在手机开发过程中,经常遇见各种紧急号码问题,在此特意总结下紧急号码相关知识。 2、紧急号码来源 在MTK RILD EccNumberSource.h中,定义了如下几种紧急号码来源。 按优先级排序介绍如下 2.1、SOURCE_NETWORK 网络下发&#xff…

车牌检测识别功能实现(pyqt)

在本专题前面相关博客中已经讲述了 pyqt + yolo + lprnet 实现的车牌检测识别功能。带qt界面的。 本博文将结合前面训练好的模型来实现车牌的检测与识别。并用pyqt实现界面。最终通过检测车牌检测识别功能。 1)、通过pyqt5设计界面 ui文件如下: <?xml version="1…

K. 子串翻转回文串

给一个串 s  s1s2... sn&#xff0c;你可以选定其一个非空子串&#xff0c;然后将该子串翻转。具体来说&#xff0c;若选定的子串区间为 [l, r]&#xff08;1 ≤ l ≤ r ≤ n&#xff09;&#xff0c;则翻转后该串变为 s1s2... sl - 1srsr - 1... slsr  1... sn…

Sharding Capital: 为什么投资全链流动性基础设施 Entangle ?

写在前面&#xff1a;Entangle 项目的名称取自于量子纠缠(Quantum entanglement)&#xff0c;体现了项目对于构建连接、关联和互通的愿景。就像量子纠缠将不同的粒子联系在一起&#xff0c;Entangle 旨在通过其跨链流动性和合成衍生品的解决方案将不同的区块链网络连接在一起&a…

我们说的数据分析,到底要分析些什么?

作者 Gam 本文为CDA志愿者投稿作品 “我们说数据分析&#xff0c;到底要分析些什么&#xff1f;” 数据分析这个话题自从进入人们的视线以来&#xff0c;这个话题就成为人们茶余饭后的谈资&#xff0c;但是一千个人眼中就有一千个哈姆雷特&#xff0c;就意味着每个人对数据分…

重识来伊份:抢滩首店经济,休闲零食品牌的“面子”和“里子”

前不久&#xff0c;苹果静安零售店的首秀频频登上热搜。 这背后&#xff0c;不仅仅因为它是中国大陆最大的苹果旗舰店&#xff0c;还在于它的设计融入了时尚又古典的上海街区&#xff0c;吸引了众多市民拍照打卡。今年3月至5月&#xff0c;上海会持续举办“首发上海”春季系列…

【C++】Vector详解

Vector是什么&#xff1f; vector是C&#xff08;STL&#xff09;中的一种序列容器Vector是一个动态数组&#xff0c;内存空间是连续的&#xff0c;支持随机访问&#xff0c;支持迭代器访问 Vector代码实现 变量指向 代码初始化 #include<iostream> using namespace …

动力电池热管理方案介绍与发展方向

摘要 随着电动汽车的快速发展&#xff0c;高性能的动力电池系统成为推动电动汽车产业发展的重要因素。然而&#xff0c;伴随着能量密度提高和放电深度增加&#xff0c;电池热管理问题逐渐凸显。良好的热管理方案能够提高电池的寿命&#xff0c;保障电池性能&#xff0c;延长电…

4.堆_树(汇总版)

目录 1.树概念及结构 1.1树的概念 1.2 树的相关定义 1.3 树的表示 2.二叉树概念及结构 2.1概念 2.2现实中的二叉树 2.3 特殊的二叉树 2.4 二叉树的性质 2.5 二叉树的存储结构 3.二叉树的顺序结构及实现 3.1 二叉树的顺序结构--堆 3.2 堆的实现 3.2.1打印 3.2.2 …

el-select 点击按钮滚动到选择框顶部

主要代码是在visibleChange 在这个 popper 里面找到 .el-select-dropdown__list let popper ref.$refs.popper const ref this.$refs.select let dom popper.querySelector(.el-select-dropdown__list) setTimeout(() > { dom.scrollIntoView() }, 800) <templat…

Debian mariadb 10.11设定表名 大小写不敏感方法

目录 问题表现&#xff1a;应用中查询 表提示 表不存在 处理步骤&#xff1a; 1、查询表名大小写敏感情况&#xff1a; show global variables like %case%; 2、修改mariadb 配置设置大小写 不敏感 mysql 配置大小写不敏感 mariadb 10.11设置表名大小写不敏感 /etc/mysq…

【项目部署】手把手带你从零部署项目:宝塔 + uwsgi + Django + 腾讯云 + Websocket

1. 前言 哈喽&#xff0c;大家好&#xff0c;我是jiaoxingk。今天带来的是有关Django项目部署的教程。 当我们完成了一个项目作品之后&#xff0c;我们肯定会迫不及待的就准备上线部署啦&#xff0c; 这篇教程将带你从服务器的配置选购&#xff0c;再通过安装宝塔的形式进行项目…

【一刷《剑指Offer》】面试题 15:链表中倒数第 k 个结点

力扣对应题目链接&#xff1a;LCR 140. 训练计划 II - 力扣&#xff08;LeetCode&#xff09; 核心考点 &#xff1a;链表&#xff0c;前后指针的使用&#xff0c;边界条件检测。 一、《剑指Offer》内容 二、分析问题 较优解题思路&#xff1a; 题目中的链表是单链表&#xff0…

数据库SQL语言实战(七)

前言 这次的有一点点难~~~~~我也写了好久 练习题 题目一 在学生表pub.student中统计名字&#xff08;姓名的第一位是姓氏&#xff0c;其余为名字&#xff0c;不考虑复姓&#xff09;的使用的频率&#xff0c;将统计结果放入表test5_01中 create table test5_01(First_name…

Mars3d实现用一个button控制一个map.control的显示与隐藏

原生js,想做一个button,控制比如compass的显示与隐藏 点一下显示 再次单击的时候就隐藏掉 写了一个function控制显示隐藏 function addCompass(){ if(compass.showtrue) { compass.showfalse; } else{ compass.showtrue; } } 功能示例(Vue版) | Mars3D三维可视化平台 | 火星…