原英文地址:dcm_tutorial

  感觉这篇文章还是很有学习价值的,所以就抽出了一些时间对本文进行的翻译.下面这个好多人用的算法就是一种DCM 滤波器.

  1. //======================================================================================
  2. // IMU.c
  3. // S.O.H. Madgwick
  4. // 25th September 2010
  5. //======================================================================================
  6. // Description:
  7. //
  8. // Quaternion implementation of the 'DCM filter' [Mayhony et al].

   这个地址可以下载到原代码.

/*======================================正文===========================================*/

介绍:

  这篇文章是继IMU Guide 后,涵盖一些方向运动(orientation kinematics )的理论,然后我会围绕Arduino和一个六自由度IMU传感器提出一个实际的例子( acc_gyro_6dof )。本文是目的是创建一种算法融合加速度计和陀螺仪从而可以进行空间中方向的估计.像这样的算法已经在第三部分"IMU Guide" 提及.代码部分可以参考"Using a 5DOF IMU" 简称为 "简单卡尔曼滤波". 在这篇文章中我们将用另外一种方法,利用DCM(方向余弦矩阵).对于不不熟悉MEMS 传感器的读者 ,建议先阅读一下IMU Guide 的  Part1 和Part2 .对于实验部分,建议先购买Arduino 电路板 和 acc_gyro_ddof 传感器.

准备:

这本不需要太高深的数学知识,只需要找一本好的矩阵方面的书. 如果你想温固一下你的知识,可以阅读下面的文章:

直角坐标系 :http://en.wikipedia.org/wiki/Cartesian_coordinate_system Rotation

旋转- http://en.wikipedia.org/wiki/Rotation_%28mathematics%29 Vector scalar product

向量叉乘- http://en.wikipedia.org/wiki/Dot_product Vector cross product

矩阵乘- http://en.wikipedia.org/wiki/Cross_product Matrix Multiplication

块矩阵- http://en.wikipedia.org/wiki/Matrix_multiplication Block Matrix

块矩阵转置- http://en.wikipedia.org/wiki/Block_matrix Transpose Matrix

三重积- http://en.wikipedia.org/wiki/Transpose Triple Product - http://en.wikipedia.org/wiki/Triple_product

标记:

  向量标记以粗体文字 - 例如“V”是一个向量和“V”是一个标量(如果你不能区分,可以回头看看这里)。(本文使用右手坐标系)

第一部分. DCM 矩阵

一般来说 orientation kinematics 是指计算物品相对全局坐标系的一个方向,体坐标系我们用 Oxyz表示,全局坐标系我们用OXYZ表示.两个坐标系O 点重合(图1)定义i,j,k 为体坐标系中x,y,z轴的相互垂直的单位向量, I,J,K为全局坐标系(global frame )OXYZ 中的单位向量.

由上面的定义可知:

全局坐标系,

  IG = {1,0,0} TJG={0,1,0} T , KG = {0,0,1} T

体坐标系:

  iB = {1,0,0} TjB={0,1,0} T , kB = {0,0,1} T

向量 i,j,k  在全局坐标系中的表示如下:

  iG = {ixG , iyG , izG} T

下面我们对来分析一下 向量 在全局坐标系中 X 轴上的投影长度 .  表示为

  ix= |i| cos(X,i) = cos(I,i)

|i|的值为1 ,cos(I,i)为两个单位向量的余弦值.所以这个公式可以写成:

  ix= cos(I,i) = |I||i| cos(I,i) = I.i

我们知道向量之间的夹角与所在的坐标系无关,所以我们可以得到

  I.i = IB.iB = IG.i= cos(IB.iB) = cos(IG.iG)

同样的我们可以得出:

  iyG = J.i , izG=K.i  

所以向量 在全局坐标系中的表示形式为:

  iG= { I.i, J.i, K.i}T

以此类推我们可以得到:

  jG= { I.j, J.j, K.j} T , kG= { I.k, J.k, K.k} T.

最终我们可以得到下面这个"方向余弦矩阵":

     (Eq. 1.1)

