Hi, i want to make yaw Axis for my 3 Axis Gimbal project, but i really confused to solve the magnetometer tilt compensation. I use HMC5883L magnetometer and BMA 180 Accelerometer. From the reference that i found on the internet, i need magnetometer and accelerometer to solve Magnetometer Tilt Compensation. Anda i found this algorithm from https://code.google.com/p/sf9domahrs/:

I don't use that concept at all, and I think the logic and methodology for it is spurious.

The basic feature of the geomagnetic field is that it isn't parallel to the ground, as you wouldthink when you have a magnetic compass sitting on a map on a table.

It is a vector field shooting down into the ground at a diagonal angle, which is more or lessconstant over short distances and which you can easily find out what it is for your region.

The 3-axis magnetometer is going to give you a vector in 3D which is going to show you thedirection of that field. Since you already know the direction of the field, you can determinethe orientation of the magnetometer, with the exception of rotation about the vector direction.

If you also have an accelerometer, and you assume your device is stationary or moving at a constantvelocity ( so it has no actual acceleration ), you can fully determine the orientation of your device.

I don't use that concept at all, and I think the logic and methodology for it is spurious.

The basic feature of the geomagnetic field is that it isn't parallel to the ground, as you wouldthink when you have a magnetic compass sitting on a map on a table.

It is a vector field shooting down into the ground at a diagonal angle, which is more or lessconstant over short distances and which you can easily find out what it is for your region.

The 3-axis magnetometer is going to give you a vector in 3D which is going to show you thedirection of that field. Since you already know the direction of the field, you can determinethe orientation of the magnetometer, with the exception of rotation about the vector direction.

If you also have an accelerometer, and you assume your device is stationary or moving at a constantvelocity ( so it has no actual acceleration ), you can fully determine the orientation of your device.

So, how i can solve tilt compensation for yaw Axis? By the way, this is my complete code:

Serial.println("Setting scale to +/- 1.3 Ga"); error = compass.SetScale(1.3); // Set the scale of the compass. if(error != 0) // If there is an error, print it out. Serial.println(compass.GetErrorText(error));

Serial.println("Setting measurement mode to continous."); error = compass.SetMeasurementMode(Measurement_Continuous); // Set the measurement mode to Continuous if(error != 0) // If there is an error, print it out. Serial.println(compass.GetErrorText(error));

// Calculate heading when the magnetometer is level, then correct for signs of axis. float heading = atan2(scaled.YAxis, scaled.XAxis);

// Once you have your heading, you must then add your 'Declination Angle', which is the 'Error' of the magnetic field in your location. // Find yours here: http://www.magnetic-declination.com/ // Mine is: 2Ã¯Â¿Â½ 37' W, which is 2.617 Degrees, or (which we need) 0.0456752665 radians, I will use 0.0457 // If you cannot find your Declination, comment out these two lines, your compass will be slightly off. float declinationAngle = 0.55; heading += declinationAngle;

// Normally we would delay the application by 66ms to allow the loop // to run at 15Hz (default bandwidth for the HMC5883L). // However since we have a long serial out (104ms at 9600) we will let // it run at its natural speed. // delay(66);

timer = millis(); //get a start value to determine the time the loop takes getAccelerometerReadings(accelResult);

//timer = millis() - timer; //how long did the loop take? //timer = (timeStep * 1000) - timer; //how much time to add to the loop to make it last time step msec //delay(timer); //make one loop last time step msec

If you literally intend to use it as a compass ( for orienteering or something ), then you need to "compensate" for the fact that you are not holding your compass flat, steady, and parallel to the ground.

If you intend to use it as an aid to orientation calculation for some moving device, that's a rather different question. The best method comes down to what sort of device you are trying to orient ( a car ? a robot on the ground ? a copter ? An acrobatic aircraft ? ), and what other devices you are using it with.

I notice in your code there, there is nothing about what you are comparing the magnetic reading TO. Do you know what the magnetic field in your area is like ?

A magnetic device is going to clarify the orientation of your device in relation to rotating aroundthe yaw axis. It's nothing to do with tilting the yaw axis.

Sorry, i mean "tilt compensation for magnetometer"

Quote

