Jump to content
I2Cdevlib Forums
wookiee82

Change default axes orientation

Recommended Posts

Hey everybody,

the title of the thread may sound a little confusing so let me explain what I would like to obtain.

I have made a custom board with an MPU6050 connected to an ATmega32u4 microcontroller and I am able to communicate without problem.

The thing is that the MPU assumes that the "0" position (or resting position) is with the board (and the chip) laying on a flat surface and consequently, the yaw/pitch/roll data are computed starting from this position.

For my project, I need to change the ZERO position to the one with the board standing 90 degrees instead of laying on the surface and so, have the yaw/pitch/roll data reflecting this new position. 

 

How can I achieve this?

 

Thanks in advance for any tips!!

 

Davide

Share this post


Link to post
Share on other sites

Hi -

 

I have the same question as above - mounting at 90 deg from flat. I'm using a madgwick filter rather than the DMP. I tried re-mapping the axis but it doesn't seem to work.

 

Davide - Any luck?

 

Any help greatly appeciated. Thanks!

D.K.

Share this post


Link to post
Share on other sites

I third this question. Can anyone provide any tips? I have the chip mounted on top of a custom PCB board and I would like to set it up so that when I lay the PCB board flat, the chip will register this as the neutral position ((yaw, pitch, roll) = (0,0,0). (x,y,z) = (0,0,0))

 

So far no luck, I've tried using the

mpu.setXGyroOffset(0);
mpu.setYGyroOffset(0);
mpu.setZGyroOffset(0);

functions with values, and I've tried following this advice from Jeff Rowberg:


Hi Wim,
 
I don't have a very scientific calibration routine, or any code beyond what you saw posted there to speak of. The basic approach is like this:

  1.     
  2. Use the set*Offset() methods to set all offsets to 0. These are effective immediately.
        
  3. Place the sensor on a flat, level surface. Measure with an actual level if you have to. The level adjustment is less critical if your main concern is yaw drift, but it's still a good baseline.
        
  4. Print out at least few dozen raw measurement values, or even better, skip 50 or so to let the device "settle" and then collect + calculate the average for each axis over 200+ readings. The correct "still/level" values for all gyro axes and the x/y accel axes should be 0, and the correct "still/level" value for the Z accel axis should be 1g, or +16384 at the default +/- 2g sensitivity setting.
        
  5. Use the opposite (positive/negative) value of the calculated averages to determine the new offset values for each axis.
        
  6. Plug the new values in on start-up using the set*Offset() methods. Note that there is some scale factor which I am not sure of yet; I believe the offset values need to be smaller, possibly by a factor of 2x, 4x, or 8x from the raw measurements.


This is about all the info I currently have. I really should build an auto-calibration routine to do this, but I haven't had the time.

But so far no luck.

Any help would be greatly appreciated.

Share this post


Link to post
Share on other sites

I had the same question and solved the problem for my application, although I have not tested others.  I wanted to access the ypr functions from the DMP, but wanted to orient the breakout board so the Y-axis was vertical.  I only cared about pitch and roll in this new configuration.  When you reorient the board, the Y-axis becomes the vertical, and the Z-axis becomes equitorial, in effect swapping roles.  The X-axis stays in the same plane (albeit 90 degrees out of the old position).  By looking at MPU6050_6Axis_MotionApps20.h file from Jeff Rowland, I found where the GetYawPitchRoll function was defined.  I simply swapped all instances of y and z in these three definitions and it worked well for pitch and roll.  I saw some discontinuity in the yaw motion, but since I was not interested in it, I did not investigate further.  Sample code is below.

 

Old version:

 

uint8_t MPU6050::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) {
    // yaw: (about Z axis)
    data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1);
    // pitch: (nose up/down, about Y axis)
    data[1] = atan(gravity -> x / sqrt(gravity -> y*gravity -> y + gravity -> z*gravity -> z));
    // roll: (tilt left/right, about X axis)
    data[2] = atan(gravity -> y / sqrt(gravity -> x*gravity -> x + gravity -> z*gravity -> z));
    return 0;
}
 

 

New version:

 

uint8_t MPU6050::dmpGetYawPitchRollOnEnd(float *data, Quaternion *q, VectorFloat *gravity) {
    // yaw: (about Y axis)
    data[0] = atan2(2*q -> x*q -> z - 2*q -> w*q -> y, 2*q -> w*q -> w + 2*q -> x*q -> x - 1);
    // pitch: (nose up/down, about Z axis)
    data[1] = atan(gravity -> x / sqrt(gravity -> z*gravity -> z + gravity -> y*gravity -> y));
    // roll: (tilt left/right, about X axis)
    data[2] = atan(gravity -> z / sqrt(gravity -> x*gravity -> x + gravity -> y*gravity -> y));
    return 0;
}
 

 

I hope this helps in part with your problems.  The sensor board calibration was done in the usual fashion before swapping the axes in code, but the calibrations held up well.

Share this post


Link to post
Share on other sites
On 4/7/2016 at 6:46 AM, ekchess said:

 

 

New version:

 

uint8_t MPU6050::dmpGetYawPitchRollOnEnd(float *data, Quaternion *q, VectorFloat *gravity) {
    // yaw: (about Y axis)
    data[0] = atan2(2*q -> x*q -> z - 2*q -> w*q -> y, 2*q -> w*q -> w + 2*q -> x*q -> x - 1);
    // pitch: (nose up/down, about Z axis)
    data[1] = atan(gravity -> x / sqrt(gravity -> z*gravity -> z + gravity -> y*gravity -> y));
    // roll: (tilt left/right, about X axis)
    data[2] = atan(gravity -> z / sqrt(gravity -> x*gravity -> x + gravity -> y*gravity -> y));
    return 0;
}
 

 

I hope this helps in part with your problems.  The sensor board calibration was done in the usual fashion before swapping the axes in code, but the calibrations held up well.

Wooow, man I just registered to say thank you sooo much to you. You made my day, not even day ,you made my week :D You are the one super smart guy :) I spent 6 hours to get what I want from gyro and finally came across your comment. It was suffering from gimbal lock when I hold it straight upwards and tilt it front/back and right/left. Right/left was affecting the values for front/back. After this change it is solved as I see. Partially, I write it because someone might encounter the the same problem and my description could be found in google.  Thank you again. 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...