如果上面这些看懂的话,我们不难得出:

  IB= { I.i, I.j, I.k}T , JB= { J.i, J.j, J.k}T , KB= { K.i, K.j, K.k}T

  

观察上面两个矩阵我们很容易可以看出,DCMB = (DCMG)or DCMG = (DCMB)T 利用这个属性,我们做下面的推导.

  DCMB. DCMG = (DCMG)T .DCMG = DCMB. (DCMB)T = I3  ,这里I3  是3x3单位矩阵,所以DCM矩阵是正交的.如下图:

(Eq. 1.3)

DCM 矩阵在方向运动(orientation kinematics )有着重要的应用,它可以定义坐标系之间的旋转.下面讲解一下如何使用DCM矩阵,我们定义一个向量r:

在体坐标系中表示   rB= { rxB, ryB, rzB} T 在全局坐标中表示 rG = { rxG , ryG , rzG } .这里取出

rxG = | rG| cos(IG,rG) = | IB || rB| cos(IB,rB) = IB. rB = IB. { rxB, ryB, rzB} T  , 因为 IB= { I.i, I.j, I.k}T  所以得出如下公式:

  rxG = IB. rB = { I.i, I.j, I.k}T . { rxB, ryB, rzB} T = rxB I.i + ryB I.j + rzB I.k

同理可得  :

  ryG = rxB J.i + ryB J.j + rzB J.k 
  rzG = rxB K.i + ryB K.j + rzB K.k


最终可以得到:

     (Eq. 1.4)

从上面这个等式我们可以看出DCM 矩阵可以用于把向量 r 的坐标从B 坐标系转为G 坐标系的坐标.同样我们可以得出下面这个等式:

    (Eq. 1.5)

第二部分 .Angular Velocity

  这里首先定义一个自由向量(非零)r,在t时间为表示为r(t) 经过dt时间之后为 r’r (t+dt) ,其中 dr = r’ – .

  

向量u是单位向量与  r x r’ 方向一致:

  u = (r x r’) / |r x r’| = (r x r’) / (|r|| r’|sin(dθ)) = (r x r’) / (|r|2 sin(dθ)) (Eq. 2.1)


定义向量v:

   v = d/ dt = ( r’ – r) / dt (Eq. 2.2)    .

在进行下面分析之前,这里我们假设 dt 趋近于 0 ,所以dθ → 0 ,则  v ⊥ r    (Eq. 2.21)    

这里用向量w 表示角速率,所以可以得到下面这个公式:

  w = (dθ/dt ) (Eq. 2.3)

结合公式  (Eq. 2.3)  (Eq. 2.1):

  w = (dθ/dt ) = (dθ/dt ) (r x r’) / (|r|2 sin(dθ))

因为 dθ趋近于0 所以sin(dθ) ≈ dθ   进一步对上式化简

  w = (r x r’) / (|r|2 dt)           (Eq. 2.4)


又因  r’ = r + dr , dr/dt = v , r r = 0   所以= (r x (r + dr)) / (|r|2 dt) = (r x r + x dr)) / (|r|2 dt) = x (dr/dt) / |r|2

最终 :

  r x / |r|2­ (Eq. 2.5)    

利用上面这个公式 ,我们可以知道向量v的情况下去求角速度(w) ,另外有一个公式与这个对应,这里不做证明.

  = w x r ­ (Eq. 2.6)   

