minimu9-ahrs icon indicating copy to clipboard operation
minimu9-ahrs copied to clipboard

Altimu10v5 strange readings in XY axis Euler output

Open GrzegorzKarczewski opened this issue 6 years ago • 7 comments

Ok, so i've calibrated the device and have a strange output in euler. sample.txt

Every axis works and shows correct values when i turn the Z axis clockwise. But when i turn it to the lef(crossing North - 0 value) Z axis shows correct values but as you can see the other pitch and roll suddenly shows really high values around 170+ being still flat on the table.

When i switch to quaternion output the readings behave just fine and shows correct values for yaw pitch and roll however i turn the board around Z axis.

Can someone point me to the code thats responsible for that? I've looked through the main cpp file, but i dont see where it can fail like that. Any help is appreciated Thanks in advance!

Ps. Somehow turning the device along the Z axis counterclockwise interferes with calculating X and Y and its quite magical to me how this is happening

GrzegorzKarczewski avatar Mar 29 '18 08:03 GrzegorzKarczewski

Conversion from a quaternion to Euler angles is handled here:

void output_euler(quaternion & rotation)
{
  std::cout << (vector)(rotation.toRotationMatrix().eulerAngles(2, 1, 0)
                        * (180 / M_PI));
}

The Eigen library does all the work.

I forget what order the pitch, yaw, and roll variables get printed and how those angles are defined so I can't easily tell whether your output looks normal or not. Some discontinuities are to be expected if you put your board at a weird angle.

DavidEGrayson avatar Mar 29 '18 19:03 DavidEGrayson

Lets say i have Y=5 P=0 R =0. Device laying flat on the table. When i turn Yaw clockwise, P and R behave normally, showing right values when turning on angles +clockwise, but when i turn Yaw counter clockwise lets say it will be looking like this: Y P R 3 0 0 2 0 0 1 0 -1 0 0 0 179 177 176 178 176 177 177 177 176 176 176 177 175 177 175 174 177 176 etc

As you see, turning the device counterclockwise makes readings from Pitch and roll acting weird

GrzegorzKarczewski avatar Mar 30 '18 04:03 GrzegorzKarczewski

The numbers are technically valid because Euler angles of {0, 0, 0} represent the same rotation as Euler angles of {180, 180, 180}. I used a Euler angle visualizer to verify that:

http://danceswithcode.net/engineeringnotes/rotations_in_3d/demo3D/rotations_in_3d_tool.html

It looks like the Eigen library method we are using is trying to keep the yaw variable between 0 and 180. That's an unfortunate choice; it would be better if it tried to keep pitch variable between -90 and 90, because that's how we think about the pitch of a plane. I'll keep this issue open as a reminder to look into that.

You can probably just subtract 180 from each angle when it gives you annoying values like this; I suspect that's valid but haven't thought about it hard enough to be sure.

DavidEGrayson avatar Mar 30 '18 07:03 DavidEGrayson

Thanks for the answer. It seems like this is the case. With a change on Yaw from 180- -> 0, Pitch and roll are also changing base angle , and are showing values from 180->0. Everything works fine between Yaw 0+ -> 180. So the solution that you proposed may be accurate.

Thanks!

GrzegorzKarczewski avatar Mar 30 '18 15:03 GrzegorzKarczewski

Hi @DavidEGrayson and @GrzegorzKarczewski - I'm struggling with the same thing as you guys. I understand that the readings are correct, but I'm having a hard time converting them to "normal" readings (although I'm also having a hard time defining "normal").

Did you guys come up with something workable or more intuitive that this? If so, how did you calculate it?

kramer65 avatar Dec 14 '18 22:12 kramer65

Hi @kramer65. I've dropped that project because there was many noise in the readings when i attached the device to car(probably due to shaking and interference from metal). I'm no cpp expert so apart from showing you my changes to code i cant really help you further.

GrzegorzKarczewski avatar Dec 27 '18 18:12 GrzegorzKarczewski

@GrzegorzKarczewski and for any future readers. In the end I read out the results in Go and converted it using the (Go) code below. This gives every number between -180 and 180.

yaw_raw, _ := strconv.ParseFloat(imu_results[0], 64)
pitch_raw, _ := strconv.ParseFloat(imu_results[1], 64)
roll_raw, _ := strconv.ParseFloat(imu_results[2], 64)

yaw := 0.0
pitch := 0.0
roll := 0.0
if pitch_raw > 90 {
	yaw = -(180 - yaw_raw)
	pitch = 180 - pitch_raw
	if roll_raw > 0 {
		roll = (180 - roll_raw) * -1
	} else {
		roll = 180 - math.Abs(roll_raw)
	}
} else if pitch_raw < -90 {
	yaw = -(180 - yaw_raw)
	pitch = 180 - math.Abs(pitch_raw)
	if roll_raw > 0 {
		roll = (180 - roll_raw) * -1
	} else {
		roll = 180 - math.Abs(roll_raw)
	}
} else {
	yaw = yaw_raw
	pitch = pitch_raw
	roll = roll_raw
}
fmt.Println("CLEAN:  yaw", yaw, "pitch", pitch, "roll", roll)

After this I'll also need a Kalman filter, but that's for later.

kramer65 avatar Dec 28 '18 09:12 kramer65