sparkfun / SparkFun_MPU-9250-DMP_Arduino_Library

Arduino library for the MPU-9250 enabling its digital motion process (DMP) features.
Other
229 stars 151 forks source link

How to change axis in DMP? #33

Closed Sketh closed 4 years ago

Sketh commented 5 years ago

In my case i want to let 9250 zaxis pointing forward like below, i want change 9250 axis, how can i do this? https://i.stack.imgur.com/pdFpI.png

remi0s commented 5 years ago

any information how to change the axis? I need the z axis to become the y and the opposite.

gabrielshanahan commented 5 years ago

Why can't you just flip the values yourself? By "forward" I'm assuming you mean the direction the Y axis is by default. Assuming you only want to flip the Y and Z axis, you can just do the equivalent of

new_z = old_y new_y = old_z

in your code.

remi0s commented 5 years ago

Why can't you just flip the values yourself? By "forward" I'm assuming you mean the direction the Y axis is by default. Assuming you only want to flip the Y and Z axis, you can just do the equivalent of

new_z = old_y new_y = old_z

in your code.

i wanted to use directly the quanternions inside Unity enviroment, which has different axis possition. Anyway the reason i needed this was because the roll pitch yaw values werent allways correct. Turns out to be a bug in computeEulerAngles () function as discussed here.

Using this functions solved my problem:

void loop()
{
  // Check for new data in the FIFO
  if ( imu.fifoAvailable() )
  {
    // Use dmpUpdateFifo to update the ax, gx, mx, etc. values
    if ( imu.dmpUpdateFifo() == INV_SUCCESS)
    {
      String imuLog = ""; // Create a fresh line to log
      double roll;
      double pitch;
      double yaw;
      toEulerianAngle(imu.calcQuat(imu.qw), imu.calcQuat(imu.qx), imu.calcQuat(imu.qy), imu.calcQuat(imu.qz), roll, pitch, yaw);
      imuLog += String(roll, 6) + ",";
      imuLog += String(pitch, 6) + ",";
      imuLog += String(yaw, 6) + ",";
      SerialPort.println(imuLog);
    }
  }
}
static void toEulerianAngle(float w, float x, float y, float z, double& roll, double& pitch, double& yaw)
{
  double ysqr = y * y;

  // roll (x-axis rotation)
  double t0 = +2.0 * (w * x + y * z);
  double t1 = +1.0 - 2.0 * (x * x + ysqr);
  roll = atan2(t0, t1) * (180.0 / PI);;

  // pitch (y-axis rotation)
  double t2 = +2.0 * (w * y - z * x);
  t2 = t2 > 1.0 ? 1.0 : t2;
  t2 = t2 < -1.0 ? -1.0 : t2;
  pitch = asin(t2) * (180.0 / PI);;

  // yaw (z-axis rotation)
  double t3 = +2.0 * (w * z + x * y);
  double t4 = +1.0 - 2.0 * (ysqr + z * z);  
  yaw = atan2(t3, t4) * (180.0 / PI);;
}
gabrielshanahan commented 5 years ago

Thanks for the explanation and for the code.

Maybe this is what you need?

https://stackoverflow.com/questions/16099979/can-i-switch-x-y-z-in-a-quaternion

From a cursory glance, it looks like you can do the flips in quaternion form, and then just multiply the real part by (-1)^(number_of_flips).

santaimpersonator commented 4 years ago

Sounds like users solved own issue... closing.