38 : m_beta(beta), m_q0(1.0), m_q1(0.0), m_q2(0.0), m_q3(0.0)
59 double ax,
double ay,
double az,
60 double mx,
double my,
double mz,
61 double dt,
bool useMag)
64 if (dt <= 0.0 || dt > 1.0)
68 double magNorm = mx * mx + my * my + mz * mz;
69 if (useMag && magNorm > 1e-12)
70 update9DOF(gx, gy, gz, ax, ay, az, mx, my, mz, dt);
72 update6DOF(gx, gy, gz, ax, ay, az, dt);
75void MadgwickFilter::update9DOF(
double gx,
double gy,
double gz,
76 double ax,
double ay,
double az,
77 double mx,
double my,
double mz,
81 double q0 = m_q0, q1 = m_q1, q2 = m_q2, q3 = m_q3;
84 double accNorm = std::sqrt(ax * ax + ay * ay + az * az);
88 update6DOF(gx, gy, gz, 0, 0, 0, dt);
96 double magNorm = std::sqrt(mx * mx + my * my + mz * mz);
102 double q0q1 = q0 * q1, q0q2 = q0 * q2, q0q3 = q0 * q3;
103 double q1q1 = q1 * q1, q1q2 = q1 * q2, q1q3 = q1 * q3;
104 double q2q2 = q2 * q2, q2q3 = q2 * q3;
105 double q3q3 = q3 * q3;
109 double hx = 2.0 * (mx * (0.5 - q2q2 - q3q3) + my * (q1q2 - q0q3) + mz * (q1q3 + q0q2));
110 double hy = 2.0 * (mx * (q1q2 + q0q3) + my * (0.5 - q1q1 - q3q3) + mz * (q2q3 - q0q1));
113 double bx = std::sqrt(hx * hx + hy * hy);
114 double bz = 2.0 * (mx * (q1q3 - q0q2) + my * (q2q3 + q0q1) + mz * (0.5 - q1q1 - q2q2));
118 double f1 = 2.0 * (q1q3 - q0q2) - ax;
119 double f2 = 2.0 * (q0q1 + q2q3) - ay;
120 double f3 = 2.0 * (0.5 - q1q1 - q2q2) - az;
123 double f4 = 2.0 * bx * (0.5 - q2q2 - q3q3) + 2.0 * bz * (q1q3 - q0q2) - mx;
124 double f5 = 2.0 * bx * (q1q2 - q0q3) + 2.0 * bz * (q0q1 + q2q3) - my;
125 double f6 = 2.0 * bx * (q0q2 + q1q3) + 2.0 * bz * (0.5 - q1q1 - q2q2) - mz;
129 double Jt_g0 = -2.0 * q2 * f1 + 2.0 * q1 * f2;
130 double Jt_g1 = 2.0 * q3 * f1 + 2.0 * q0 * f2 - 4.0 * q1 * f3;
131 double Jt_g2 = -2.0 * q0 * f1 + 2.0 * q3 * f2 - 4.0 * q2 * f3;
132 double Jt_g3 = 2.0 * q1 * f1 + 2.0 * q2 * f2;
135 double Jt_b0 = -2.0 * bz * q2 * f4 + (-2.0 * bx * q3 + 2.0 * bz * q1) * f5 + 2.0 * bx * q2 * f6;
136 double Jt_b1 = 2.0 * bz * q3 * f4 + ( 2.0 * bx * q2 + 2.0 * bz * q0) * f5 +
137 (2.0 * bx * q3 - 4.0 * bz * q1) * f6;
138 double Jt_b2 = (-4.0 * bx * q2 - 2.0 * bz * q0) * f4 + ( 2.0 * bx * q1 + 2.0 * bz * q3) * f5 +
139 (2.0 * bx * q0 - 4.0 * bz * q2) * f6;
140 double Jt_b3 = (-4.0 * bx * q3 + 2.0 * bz * q1) * f4 + (-2.0 * bx * q0 + 2.0 * bz * q2) * f5 + 2.0 * bx * q1 * f6;
143 double step0 = Jt_g0 + Jt_b0;
144 double step1 = Jt_g1 + Jt_b1;
145 double step2 = Jt_g2 + Jt_b2;
146 double step3 = Jt_g3 + Jt_b3;
149 double stepNorm = std::sqrt(step0 * step0 + step1 * step1 + step2 * step2 + step3 * step3);
156 double qDot0 = 0.5 * (-q1 * gx - q2 * gy - q3 * gz);
157 double qDot1 = 0.5 * ( q0 * gx + q2 * gz - q3 * gy);
158 double qDot2 = 0.5 * ( q0 * gy - q1 * gz + q3 * gx);
159 double qDot3 = 0.5 * ( q0 * gz + q1 * gy - q2 * gx);
162 qDot0 -= m_beta * step0;
163 qDot1 -= m_beta * step1;
164 qDot2 -= m_beta * step2;
165 qDot3 -= m_beta * step3;
173 double qNorm = std::sqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
180void MadgwickFilter::update6DOF(
double gx,
double gy,
double gz,
181 double ax,
double ay,
double az,
184 double q0 = m_q0, q1 = m_q1, q2 = m_q2, q3 = m_q3;
187 double qDot0 = 0.5 * (-q1 * gx - q2 * gy - q3 * gz);
188 double qDot1 = 0.5 * ( q0 * gx + q2 * gz - q3 * gy);
189 double qDot2 = 0.5 * ( q0 * gy - q1 * gz + q3 * gx);
190 double qDot3 = 0.5 * ( q0 * gz + q1 * gy - q2 * gx);
193 double accNorm = std::sqrt(ax * ax + ay * ay + az * az);
201 double f1 = 2.0 * (q1 * q3 - q0 * q2) - ax;
202 double f2 = 2.0 * (q0 * q1 + q2 * q3) - ay;
203 double f3 = 2.0 * (0.5 - q1 * q1 - q2 * q2) - az;
206 double Jt0 = -2.0 * q2 * f1 + 2.0 * q1 * f2;
207 double Jt1 = 2.0 * q3 * f1 + 2.0 * q0 * f2 - 4.0 * q1 * f3;
208 double Jt2 = -2.0 * q0 * f1 + 2.0 * q3 * f2 - 4.0 * q2 * f3;
209 double Jt3 = 2.0 * q1 * f1 + 2.0 * q2 * f2;
211 double stepNorm = std::sqrt(Jt0 * Jt0 + Jt1 * Jt1 + Jt2 * Jt2 + Jt3 * Jt3);
212 qDot0 -= m_beta * Jt0 / stepNorm;
213 qDot1 -= m_beta * Jt1 / stepNorm;
214 qDot2 -= m_beta * Jt2 / stepNorm;
215 qDot3 -= m_beta * Jt3 / stepNorm;
224 double qNorm = std::sqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
236 : m_kp(kp), m_ki(ki),
237 m_q0(1.0), m_q1(0.0), m_q2(0.0), m_q3(0.0),
238 m_integralFBx(0.0), m_integralFBy(0.0), m_integralFBz(0.0)
262 double ax,
double ay,
double az,
263 double mx,
double my,
double mz,
264 double dt,
bool useMag)
267 if (dt <= 0.0 || dt > 1.0)
270 double q0 = m_q0, q1 = m_q1, q2 = m_q2, q3 = m_q3;
272 double halfex = 0.0, halfey = 0.0, halfez = 0.0;
275 double magNorm = mx * mx + my * my + mz * mz;
276 if (useMag && magNorm > 1e-12)
279 double accNorm = std::sqrt(ax * ax + ay * ay + az * az);
282 double axn = ax / accNorm, ayn = ay / accNorm, azn = az / accNorm;
285 double mxn = mx / std::sqrt(magNorm);
286 double myn = my / std::sqrt(magNorm);
287 double mzn = mz / std::sqrt(magNorm);
290 double hx = 2.0 * (mxn * (0.5 - q2 * q2 - q3 * q3) + myn * (q1 * q2 - q0 * q3) + mzn * (q1 * q3 + q0 * q2));
291 double hy = 2.0 * (mxn * (q1 * q2 + q0 * q3) + myn * (0.5 - q1 * q1 - q3 * q3) + mzn * (q2 * q3 - q0 * q1));
292 double bx = std::sqrt(hx * hx + hy * hy);
293 double bz = 2.0 * (mxn * (q1 * q3 - q0 * q2) + myn * (q2 * q3 + q0 * q1) + mzn * (0.5 - q1 * q1 - q2 * q2));
296 double vx = 2.0 * (q1 * q3 - q0 * q2);
297 double vy = 2.0 * (q0 * q1 + q2 * q3);
298 double vz = q0 * q0 - q1 * q1 - q2 * q2 + q3 * q3;
299 double wx = 2.0 * bx * (0.5 - q2 * q2 - q3 * q3) + 2.0 * bz * (q1 * q3 - q0 * q2);
300 double wy = 2.0 * bx * (q1 * q2 - q0 * q3) + 2.0 * bz * (q0 * q1 + q2 * q3);
301 double wz = 2.0 * bx * (q0 * q2 + q1 * q3) + 2.0 * bz * (0.5 - q1 * q1 - q2 * q2);
304 halfex = (ayn * vz - azn * vy) + (myn * wz - mzn * wy);
305 halfey = (azn * vx - axn * vz) + (mzn * wx - mxn * wz);
306 halfez = (axn * vy - ayn * vx) + (mxn * wy - myn * wx);
312 double accNorm = std::sqrt(ax * ax + ay * ay + az * az);
315 double axn = ax / accNorm, ayn = ay / accNorm, azn = az / accNorm;
318 double vx = 2.0 * (q1 * q3 - q0 * q2);
319 double vy = 2.0 * (q0 * q1 + q2 * q3);
320 double vz = q0 * q0 - q1 * q1 - q2 * q2 + q3 * q3;
322 halfex = ayn * vz - azn * vy;
323 halfey = azn * vx - axn * vz;
324 halfez = axn * vy - ayn * vx;
331 m_integralFBx += m_ki * halfex * dt;
332 m_integralFBy += m_ki * halfey * dt;
333 m_integralFBz += m_ki * halfez * dt;
343 gx += m_kp * halfex + m_integralFBx;
344 gy += m_kp * halfey + m_integralFBy;
345 gz += m_kp * halfez + m_integralFBz;
348 double qDot0 = 0.5 * (-q1 * gx - q2 * gy - q3 * gz);
349 double qDot1 = 0.5 * ( q0 * gx + q2 * gz - q3 * gy);
350 double qDot2 = 0.5 * ( q0 * gy - q1 * gz + q3 * gx);
351 double qDot3 = 0.5 * ( q0 * gz + q1 * gy - q2 * gx);
359 double qNorm = std::sqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
MadgwickFilter(double beta=0.1)
void getQuaternion(double &w, double &i, double &j, double &k) const override
Return the current orientation quaternion.
void update(double gx, double gy, double gz, double ax, double ay, double az, double mx, double my, double mz, double dt, bool useMag=true) override
Perform one filter update step.
void reset() override
Reset the filter to the identity quaternion.
void reset() override
Reset the filter to the identity quaternion.
MahonyFilter(double kp=2.0, double ki=0.005)
void getQuaternion(double &w, double &i, double &j, double &k) const override
Return the current orientation quaternion.
void update(double gx, double gy, double gz, double ax, double ay, double az, double mx, double my, double mz, double dt, bool useMag=true) override
Perform one filter update step.
Namespace to encapsulate INDI client, drivers, and mediator classes.