forked from logzhan/NotesUESTC
2.2 KiB
2.2 KiB
Mahony姿态解算
2022-09-27 :詹力
一、从IMU到Mahony的坐标系
实际上,Mahony是没有明确的坐标系的概念的,不管是什么传感器的坐标轴输入到Mahony,解算出来的四元数的qx,qy,qz就和原始输入Mahony的IMU的轴是对应的。但是,这样做的会造成四元数到欧拉角的计算出现混乱麻烦。为了代码方便,我们最好是先 将IMU的坐标系映射到笛卡尔3D坐标系 。以MPU9250为例子,其坐标轴定义如下图所示(加速度计和陀螺仪,MPU9250内置磁力计坐标系不同)。
笛卡尔3D坐标系如下图所示:
将Mahony算法确定以笛卡尔3D坐标系方式描述,那么对应的转换代码如下所示:
Mahony.x = -Imu.y;
Mahony.y = Imu.x;
Mahony.z = Imu.z;
二、从四元数到欧拉角的转换
四元数到欧拉角的转换是和坐标系的定义存在关系的,在不同的坐标系下需要推导四元数到欧拉角的转换公式。这样非常的麻烦,除非在必要的情况下,一般用标准的笛卡尔3D坐标计算会比较方便。
笛卡尔3D坐标系下的四元数转换到欧拉角代码,如下所示:
Mahony.Pitch = asin(-2.0f*(z*x-w*y))* (180.0f /PI);
Mahony.Yaw = atan2(y*x + w*z,0.5f - y*y - z*z)* (180.0f /PI);
Mahony.Roll = atan2(y*z + w*x,0.5f - y*y - x*x)* (180.0f /PI);
三、Mahony算法中载体系的重力投影到地理系
常见代码的写法如下图所示:
// 写法1
float halfvx = q1 * q3 - q0 * q2;
float halfvy = q0 * q1 + q2 * q3;
float halfvz = q0 * q0 - 0.5f + q3 * q3;
// 写法2
float vx = 2.0f*(q1*q3 - q0*q2);
float vy = 2.0f*(q0*q1 + q2*q3);
float vz = q0*q0 - q1*q1 - q2*q2 + q3*q3;
比较有差异的主要在于vz的写法,这两种的写法其实是一样的,推导如下所示
\begin{align*}
vz &= q_0^2-0.5+q_3^2 \\
2vz &= 2q_0^2-1+2q_3^2 \\
&= 2q_0^2+2q_3^2-q_0^2-q_1^2-q_2^2-q_3^2 \\
&= q_0^2-q_1^2-q_2^2+q_3^2 \\
\end{align*}