If you literally intend to use it as a compass ( for orienteering or something ), then you need to "compensate" for the fact that you are not holding your compass flat, steady, and parallel to the ground.

If you intend to use it as an aid to orientation calculation for some moving device, that's a rather different question. The best method comes down to what sort of device you are trying to orient ( a car ? a robot on the ground ? a copter ? An acrobatic aircraft ? ), and what other devices you are using it with.

That's it, i am going to use this magnetometer for Multicopter to know where we are heading, so the magnetometer is not always flat, steady, and parallel to the ground. And the problem is the magnetometer need to be held flat to function properly. If we tilt it (pitch or roll) to certain angle (for example to 45 degrees) the reading will be more inaccurate the further the compass is tilted. So I need to keep the accuracy of magnetometer even we tilt it.

I am looking for some references on the internet and found some useful sites like this (Maybe it will help explain my problem more clearly):https://www.loveelectronics.co.uk/Tutorials/13/tilt-compensated-compass-arduino-tutorialhttp://diy.powet.eu/2011/03/19/tilt-compensation-azimuth-pitch-le-roll/?lang=enhttps://gist.github.com/timtrueman/322555http://n0m1.com/2012/02/27/6dof-arduino-compass-accelerometer/

They are says we need both accelerometer and magnetometer to solve magnetometer inaccurate problem when it tilted, and use an algorithm. But, i still not yet success to solve this problem.

And the problem is the magnetometer need to be held flat to function properly. If we tilt it (pitch or roll) to certain angle (for example to 45 degrees) the reading will be more inaccurate the further the compass is tilted. So I need to keep the accuracy of magnetometer even we tilt it.

Thats not really correct. That is spurious wooly thinking which comes from the days of 2-axis magnetometers, maybe. A 3-axis magnetometer DOES NOT need to be held flat to function properly. It is always going to correctly show you the direction of the geomagnetic field ( or any other magnetic field which is present ), relative to its own current orientation. Apart from scaling and offset calibration for the different axial directions ( which will be an issue whether you are holding it flat and level, or not ), the assertion that the reading will be more inaccurate the further the compass is tilted, is simply not correct.

If you know the orientation of the device, you can always determine the projection of the magnetic field vector into a plane parallel to the ground. If you don't know the orientation of the device, you can compare the measured magnetic field vector to the expected magnetic field vector in your region, to determine the correct which needs to be made to the modelled orientation of the device.

The direction of the magnetism is flat at the equator, and pointing down at the poles.http://geokov.com/education/magnetic-declination-inclination.aspxhttp://en.wikipedia.org/wiki/Magnetic_dipThis site tells how much the inclination is, http://magnetic-declination.com/ (if you type your location, click on the location marker).This site tells even more, http://www.geomag.bgs.ac.uk/data_service/models_compass/wmm_calc.html (click on the map to place the marker).

The direction of the magnetism is flat at the equator, and pointing down at the poles.http://geokov.com/education/magnetic-declination-inclination.aspxhttp://en.wikipedia.org/wiki/Magnetic_dipThis site tells how much the inclination is, http://magnetic-declination.com/ (if you type your location, click on the location marker).This site tells even more, http://www.geomag.bgs.ac.uk/data_service/models_compass/wmm_calc.html (click on the map to place the marker).

Ok thanks Erdin..

Quote

Thats not really correct. That is spurious wooly thinking which comes from the days of 2-axis magnetometers, maybe. A 3-axis magnetometer DOES NOT need to be held flat to function properly. It is always going to correctly show you the direction of the geomagnetic field ( or any other magnetic field which is present ), relative to its own current orientation. Apart from scaling and offset calibration for the different axial directions ( which will be an issue whether you are holding it flat and level, or not ), the assertion that the reading will be more inaccurate the further the compass is tilted, is simply not correct.

If you know the orientation of the device, you can always determine the projection of the magnetic field vector into a plane parallel to the ground. If you don't know the orientation of the device, you can compare the measured magnetic field vector to the expected magnetic field vector in your region, to determine the correct which needs to be made to the modelled orientation of the device.

