如何根据三维陀螺数据更新四元数?

时间:2014-05-06 19:19:39

标签: orientation velocity quaternions gyroscope

我有一个初始四元数,q0。我得到了角速度测量,我整合了速度,所以我得到了50Hz左右的3个角度。如何根据3个角度制作四元数?我不能做3个四元数,可以吗?

所以说清楚。

Q.new = Q.new * Q.update(-α,β,γ)

Q.new表示我在四元数中的当前方向,我想通过乘以Q.update四元数来更新它。如何用角度制作Q.update?

谢谢!

5 个答案:

答案 0 :(得分:6)

我认为你正在整合欧拉角,因为你喜欢让你的生活变得困难。首先,陀螺仪并没有直接融入你的欧拉角。如果你问这个问题,我会假设你也不知道如何从你的陀螺仪测量中正确找到变化率欧拉角。您需要一个转换矩阵才能工作。我强烈建议你拿一份Farrell" Aided navagition"在第57页,他解释了如何计算转换矩阵以将陀螺仪速率更改为欧拉速率。但是,当您可以直接从四元数和陀螺仪数据中获得变化率四元数时,为什么还要烦恼:

rate of change quaternion  = qdot
quaternion = q
gyro quaternion = w = [0,gyrox,gyroy,gyroz]

所以

qdot = 0.5 *  q Ⓧ w

其中Ⓧ代表四元数产品。这里要小心你的框架。陀螺仪表示传感器框架相对于传感器框架中表示的惯性框架的角速率。这意味着您的四元数需要表示从传感器到惯性框架的类似旋转。在这种情况下,它应表示从惯性框架到陀螺仪框架的旋转。如果我们忽略诸如地球自转之类的事情,那么前面的等式是有效的。

了解"辅助导航。"在我看来,他对四元数的处理非常混乱。

答案 1 :(得分:5)

你可以整合你的角速度来获得角位置(如欧拉角),将欧拉角转换为四元数,然后乘以四元数以累积方向。

假设您的输入是由角速度的3D矢量给出的: omega =( alpha beta gamma ),以度/秒为单位给出。要获得欧拉角, E ,以度为单位,将 omega 乘以时间的变化,我们可以将其称为 dt 。结果是:

Vector3D omega = new Vector3D(alpha, beta, gamma);
Vector3D E = omega * dt;

您可以通过在上次更新时减去当前时间来获取 dt 。从陀螺仪数据中获取3D欧拉角后,通过此等式(来自Wikipedia)将其转换为四元数(w,x,y,z):

float w = cos(E.x/2) * cos(E.y/2) * cos(E.z/2) + sin(E.x/2) * sin(E.y/2) * sin(E.z/2);
float x = sin(E.x/2) * cos(E.y/2) * cos(E.z/2) - cos(E.x/2) * sin(E.y/2) * sin(E.z/2);
float y = cos(E.x/2) * sin(E.y/2) * cos(E.z/2) + sin(E.x/2) * cos(E.y/2) * sin(E.z/2);
float z = cos(E.x/2) * cos(E.y/2) * sin(E.z/2) - sin(E.x/2) * sin(E.y/2) * cos(E.z/2);

Quaternion q = new Quaternion(w, x, y, z);

只需将上面的两个代码段复制粘贴到Q.update()方法中,然后返回Quaternion。如果您想知道方程式如何工作,只需查看Wiki链接并阅读它。

答案 2 :(得分:5)

请原谅我的线程坏死,但答案似乎都很复杂,有些像我一样,可能更喜欢这种“方便”的方法:

假设omega =(alpha,beta,gamma)是陀螺仪的测量速度矢量。然后我们旅行

theta = ||omega||*dt; //length of velocity vector

许多单位(deg或rad取决于陀螺仪)

v = omega / ( ||omega|| ); // normalized orientation of velocity vector

因此,我们可以将旋转四元数构造为:

Q.update = (cos(theta/2),v_x * sin(theta/2), v_y * sin(theta/2), v_z * sin(theta/2));

现在剩下的就是将我们当前的轮换旋转Q.update。这是微不足道的:

Q.new = multiply_quaternions(Q.update,Q.new); 
// note that Q.update * Q.new != Q.new * Q.update for quaternions

完成。四元数是美丽的,不是吗?

陀螺仪和四元数上的一些幻灯片可能很有用: http://stanford.edu/class/ee267/lectures/lecture10.pdf

答案 3 :(得分:0)

您可以将这些角度转换为单个四元数,然后执行您描述的操作,或者您可以将它们中的每一个转换为轴角度对,然后转换为四元数,然后将三个四元数相乘。 请参阅http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angleshttp://www.j3d.org/matrix_faq/matrfaq_latest.html#Q60了解更多细节。

答案 4 :(得分:0)

1)更新本身很简单。只需从"轴角度"角速度表示创建四元数。

BWT,表示角速度的常用方法"是3个标量的矢量。矢量与LOCAL对象框架中的力矩旋转轴平行。所以你的等式看起来:Q.new = Q.update(alfa,beta,gamma)* Q.new。 http://en.wikipedia.org/wiki/Axis%E2%80%93angle_representation#Unit_quaternions

并考虑整合的时间(最简单的近似,欧拉积分) Q.new = Q.fromVector(angularVelocity * deltaTime)* Q.new

另外注意,angularVelocity * deltaTime产生"指数映射"旋转,这很容易转换成四元数。

为了精确积分,应使用更复杂的近似。但是你必须知道测量的确切含义(测量时间,噪声等)。

2)您的问题不清楚功能更新。什么是(alfa,beta,gamma)参数?如果这是一个约3正交轴的力矩旋转速度,那么你可以简单地从这个角度建立角速度。请确保以适当的单位(每秒弧度)。

3)获得有用的加速度计数据集成的方法对于简短的回答来说太复杂了。应使用自己的自定义属性处理每个硬件。此外,它应融合来自线性加速度的数据以避免漂移。