Simple gravity compensation for 9 DOM IMUs
An accelerometer is subject to dynamic (or external) and static (gravity) accelerations (see my thesis, chapter 5.1). This means that whenever you are interested in measuring dynamic accelerations rather than gravity you have to compensate for gravity.
I implemented a very simple approach for doing so, assuming that you have a 9 degrees of measurement inertial measurement unit as my FreeIMU, from which you are able to compute its orientation quaternion representing the orientation of the Earth frame with respect to the Sensor frame and that you have the readings coming from the accelerometer.
This is the code, implemented in Python:
# compensate the accelerometer readings from gravity. # @param q the quaternion representing the orientation of a 9DOM MARG sensor array # @param acc the readings coming from an accelerometer expressed in g # # @return a 3d vector representing dinamic acceleration expressed in g def gravity_compensate(q, acc): g = [0.0, 0.0, 0.0] # get expected direction of gravity g[0] = 2 * (q[1] * q[3] - q[0] * q[2]) g[1] = 2 * (q[0] * q[1] + q[2] * q[3]) g[2] = q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3] # compensate accelerometer readings with the expected direction of gravity return [acc[0] - g[0], acc[1] - g[1], acc[2] - g[2]]
The idea behind this is pretty simple. With the quaternion we can compute the expected direction of gravity and then subtract that from the accelerometer readings. The result is the dynamic acceleration.
I'm sure that there could be a better solution but this is just the result of a 10 minutes coding and seems working pretty good.



how does this deal with stuff like centripetal acceleration
Suppose you have the IMU unit on the end of a rope, being swung around in a vertical circle. The accelerometer would be sensing the centripetal acceleration as dynamic acceleration right ? Wouldn't that confuse this algorithm when used for computing vertical position (complementary filter with baro pressure sensor).
Yeah, it will sense the
Yeah, it will sense the centripetal acceleration.
In theory, given a perfect filter and a perfect sensor, it wouldn't effect the altitude estimation.. but in reality, tests are needed and probably the algorithm parameters as well as the sensor configurations should be adapted to this use case.
NOTE: We are trying to move to the newly launched FreeIMU community website to answer such kind of questions. Please post there your future questions. Thanks!
Fabio a quick question on the
Fabio a quick question on the units:
Are you assuming that q0, q1, q2 and q3 form a unit quaternion? And the units for gz gy gz are in 'g'?
-S
Yes. Yes. :-)
Yes. Yes. :-)
Can it be used for 6DOF IMU?
I would also like to remove gravity component from my accelerometer readings - however, I have only 6DOF IMU (no magnetometer). Is it still possible to use this code? I always get wrong results (but this may be because of wrong implementation on my side OR the fact that this code can't be used for 6DOF IMU - which is correct?).
Hi Fabio, can you please
Hi Fabio,
can you please explain me your calculation? What are you doing in the first step of your calculation and the second step? Moreover what are the requirements for the quaternion. Do you assume that you know the absolute orientaton based on a start position? Or do you just take the relative orientation change from the last update of the AHRS algorithm?
(I am the guy from mathematics, if you are wondering)
Best regards
Chris
Given a vector of dimension 1
Given a vector of dimension 1 normal to the Earth plane pointing the sky expressed in the Earth frame representing the gravity (1g) and given a quaternion coming out from the sensor fusion algorithm representing the orientation of the board with respect to the Earth, the first part of the code express the vector into the sensor frame.
Then as your accelerometers readings expressed in g in the sensor frame are effected by gravity too, you can simply subtract the gravity vector expressed in the sensor frame computed in the first step and you obtain gravity free accelerometer readings.
Hope this helps, if you know a better way or if it is not clear, let me know.
Hi Fabio, thanks for the fast
Hi Fabio,
thanks for the fast answer.
Ok I know understand what you have done, but the problem is that it is only working well if you know your device orientation at the beginning, because the AHRS algorithm is only giving relative orientation changes.
Or do I have overlooked something?
What do you think about my aproach on stackoverflow?
Best regards
chris
No, the orientation from the
No, the orientation from the AHRS is absolute. I personally used this code in a project so it should work. what stackoverflow are you talking about?
Yes the orientation is
Yes the orientation is absolute but only based on the initial conditions, as far as I understand and tried on implementing myself.
I am talking about this thread, where you have answered to my questions:
http://stackoverflow.com/questions/10801951/remove-gravity-from-raw-acce...
Do you have shared the sources of mentioned project? I would like to have a look.
Thanks Chris
Not entirely true..
Yes the orientation is absolute but only based on the initial conditions, as far as I understand and tried on implementing myself.
That would be true for a 6DOF board (gyro + acc) but for a 9 DOF (gyro + acc + magn) it is not. Despite of the board initial conditions, the algorithm always get to the correct absolute orientation.
That source code is part of a bigger project which I still didn't published so I still can't share such code. I will do it in September or October.
gravity compensation
This could be also a good idea for vertical position estimation:
- Compensate gravity from vertical acc.
- Double integrate vertical acc.
- Use complementary filter (high-pass) for double integrated acc and lowpass for baro.
-> Drift from double integral does not affect to result and baro can be filtered at much lower freq.
Yep! That's exactly how it's
Yep! That's exactly how it's done in the MultiWii software for controlling quadcopters! See the code available from http://code.google.com/p/multiwii/
Post new comment