1
- // =====================================================================================================
1
+ // =============================================================================================
2
2
// MadgwickAHRS.c
3
- // =====================================================================================================
3
+ // =============================================================================================
4
4
//
5
5
// Implementation of Madgwick's IMU and AHRS algorithms.
6
6
// See: http://www.x-io.co.uk/open-source-imu-and-ahrs-algorithms/
14
14
// 02/10/2011 SOH Madgwick Optimised for reduced CPU load
15
15
// 19/02/2012 SOH Madgwick Magnetometer measurement is normalised
16
16
//
17
- // =====================================================================================================
17
+ // =============================================================================================
18
18
19
- // ---------------------------------------------------------------------------------------------------
19
+ // -------------------------------------------------------------------------------------------
20
20
// Header files
21
21
22
22
#include " MadgwickAHRS.h"
23
23
#include < math.h>
24
24
25
- // ---------------------------------------------------------------------------------------------------
25
+ // -------------------------------------------------------------------------------------------
26
26
// Definitions
27
27
28
+ #define sampleFreqDef 512 .0f // sample frequency in Hz
29
+ #define betaDef 0 .1f // 2 * proportional gain
28
30
29
31
30
- // ====================================================================================================
32
+ // ============================================================================================
31
33
// Functions
32
34
33
- // ---------------------------------------------------------------------------------------------------
35
+ // -------------------------------------------------------------------------------------------
34
36
// AHRS algorithm update
35
37
36
38
Madgwick::Madgwick () {
@@ -39,6 +41,8 @@ Madgwick::Madgwick() {
39
41
q1 = 0 .0f ;
40
42
q2 = 0 .0f ;
41
43
q3 = 0 .0f ;
44
+ invSampleFreq = 1 .0f / sampleFreqDef;
45
+ anglesComputed = 0 ;
42
46
}
43
47
44
48
void 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
54
58
return ;
55
59
}
56
60
61
+ // Convert gyroscope degrees/sec to radians/sec
62
+ gx *= 0 .0174533f ;
63
+ gy *= 0 .0174533f ;
64
+ gz *= 0 .0174533f ;
65
+
57
66
// Rate of change of quaternion from gyroscope
58
67
qDot1 = 0 .5f * (-q1 * gx - q2 * gy - q3 * gz);
59
68
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
67
76
recipNorm = invSqrt (ax * ax + ay * ay + az * az);
68
77
ax *= recipNorm;
69
78
ay *= recipNorm;
70
- az *= recipNorm;
79
+ az *= recipNorm;
71
80
72
81
// Normalise magnetometer measurement
73
82
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
100
109
// Reference direction of Earth's magnetic field
101
110
hx = mx * q0q0 - _2q0my * q3 + _2q0mz * q2 + mx * q1q1 + _2q1 * my * q2 + _2q1 * mz * q3 - mx * q2q2 - mx * q3q3;
102
111
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);
104
113
_2bz = -_2q0mx * q2 + _2q0my * q1 + mz * q0q0 + _2q1mx * q3 - mz * q1q1 + _2q2 * my * q3 - mz * q2q2 + mz * q3q3;
105
114
_4bx = 2 .0f * _2bx;
106
115
_4bz = 2 .0f * _2bz;
@@ -124,20 +133,21 @@ void Madgwick::update(float gx, float gy, float gz, float ax, float ay, float az
124
133
}
125
134
126
135
// 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 ;
131
140
132
141
// Normalise quaternion
133
142
recipNorm = invSqrt (q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
134
143
q0 *= recipNorm;
135
144
q1 *= recipNorm;
136
145
q2 *= recipNorm;
137
146
q3 *= recipNorm;
147
+ anglesComputed = 0 ;
138
148
}
139
149
140
- // ---------------------------------------------------------------------------------------------------
150
+ // -------------------------------------------------------------------------------------------
141
151
// IMU algorithm update
142
152
143
153
void 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
146
156
float qDot1, qDot2, qDot3, qDot4;
147
157
float _2q0, _2q1, _2q2, _2q3, _4q0, _4q1, _4q2 ,_8q1, _8q2, q0q0, q1q1, q2q2, q3q3;
148
158
159
+ // Convert gyroscope degrees/sec to radians/sec
160
+ gx *= 0 .0174533f ;
161
+ gy *= 0 .0174533f ;
162
+ gz *= 0 .0174533f ;
163
+
149
164
// Rate of change of quaternion from gyroscope
150
165
qDot1 = 0 .5f * (-q1 * gx - q2 * gy - q3 * gz);
151
166
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
195
210
}
196
211
197
212
// 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 ;
202
217
203
218
// Normalise quaternion
204
219
recipNorm = invSqrt (q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
205
220
q0 *= recipNorm;
206
221
q1 *= recipNorm;
207
222
q2 *= recipNorm;
208
223
q3 *= recipNorm;
224
+ anglesComputed = 0 ;
209
225
}
210
226
211
- // ---------------------------------------------------------------------------------------------------
227
+ // -------------------------------------------------------------------------------------------
212
228
// Fast inverse square-root
213
229
// See: http://en.wikipedia.org/wiki/Fast_inverse_square_root
214
230
@@ -219,9 +235,20 @@ float Madgwick::invSqrt(float x) {
219
235
i = 0x5f3759df - (i>>1 );
220
236
y = *(float *)&i;
221
237
y = y * (1 .5f - (halfx * y * y));
238
+ y = y * (1 .5f - (halfx * y * y));
222
239
return y;
223
240
}
224
241
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