|
本人平生第一帖,献给阿莫了!
问题是这样的,陀螺仪传回的三个角分别是 a,b,c,那应该怎么用一个四元数来表示这次旋转呢?
假设原始姿态q0={1,0,0,0},q1={cos(a/2),sin(a/2),0,0}表示绕x轴转角,
q2={cos(b/2),0,sin(b/2),0}表示绕y轴转角,q3= {cos(c/2),0,0,sin(c/2)}表示绕z轴转角,
我开始想用三个四元数连乘,来表示组合,即q0 = q0*q1*q2*q3,
但是我后来又想,q0*q1后,y轴在世界坐标系里已经不是(0,1,0)了,那q2也就不适用了,继续连乘就不对了,一直不得解,后来看到一个坛友同志发的外国人的代码,代码如下- #include "IMU.h"
- #include <math.h>
- //----------------------------------------------------------------------------------------------------
- // Definitions
- #define Kp 2.0f // 比例增益支配率收敛到加速度计/磁强计
- #define Ki 0.005f // 积分增益支配率的陀螺仪偏见的衔接
- #define halfT 0.5f // 采样周期的一半
- //---------------------------------------------------------------------------------------------------
- // 变量定义
- float q0 = 1, q1 = 0, q2 = 0, q3 = 0; // 四元数的元素,代表估计方向
- float exInt = 0, eyInt = 0, ezInt = 0; // 按比例缩小积分误差
- //====================================================================================================
- // Function
- //====================================================================================================
- void IMUupdate(float gx, float gy, float gz, float ax, float ay, float az) {
- float norm;
- float vx, vy, vz;
- float ex, ey, ez;
-
- // 测量正常化
- norm = sqrt(ax*ax + ay*ay + az*az);
- ax = ax / norm;
- ay = ay / norm;
- az = az / norm;
-
- // 估计方向的重力
- vx = 2*(q1*q3 - q0*q2);
- vy = 2*(q0*q1 + q2*q3);
- vz = q0*q0 - q1*q1 - q2*q2 + q3*q3;
-
- // 错误的领域和方向传感器测量参考方向之间的交叉乘积的总和
- ex = (ay*vz - az*vy);
- ey = (az*vx - ax*vz);
- ez = (ax*vy - ay*vx);
-
- // 积分误差比例积分增益
- exInt = exInt + ex*Ki;
- eyInt = eyInt + ey*Ki;
- ezInt = ezInt + ez*Ki;
-
- // 调整后的陀螺仪测量
- gx = gx + Kp*ex + exInt;
- gy = gy + Kp*ey + eyInt;
- gz = gz + Kp*ez + ezInt;
-
- // 整合四元数率和正常化
- q0 = q0 + (-q1*gx - q2*gy - q3*gz)*halfT;
- q1 = q1 + (q0*gx + q2*gz - q3*gy)*halfT;
- q2 = q2 + (q0*gy - q1*gz + q3*gx)*halfT;
- q3 = q3 + (q0*gz + q1*gy - q2*gx)*halfT;
-
- // 正常化四元
- norm = sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);
- q0 = q0 / norm;
- q1 = q1 / norm;
- q2 = q2 / norm;
- q3 = q3 / norm;
- }
复制代码 整合四元数和正常化那段,他的意思是用(1,sin(a/2),sin(b/2),sin(c/2))表示一次叁轴旋转。但是我们用a=60,b=0,c=0,即只绕x轴转了60度来验证一下。
以外国人的意思,这次旋转的四元数应该是(1,1/2,0,0),而根据四元数表示旋转的资料说明,应该是(cos30,sin30,0,0)=(根号3/2,1/2,0,0)显然外国的表示法是不符合事实的.
求救,到底要怎样才对? |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|