Opengl 旋转:四元数到矩阵
我试图显示一个360全景使用IMU的头部跟踪 偏航工作正常,但横摇和俯仰方向相反。我还注意到音高包含一些滚动(可能反之亦然) 我从IMU接收(W,X,Y,Z)坐标,并将其作为X,Y,Z,W存储在阵列中 下一步是将四元数转换为旋转矩阵。我看了很多示例,似乎没有发现以下代码有任何错误:Opengl 旋转:四元数到矩阵,opengl,rotation,quaternions,Opengl,Rotation,Quaternions,我试图显示一个360全景使用IMU的头部跟踪 偏航工作正常,但横摇和俯仰方向相反。我还注意到音高包含一些滚动(可能反之亦然) 我从IMU接收(W,X,Y,Z)坐标,并将其作为X,Y,Z,W存储在阵列中 下一步是将四元数转换为旋转矩阵。我看了很多示例,似乎没有发现以下代码有任何错误: static GLfloat rotation[16]; // Quaternion (x, y, z, w) static void quaternionToRotation(float* quaternion)
static GLfloat rotation[16];
// Quaternion (x, y, z, w)
static void quaternionToRotation(float* quaternion)
{
// Normalize quaternion
float magnitude = sqrt(quaternion[0] * quaternion[0] +
quaternion[1] * quaternion[1] +
quaternion[2] * quaternion[2] +
quaternion[3] * quaternion[3]);
for (int i = 0; i < 4; ++i)
{
quaternion[i] /= magnitude;
}
double xx = quaternion[0] * quaternion[0], xy = quaternion[0] * quaternion[1],
xz = quaternion[0] * quaternion[2], xw = quaternion[0] * quaternion[3];
double yy = quaternion[1] * quaternion[1], yz = quaternion[1] * quaternion[2],
yw = quaternion[1] * quaternion[3];
double zz = quaternion[2] * quaternion[2], zw = quaternion[2] * quaternion[3];
// Column major order
rotation[0] = 1.0f - 2.0f * (yy + zz);
rotation[1] = 2.0f * (xy - zw);
rotation[2] = 2.0f * (xz + yw);
rotation[3] = 0;
rotation[4] = 2.0f * (xy + zw);
rotation[5] = 1.0f - 2.0f * (xx + zz);
rotation[6] = 2.0f * (yz - xw);
rotation[7] = 0;
rotation[8] = 2.0f * (xz - yw);
rotation[9] = 2.0f * (yz + xw);
rotation[10] = 1.0f - 2.0f * (xx + yy);
rotation[11] = 0;
rotation[12] = 0;
rotation[13] = 0;
rotation[14] = 0;
rotation[15] = 1;
}
我尝试将四元数中除一个字段外的所有字段都设置为0,我注意到它们都单独工作,除了滚动和俯仰是交换的。我尝试交换X和Y,但这似乎没有帮助
任何帮助都将不胜感激。请让我知道,如果你有任何步骤,可以让我调试我的问题。谢谢 您是否确认了
tracker.getTrackingData()
中的四元数实际上是有意义的?您的IMU是否正确校准?似乎除了将四元数转换成矩阵之外,还有很多其他事情会引起麻烦。我相信是的,不过我会再检查一遍。我已经运行了一个示例应用程序,该应用程序显示了IMU的图像(旋转时),并且看起来是正确的。我将再次检查我的代码是否正确地模拟了它,但我相信它是有效的。您还想到了什么(除了校准)?也许我可以试着一个接一个地排除它们。我一直在考虑你的评论。突出的一点是,如果我将3个四元数(x,y,z)中的2个设置为0,则偏航、横摇和俯仰分别工作(俯仰和横摇除外)。将它们全部打开会产生一个问题,roll会有一些音调,反之亦然。我想到的问题大多与硬件有关,I2C总线上的坏数据或类似的问题(当然取决于IMU的实际连接方式)。但我真的只是在考虑,因为你的四元数矩阵代码看起来都很好。
static void draw()
{
// Get IMU quaternion
float* quaternion = tracker.getTrackingData();
if (quaternion != NULL)
{
quaternionToRotation(quaternion);
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glPushMatrix();
// TODO: Multiply initialRotation quaternion with IMU quaternion
glMultMatrixf(initialRotation); // Initial rotation to point forward
glMultMatrixf(rotation); // Rotation based on IMU
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
gluSphere(quad, 0.1, 50, 50);
glBindTexture(GL_TEXTURE_2D, 0);
glPopMatrix();
glFlush();
glutSwapBuffers();
}