我一开始做IMU算法的时候,对传感器的安装方向多少有点执念。
最好是平着装,芯片的X轴对着机头,Y轴对着机身右侧,Z轴规规矩矩朝下。这样传感器吐出来的三个数,差不多可以直接送进后面的姿态算法,大家都省事。
可实际做产品,电路板并不总肯这么配合。
有时结构空间不够,只能把板子竖起来;有时接口和螺丝孔挡着,板子还要再转90度。于是代码里就多出一组轴映射:这次把传感器的X给机体Y,Y给机体负X;下次安装方向又变了,再把X、Y、Z重新排一遍,顺便检查哪个轴该加负号。
这种办法当然能用。只是每换一种结构,我都得拿着板子比画半天:机头往前时,到底哪个数变了;右侧抬起来,数值应该为正还是为负。最怕的是三个轴都对上了,唯独漏掉一个负号。板子平放时看不出什么,真正一转起来,屏幕里的模型便像喝多了一样。
后来我才明白,X→Y、Y→−X这些零散的判断,其实都在做同一件事:把传感器坐标系里的数据,翻译到机体坐标系。
而这件事,旋转矩阵本来就是专门干这个的。
传感器说的是自己的XYZ
IMU焊在电路板上以后,只认识芯片丝印和手册规定的三个方向。无论整机向前、向右还是向上,它报告的加速度和角速度,都是沿传感器自身X、Y、Z轴测到的分量。
姿态算法却不关心芯片丝印朝哪边。它需要的是机体坐标:哪个方向算向前,哪个方向算向右,哪个方向算向下。无人机、汽车、机器人各有约定,但有一点相同——整个系统必须说同一种坐标语言。
如果IMU恰好摆正,两个坐标系重合,原始数据可以直接使用。如果板子转了90度,交换轴、修改正负号也能完成翻译。
问题在于,这种写法只擅长处理90度、180度这一类整齐的安装方式。
假如结构工程师说:“这块板既不是平装,也不是竖装,要沿这个斜面装上去,大约歪了27度。”这时就很难再说X对应Y,或者X对应负Z。传感器的一根轴,可能同时在机体的三个方向上都有分量。
一根轴再也不能简单对应另一根轴了。
旋转矩阵就是一张翻译表
旋转矩阵听着挺吓人,写出来是一个三行三列、共有九个数的小方阵。
我更愿意把它看成一张翻译表。表里的每个数,都在描述传感器某根轴对机体某根轴贡献了多少。完全同向就是1,完全反向就是−1,互相垂直就是0;斜着装时,则会出现0到1之间的数。
过去的交换轴和改正负号,并没有被推翻。它们其实是旋转矩阵最简单的一种:九个位置里只放0、1和−1。
当安装角度不再是整90度,矩阵只是把这张表写得更完整。
程序运行时,可以把事情压缩成一句:
机体坐标数据 = 安装旋转矩阵 × 传感器坐标数据
加速度计读出一组三轴数据,先乘一次矩阵;陀螺仪读出一组三轴角速度,也乘同一个矩阵;如果还有磁力计,并且它与IMU共用相同安装关系,同样先转到机体坐标系。
完成这一步以后,后面的互补滤波、四元数更新或卡尔曼滤波,都只看统一的机体坐标。至于IMU是平放、竖放还是斜着塞进壳体里,姿态算法不需要知道,也不必跟着改。
从计算量上看,这件事也没有想象中沉重。一个三维向量乘以3×3矩阵,本质上就是九次乘法和几次加法。对现在常见的单片机来说,通常不算什么负担。若安装方式固定,矩阵甚至可以提前算好,放在程序里当常量使用。
任意角度安装,不等于随便装上就能用
旋转矩阵能处理任意已知的安装角度,但它不会自动知道板子是怎么装的。这个安装关系,要么来自结构设计,要么来自标定。
如果CAD已经给出了IMU相对机体绕三个轴的安装角,可以按约定的旋转顺序算出矩阵。这里的“顺序”很重要:先绕X再绕Y,与先绕Y再绕X,结果通常不同。角度使用度还是弧度,坐标系采用右手系还是左手系,机体Z轴朝上还是朝下,也必须一开始就写清楚。
如果板子装配后有误差,或者实际安装角说不准,可以把整机放到几个已知姿态上,用测得的数据反求安装矩阵。工装越可靠、姿态覆盖越充分,算出来的关系越可信。
只把设备静止放一次,通常还不够。重力能帮助我们确定倾斜方向,却无法单独告诉我们绕重力轴转了多少,也就是无法仅靠一次静态加速度数据确定完整的三维安装关系。要补上这个自由度,需要更多已知姿态、磁场或其他方向参考。
另外,坐标变换最好放在算法入口处,而且加速度、角速度等所有相关三轴量要使用同一套约定。只转加速度、不转陀螺仪,或者把矩阵方向写反,得到的姿态往往比手工换轴还难查。
我后来怎么做
后来再做IMU项目,我会先在文档里画清两个坐标系:传感器的Xs、Ys、Zs,机体的Xb、Yb、Zb。接着明确矩阵到底是“传感器转机体”,还是“机体转传感器”。这两者互为转置,但在代码里不能混着用。
矩阵确定以后,我会做三个很朴素的检查:机头向前加速,机体X轴读数方向是否正确;绕机体每根轴分别转动,角速度是否只在对应轴上占主导;设备放在几个已知姿态时,重力方向能否对上。
这几步比盯着九个数字看有效得多。
从手工交换XYZ,到使用旋转矩阵,代码并没有突然变得多高深。只是原来散落在各处的安装判断,被收进了一张固定的表里。结构以后再换角度,需要重新确认的是这张表,而不是把整套姿态算法翻出来重改一遍。
前些年调板子,我常把一块IMU捏在手里,先看丝印,再看机头,手指绕来绕去,最后还要在纸上写下“X给Y,Y给负X”。
现在板子仍旧可能斜着装。只是数据进来以后,先安静地经过那九个数,走出来时,三个轴已经站到了机体该站的位置上。
173