ACwing FC firmware
STM32WB55: attitude IEKF, altitude Kalman filter, flight core, protocol v2
Loading...
Searching...
No Matches
so3.c
Go to the documentation of this file.
1
12#include "so3.h"
13#include <math.h>
14
15void so3_skew(const float v[3], float S[9])
16{
17 S[0] = 0.0f; S[1] = -v[2]; S[2] = v[1];
18 S[3] = v[2]; S[4] = 0.0f; S[5] = -v[0];
19 S[6] = -v[1]; S[7] = v[0]; S[8] = 0.0f;
20}
21
22void so3_exp(const float phi[3], float R[9])
23{
24 const float t2 = phi[0]*phi[0] + phi[1]*phi[1] + phi[2]*phi[2];
25 float a, b;
26 if (t2 < 2.5e-3f) {
27 a = 1.0f - t2*(1.0f/6.0f) + t2*t2*(1.0f/120.0f); /* sin(t)/t */
28 b = 0.5f - t2*(1.0f/24.0f) + t2*t2*(1.0f/720.0f); /* (1-cos t)/t^2 */
29 } else {
30 const float t = sqrtf(t2);
31 a = sinf(t) / t;
32 b = (1.0f - cosf(t)) / t2;
33 }
34 /* Rodrigues: R = I + a*[phi]x + b*[phi]x^2, [phi]x^2 = phi*phi' - t2*I */
35 R[0] = 1.0f + b*(phi[0]*phi[0] - t2);
36 R[1] = -a*phi[2] + b*phi[0]*phi[1];
37 R[2] = a*phi[1] + b*phi[0]*phi[2];
38 R[3] = a*phi[2] + b*phi[1]*phi[0];
39 R[4] = 1.0f + b*(phi[1]*phi[1] - t2);
40 R[5] = -a*phi[0] + b*phi[1]*phi[2];
41 R[6] = -a*phi[1] + b*phi[2]*phi[0];
42 R[7] = a*phi[0] + b*phi[2]*phi[1];
43 R[8] = 1.0f + b*(phi[2]*phi[2] - t2);
44}
45
46float vec3_dot(const float a[3], const float b[3]) { return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; }
47float vec3_norm(const float v[3]) { return sqrtf(vec3_dot(v, v)); }
48
49void vec3_cross(const float a[3], const float b[3], float c[3])
50{
51 c[0] = a[1]*b[2] - a[2]*b[1];
52 c[1] = a[2]*b[0] - a[0]*b[2];
53 c[2] = a[0]*b[1] - a[1]*b[0];
54}
55
56int vec3_normalize(float v[3])
57{
58 const float n = vec3_norm(v);
59 if (n < 1e-12f) return -1;
60 v[0] /= n; v[1] /= n; v[2] /= n;
61 return 0;
62}
63
64/* Gram-Schmidt on the columns (= body axes expressed in the world frame) */
65void so3_orthonormalize(float R[9])
66{
67 float c0[3] = { R[0], R[3], R[6] };
68 float c1[3] = { R[1], R[4], R[7] };
69 float c2[3];
70 if (vec3_normalize(c0)) return;
71 const float d = vec3_dot(c0, c1);
72 c1[0] -= d*c0[0]; c1[1] -= d*c0[1]; c1[2] -= d*c0[2];
73 if (vec3_normalize(c1)) return;
74 vec3_cross(c0, c1, c2);
75 R[0] = c0[0]; R[1] = c1[0]; R[2] = c2[0];
76 R[3] = c0[1]; R[4] = c1[1]; R[5] = c2[1];
77 R[6] = c0[2]; R[7] = c1[2]; R[8] = c2[2];
78}
79
80void so3_to_quat(const float R[9], float q[4])
81{
82 const float tr = R[0] + R[4] + R[8];
83 float S;
84 if (tr > 0.0f) {
85 S = sqrtf(tr + 1.0f) * 2.0f;
86 q[0] = 0.25f*S; q[1] = (R[7] - R[5]) / S;
87 q[2] = (R[2] - R[6]) / S; q[3] = (R[3] - R[1]) / S;
88 } else if (R[0] > R[4] && R[0] > R[8]) {
89 S = sqrtf(1.0f + R[0] - R[4] - R[8]) * 2.0f;
90 q[0] = (R[7] - R[5]) / S; q[1] = 0.25f*S;
91 q[2] = (R[1] + R[3]) / S; q[3] = (R[2] + R[6]) / S;
92 } else if (R[4] > R[8]) {
93 S = sqrtf(1.0f + R[4] - R[0] - R[8]) * 2.0f;
94 q[0] = (R[2] - R[6]) / S; q[1] = (R[1] + R[3]) / S;
95 q[2] = 0.25f*S; q[3] = (R[5] + R[7]) / S;
96 } else {
97 S = sqrtf(1.0f + R[8] - R[0] - R[4]) * 2.0f;
98 q[0] = (R[3] - R[1]) / S; q[1] = (R[2] + R[6]) / S;
99 q[2] = (R[5] + R[7]) / S; q[3] = 0.25f*S;
100 }
101 float n = sqrtf(q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]);
102 if (q[0] < 0.0f) n = -n; /* hemisphere w >= 0: no jumps in plots */
103 q[0] /= n; q[1] /= n; q[2] /= n; q[3] /= n;
104}
105
106void mat3_mul(const float A[9], const float B[9], float C[9])
107{
108 for (int r = 0; r < 3; ++r)
109 for (int c = 0; c < 3; ++c)
110 C[3*r + c] = A[3*r]*B[c] + A[3*r + 1]*B[3 + c] + A[3*r + 2]*B[6 + c];
111}
112
113void mat3_vec(const float A[9], const float x[3], float y[3])
114{
115 y[0] = A[0]*x[0] + A[1]*x[1] + A[2]*x[2];
116 y[1] = A[3]*x[0] + A[4]*x[1] + A[5]*x[2];
117 y[2] = A[6]*x[0] + A[7]*x[1] + A[8]*x[2];
118}
119
120void mat3t_vec(const float A[9], const float x[3], float y[3])
121{
122 y[0] = A[0]*x[0] + A[3]*x[1] + A[6]*x[2];
123 y[1] = A[1]*x[0] + A[4]*x[1] + A[7]*x[2];
124 y[2] = A[2]*x[0] + A[5]*x[1] + A[8]*x[2];
125}
126
127int mat3_inv(const float A[9], float B[9])
128{
129 const float c00 = A[4]*A[8] - A[5]*A[7];
130 const float c01 = A[5]*A[6] - A[3]*A[8];
131 const float c02 = A[3]*A[7] - A[4]*A[6];
132 const float det = A[0]*c00 + A[1]*c01 + A[2]*c02;
133 if (fabsf(det) < 1e-30f) return -1;
134 const float id = 1.0f / det;
135 B[0] = c00*id; B[1] = (A[2]*A[7] - A[1]*A[8])*id; B[2] = (A[1]*A[5] - A[2]*A[4])*id;
136 B[3] = c01*id; B[4] = (A[0]*A[8] - A[2]*A[6])*id; B[5] = (A[2]*A[3] - A[0]*A[5])*id;
137 B[6] = c02*id; B[7] = (A[1]*A[6] - A[0]*A[7])*id; B[8] = (A[0]*A[4] - A[1]*A[3])*id;
138 return 0;
139}
static struct @10 B
double b[6]
Definition calib_mgr.c:53
uint32_t n
Definition calib_mgr.c:35
static struct @7 A
static struct @11 C
uint16_t id
Definition log_task.c:49
void so3_exp(const float phi[3], float R[9])
Definition so3.c:22
int mat3_inv(const float A[9], float B[9])
0 = OK
Definition so3.c:127
void mat3_vec(const float A[9], const float x[3], float y[3])
y = A*x
Definition so3.c:113
void so3_to_quat(const float R[9], float q[4])
Definition so3.c:80
void mat3t_vec(const float A[9], const float x[3], float y[3])
y = A'*x
Definition so3.c:120
void vec3_cross(const float a[3], const float b[3], float c[3])
Definition so3.c:49
float vec3_norm(const float v[3])
Definition so3.c:47
void mat3_mul(const float A[9], const float B[9], float C[9])
C = A*B
Definition so3.c:106
void so3_orthonormalize(float R[9])
Definition so3.c:65
float vec3_dot(const float a[3], const float b[3])
Definition so3.c:46
int vec3_normalize(float v[3])
0 = OK
Definition so3.c:56
void so3_skew(const float v[3], float S[9])
Definition so3.c:15
Single-precision SO(3) Lie-group utilities (port of expSO3.m / skewSym.m + firmware helpers).