我有一个初始四元数,q0。接着我获得角速度测量值,然后积分这些速度,以得到每秒约50个角度。如何基于这3个角度生成一个新的四元数?我不能只制作3个四元数,对吧?
具体来说,我要更新当前方向的四元数Q.new,通过乘以Q.update quaternion来实现。我该如何用这三个角度创建Q.update quaternion呢?
谢谢!
我有一个初始四元数,q0。接着我获得角速度测量值,然后积分这些速度,以得到每秒约50个角度。如何基于这3个角度生成一个新的四元数?我不能只制作3个四元数,对吧?
具体来说,我要更新当前方向的四元数Q.new,通过乘以Q.update quaternion来实现。我该如何用这三个角度创建Q.update quaternion呢?
谢谢!
请原谅我的回复有些晚了,但是所有的答案似乎都太复杂了。像我这样的人可能更喜欢这种更“方便”的方法:
假设omega=(alpha,beta,gamma) 是陀螺仪测量得到的角速度矢量。然后我们进行旋转。
theta = ||omega||*dt; //length of angular velocity vector
许多单位(根据陀螺仪而定,可能是度或弧度)周围
v = omega / ( ||omega|| ); // normalized orientation of angular 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
我猜你正在整合欧拉角,因为你喜欢让自己变得困难。首先,陀螺仪不能直接集成到你的欧拉角中。如果你问这个问题,我会假设你也不知道如何正确地从你的陀螺仪测量中找到欧拉角的速率变化。你需要一个转换矩阵才能使其工作。我强烈建议你购买Farrell的"Aided Navigation"一书。在第57页上,他解释了如何计算转换矩阵以将您的陀螺仪速率转换为欧拉速率。但是,为什么要麻烦呢?当你可以直接从四元数和陀螺仪数据中获得速率变化四元数时。
rate of change quaternion = qdot
quaternion = q
gyro quaternion = w = [0,gyrox,gyroy,gyroz]
qdot = 0.5 * q Ⓧ w
在这里,Ⓧ代表四元数积。在这里要注意坐标系的问题。陀螺仪表示传感器坐标系相对于惯性坐标系的角速度,这个旋转需要用四元数表示从传感器坐标系到惯性坐标系的类似旋转。在这种情况下,它应该表示从惯性坐标系到陀螺仪坐标系的旋转。如果我们忽略地球的旋转等因素,上述方程式是成立的。
请注意“辅助导航”。我认为他对四元数的处理非常令人困惑。
qdot = 0.5 * q Ⓧ w
中的0.5是什么意思?我们应该对四元数q进行标量乘法吗?时间尺度去哪了? - AriksuVector3D omega = new Vector3D(alpha, beta, gamma);
Vector3D E = omega * dt;
通过将当前时间减去上次更新时间,您可以得到dt。从陀螺仪数据中获取三维欧拉角后,通过以下公式将其转换为四元数(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()方法中,然后返回四元数即可。如果您想知道方程式的工作原理,请查看维基链接并仔细阅读。
E.x=pi/2
和 Ex=pi/2+2*pi
给出了相同的旋转。 - anishtain41) 更新本身很简单。只需从角速度的“轴角”表示中创建四元数。
顺便提一下,“角速度”的常见表示方式是三个标量的向量。该向量与局部对象框架中的瞬时旋转轴平行。因此,您的方程将如下所示: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) 从您的问题中无法确定函数update的含义。 (alfa,beta,gamma)参数是什么?如果这是关于3个正交轴的瞬时旋转速度,则可以简单地从中构建角速度。只需确保使用正确的单位(每秒弧度)。
3) 获取加速度计数据的有用集成方式对于简短的答案来说过于复杂。每个硬件都应该使用自己的定制属性进行处理。此外,它还应该融合线性加速度数据以避免漂移。