Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
pprz_algebra_float.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2008-2014 The Paparazzi Team
3 *
4 * This file is part of paparazzi.
5 *
6 * paparazzi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * paparazzi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with paparazzi; see the file COPYING. If not, see
18 * <http://www.gnu.org/licenses/>.
19 */
20
31#ifndef PPRZ_ALGEBRA_FLOAT_H
32#define PPRZ_ALGEBRA_FLOAT_H
33
34#ifdef __cplusplus
35extern "C" {
36#endif
37
38#include "pprz_algebra.h"
39#include "message_pragmas.h"
40
41#include <math.h>
42#include <float.h> // for FLT_MIN
43
44/* this seems to be missing for some arch */
45#ifndef M_SQRT2
46#define M_SQRT2 1.41421356237309504880
47#endif
48
49struct FloatVect2 {
50 float x;
51 float y;
52};
53
54struct FloatVect3 {
55 float x;
56 float y;
57 float z;
58};
59
63struct FloatQuat {
64 float qi;
65 float qx;
66 float qy;
67 float qz;
68};
69
70struct FloatMat33 {
71 float m[3 * 3];
72};
73
77struct FloatRMat {
78 float m[3 * 3];
79};
80
85 float phi;
86 float theta;
87 float psi;
88};
89
93struct FloatRates {
94 float p;
95 float q;
96 float r;
97};
98
99#define FLOAT_ANGLE_NORMALIZE(_a) { \
100 while (_a > M_PI) _a -= (2.*M_PI); \
101 while (_a < -M_PI) _a += (2.*M_PI); \
102 }
103
104/*
105 * Returns the real part of the log of v in base of n
106 */
107static inline float float_log_n(const float v, const float n)
108{
109 if (fabsf(v) < 1e-4) { // avoid inf
110 return - 1.0E+30;
111 }
112 if (fabsf(n) < 1e-4) { // avoid nan
113 return 0;
114 }
115 return logf(fabsf(v)) / logf(n);
116}
117
118//
119//
120// Vector algebra
121//
122//
123
124
125/*
126 * Dimension 2 Vectors
127 */
128
129#define FLOAT_VECT2_ZERO(_v) VECT2_ASSIGN(_v, 0., 0.)
130
131/* macros also usable if _v is not a FloatVect2, but a different struct with x,y members */
132#define FLOAT_VECT2_NORM(_v) sqrtf(VECT2_NORM2(_v))
133
134static inline float float_vect2_norm2(const struct FloatVect2 *v)
135{
136 return v->x * v->x + v->y * v->y;
137}
138
139static inline float float_vect2_norm(const struct FloatVect2 *v)
140{
141 return sqrtf(float_vect2_norm2(v));
142}
143
145static inline void float_vect2_normalize(struct FloatVect2 *v)
146{
147 const float n = float_vect2_norm(v);
148 if (n > 1e-4f) {
149 v->x /= n;
150 v->y /= n;
151 }
152}
153
154#define FLOAT_VECT2_NORMALIZE(_v) float_vect2_normalize(&(_v))
155
156
157/*
158 * Dimension 3 Vectors
159 */
160
161#define FLOAT_VECT3_ZERO(_v) VECT3_ASSIGN(_v, 0., 0., 0.)
162
163/* macros also usable if _v is not a FloatVect3, but a different struct with x,y,z members */
164#define FLOAT_VECT3_NORM(_v) sqrtf(VECT3_NORM2(_v))
165
166static inline float float_vect3_norm2(const struct FloatVect3 *v)
167{
168 return v->x * v->x + v->y * v->y + v->z * v->z;
169}
170
171static inline float float_vect3_norm(const struct FloatVect3 *v)
172{
173 return sqrtf(float_vect3_norm2(v));
174}
175
177static inline void float_vect3_normalize(struct FloatVect3 *v)
178{
179 const float n = float_vect3_norm(v);
180 if (n > 1e-4f) {
181 v->x /= n;
182 v->y /= n;
183 v->z /= n;
184 }
185}
186
187#define FLOAT_VECT3_NORMALIZE(_v) float_vect3_normalize(&(_v))
188
189
190
191#define FLOAT_RATES_ZERO(_r) { \
192 RATES_ASSIGN(_r, 0., 0., 0.); \
193 }
194
195#define FLOAT_RATES_NORM(_v) (sqrtf((_v).p*(_v).p + (_v).q*(_v).q + (_v).r*(_v).r))
196
197#define FLOAT_RATES_LIN_CMB(_ro, _r1, _s1, _r2, _s2) { \
198 _ro.p = _s1 * _r1.p + _s2 * _r2.p; \
199 _ro.q = _s1 * _r1.q + _s2 * _r2.q; \
200 _ro.r = _s1 * _r1.r + _s2 * _r2.r; \
201 }
202
203
204extern void float_vect3_integrate_fi(struct FloatVect3 *vec, const struct FloatVect3 *dv,
205 const float dt);
206
207extern void float_rates_integrate_fi(struct FloatRates *r, const struct FloatRates *dr,
208 const float dt);
209
210extern void float_rates_vect3_integrate_fi(struct FloatRates *r, const struct FloatVect3 *dr,
211 const float dt);
212
213extern void float_rates_of_euler_dot(struct FloatRates *r, const struct FloatEulers *e,
214 const struct FloatEulers *edot);
215
216/* defines for backwards compatibility */
217#define FLOAT_VECT3_INTEGRATE_FI(_vo, _dv, _dt) WARNING("FLOAT_VECT3_INTEGRATE_FI macro is deprecated, use the lower case function instead") float_vect3_integrate_fi(&(_vo), &(_dv), _dt)
218#define FLOAT_RATES_INTEGRATE_FI(_ra, _racc, _dt) WARNING("FLOAT_RATES_INTEGRATE_FI macro is deprecated, use the lower case function instead") float_rates_integrate_fi(&(_ra), &(_racc), _dt)
219#define FLOAT_RATES_OF_EULER_DOT(_ra, _e, _ed) WARNING("FLOAT_RATES_OF_EULER_DOT macro is deprecated, use the lower case function instead") float_rates_of_euler_dot(&(_ra), &(_e), &(_ed))
220
221
222/*
223 * 3x3 matrices
224 */
225#define FLOAT_MAT33_ZERO(_m) { \
226 MAT33_ELMT(_m, 0, 0) = 0.; \
227 MAT33_ELMT(_m, 0, 1) = 0.; \
228 MAT33_ELMT(_m, 0, 2) = 0.; \
229 MAT33_ELMT(_m, 1, 0) = 0.; \
230 MAT33_ELMT(_m, 1, 1) = 0.; \
231 MAT33_ELMT(_m, 1, 2) = 0.; \
232 MAT33_ELMT(_m, 2, 0) = 0.; \
233 MAT33_ELMT(_m, 2, 1) = 0.; \
234 MAT33_ELMT(_m, 2, 2) = 0.; \
235 }
236
237#define FLOAT_MAT33_DIAG(_m, _d00, _d11, _d22) { \
238 MAT33_ELMT(_m, 0, 0) = _d00; \
239 MAT33_ELMT(_m, 0, 1) = 0.; \
240 MAT33_ELMT(_m, 0, 2) = 0.; \
241 MAT33_ELMT(_m, 1, 0) = 0.; \
242 MAT33_ELMT(_m, 1, 1) = _d11; \
243 MAT33_ELMT(_m, 1, 2) = 0.; \
244 MAT33_ELMT(_m, 2, 0) = 0.; \
245 MAT33_ELMT(_m, 2, 1) = 0.; \
246 MAT33_ELMT(_m, 2, 2) = _d22; \
247 }
248
249
250//
251//
252// Rotation Matrices
253//
254//
255
256
258static inline void float_rmat_identity(struct FloatRMat *rm)
259{
260 FLOAT_MAT33_DIAG(*rm, 1., 1., 1.);
261}
262
266extern void float_rmat_inv(struct FloatRMat *m_b2a, const struct FloatRMat *m_a2b);
267
271extern void float_rmat_comp(struct FloatRMat *m_a2c, const struct FloatRMat *m_a2b,
272 const struct FloatRMat *m_b2c);
273
277extern void float_rmat_comp_inv(struct FloatRMat *m_a2b, const struct FloatRMat *m_a2c,
278 const struct FloatRMat *m_b2c);
279
281extern float float_rmat_norm(const struct FloatRMat *rm);
282
286extern void float_rmat_vmult(struct FloatVect3 *vb, const struct FloatRMat *m_a2b,
287 const struct FloatVect3 *va);
288
292extern void float_rmat_transp_vmult(struct FloatVect3 *vb, const struct FloatRMat *m_b2a,
293 const struct FloatVect3 *va);
294
298extern void float_rmat_mult(struct FloatEulers *rb, const struct FloatRMat *m_a2b,
299 const struct FloatEulers *ra);
300
304extern void float_rmat_transp_mult(struct FloatEulers *rb, const struct FloatRMat *m_b2a,
305 const struct FloatEulers *ra);
306
310extern void float_rmat_ratemult(struct FloatRates *rb, const struct FloatRMat *m_a2b,
311 const struct FloatRates *ra);
312
316extern void float_rmat_transp_ratemult(struct FloatRates *rb, const struct FloatRMat *m_b2a,
317 const struct FloatRates *ra);
318
320extern void float_rmat_of_axis_angle(struct FloatRMat *rm, const struct FloatVect3 *uv, const float angle);
321
334extern void float_rmat_of_eulers_321(struct FloatRMat *rm, const struct FloatEulers *e);
335extern void float_rmat_of_eulers_312(struct FloatRMat *rm, const struct FloatEulers *e);
336#define float_rmat_of_eulers float_rmat_of_eulers_321
337
338extern void float_rmat_of_quat(struct FloatRMat *rm, const struct FloatQuat *q);
340extern void float_rmat_integrate_fi(struct FloatRMat *rm, const struct FloatRates *omega, const float dt);
341extern float float_rmat_reorthogonalize(struct FloatRMat *rm);
342
343/* defines for backwards compatibility */
344#define FLOAT_RMAT_INV(_m_b2a, _m_a2b) WARNING("FLOAT_RMAT_INV macro is deprecated, use the lower case function instead") float_rmat_inv(&(_m_b2a), &(_m_a2b))
345#define FLOAT_RMAT_NORM(_m) WARNING("FLOAT_RMAT_NORM macro is deprecated, use the lower case function instead") float_rmat_norm(&(_m))
346#define FLOAT_RMAT_COMP(_m_a2c, _m_a2b, _m_b2c) WARNING("FLOAT_RMAT_COMP macro is deprecated, use the lower case function instead") float_rmat_comp(&(_m_a2c), &(_m_a2b), &(_m_b2c))
347#define FLOAT_RMAT_COMP_INV(_m_a2b, _m_a2c, _m_b2c) WARNING("FLOAT_RMAT_COMP_INV macro is deprecated, use the lower case function instead") float_rmat_comp_inv(&(_m_a2b), &(_m_a2c), &(_m_b2c))
348#define FLOAT_RMAT_VMULT(_vb, _m_a2b, _va) WARNING("FLOAT_RMAT_VMULT macro is deprecated, use the lower case function instead") float_rmat_vmult(&(_vb), &(_m_a2b), &(_va))
349#define FLOAT_RMAT_TRANSP_VMULT(_vb, _m_b2a, _va) WARNING("FLOAT_RMAT_TRANSP_VMULT macro is deprecated, use the lower case function instead") float_rmat_transp_vmult(&(_vb), &(_m_b2a), &(_va))
350#define FLOAT_RMAT_RATEMULT(_rb, _m_a2b, _ra) WARNING("FLOAT_RMAT_RATEMULT macro is deprecated, use the lower case function instead") float_rmat_ratemult(&(_rb), &(_m_a2b), &(_ra))
351#define FLOAT_RMAT_TRANSP_RATEMULT(_rb, _m_b2a, _ra) WARNING("FLOAT_RMAT_TRANSP_RATEMULT macro is deprecated, use the lower case function instead") float_rmat_ratemult(&(_rb), &(_m_b2a), &(_ra))
352#define FLOAT_RMAT_OF_AXIS_ANGLE(_rm, _uv, _an) WARNING("FLOAT_RMAT_OF_AXIS_ANGLE macro is deprecated, use the lower case function instead") float_rmat_of_axis_angle(&(_rm), &(_uv), _an)
353#define FLOAT_RMAT_OF_EULERS(_rm, _e) WARNING("FLOAT_RMAT_OF_EULERS macro is deprecated, use the lower case function instead") float_rmat_of_eulers_321(&(_rm), &(_e))
354#define FLOAT_RMAT_OF_EULERS_321(_rm, _e) WARNING("FLOAT_RMAT_OF_EULERS_321 macro is deprecated, use the lower case function instead") float_rmat_of_eulers_321(&(_rm), &(_e))
355#define FLOAT_RMAT_OF_EULERS_312(_rm, _e) WARNING("FLOAT_RMAT_OF_EULERS_312 macro is deprecated, use the lower case function instead") float_rmat_of_eulers_312(&(_rm), &(_e))
356#define FLOAT_RMAT_OF_QUAT(_rm, _q) WARNING("FLOAT_RMAT_OF_QUAT macro is deprecated, use the lower case function instead") float_rmat_of_quat(&(_rm), &(_q))
357#define FLOAT_RMAT_INTEGRATE_FI(_rm, _omega, _dt) WARNING("FLOAT_RMAT_INTEGRATE_FI macro is deprecated, use the lower case function instead") float_rmat_integrate_fi(&(_rm), &(_omega), &(_dt))
358
359
360
361//
362//
363// Quaternion algebras
364//
365//
366
368static inline void float_quat_identity(struct FloatQuat *q)
369{
370 q->qi = 1.0;
371 q->qx = 0;
372 q->qy = 0;
373 q->qz = 0;
374}
375
376#define FLOAT_QUAT_NORM2(_q) (SQUARE((_q).qi) + SQUARE((_q).qx) + SQUARE((_q).qy) + SQUARE((_q).qz))
377
378static inline float float_quat_norm(const struct FloatQuat *q)
379{
380 return sqrtf(SQUARE(q->qi) + SQUARE(q->qx) + SQUARE(q->qy) + SQUARE(q->qz));
381}
382
383static inline void float_quat_normalize(struct FloatQuat *q)
384{
385 float qnorm = float_quat_norm(q);
386 if (qnorm > FLT_MIN) {
387 q->qi = q->qi / qnorm;
388 q->qx = q->qx / qnorm;
389 q->qy = q->qy / qnorm;
390 q->qz = q->qz / qnorm;
391 }
392}
393
394static inline void float_quat_invert(struct FloatQuat *qo, const struct FloatQuat *qi)
395{
396 QUAT_INVERT(*qo, *qi);
397}
398
399static inline void float_quat_wrap_shortest(struct FloatQuat *q)
400{
401 if (q->qi < 0.) {
402 QUAT_EXPLEMENTARY(*q, *q);
403 }
404}
405
406#define FLOAT_QUAT_EXTRACT(_vo, _qi) QUAT_EXTRACT_Q(_vo, _qi)
407
408
412extern void float_quat_comp(struct FloatQuat *a2c, const struct FloatQuat *a2b, const struct FloatQuat *b2c);
413
417extern void float_quat_comp_inv(struct FloatQuat *a2b, const struct FloatQuat *a2c, const struct FloatQuat *b2c);
418
422extern void float_quat_inv_comp(struct FloatQuat *b2c, const struct FloatQuat *a2b, const struct FloatQuat *a2c);
423
427extern void float_quat_comp_norm_shortest(struct FloatQuat *a2c, const struct FloatQuat *a2b,
428 const struct FloatQuat *b2c);
429
433extern void float_quat_comp_inv_norm_shortest(struct FloatQuat *a2b, const struct FloatQuat *a2c,
434 const struct FloatQuat *b2c);
435
439extern void float_quat_inv_comp_norm_shortest(struct FloatQuat *b2c, const struct FloatQuat *a2b,
440 const struct FloatQuat *a2c);
441
447extern void float_quat_derivative(struct FloatQuat *qd, const struct FloatRates *r, const struct FloatQuat *q);
448
454extern void float_quat_derivative_lagrange(struct FloatQuat *qd, const struct FloatRates *r, const struct FloatQuat *q);
455
458extern void float_quat_differential(struct FloatQuat *q_out, const struct FloatRates *w, const float dt);
459
461extern void float_quat_integrate_fi(struct FloatQuat *q, const struct FloatRates *omega, const float dt);
462
464extern void float_quat_integrate(struct FloatQuat *q, const struct FloatRates *omega, const float dt);
465
469extern void float_quat_vmult(struct FloatVect3 *v_out, const struct FloatQuat *q, const struct FloatVect3 *v_in);
470
472extern void float_quat_of_eulers(struct FloatQuat *q, const struct FloatEulers *e);
473extern void float_quat_of_eulers_zxy(struct FloatQuat *q, const struct FloatEulers *e);
474extern void float_quat_of_eulers_yxz(struct FloatQuat *q, const struct FloatEulers *e);
475
480extern void float_quat_of_axis_angle(struct FloatQuat *q, const struct FloatVect3 *uv, const float angle);
481
485extern void float_quat_of_orientation_vect(struct FloatQuat *q, const struct FloatVect3 *ov);
486
488extern void float_quat_of_rmat(struct FloatQuat *q, const struct FloatRMat *rm);
489
491extern void float_quat_tilt_twist(struct FloatQuat *tilt, struct FloatQuat *twist, const struct FloatQuat *quat);
492
493
494/* defines for backwards compatibility */
495#define FLOAT_QUAT_ZERO(_q) WARNING("FLOAT_QUAT_ZERO macro is deprecated, use the lower case function instead") float_quat_identity(&(_q))
496#define FLOAT_QUAT_INVERT(_qo, _qi) WARNING("FLOAT_QUAT_INVERT macro is deprecated, use the lower case function instead") float_quat_invert(&(_qo), &(_qi))
497#define FLOAT_QUAT_WRAP_SHORTEST(_q) WARNING("FLOAT_QUAT_WRAP_SHORTEST macro is deprecated, use the lower case function instead") float_quat_wrap_shortest(&(_q))
498#define FLOAT_QUAT_NORM(_q) WARNING("FLOAT_QUAT_NORM macro is deprecated, use the lower case function instead") float_quat_norm(&(_q))
499#define FLOAT_QUAT_NORMALIZE(_q) WARNING("FLOAT_QUAT_NORMALIZE macro is deprecated, use the lower case function instead") float_quat_normalize(&(_q))
500#define FLOAT_QUAT_COMP(_a2c, _a2b, _b2c) WARNING("FLOAT_QUAT_COMP macro is deprecated, use the lower case function instead") float_quat_comp(&(_a2c), &(_a2b), &(_b2c))
501#define FLOAT_QUAT_MULT(_a2c, _a2b, _b2c) WARNING("FLOAT_QUAT_MULT macro is deprecated, use the lower case function instead") float_quat_comp(&(_a2c), &(_a2b), &(_b2c))
502#define FLOAT_QUAT_INV_COMP(_b2c, _a2b, _a2c) WARNING("FLOAT_QUAT_INV_COMP macro is deprecated, use the lower case function instead") float_quat_inv_comp(&(_b2c), &(_a2b), &(_a2c))
503#define FLOAT_QUAT_COMP_INV(_a2b, _a2c, _b2c) WARNING("FLOAT_QUAT_COMP_INV macro is deprecated, use the lower case function instead") float_quat_comp_inv(&(_a2b), &(_a2c), &(_b2c))
504#define FLOAT_QUAT_COMP_NORM_SHORTEST(_a2c, _a2b, _b2c) WARNING("FLOAT_QUAT_COMP_NORM_SHORTEST macro is deprecated, use the lower case function instead") float_quat_comp_norm_shortest(&(_a2c), &(_a2b), &(_b2c))
505#define FLOAT_QUAT_COMP_INV_NORM_SHORTEST(_a2b, _a2c, _b2c) WARNING("FLOAT_QUAT_COMP_INV_NORM_SHORTEST macro is deprecated, use the lower case function instead") float_quat_comp_inv_norm_shortest(&(_a2b), &(_a2c), &(_b2c))
506#define FLOAT_QUAT_INV_COMP_NORM_SHORTEST(_b2c, _a2b, _a2c) WARNING("FLOAT_QUAT_INV_COMP_NORM_SHORTEST macro is deprecated, use the lower case function instead") float_quat_inv_comp_norm_shortest(&(_b2c), &(_a2b), &(_a2c))
507#define FLOAT_QUAT_DIFFERENTIAL(q_out, w, dt) WARNING("FLOAT_QUAT_DIFFERENTIAL macro is deprecated, use the lower case function instead") float_quat_differential(&(q_out), &(w), dt)
508#define FLOAT_QUAT_INTEGRATE(_q, _omega, _dt) WARNING("FLOAT_QUAT_INTEGRATE macro is deprecated, use the lower case function instead") float_quat_integrate(&(_q), &(_omega), _dt)
509#define FLOAT_QUAT_VMULT(v_out, q, v_in) WARNING("FLOAT_QUAT_VMULT macro is deprecated, use the lower case function instead") float_quat_vmult(&(v_out), &(q), &(v_in))
510#define FLOAT_QUAT_DERIVATIVE(_qd, _r, _q) WARNING("FLOAT_QUAT_DERIVATIVE macro is deprecated, use the lower case function instead") float_quat_derivative(&(_qd), &(_r), &(_q))
511#define FLOAT_QUAT_DERIVATIVE_LAGRANGE(_qd, _r, _q) WARNING("FLOAT_QUAT_DERIVATIVE_LAGRANGE macro is deprecated, use the lower case function instead") float_quat_derivative_lagrange(&(_qd), &(_r), &(_q))
512#define FLOAT_QUAT_OF_EULERS(_q, _e) WARNING("FLOAT_QUAT_OF_EULERS macro is deprecated, use the lower case function instead") float_quat_of_eulers(&(_q), &(_e))
513#define FLOAT_QUAT_OF_AXIS_ANGLE(_q, _uv, _an) WARNING("FLOAT_QUAT_OF_AXIS_ANGLE macro is deprecated, use the lower case function instead") float_quat_of_axis_angle(&(_q), &(_uv), _an)
514#define FLOAT_QUAT_OF_ORIENTATION_VECT(_q, _ov) WARNING("FLOAT_QUAT_OF_ORIENTATION_VECT macro is deprecated, use the lower case function instead") float_quat_of_orientation_vect(&(_q), &(_ov))
515#define FLOAT_QUAT_OF_RMAT(_q, _r) WARNING("FLOAT_QUAT_OF_RMAT macro is deprecated, use the lower case function instead") float_quat_of_rmat(&(_q), &(_r))
516
517
518
519//
520//
521// Euler angles
522//
523//
524
525#define FLOAT_EULERS_ZERO(_e) EULERS_ASSIGN(_e, 0., 0., 0.);
526
527static inline float float_eulers_norm(const struct FloatEulers *e)
528{
529 return sqrtf(SQUARE(e->phi) + SQUARE(e->theta) + SQUARE(e->psi));
530}
531extern void float_eulers_of_rmat(struct FloatEulers *e, const struct FloatRMat *rm);
532extern void float_eulers_of_quat(struct FloatEulers *e, const struct FloatQuat *q);
533extern void float_eulers_of_quat_zxy(struct FloatEulers *e, const struct FloatQuat *q);
534extern void float_eulers_of_quat_yxz(struct FloatEulers *e, const struct FloatQuat *q);
535
536/* defines for backwards compatibility */
537#define FLOAT_EULERS_OF_RMAT(_e, _rm) WARNING("FLOAT_EULERS_OF_RMAT macro is deprecated, use the lower case function instead") float_eulers_of_rmat(&(_e), &(_rm))
538#define FLOAT_EULERS_OF_QUAT(_e, _q) WARNING("FLOAT_EULERS_OF_QUAT macro is deprecated, use the lower case function instead") float_eulers_of_quat(&(_e), &(_q))
539#define FLOAT_EULERS_NORM(_e) WARNING("FLOAT_EULERS_NORM macro is deprecated, use the lower case function instead") float_eulers_norm(&(_e))
540
541//
542//
543// Generic vector algebra
544//
545//
546
548static inline void float_vect_zero(float *a, const int n)
549{
550 int i;
551 for (i = 0; i < n; i++) { a[i] = 0.; }
552}
553
555static inline void float_vect_copy(float *a, const float *b, const int n)
556{
557 int i;
558 for (i = 0; i < n; i++) { a[i] = b[i]; }
559}
560
562static inline void float_vect_sum(float *o, const float *a, const float *b, const int n)
563{
564 int i;
565 for (i = 0; i < n; i++) { o[i] = a[i] + b[i]; }
566}
567
569static inline void float_vect_diff(float *o, const float *a, const float *b, const int n)
570{
571 int i;
572 for (i = 0; i < n; i++) { o[i] = a[i] - b[i]; }
573}
574
576static inline void float_vect_mul(float *o, const float *a, const float *b, const int n)
577{
578 int i;
579 for (i = 0; i < n; i++) { o[i] = a[i] * b[i]; }
580}
581
583static inline void float_vect_add(float *a, const float *b, const int n)
584{
585 int i;
586 for (i = 0; i < n; i++) { a[i] += b[i]; }
587}
588
590static inline void float_vect_sub(float *a, const float *b, const int n)
591{
592 int i;
593 for (i = 0; i < n; i++) { a[i] -= b[i]; }
594}
595
597static inline void float_vect_smul(float *o, const float *a, const float s, const int n)
598{
599 int i;
600 for (i = 0; i < n; i++) { o[i] = a[i] * s; }
601}
602
604static inline void float_vect_sdiv(float *o, const float *a, const float s, const int n)
605{
606 int i;
607 if (fabs(s) > 1e-5) {
608 for (i = 0; i < n; i++) { o[i] = a[i] / s; }
609 }
610}
611
613static inline float float_vect_norm(const float *a, const int n)
614{
615 int i;
616 float sum = 0;
617 for (i = 0; i < n; i++) { sum += a[i] * a[i]; }
618 return sqrtf(sum);
619}
620
622static inline void float_vect_scale(float *a, const float s, const int n)
623{
624 int i;
625 for (i = 0; i < n; i++) { a[i] *= s; }
626}
627
629static inline float float_vect_dot_product(const float *a, const float *b, const int n)
630{
631 int i;
632 float dot = 0.f;
633 for (i = 0; i < n; i++) { dot += a[i] * b[i]; }
634 return dot;
635}
636
637//
638//
639// Generic matrix algebra
640//
641//
642
644#define MAKE_MATRIX_PTR(_ptr, _mat, _rows) \
645 float * _ptr[_rows]; \
646 { \
647 int __i; \
648 for (__i = 0; __i < _rows; __i++) { _ptr[__i] = &_mat[__i][0]; } \
649 }
650
651extern void float_mat_invert(float **o, float **mat, const int n);
652extern void float_mat_exp(float **a, float **o, const int n);
653extern float float_mat_norm_li(float **o, const int m, const int n);
654
656static inline void float_mat_zero(float **a, const int m, const int n)
657{
658 int i, j;
659 for (i = 0; i < m; i++) {
660 for (j = 0; j < n; j++) { a[i][j] = 0.; }
661 }
662}
663
665static inline void float_mat_copy(float **a, float **b, const int m, const int n)
666{
667 int i, j;
668 for (i = 0; i < m; i++) {
669 for (j = 0; j < n; j++) { a[i][j] = b[i][j]; }
670 }
671}
672
673
674
676static inline void float_mat_sum(float **o, float **a, float **b, const int m, const int n)
677{
678 int i, j;
679 for (i = 0; i < m; i++) {
680 for (j = 0; j < n; j++) { o[i][j] = a[i][j] + b[i][j]; }
681 }
682}
683
685static inline void float_mat_diff(float **o, float **a, float **b, const int m, const int n)
686{
687 int i, j;
688 for (i = 0; i < m; i++) {
689 for (j = 0; j < n; j++) { o[i][j] = a[i][j] - b[i][j]; }
690 }
691}
692
694static inline void float_mat_transpose_square(float **a, const int n)
695{
696 int i, j;
697 for (i = 0; i < n; i++) {
698 for (j = 0; j < i; j++) {
699 float t = a[i][j];
700 a[i][j] = a[j][i];
701 a[j][i] = t;
702 }
703 }
704}
705
706
708static inline void float_mat_transpose(float **o, float **a, const int n, const int m)
709{
710 int i, j;
711 for (i = 0; i < n; i++) {
712 for (j = 0; j < m; j++) {
713 o[j][i] = a[i][j];
714 }
715 }
716}
717
724static inline void float_mat_mul(float **o, float **a, float **b, const int m, const int n, const int l)
725{
726 int i, j, k;
727 for (i = 0; i < m; i++) {
728 for (j = 0; j < l; j++) {
729 o[i][j] = 0.;
730 for (k = 0; k < n; k++) {
731 o[i][j] += a[i][k] * b[k][j];
732 }
733 }
734 }
735}
736
743static inline void float_mat_mul_transpose(float **o, float **a, float **b, const int m, const int n, const int l)
744{
745 int i, j, k;
746 for (i = 0; i < m; i++) {
747 for (j = 0; j < l; j++) {
748 o[i][j] = 0.;
749 for (k = 0; k < n; k++) {
750 o[i][j] += a[i][k] * b[j][k];
751 }
752 }
753 }
754}
755
767static inline void float_mat_mul_copy(float **o, float **a, float **b, const int m, const int n, const int l)
768{
769 float temp[m][l];
770 int i, j, k;
771 for (i = 0; i < m; i++) {
772 for (j = 0; j < l; j++) {
773 temp[i][j] = 0.;
774 for (k = 0; k < n; k++) {
775 temp[i][j] += a[i][k] * b[k][j];
776 }
777 }
778 }
779 MAKE_MATRIX_PTR(_o, o, m);
780 MAKE_MATRIX_PTR(_temp, temp, m);
781 float_mat_copy(_o, _temp, m, l);
782}
783
784
791static inline void float_mat_vect_mul(float *o, float **a, const float *b, const int m, const int n)
792{
793 int i, j;
794 for (i = 0; i < m; i++) {
795 o[i] = 0;
796 for (j = 0; j < n; j++) {
797 o[i] += a[i][j] * b[j];
798 }
799 }
800}
801
807static inline void float_mat_scale(float **a, float k, const int m, const int n)
808{
809 int i, j;
810 for (i = 0; i < m; i++) {
811 for (j = 0; j < n; j++) {
812 a[i][j] *= k;
813 }
814 }
815}
816
823static inline void float_mat_sum_scaled(float **a, float **b, const float k, const int m, const int n)
824{
825 int i, j;
826 for (i = 0; i < m; i++) {
827 for (j = 0; j < n; j++) {
828 a[i][j] += k * b[i][j];
829 }
830 }
831}
832
833
840static inline void float_mat_minor(float **o, float **a, const int m, const int n, const int d)
841{
842 int i, j;
843 float_mat_zero(o, m, n);
844 for (i = 0; i < d; i++) { o[i][i] = 1.0; }
845 for (i = d; i < m; i++) {
846 for (j = d; j < n; j++) {
847 o[i][j] = a[i][j];
848 }
849 }
850}
851
853static inline void float_mat_vmul(float **o, const float *v, const int n)
854{
855 int i, j;
856 for (i = 0; i < n; i++) {
857 for (j = 0; j < n; j++) {
858 o[i][j] = -2. * v[i] * v[j];
859 }
860 }
861 for (i = 0; i < n; i++) {
862 o[i][i] += 1.;
863 }
864}
865
867static inline void float_mat_col(float *o, float **a, const int m, const int c)
868{
869 int i;
870 for (i = 0; i < m; i++) {
871 o[i] = a[i][c];
872 }
873}
874
876static inline void float_mat_diagonal_scal(float **o, float v, const int n)
877{
878 int i, j;
879 for (i = 0 ; i < n; i++) {
880 for (j = 0 ; j < n; j++) {
881 if (i == j) {
882 o[i][j] = v;
883 } else {
884 o[i][j] = 0.0;
885 }
886 }
887 }
888}
889
890
892static inline void float_mat_div_scalar(float **o, float **a, const float scalar, const int m, const int n)
893{
894 int i, j;
895 for (i = 0; i < m; i++) {
896 for (j = 0; j < n; j++) {
897 o[i][j] = a[i][j] / scalar;
898 }
899 }
900}
901
903static inline void float_mat_mul_scalar(float **o, float **a, const float scalar, const int m, const int n)
904{
905 int i, j;
906 for (i = 0; i < m; i++) {
907 for (j = 0; j < n; j++) {
908 o[i][j] = a[i][j] * scalar;
909 }
910 }
911}
912
913
914
915extern bool float_mat_inv_2d(float inv_out[4], const float mat_in[4]);
916extern void float_mat2_mult(struct FloatVect2 *vect_out, const float mat[4], const struct FloatVect2 vect_in);
917extern bool float_mat_inv_3d(float inv_out[3][3], const float mat_in[3][3]);
918extern void float_mat3_mult(struct FloatVect3 *vect_out, const float mat[3][3], const struct FloatVect3 vect_in);
919extern bool float_mat_inv_4d(float invOut[4][4], const float mat_in[4][4]);
920
921extern void float_vect3_bound_in_2d(struct FloatVect3 *vect3, const float bound);
922extern void float_vect3_bound_in_3d(struct FloatVect3 *vect3, const float bound);
923extern void float_vect3_scale_in_2d(struct FloatVect3 *vect3, const float norm_des);
924extern void float_vect2_bound_in_2d(struct FloatVect2 *vect2, const float bound);
925extern void float_vect2_scale_in_2d(struct FloatVect2 *vect2, const float norm_des);
926#ifdef __cplusplus
927} /* extern "C" */
928#endif
929
930#endif /* PPRZ_ALGEBRA_FLOAT_H */
float q
in rad/s
float phi
in radians
float p
in rad/s
float r
in rad/s
float theta
in radians
float m[3 *3]
float psi
in radians
float m[3 *3]
static void float_quat_normalize(struct FloatQuat *q)
void float_vect2_scale_in_2d(struct FloatVect2 *vect2, const float norm_des)
static void float_vect_sub(float *a, const float *b, const int n)
a -= b
static void float_vect_add(float *a, const float *b, const int n)
a += b
void float_rates_of_euler_dot(struct FloatRates *r, const struct FloatEulers *e, const struct FloatEulers *edot)
void float_vect3_bound_in_3d(struct FloatVect3 *vect3, const float bound)
static void float_vect_sum(float *o, const float *a, const float *b, const int n)
o = a + b
static float float_vect3_norm(const struct FloatVect3 *v)
static void float_quat_identity(struct FloatQuat *q)
initialises a quaternion to identity
float float_rmat_reorthogonalize(struct FloatRMat *rm)
static void float_vect_zero(float *a, const int n)
a = 0
void float_eulers_of_quat_zxy(struct FloatEulers *e, const struct FloatQuat *q)
euler rotation 'ZXY' This rotation order is useful if you need 90 deg pitch
void float_vect3_scale_in_2d(struct FloatVect3 *vect3, const float norm_des)
static void float_mat_col(float *o, float **a, const int m, const int c)
o = c-th column of matrix a[m x n]
static void float_vect_mul(float *o, const float *a, const float *b, const int n)
o = a * b (element wise)
static void float_vect_smul(float *o, const float *a, const float s, const int n)
o = a * s
void float_mat3_mult(struct FloatVect3 *vect_out, const float mat[3][3], const struct FloatVect3 vect_in)
Multiply 3D matrix with vector.
float float_rmat_norm(const struct FloatRMat *rm)
Norm of a rotation matrix.
void float_rmat_transp_ratemult(struct FloatRates *rb, const struct FloatRMat *m_b2a, const struct FloatRates *ra)
rotate anglular rates by transposed rotation matrix.
void float_quat_derivative_lagrange(struct FloatQuat *qd, const struct FloatRates *r, const struct FloatQuat *q)
Quaternion derivative from rotational velocity with Lagrange multiplier.
void float_mat_invert(float **o, float **mat, const int n)
Calculate inverse of any n x n matrix (passed as C array) o = mat^-1 Algorithm verified with Matlab.
void float_rmat_of_eulers_312(struct FloatRMat *rm, const struct FloatEulers *e)
static void float_vect_sdiv(float *o, const float *a, const float s, const int n)
o = a / s
static void float_mat_transpose(float **o, float **a, const int n, const int m)
transpose non-square matrix
static void float_rmat_identity(struct FloatRMat *rm)
initialises a rotation matrix to identity
void float_quat_inv_comp(struct FloatQuat *b2c, const struct FloatQuat *a2b, const struct FloatQuat *a2c)
Composition (multiplication) of two quaternions.
static void float_mat_scale(float **a, float k, const int m, const int n)
a *= k, where k is a scalar value
void float_vect3_integrate_fi(struct FloatVect3 *vec, const struct FloatVect3 *dv, const float dt)
in place first order integration of a 3D-vector
void float_quat_of_rmat(struct FloatQuat *q, const struct FloatRMat *rm)
Quaternion from rotation matrix.
void float_mat2_mult(struct FloatVect2 *vect_out, const float mat[4], const struct FloatVect2 vect_in)
Multiply 2D matrix with vector.
void float_eulers_of_quat_yxz(struct FloatEulers *e, const struct FloatQuat *q)
euler rotation 'YXZ' This function calculates from a quaternion the Euler angles with the order YXZ,...
static void float_vect_scale(float *a, const float s, const int n)
a *= s
void float_rmat_transp_mult(struct FloatEulers *rb, const struct FloatRMat *m_b2a, const struct FloatEulers *ra)
rotate angle by transposed rotation matrix.
void float_rmat_integrate_fi(struct FloatRMat *rm, const struct FloatRates *omega, const float dt)
in place first order integration of a rotation matrix
void float_quat_differential(struct FloatQuat *q_out, const struct FloatRates *w, const float dt)
Delta rotation quaternion with constant angular rates.
static void float_mat_mul_transpose(float **o, float **a, float **b, const int m, const int n, const int l)
o = a * b'
void float_quat_comp_norm_shortest(struct FloatQuat *a2c, const struct FloatQuat *a2b, const struct FloatQuat *b2c)
Composition (multiplication) of two quaternions with normalization.
void float_eulers_of_rmat(struct FloatEulers *e, const struct FloatRMat *rm)
void float_quat_of_eulers_yxz(struct FloatQuat *q, const struct FloatEulers *e)
quat from euler rotation 'YXZ' This function calculates a quaternion from Euler angles with the order...
void float_rates_vect3_integrate_fi(struct FloatRates *r, const struct FloatVect3 *dr, const float dt)
in place first order integration of angular rates
static void float_mat_mul(float **o, float **a, float **b, const int m, const int n, const int l)
o = a * b
bool float_mat_inv_3d(float inv_out[3][3], const float mat_in[3][3])
3x3 matrix inverse
void float_rmat_of_eulers_321(struct FloatRMat *rm, const struct FloatEulers *e)
Rotation matrix from 321 Euler angles (float).
static void float_mat_transpose_square(float **a, const int n)
transpose square matrix
static float float_log_n(const float v, const float n)
void float_quat_of_eulers_zxy(struct FloatQuat *q, const struct FloatEulers *e)
quat from euler rotation 'ZXY' This rotation order is useful if you need 90 deg pitch
void float_quat_integrate_fi(struct FloatQuat *q, const struct FloatRates *omega, const float dt)
in place first order quaternion integration with constant rotational velocity
static void float_mat_copy(float **a, float **b, const int m, const int n)
a = b
static void float_mat_diagonal_scal(float **o, float v, const int n)
Make an n x n identity matrix (for matrix passed as array)
static void float_mat_div_scalar(float **o, float **a, const float scalar, const int m, const int n)
Divide a matrix by a scalar.
void float_quat_comp(struct FloatQuat *a2c, const struct FloatQuat *a2b, const struct FloatQuat *b2c)
Composition (multiplication) of two quaternions.
static void float_mat_vect_mul(float *o, float **a, const float *b, const int m, const int n)
o = a * b
static void float_quat_invert(struct FloatQuat *qo, const struct FloatQuat *qi)
static void float_mat_minor(float **o, float **a, const int m, const int n, const int d)
matrix minor
float float_mat_norm_li(float **o, const int m, const int n)
void float_rmat_vmult(struct FloatVect3 *vb, const struct FloatRMat *m_a2b, const struct FloatVect3 *va)
rotate 3D vector by rotation matrix.
bool float_mat_inv_2d(float inv_out[4], const float mat_in[4])
2x2 matrix inverse
void float_quat_integrate(struct FloatQuat *q, const struct FloatRates *omega, const float dt)
in place quaternion integration with constant rotational velocity
static float float_vect_dot_product(const float *a, const float *b, const int n)
a.b
static void float_mat_zero(float **a, const int m, const int n)
a = 0
static void float_quat_wrap_shortest(struct FloatQuat *q)
void float_rmat_ratemult(struct FloatRates *rb, const struct FloatRMat *m_a2b, const struct FloatRates *ra)
rotate anglular rates by rotation matrix.
static void float_vect_copy(float *a, const float *b, const int n)
a = b
static void float_mat_vmul(float **o, const float *v, const int n)
o = I - v v^T
void float_quat_of_orientation_vect(struct FloatQuat *q, const struct FloatVect3 *ov)
Quaternion from orientation vector.
static float float_eulers_norm(const struct FloatEulers *e)
void float_rmat_comp_inv(struct FloatRMat *m_a2b, const struct FloatRMat *m_a2c, const struct FloatRMat *m_b2c)
Composition (multiplication) of two rotation matrices.
static void float_vect_diff(float *o, const float *a, const float *b, const int n)
o = a - b
void float_rates_integrate_fi(struct FloatRates *r, const struct FloatRates *dr, const float dt)
in place first order integration of angular rates
void float_rmat_mult(struct FloatEulers *rb, const struct FloatRMat *m_a2b, const struct FloatEulers *ra)
rotate angle by rotation matrix.
static void float_vect2_normalize(struct FloatVect2 *v)
normalize 2D vector in place
static void float_mat_sum_scaled(float **a, float **b, const float k, const int m, const int n)
a += k*b, where k is a scalar value
#define FLOAT_MAT33_DIAG(_m, _d00, _d11, _d22)
void float_vect3_bound_in_2d(struct FloatVect3 *vect3, const float bound)
bool float_mat_inv_4d(float invOut[4][4], const float mat_in[4][4])
4x4 Matrix inverse
void float_quat_of_eulers(struct FloatQuat *q, const struct FloatEulers *e)
Quaternion from Euler angles.
void float_eulers_of_quat(struct FloatEulers *e, const struct FloatQuat *q)
euler rotation 'ZYX'
static void float_mat_sum(float **o, float **a, float **b, const int m, const int n)
o = a + b
static float float_quat_norm(const struct FloatQuat *q)
void float_rmat_of_quat(struct FloatRMat *rm, const struct FloatQuat *q)
#define MAKE_MATRIX_PTR(_ptr, _mat, _rows)
Make a pointer to a matrix of _rows lines.
static float float_vect2_norm(const struct FloatVect2 *v)
void float_quat_tilt_twist(struct FloatQuat *tilt, struct FloatQuat *twist, const struct FloatQuat *quat)
Tilt twist decomposition of quaternion.
static float float_vect2_norm2(const struct FloatVect2 *v)
void float_vect2_bound_in_2d(struct FloatVect2 *vect2, const float bound)
void float_rmat_of_axis_angle(struct FloatRMat *rm, const struct FloatVect3 *uv, const float angle)
initialises a rotation matrix from unit vector axis and angle
static float float_vect_norm(const float *a, const int n)
||a||
void float_quat_comp_inv_norm_shortest(struct FloatQuat *a2b, const struct FloatQuat *a2c, const struct FloatQuat *b2c)
Composition (multiplication) of two quaternions with normalization.
void float_mat_exp(float **a, float **o, const int n)
void float_rmat_transp_vmult(struct FloatVect3 *vb, const struct FloatRMat *m_b2a, const struct FloatVect3 *va)
rotate 3D vector by transposed rotation matrix.
void float_rmat_inv(struct FloatRMat *m_b2a, const struct FloatRMat *m_a2b)
Inverse/transpose of a rotation matrix.
void float_quat_of_axis_angle(struct FloatQuat *q, const struct FloatVect3 *uv, const float angle)
Quaternion from unit vector and angle.
void float_quat_inv_comp_norm_shortest(struct FloatQuat *b2c, const struct FloatQuat *a2b, const struct FloatQuat *a2c)
Composition (multiplication) of two quaternions with normalization.
void float_quat_comp_inv(struct FloatQuat *a2b, const struct FloatQuat *a2c, const struct FloatQuat *b2c)
Composition (multiplication) of two quaternions.
static float float_vect3_norm2(const struct FloatVect3 *v)
static void float_mat_mul_copy(float **o, float **a, float **b, const int m, const int n, const int l)
o = a * b
static void float_mat_diff(float **o, float **a, float **b, const int m, const int n)
o = a - b
void float_rmat_comp(struct FloatRMat *m_a2c, const struct FloatRMat *m_a2b, const struct FloatRMat *m_b2c)
Composition (multiplication) of two rotation matrices.
static void float_vect3_normalize(struct FloatVect3 *v)
normalize 3D vector in place
static void float_mat_mul_scalar(float **o, float **a, const float scalar, const int m, const int n)
Multiply a matrix by a scalar.
void float_quat_derivative(struct FloatQuat *qd, const struct FloatRates *r, const struct FloatQuat *q)
Quaternion derivative from rotational velocity.
void float_quat_vmult(struct FloatVect3 *v_out, const struct FloatQuat *q, const struct FloatVect3 *v_in)
rotate 3D vector by quaternion.
euler angles
Roation quaternion.
rotation matrix
angular rates
#define SQUARE(_a)
#define QUAT_INVERT(_qo, _qi)
#define QUAT_EXPLEMENTARY(b, a)
static uint32_t s
uint16_t foo
Definition main_demo5.c:58
Paparazzi generic algebra macros.
float b
Definition wedgebug.c:202