23
23
24
24
/* Private typedef -------------------------------------------------------------------------*/
25
25
/* Private define --------------------------------------------------------------------------*/
26
- #define MF_KP 0.4f
27
- //#define MF_KI 0.001f
26
+ #define MF_A_THR 0.4f
27
+ #define MF_M_THR 0.1f
28
+
29
+ #define MF_KPA 0.4f
30
+ //#define MF_KIA 0.001f
31
+
32
+ #define MF_KPM 0.01f
33
+ //#define MF_KIM 0.001f
28
34
29
35
//#define MAHONY_FILTER_9DOF
30
36
39
45
* @param imu:
40
46
* @retval None
41
47
*/
42
- void MahonyFilter_Init ( MahonyFilter_t * mf , IMU_DataTypeDef * imu , float32_t sampleRate )
48
+ void MahonyFilter_Init ( MahonyFilter_t * mf , IMU_DataTypeDef * imu , float32_t sampleTime )
43
49
{
44
50
mf -> angE .pitch = 0.0f ;
45
51
mf -> angE .roll = 0.0f ;
@@ -49,7 +55,7 @@ void MahonyFilter_Init( MahonyFilter_t *mf, IMU_DataTypeDef *imu, float32_t samp
49
55
50
56
mf -> imu = imu ;
51
57
52
- mf -> sampleRate = sampleRate ;
58
+ mf -> sampleTime = sampleTime ;
53
59
}
54
60
55
61
/**
@@ -59,17 +65,20 @@ void MahonyFilter_Init( MahonyFilter_t *mf, IMU_DataTypeDef *imu, float32_t samp
59
65
*/
60
66
void MahonyFilter_Update ( MahonyFilter_t * mf )
61
67
{
68
+ float32_t err [3 ];
69
+
62
70
float32_t gVect [3 ];
63
71
float32_t gyr [3 ], acc [3 ];
72
+ #if defined(MF_KIA )
73
+ static float32_t errIntA [3 ] = {0 };
74
+ #endif
64
75
65
76
#if defined(MAHONY_FILTER_9DOF )
66
77
float32_t hVect [3 ], wVect [3 ];
67
78
float32_t mag [3 ];
79
+ #if defined(MF_KIM )
80
+ static float32_t errIntM [3 ] = {0 };
68
81
#endif
69
-
70
- float32_t err [3 ];
71
- #if defined(MF_KI )
72
- static float32_t errInt [3 ] = {0 };
73
82
#endif
74
83
75
84
gyr [0 ] = toRad (mf -> imu -> gyrData [0 ]);
@@ -80,30 +89,47 @@ void MahonyFilter_Update( MahonyFilter_t *mf )
80
89
acc [2 ] = mf -> imu -> accData [2 ];
81
90
82
91
/* Normalise accelerometer measurement */
83
- const float32_t normAcc = invSqrtf (acc [0 ] * acc [0 ] + acc [1 ] * acc [1 ] + acc [2 ] * acc [2 ]);
84
- acc [0 ] *= normAcc ;
85
- acc [1 ] *= normAcc ;
86
- acc [2 ] *= normAcc ;
92
+ const float32_t normAcc = sqrtf (acc [0 ] * acc [0 ] + acc [1 ] * acc [1 ] + acc [2 ] * acc [2 ]);
93
+ if ((normAcc < (mf -> imu -> accStrength * (1.0f + MF_A_THR ))) && (normAcc > (mf -> imu -> accStrength * (1.0f - MF_A_THR )))) {
94
+ acc [0 ] /= normAcc ;
95
+ acc [1 ] /= normAcc ;
96
+ acc [2 ] /= normAcc ;
97
+
98
+ /* Estimated direction of gravity */
99
+ gVect [0 ] = mf -> numQ .rMat [0 ][2 ];
100
+ gVect [1 ] = mf -> numQ .rMat [1 ][2 ];
101
+ gVect [2 ] = mf -> numQ .rMat [2 ][2 ];
102
+
103
+ err [0 ] = acc [1 ] * gVect [2 ] - acc [2 ] * gVect [1 ];
104
+ err [1 ] = acc [2 ] * gVect [0 ] - acc [0 ] * gVect [2 ];
105
+ err [2 ] = acc [0 ] * gVect [1 ] - acc [1 ] * gVect [0 ];
106
+
107
+ #if defined(MF_KIA )
108
+ /* Compute and apply integral feedback */
109
+ errIntA [0 ] += MF_KIA * err [0 ];
110
+ errIntA [1 ] += MF_KIA * err [1 ];
111
+ errIntA [2 ] += MF_KIA * err [2 ];
112
+
113
+ /* Apply proportional feedback */
114
+ gyr [0 ] += MF_KPA * err [0 ] + errIntA [0 ];
115
+ gyr [1 ] += MF_KPA * err [1 ] + errIntA [1 ];
116
+ gyr [2 ] += MF_KPA * err [2 ] + errIntA [2 ];
87
117
88
- /* Estimated direction of gravity */
89
- gVect [0 ] = mf -> numQ . rMat [ 0 ][ 2 ];
90
- gVect [1 ] = mf -> numQ . rMat [ 1 ][ 2 ];
91
- gVect [2 ] = mf -> numQ . rMat [ 2 ] [2 ];
118
+ #else
119
+ gyr [0 ] += MF_KPA * err [ 0 ];
120
+ gyr [1 ] += MF_KPA * err [ 1 ];
121
+ gyr [2 ] += MF_KPA * err [2 ];
92
122
93
- err [0 ] = acc [1 ] * gVect [2 ] - acc [2 ] * gVect [1 ];
94
- err [1 ] = acc [2 ] * gVect [0 ] - acc [0 ] * gVect [2 ];
95
- err [2 ] = acc [0 ] * gVect [1 ] - acc [1 ] * gVect [0 ];
123
+ #endif
124
+ }
96
125
97
126
#if defined(MAHONY_FILTER_9DOF )
98
127
mag [0 ] = mf -> imu -> magData [0 ];
99
128
mag [1 ] = mf -> imu -> magData [1 ];
100
129
mag [2 ] = mf -> imu -> magData [2 ];
101
-
102
- // const float32_t normMag = invSqrtf(mag[0] * mag[0] + mag[1] * mag[1] + mag[2] * mag[2]);
103
- // if ((normMag < fusionAhrs->minMagneticFieldSquared) ||
104
- // (normMag > fusionAhrs->maxMagneticFieldSquared)) {
105
- // break;
106
- // }
130
+ const float32_t normMag = sqrtf (mag [0 ] * mag [0 ] + mag [1 ] * mag [1 ] + mag [2 ] * mag [2 ]);
131
+ if ((normMag < (mf -> imu -> magStrength * (1.0f + MF_M_THR ))) && (normMag > (mf -> imu -> magStrength * (1.0f - MF_M_THR )))) {
132
+ }
107
133
108
134
/* Reference direction of Earth's magnetic field */
109
135
wVect [0 ] = acc [1 ] * mag [2 ] - acc [2 ] * mag [1 ];
@@ -112,8 +138,8 @@ void MahonyFilter_Update( MahonyFilter_t *mf )
112
138
113
139
/* Normalise magnetometer measurement */
114
140
const float32_t normVect = invSqrtf (wVect [0 ] * wVect [0 ] + wVect [1 ] * wVect [1 ] + wVect [2 ] * wVect [2 ]);
115
- wVect [2 ] *= normVect ;
116
- wVect [2 ] *= normVect ;
141
+ wVect [0 ] *= normVect ;
142
+ wVect [1 ] *= normVect ;
117
143
wVect [2 ] *= normVect ;
118
144
119
145
/* Estimated direction of Earth's magnetic field */
@@ -122,41 +148,35 @@ void MahonyFilter_Update( MahonyFilter_t *mf )
122
148
hVect [2 ] = mf -> numQ .rMat [2 ][1 ];
123
149
124
150
/* Error is sum of cross product between estimated direction and measured direction of field vectors */
125
- err [0 ] += wVect [1 ] * hVect [2 ] - wVect [2 ] * hVect [1 ];
126
- err [1 ] += wVect [2 ] * hVect [0 ] - wVect [0 ] * hVect [2 ];
127
- err [2 ] += wVect [0 ] * hVect [1 ] - wVect [1 ] * hVect [0 ];
128
-
129
- #endif
151
+ err [0 ] = wVect [1 ] * hVect [2 ] - wVect [2 ] * hVect [1 ];
152
+ err [1 ] = wVect [2 ] * hVect [0 ] - wVect [0 ] * hVect [2 ];
153
+ err [2 ] = wVect [0 ] * hVect [1 ] - wVect [1 ] * hVect [0 ];
130
154
131
- #if defined(MF_KI )
132
- /* Compute and apply integral feedback */
133
- errInt [0 ] += ( SAMPLE_RATE * MF_KI ) * err [0 ];
134
- errInt [1 ] += ( SAMPLE_RATE * MF_KI ) * err [1 ];
135
- errInt [2 ] += ( SAMPLE_RATE * MF_KI ) * err [2 ];
155
+ #if defined(MF_KIA )
156
+ /* Compute and apply integral feedback */
157
+ errIntA [0 ] += MF_KIM * err [0 ];
158
+ errIntA [1 ] += MF_KIM * err [1 ];
159
+ errIntA [2 ] += MF_KIM * err [2 ];
136
160
137
- /* Apply proportional feedback */
138
- gyr [0 ] += MF_KP * err [0 ] + errInt [0 ];
139
- gyr [1 ] += MF_KP * err [1 ] + errInt [1 ];
140
- gyr [2 ] += MF_KP * err [2 ] + errInt [2 ];
161
+ /* Apply proportional feedback */
162
+ gyr [0 ] += MF_KPM * err [0 ] + errIntM [0 ];
163
+ gyr [1 ] += MF_KPM * err [1 ] + errIntM [1 ];
164
+ gyr [2 ] += MF_KPM * err [2 ] + errIntM [2 ];
141
165
142
166
#else
143
- gyr [0 ] += MF_KP * err [0 ];
144
- gyr [1 ] += MF_KP * err [1 ];
145
- gyr [2 ] += MF_KP * err [2 ];
167
+ gyr [0 ] += MF_KPM * err [0 ];
168
+ gyr [1 ] += MF_KPM * err [1 ];
169
+ gyr [2 ] += MF_KPM * err [2 ];
170
+
171
+ #endif
146
172
147
173
#endif
148
174
149
175
/* Integrate rate of change of quaternion */
150
- // Quaternion_Conjugate(&mf->numQ, &mf->numQ);
151
- Quaternion_RungeKutta (& mf -> numQ , gyr , mf -> sampleRate * 0.5f );
176
+ Quaternion_RungeKutta (& mf -> numQ , gyr , mf -> sampleTime * 0.5f );
152
177
Quaternion_Normalize (& mf -> numQ , & mf -> numQ );
153
178
Quaternion_UpdateRotMatrix (& mf -> numQ );
154
- Quaternion_ToAngE (& mf -> angE , & mf -> numQ );
155
-
156
- // // Get Euler Angle */
157
- // mf->angE.pitch = -toDeg(mf->angE.pitch);
158
- // mf->angE.roll = toDeg(mf->angE.roll);
159
- // mf->angE.yaw = -toDeg(mf->angE.yaw);
179
+ // Quaternion_ToAngE(&mf->angE, &mf->numQ);
160
180
}
161
181
162
182
/*************************************** END OF FILE ****************************************/
0 commit comments