Opengl 旋转:四元数到矩阵

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)

我试图显示一个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)
{
  // 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();
}