Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] Orientation of MPU9250 and MPU9150 axis #8

Open
SivertHavso opened this issue Jan 27, 2022 · 2 comments
Open

[Question] Orientation of MPU9250 and MPU9150 axis #8

SivertHavso opened this issue Jan 27, 2022 · 2 comments
Assignees

Comments

@SivertHavso
Copy link
Contributor

I'm struggling to see why the orientation is handled the way it is for the MPU9250 (and similarly for the MPU9150), and have been getting unexpected outputs from the fusion with an offset on the z axis.

The relevant lines are:

m_imuData.gyro.setX(m_imuData.gyro.x());
m_imuData.gyro.setY(-m_imuData.gyro.y());
m_imuData.gyro.setZ(-m_imuData.gyro.z());
// sort out accel data;
m_imuData.accel.setX(-m_imuData.accel.x());
// use the compass fuse data adjustments
m_imuData.compass.setX(m_imuData.compass.x() * m_compassAdjust[0]);
m_imuData.compass.setY(m_imuData.compass.y() * m_compassAdjust[1]);
m_imuData.compass.setZ(m_imuData.compass.z() * m_compassAdjust[2]);
// sort out compass axes
float temp;
temp = m_imuData.compass.x();
m_imuData.compass.setX(m_imuData.compass.y());
m_imuData.compass.setY(-temp);

Natively, the compass follows a North-East-Down (NED) frame convention, while the accelerometer and gyroscope is using East-North-Up (ENU) convention:

AxisOrientation

As RTIMULib expects the default orientation to be NED, I would have expected the accelerometer and gyroscope to have their x and y axis swapped and z axis flipped to bring it into the same orientation as the compass which is already in NED.

With the current solution, the y and z axis of the gyroscope is flipped which also brings it into NED, but 180 degrees offset from the native compass orientation:

mpu9250

The accelerometer only has its x axis flipped with its z axis left pointing up. Which neither follows NED nor ENU.

The compass has its x axis flipped then swapped with the y axis. Effectively rotating them 90 degrees, but it does not add an accompanying 90 degree offset on the z axis.

I might be misunderstanding completely, and am not very familiar with the core RTIMULib library codebase. What's the reason it's been done this way?

@HongshiTan HongshiTan self-assigned this Jan 28, 2022
@gigcastro
Copy link

Around a year ago, we had the same doubt and sent a mail to the original author asking for this.

He kindly responded:

Hi there! While it is true that the axes of the gyro and accelerometer are aligned, the problem is that the gyro rotation directions are inverted from what I want for the rest of the calculations. So what you are seeing in the code is first the gyro rates having their signs changed. However, they also use a right hand rule for axes and RTIMULib uses a left hand rule so the X axis has to be reversed. That's why you see the gyro Y and Z values being negated but not the X value - the X value has been negated twice. The sense of the accelerometer is correct but it also needs the right hand to left hand conversion, hence the X value is negated.

Hope that makes sense!

Richard.

The key thing is that the gyro data are ANGLE RATES and are required in left-hand rule which are conventionally CLOCKWISE (contrary to the chip's right-hand standard). So a new left-hand axis needs to be decided, and it just invert the X axis as you noted in the accelerometer axis. That requires to negate angles rates of Y and Z, but not X, while only negates X axis in the accelerometer.

This leads to:

mpu9250

The compass remained kind of a mystery for us, but we did ask him about that and, while he was a bit hesitant, we got:

...
If you look at lines 633 to 635 of that file you can see the magnetometer
outputs being adjusted to match the IMU as the raw IMU and magnetometer data are in different
frames. All of the drivers output data in the standard AxisRotation 0 frame.
...

So we understand that, to take the compass MPU9250-Right-Hand-NED (RH) to the same RTIMULib-MPU9250-Left-Hand (LH) as the gyro/accel it should:
LH_X = -RH_Y
LH_Y = RH_X
LH_Z = -RH_Z

But he doesn't do that, he ends up with a right-hand axis again. I disagree with your interpretation of the resulting axis @SivertHavso, as I understand it is rotating 90 degrees in the opposite direction that you drawn.

At that point we just commented the lines in our internal repo and move on with our lives.

What is mind-blowing to me is that the default AxisRotation (explained in RTIMU.h) is in right-hand, as It is stated that "Standard configuration is X pointing at north, Y pointing east and Z pointing down", which is right-hand NED. That greatly differs from the gyro+accel left-hand axis delivered by the MPU9250 driver.
Also, as I understand, changing AxisRotation, would lead to a right-hand matrix transformation being applied to left-hand raw data in the RTIMU::handleGyroBias() function.

I don't know if any of this happens with any other IMU chip/driver, but we set the AxisRotation as 0, so identity matrix would be used and performed data reinterpretation at a later point in our code and didn't use any fusion capabilities.

I would be really nice to document and state requirements for the drivers on which coordinate system they should deliver the samples, what is left-hand / right-hand and how data should be expected. Some examples on how to use the AxisRotation would be nice also.

Hope this helps.

@brightproject
Copy link

brightproject commented Nov 20, 2023

I use an Adafruit 10DOF breadboard.
I orient it vertically, as in the picture.
IMU
In the settings I select the orientation RTIMU_XSOUTH_YDOWN
https://github.com/jordandcarter/RTIMULib-Arduino/blob/cac4454680dd6798f1f4d7fa61ab465e960dd570/libraries/RTIMULib/RTIMULibDefs.h#L96
And everything seems to work, but in the code itself
https://github.com/jordandcarter/RTIMULib-Arduino/blob/cac4454680dd6798f1f4d7fa61ab465e960dd570/libraries/RTIMULib/RTIMU.cpp#L134
As far as I understand, if the axis is -1 or 1, then the sign changes for all axes and for the accelerometer and for the gyroscope and for the magnetometer.
But this is not true, because sometimes the rotation axes need to be changed on different axes and these settings do not always match.
I had an idea to rewrite the logic for assigning signs and rotating axes, but I’m not yet sure exactly how to do it.
In the example, the IMU code
axes are defined using coefficients
int SENSOR_SIGN[9] = {1,1,1,1,1,1,1,1,1};
Perhaps someone had similar thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants