18 if (gn > gyro_still_thr)
return -1;
20 memcpy(c->
acc[c->
n], acc, 3*
sizeof(
float));
21 memcpy(c->
mag[c->
n], mag, 3*
sizeof(
float));
22 for (
int i = 0; i < 3; ++i) c->
gyro_sum[i] += gyro[i];
31 if (
n < 2)
return 0.0f;
32 float um[3] = { 0, 0, 0 };
33 for (uint32_t k = 0; k <
n; ++k) {
35 if (nk < 1e-9f)
continue;
36 for (
int i = 0; i < 3; ++i) um[i] += v[k][i] / nk;
41 for (uint32_t k = 0; k <
n; ++k) {
43 if (nk < 1e-9f)
continue;
44 float u[3] = { v[k][0]/nk, v[k][1]/nk, v[k][2]/nk };
46 float r[3] = { u[0] - d*um[0], u[1] - d*um[1], u[2] - d*um[2] };
49 return sqrtf((e / (
float)
n) / 2.0f);
54 if (c->
n < 10)
return -1;
55 const float inv_n = 1.0f / (float)c->
n;
57 float am[3] = { 0, 0, 0 }, mm[3] = { 0, 0, 0 };
58 float an = 0.0f, mn = 0.0f;
59 for (uint32_t k = 0; k < c->
n; ++k) {
60 for (
int i = 0; i < 3; ++i) { am[i] += c->
acc[k][i]; mm[i] += c->
mag[k][i]; }
64 for (
int i = 0; i < 3; ++i) { am[i] *= inv_n; mm[i] *= inv_n; }
68 float z[3] = { am[0], am[1], am[2] };
70 float x[3] = { mm[0] - d*z[0], mm[1] - d*z[1], mm[2] - d*z[2] };
77 s->R0[0] = x[0];
s->R0[1] = x[1];
s->R0[2] = x[2];
78 s->R0[3] = y[0];
s->R0[4] = y[1];
s->R0[5] = y[2];
79 s->R0[6] = z[0];
s->R0[7] = z[1];
s->R0[8] = z[2];
83 for (
int i = 0; i < 3; ++i)
s->b0[i] = c->
gyro_sum[i] * inv_n;
84 s->nom_acc = an * inv_n;
85 s->nom_mag = mn * inv_n;
void calib_reset(calib_t *c)
int calib_finish(const calib_t *c, float sigma_min, calib_result_t *out)
float direction_noise_std(const float(*v)[3], uint32_t n)
int calib_add(calib_t *c, const float acc[3], const float gyro[3], const float mag[3], float gyro_still_thr)
Returns 0 if the sample is compatible with "still", -1 if moving.
uint32_t calib_count(const calib_t *c)
Initial static window: references, noise and initial attitude.
#define CALIB_MAX_SAMPLES
void mat3_vec(const float A[9], const float x[3], float y[3])
y = A*x
void vec3_cross(const float a[3], const float b[3], float c[3])
float vec3_norm(const float v[3])
float vec3_dot(const float a[3], const float b[3])
int vec3_normalize(float v[3])
0 = OK
Single-precision SO(3) Lie-group utilities (port of expSO3.m / skewSym.m + firmware helpers).
float sigma_acc_raw
measured values, for diagnostics
float sigma_acc
already lower-bounded by sigma_min
float mag[CALIB_MAX_SAMPLES][3]
float acc[CALIB_MAX_SAMPLES][3]
Initial conditions, typically from calib_finish()