第三部分.   陀螺仪和角速度向量

  三轴陀螺仪可以分别测出在三个轴上的旋转角速度,这里用 w, w, w来表示陀螺仪的三个方向的输出值, 单位 rad/s. 同时我们应该知道 dθx = wxdt ,dθy = wydt ,dθz = wzdt  . 我们用向量的形式表示旋转 wx = wx i = {w, 0 , 0 }wy = wy j = { 0 , w, 0 }T , wz = wz k = { 0 , 0, w}T   i,j,k  分别为体坐标系中x,y,z 轴上的方向向量).物体的旋转会产生线位移(linear displacement) ,可以用公式表示如下:

  dr1 = dt v1 = dt (wx x r) ; dr2 = dt v2 = dt (wy x r) ; dr3 = dt v3 = dt (wz x r.

合成这三个向量,  d= dr+ dr+ dr= dt (wx x r wy x r + wz x r) = dt (wx wy + wz) x r 


所以等效线速度可以表示为:

  v = dr/dt = (wx wy + wz) x r x r   这里  w = wx wy + wz = {w, w, w}  ,需要强调一点这是在小角的情况下,否则不能像这样简单的合成.

第四部分. DCM 互补滤波器在6DOF或9DOF IMU 传感器上的应用

  6DOF IMU模块指的是3轴陀螺仪和3轴加速度计.9DOF 模块指的是3轴陀螺仪3轴加速度计和3轴磁阻传感器.这里把全局右手坐标系与地理坐标不系联系起来(Earth's frame)  I向量指向北, K 指向"天", 向量指向东.如下图:

这里首先定义IMU设备中的坐标系,如下图:

    

      图4

 我们已经知道陀螺仪可以测得角速度向量,下面介绍加速度计和磁阻传感器如何所测量值加入到模块中来.假设加速度计测得的值为 = {A, Ay , Az },  今KB = -A(与传感器位置有关). 磁阻传感器与加速度计类似,用 = {M, My , Mz }表示测得值,因此IB = M.知道了IB 和 KB 则允许计算 JB = KB x IB(都是单位向量).

因此通过加速度计和磁阻传感器我们可以得到DCM矩阵, 表示为DCMB 或 DCMG.

  DCMG = DCMBT = [IB, JB, KB]T

任何位于体坐标系中的向量利用DCM矩阵可以转化到全局坐标系中来.比如说飞机的机头朝向位于体坐标系统中用rB = {1,0,0}表示,我们便可以计算得出在全局坐标中的航向,如下面这个公式:(Eq. 1.4)

  rG = DCMG rB

  简要介绍一下加速度计和磁阻,陀螺仪传感器的一些特性.陀螺仪瞬时的测量比较准确,但是有漂移,这里加计和磁阻起到观测者的作用.同时陀螺仪不知道哪里是"北""天"所以多个传感器可以融合起来得到准确的空间方位.下面进行介绍如何使用DCM 计算方位.

每一行来看,我们可以得到三个向量 IB, JB, KB.我们会经常用到这个向量K(这个可以用加速度计测量得到),向量IB(可以于磁阻传感器测得).向量J可以简单计算得到JB = KB x I(单位向量,且正交).

我们定义向量在t时刻 在体坐标系内的值为KB0. 陀螺仪的输出值为w = {w, wy, w}.利用陀螺仪我们想知道经过一个小的时间间隔 dt 的 KB1G .我们使用公式 (Eq. 2.6):

  KB1G ≈ KB0 + dt v KB0 + dt (wg x KB0) = KB0 + ( dθg x KB0)

其中 dθg = dt wg.

很明显K也可以直接从加速度计测得,测得的值为KB1A .这里测得的角速度我们用 wa  表示,角位移 θa ­= dt wa , 使用公式(Eq. 2.5):

  w­a KB0 va / | KB0|2

其中 v= (KB1A­ KB0) / dt ,因为KB0为单位向量,所以推出:

  dθa ­= dt wKB0 x (KB1A­ KB0)

读到这里大家也可能已经明白,我们是想融合 KB1A  KB1G 得到一个新的KB1 ,所以首先需要整合dθ ,公式如下:

  dθ = (sa dθa + sg dθg) / (sa + s),    sa sg  为权重.

这里我们得到一个新的KB1  :

  KB1 ≈ KB0 + ( dθ x KB0)   ,dθ 为融合之后的.

类似的我们可以计算: 

  IB1 ≈ IB0 + ( dθ x IB0)

  JB1 ≈ JB0 + ( dθ x JB0)

到这里我们完成了从0时刻经过dt 时间到1时刻的DCM矩阵更新.这个矩阵不那么容易受外部加速度的影响,因为有陀螺仪参与更新.到目前我们还没有提及如何使用磁阻传感器.因为我们这里用的是6dof imu传感器,这里介绍如何使用虚拟磁阻,它是一直指向北部.

下面整合磁阻到我们的算法中来.过程与加速度计相似,这里用向量I表示.

  dθm ­= dt wIB0 x (IB1M­ IB0)

融合:

  dθ = (sa dθa + sg dθ+ sm dθm) / (sa + sg +­ sm)

到这里我们采用相同的方法更新DCM 矩阵

  IB1 ≈ IB0 + ( dθ x IB0) , KB1 ≈ KB0 + ( dθ x KB0) and JB≈ JB0 + ( dθ x JB0)

在实际运用中,我们会用JBKBIB,在重新校正 KBIB1 垂直之后.强调一点,所有的计算都是在小的dt 基础之上的,否则将会出现错误.在每次进行矩阵更新时,我们不能保证是单位正交矩阵,所以每次更新都需要校正.

  首先我们先了解如果让两个向量重新正交.如下图:

图5

这里向量 a 和 接近正交,向量 c为 其叉积.向量 b’为向量a和向量c的叉积. 根据叉积的定义,所以b’及为b校正后的向量.根据矢量三重积进一步推导:

  b’ = c x a = (a x b) x a = -a (a.b) + b(a.a) = b – a (a.b) = + d , where = – a (a.b)   (方案1, a 固定 b 被校正)

这里向量d  称之为修正量.向量d  平行于向量a ,其方向取决于a 与 的夹角.

上面我们讨论的是固定向量,去寻找向量b’ .我们也可以反过来考虑问题,如下面公式.

  a’ a – b (b.a) = a – b (a.b) = a + e, where = - b (a.b) (方案2, b 固定 a 被校正)

所以我们综合考虑,

  a’ a – b (a.b) / 2 (方案3, a 和都需要校正)
  b’ b – a (a.b) / 2

图6

这里为了减少处理器计算量,我们提前计算出  Err = (a.b)/2 ,然后再有这个值去校正两个向量.

  a’ a – Err * b
  b’ b – Err * a


需要注意一点,在方案三这里没有证明a’ b’ 是正交的,只是进行了直观的推理更接近于90度.

现在我们回到更新DCM 矩阵这个问题上来 ,我们如下的方法进行矩阵更新:

  Err = ( IB1 . JB) / 2

  IB1’ IB1 – Err * JB
  JB1’ JB1 – Err * IB
  IB1’’ = Normalize[IB1]
  JB1’’ = Normalize[JB1]
  KB1’’ IB1’’ x JB1’’

然后像这样[a] = / |a|进行向量的单位化,重复上面的过程,我们得到DCM2 , DCM3 ,  ....DCM n .

其原作者的代码  https://code.google.com/p/picquadcontroller/source/browse/trunk/imu.h

参考:

1. Theory of Applied Robotics: Kinematics, Dynamics, and Control (Reza N. Jazar)

2. Linear Algebra and Its Applications (David C. Lay)

3. Fundamentals of Matrix Computations (David S. Watkins)

4. Direction Cosine Matrix IMU: Theory (W Premerlani)

有翻译不对的地方希望大家给予反馈,我们及时更新.

DCM TUTORIAL – AN INTRODUCTION TO ORIENTATION KINEMATICS (REV 0.1)的更多相关文章

  1. [转]DCM Tutorial – An Introduction to Orientation Kinematics

    原地址http://www.starlino.com/dcm_tutorial.html Introduction This article is a continuation of my IMU G ...

  2. 课程一(Neural Networks and Deep Learning),第一周(Introduction to Deep Learning)—— 0、学习目标

    1. Understand the major trends driving the rise of deep learning.2. Be able to explain how deep lear ...

  3. 《RabbitMQ Tutorial》第 1 章 简介

    本文来自英文官网,其示例代码采用了 .NET C# 语言. <RabbitMQ Tutorial>第 1 章 简介(Introduction) RabbitMQ is a message ...

  4. 《RabbitMQ Tutorial》译文 第 1 章 简介

    原文来自 RabbitMQ 英文官网的教程(1.Introduction),其示例代码采用了 .NET C# 语言. RabbitMQ is a message broker: it accepts ...

  5. 图片Exif 信息中Orientation的理解和对此的处理

    这个问题是在用七牛上传图片后获取宽高时发现的,一张图片,用图片浏览器打开始终是竖图,但是查看属性或者用七牛获取宽高,却发现宽大于高,也就是在属性中这是个横图.这样导致客户端用该宽高来展示图片会出现问题 ...

  6. [转载] CMake Official Tutorial——教程还是官方的好

    CMake官方教程传送门:https://cmake.org/cmake-tutorial/ 以下的内容跟官方教程基本一致,少数地方根据自己的测试有所改动: A Basic Starting Poin ...

  7. Entity Framework 6.0 Tutorials(1):Introduction

    以下系统文章为EF6.0知识的介绍,本章是第一篇 原文地址:http://www.entityframeworktutorial.net/entityframework6/introduction.a ...

  8. DCM:一个能够改善所有应用数据交互场景的中间件新秀

    摘要:几乎所有涉及应用数据交互的场景都可以通过DCM来改善应用结构,提升开发与计算效率. 本文分享自华为云社区<DCM:中间件家族迎来新成员>,作者: 石臻臻的杂货铺. DCM是什么 现代 ...

  9. ARTIFICIAL INTELLIGENCE FOR GAMES (Ian Millington / John Funge 著)

    相关网站:http://www.ai4g.com PART I AI AND GAMESCHAPTER1 INTRODUCTIONCHAPTER2 GAME AIPART II TECHNIQUESC ...

随机推荐

  1. 一个简单的数据查询显示jsp

    以前使用jstl标签库只是使用core来显示一些数据,非常方便,今天看了下发现jstl还有其他的标签,使用都非常方便, 1.sql标签,可以直接访问数据库,后台代码都不需要了,这在某些时候非常适合使用 ...

  2. 介绍开源的.net通信框架NetworkComms框架之九 合并DLL

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 目前作者已经开源  许可是 ...

  3. iOS开发UI篇—模仿ipad版QQ空间登录界面

    iOS开发UI篇—模仿ipad版QQ空间登录界面 一.实现和步骤 1.一般ipad项目在命名的时候可以加一个HD,标明为高清版 2.设置项目的文件结构,分为home和login两个部分 3.登陆界面的 ...

  4. JavaWeb chapeter 5 Web应用程序状态管理

    1.  HTTP协议使用的是无状态连接,对容器而言,每一个请求都来自于一个新的客户. 2. html表单隐藏字段:对用户在网站上的访问进行会话跟踪.为服务器端程序提供预定义的输入.存储动态产生的页面上 ...

  5. [css]input text ie6/7 border兼容问题

    [border:none;]当border为“none”时对IE6/7无效边框依然存在 [border:0;]当border为“0”时,所有浏览器都一致把边框隐藏 [border:0;]把border ...

  6. centos55_oracle11gr2_install

    第一个阶段:安装centos55 a:安装centos5.5   用图形界面安装  硬盘 16G 注意:用图形界面安装.. 第二个阶段:配置1:检查内存情况# grep MemTotal /proc/ ...

  7. composer -vvv

    然后在使用Composer install 或者 composer update 的时候会停住不动.使用-vvv可以输出更多信息,其命令参数输出的级别是Debug.具体可以查看composer hel ...

  8. CodeForces 686B-Little Robber Girl's Zoo

    题目: 有n头数量的动物,开始它们站在一排,它们之间有高度差,所以需要将它们进行交换使得最终形成一个不减的序列,求它们交换的区间.交换的规则:一段区间[l, r]将l与l+1.l+2与l+3..... ...

  9. Winform基础知识

    1.关于登陆部分 this.DialogResult = DialogResult.OK; this.Close(); FrmLogin login = new FrmLogin(m_CurUser) ...

  10. (转)JAVA实现Windows拨号、IP切换

    原理: 通过调用windows下的dos命令实现拨号 PS:连接名称获取不一定都是适用,但苦于知道的dos命令太少了,只能将就这么用着. 如有更好的方法,烦请不吝赐教. public class Co ...