1- // =====================================================================================================
1+ // =============================================================================================
22// MadgwickAHRS.c
3- // =====================================================================================================
3+ // =============================================================================================
44//
55// Implementation of Madgwick's IMU and AHRS algorithms.
66// See: http://www.x-io.co.uk/open-source-imu-and-ahrs-algorithms/
1414// 02/10/2011 SOH Madgwick Optimised for reduced CPU load
1515// 19/02/2012 SOH Madgwick Magnetometer measurement is normalised
1616//
17- // =====================================================================================================
17+ // =============================================================================================
1818
19- // ---------------------------------------------------------------------------------------------------
19+ // -------------------------------------------------------------------------------------------
2020// Header files
2121
2222#include " MadgwickAHRS.h"
2323#include < math.h>
2424
25- // ---------------------------------------------------------------------------------------------------
25+ // -------------------------------------------------------------------------------------------
2626// Definitions
2727
28+ #define sampleFreqDef 512 .0f // sample frequency in Hz
29+ #define betaDef 0 .1f // 2 * proportional gain
2830
2931
30- // ====================================================================================================
32+ // ============================================================================================
3133// Functions
3234
33- // ---------------------------------------------------------------------------------------------------
35+ // -------------------------------------------------------------------------------------------
3436// AHRS algorithm update
3537
3638Madgwick::Madgwick () {
@@ -39,6 +41,8 @@ Madgwick::Madgwick() {
3941 q1 = 0 .0f ;
4042 q2 = 0 .0f ;
4143 q3 = 0 .0f ;
44+ invSampleFreq = 1 .0f / sampleFreqDef;
45+ anglesComputed = 0 ;
4246}
4347
4448void Madgwick::update (float gx, float gy, float gz, float ax, float ay, float az, float mx, float my, float mz) {
@@ -54,6 +58,11 @@ void Madgwick::update(float gx, float gy, float gz, float ax, float ay, float az
5458 return ;
5559 }
5660
61+ // Convert gyroscope degrees/sec to radians/sec
62+ gx *= 0 .0174533f ;
63+ gy *= 0 .0174533f ;
64+ gz *= 0 .0174533f ;
65+
5766 // Rate of change of quaternion from gyroscope
5867 qDot1 = 0 .5f * (-q1 * gx - q2 * gy - q3 * gz);
5968 qDot2 = 0 .5f * (q0 * gx + q2 * gz - q3 * gy);
@@ -67,7 +76,7 @@ void Madgwick::update(float gx, float gy, float gz, float ax, float ay, float az
6776 recipNorm = invSqrt (ax * ax + ay * ay + az * az);
6877 ax *= recipNorm;
6978 ay *= recipNorm;
70- az *= recipNorm;
79+ az *= recipNorm;
7180
7281 // Normalise magnetometer measurement
7382 recipNorm = invSqrt (mx * mx + my * my + mz * mz);
@@ -100,7 +109,7 @@ void Madgwick::update(float gx, float gy, float gz, float ax, float ay, float az
100109 // Reference direction of Earth's magnetic field
101110 hx = mx * q0q0 - _2q0my * q3 + _2q0mz * q2 + mx * q1q1 + _2q1 * my * q2 + _2q1 * mz * q3 - mx * q2q2 - mx * q3q3;
102111 hy = _2q0mx * q3 + my * q0q0 - _2q0mz * q1 + _2q1mx * q2 - my * q1q1 + my * q2q2 + _2q2 * mz * q3 - my * q3q3;
103- _2bx = sqrt (hx * hx + hy * hy);
112+ _2bx = sqrtf (hx * hx + hy * hy);
104113 _2bz = -_2q0mx * q2 + _2q0my * q1 + mz * q0q0 + _2q1mx * q3 - mz * q1q1 + _2q2 * my * q3 - mz * q2q2 + mz * q3q3;
105114 _4bx = 2 .0f * _2bx;
106115 _4bz = 2 .0f * _2bz;
@@ -124,20 +133,21 @@ void Madgwick::update(float gx, float gy, float gz, float ax, float ay, float az
124133 }
125134
126135 // Integrate rate of change of quaternion to yield quaternion
127- q0 += qDot1 * ( 1 . 0f / sampleFreq) ;
128- q1 += qDot2 * ( 1 . 0f / sampleFreq) ;
129- q2 += qDot3 * ( 1 . 0f / sampleFreq) ;
130- q3 += qDot4 * ( 1 . 0f / sampleFreq) ;
136+ q0 += qDot1 * invSampleFreq ;
137+ q1 += qDot2 * invSampleFreq ;
138+ q2 += qDot3 * invSampleFreq ;
139+ q3 += qDot4 * invSampleFreq ;
131140
132141 // Normalise quaternion
133142 recipNorm = invSqrt (q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
134143 q0 *= recipNorm;
135144 q1 *= recipNorm;
136145 q2 *= recipNorm;
137146 q3 *= recipNorm;
147+ anglesComputed = 0 ;
138148}
139149
140- // ---------------------------------------------------------------------------------------------------
150+ // -------------------------------------------------------------------------------------------
141151// IMU algorithm update
142152
143153void Madgwick::updateIMU (float gx, float gy, float gz, float ax, float ay, float az) {
@@ -146,6 +156,11 @@ void Madgwick::updateIMU(float gx, float gy, float gz, float ax, float ay, float
146156 float qDot1, qDot2, qDot3, qDot4;
147157 float _2q0, _2q1, _2q2, _2q3, _4q0, _4q1, _4q2 ,_8q1, _8q2, q0q0, q1q1, q2q2, q3q3;
148158
159+ // Convert gyroscope degrees/sec to radians/sec
160+ gx *= 0 .0174533f ;
161+ gy *= 0 .0174533f ;
162+ gz *= 0 .0174533f ;
163+
149164 // Rate of change of quaternion from gyroscope
150165 qDot1 = 0 .5f * (-q1 * gx - q2 * gy - q3 * gz);
151166 qDot2 = 0 .5f * (q0 * gx + q2 * gz - q3 * gy);
@@ -195,20 +210,21 @@ void Madgwick::updateIMU(float gx, float gy, float gz, float ax, float ay, float
195210 }
196211
197212 // Integrate rate of change of quaternion to yield quaternion
198- q0 += qDot1 * ( 1 . 0f / sampleFreq) ;
199- q1 += qDot2 * ( 1 . 0f / sampleFreq) ;
200- q2 += qDot3 * ( 1 . 0f / sampleFreq) ;
201- q3 += qDot4 * ( 1 . 0f / sampleFreq) ;
213+ q0 += qDot1 * invSampleFreq ;
214+ q1 += qDot2 * invSampleFreq ;
215+ q2 += qDot3 * invSampleFreq ;
216+ q3 += qDot4 * invSampleFreq ;
202217
203218 // Normalise quaternion
204219 recipNorm = invSqrt (q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
205220 q0 *= recipNorm;
206221 q1 *= recipNorm;
207222 q2 *= recipNorm;
208223 q3 *= recipNorm;
224+ anglesComputed = 0 ;
209225}
210226
211- // ---------------------------------------------------------------------------------------------------
227+ // -------------------------------------------------------------------------------------------
212228// Fast inverse square-root
213229// See: http://en.wikipedia.org/wiki/Fast_inverse_square_root
214230
@@ -219,9 +235,20 @@ float Madgwick::invSqrt(float x) {
219235 i = 0x5f3759df - (i>>1 );
220236 y = *(float *)&i;
221237 y = y * (1 .5f - (halfx * y * y));
238+ y = y * (1 .5f - (halfx * y * y));
222239 return y;
223240}
224241
225- // ====================================================================================================
226- // END OF CODE
227- // ====================================================================================================
242+ // -------------------------------------------------------------------------------------------
243+
244+ void Madgwick::computeAngles ()
245+ {
246+ float x = 2 .0f * (q1*q3 - q0*q2);
247+ float y = 2 .0f * (q0*q1 + q2*q3);
248+ float z = q0*q0 - q1*q1 - q2*q2 + q3*q3;
249+ pitch = atan2f (x, sqrtf (y*y + z*z));
250+ roll = atan2f (y, sqrtf (x*x + z*z));
251+ yaw = atan2f (2 .0f *q1*q2 - 2 .0f *q0*q3, 2 .0f *q0*q0 + 2 .0f *q1*q1 - 1 .0f );
252+ anglesComputed = 1 ;
253+ }
254+
0 commit comments