Ok, so the 3 axis magnetometer give us magnetic field in three axis, X, Y and Z. From my program that i have posted before, I successfully get magnetic field value in all 3 axis vector. Then, i want to know where we are heading (degree from north pole) by using this data . And according to this site:https://www.loveelectronics.co.uk/Tutorials/8/hmc5883l-tutorial-and-arduino-library

To Calculate heading of magnetometer, we can use this formulation:heading = arc tan (magnetic filed on Y Axis/magnetic filed on X Axis)

And finally i get the heading degrees, pretty nice when magnetometer keep flat. But, when i tilt the magnetometer (Pitch or Roll), the degrees value is change. And so far, I still not found a way to maintain the value of degree when the magnetometer tilted. Is there something wrong with my calculations?

The problem starts, when you assume that you can calculate the direction of the magnetic field simply by taking the arctan of the Y axis and X ais readings of the magnetometer. That assumption is misguided. And once you have made that assumption, you have all kinds of work-arounds to "compensate" for the fact that you have made a poor assumption.

If you assume that your vehicle has very small actual real acceleration, then you can estimate the orientation of your device by observing the apparent direction of the gravitational "down" direction using your accelerometer.

You can then estimate the rotation matrix which transforms the actual orientation of your device into a reference frame which is parallel to the ground. You can then transform the apparent magnetic field vector into the reference frame. You can compare that to the assumed actual magnetic field vector, to estimate the discrepancy between the reference direction in the horizontal direction of your calculated reference frame, and the actual "true" reference horizontal direction of the reference frame.

This is conceptually quite simple. Further complications emerge because different people use different conventions for which way the reference axes run.

The problem starts, when you assume that you can calculate the direction of the magnetic field simply by taking the arctan of the Y axis and X ais readings of the magnetometer. That assumption is misguided. And once you have made that assumption, you have all kinds of work-arounds to "compensate" for the fact that you have made a poor assumption.

If you assume that your vehicle has very small actual real acceleration, then you can estimate the orientation of your device by observing the apparent direction of the gravitational "down" direction using your accelerometer.

You can then estimate the rotation matrix which transforms the actual orientation of your device into a reference frame which is parallel to the ground. You can then transform the apparent magnetic field vector into the reference frame. You can compare that to the assumed actual magnetic field vector, to estimate the discrepancy between the reference direction in the horizontal direction of your calculated reference frame, and the actual "true" reference horizontal direction of the reference frame.

This is conceptually quite simple. Further complications emerge because different people use different conventions for which way the reference axes run.

Well, thank you about the Explanation michinyon, but i little bit confusing, can you explain it again with some mathematical form, formulation or algorithm?

The problem starts, when you assume that you can calculate the direction of the magnetic field simply by taking the arctan of the Y axis and X ais readings of the magnetometer. That assumption is misguided. And once you have made that assumption, you have all kinds of work-arounds to "compensate" for the fact that you have made a poor assumption.

If you assume that your vehicle has very small actual real acceleration, then you can estimate the orientation of your device by observing the apparent direction of the gravitational "down" direction using your accelerometer.

You can then estimate the rotation matrix which transforms the actual orientation of your device into a reference frame which is parallel to the ground. You can then transform the apparent magnetic field vector into the reference frame. You can compare that to the assumed actual magnetic field vector, to estimate the discrepancy between the reference direction in the horizontal direction of your calculated reference frame, and the actual "true" reference horizontal direction of the reference frame.

This is conceptually quite simple. Further complications emerge because different people use different conventions for which way the reference axes run.

Hi, michinyon. I found Quaternion based algorithm from here:http://www.x-io.co.uk/open-source-imu-and-ahrs-algorithms/

It's open source, and i tried to use that algorithm on my code. This is my coomplete Code:https://github.com/mamette/quaternion/blob/master/AHRS.ino

I got the Pitch, Roll and Yaw value, but they are irregularly. Is anything wrong with my code?

And i have some question:1. When we insert the Accelerometer value to Quaternion, the Accelerometer value must be in "g" scale or just raw value on each axis? 2. When we insert the Gyroscope value to Quaternion, the Gyroscope value must be in rad/s, it is right?3. When we insert the Magnetometer value to Quaternion, just insert Magnetometer raw value on each axis, it is right?