IMU - increase gain on large Course over ground error (#12792)
[betaflight.git] / src / main / common / vector.h
blob4a0d521983157bbf2358caa66210ab70578e616e
1 /*
2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
8 * any later version.
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
22 * some functions are taken from https://github.com/iNavFlight/inav/
25 #pragma once
27 #include "common/maths.h"
29 typedef union {
30 float v[2];
31 struct {
32 float x,y;
34 } fpVector2_t;
37 typedef union {
38 float v[3];
39 struct {
40 float x, y, z;
42 } fpVector3_t;
44 typedef struct {
45 float m[3][3];
46 } fpMat33_t;
48 static inline fpVector3_t * vectorZero(fpVector3_t *v)
50 v->x = 0.0f;
51 v->y = 0.0f;
52 v->z = 0.0f;
53 return v;
56 static inline float vectorNormSquared(const fpVector3_t * v)
58 return sq(v->x) + sq(v->y) + sq(v->z);
61 static inline float vectorNorm(const fpVector3_t * v)
63 return sqrtf(vectorNormSquared(v));
66 static inline fpVector3_t * vectorCrossProduct(fpVector3_t *result, const fpVector3_t *a, const fpVector3_t *b)
68 fpVector3_t ab;
70 ab.x = a->y * b->z - a->z * b->y;
71 ab.y = a->z * b->x - a->x * b->z;
72 ab.z = a->x * b->y - a->y * b->x;
74 *result = ab;
75 return result;
78 static inline fpVector3_t * vectorAdd(fpVector3_t *result, const fpVector3_t *a, const fpVector3_t *b)
80 fpVector3_t ab;
82 ab.x = a->x + b->x;
83 ab.y = a->y + b->y;
84 ab.z = a->z + b->z;
86 *result = ab;
87 return result;
90 static inline fpVector3_t * vectorScale(fpVector3_t *result, const fpVector3_t *a, const float b)
92 fpVector3_t ab;
94 ab.x = a->x * b;
95 ab.y = a->y * b;
96 ab.z = a->z * b;
98 *result = ab;
99 return result;
102 static inline fpVector3_t * vectorNormalize(fpVector3_t *result, const fpVector3_t *v)
104 float normSq = vectorNormSquared(v);
105 if (normSq > 0) { // Hopefully sqrt(nonzero) is quite large
106 return vectorScale(result, v, 1.0f / sqrtf(normSq));
107 } else {
108 return vectorZero(result);
112 static inline fpVector3_t * matrixVectorMul(fpVector3_t * result, const fpMat33_t * mat, const fpVector3_t * a)
114 fpVector3_t r;
116 r.x = mat->m[0][0] * a->x + mat->m[0][1] * a->y + mat->m[0][2] * a->z;
117 r.y = mat->m[1][0] * a->x + mat->m[1][1] * a->y + mat->m[1][2] * a->z;
118 r.z = mat->m[2][0] * a->x + mat->m[2][1] * a->y + mat->m[2][2] * a->z;
120 *result = r;
121 return result;
124 static inline fpVector3_t * matrixTrnVectorMul(fpVector3_t * result, const fpMat33_t * mat, const fpVector3_t * a)
126 fpVector3_t r;
128 r.x = mat->m[0][0] * a->x + mat->m[1][0] * a->y + mat->m[2][0] * a->z;
129 r.y = mat->m[0][1] * a->x + mat->m[1][1] * a->y + mat->m[2][1] * a->z;
130 r.z = mat->m[0][2] * a->x + mat->m[1][2] * a->y + mat->m[2][2] * a->z;
132 *result = r;
133 return result;
136 static inline float vector2Cross(const fpVector2_t *a, const fpVector2_t *b)
138 return a->x * b->y - a->y * b->x;
141 static inline float vector2Dot(const fpVector2_t *a, const fpVector2_t *b)
143 return a->x * b->x + a->y * b->y;
146 static inline float vector2Mag(const fpVector2_t *a)
148 return sqrtf(sq(a->x) + sq(a->y));