ACwing FC firmware
STM32WB55: attitude IEKF, altitude Kalman filter, flight core, protocol v2
Loading...
Searching...
No Matches
tlm_build.c
Go to the documentation of this file.
1
6#include "tlm_build.h"
7#include "so3.h"
8#include <string.h>
9
10size_t tlm_build_state(const est_t *e, uint8_t *frame, size_t cap)
11{
13 float q[4];
14 p.seq = (uint16_t)(e->step / e->cfg.steps_per_acc);
15 p.t_us = (uint32_t)(e->t * 1e6f);
16 iekf_get_quat(&e->f, q);
17 memcpy(p.q, q, sizeof q);
18 memcpy(p.bias, e->f.b, sizeof p.bias);
19 memcpy(p.acc, e->acc_mean, sizeof p.acc);
20 memcpy(p.gyro, e->gyro_mean, sizeof p.gyro);
21 memcpy(p.mag, e->mag, sizeof p.mag);
22 p.flags = e->flags;
23 return tlm_encode(TLM_TYPE_STATE, &p, sizeof p, frame, cap);
24}
25
26size_t tlm_build_init(const est_t *e, float fs_state_hz, uint8_t *frame, size_t cap)
27{
28 const calib_result_t *cr = &e->calres;
29 const iekf_config_t *c = &e->cfg.ekf;
30 tlm_init_t p;
31 float q0[4], v;
32 so3_to_quat(cr->seed.R0, q0);
33 memcpy(p.q0, q0, sizeof q0);
34 memcpy(p.g_ref, cr->seed.g_ref, sizeof p.g_ref);
35 memcpy(p.m_ref, cr->seed.m_ref, sizeof p.m_ref);
36 memcpy(p.b0, cr->seed.b0, sizeof p.b0);
37#define PUT(field, val) do { v = (val); memcpy(&p.field, &v, sizeof v); } while (0)
38 PUT(sigma_acc, c->sigma_acc); PUT(sigma_mag, c->sigma_mag);
39 PUT(sigma_gyro, c->sigma_gyro); PUT(sigma_bias, c->sigma_bias);
40 PUT(nom_acc, cr->seed.nom_acc); PUT(nom_mag, cr->seed.nom_mag);
41 PUT(fs_hz, fs_state_hz);
42 PUT(acc_tol, c->acc_tol); PUT(mag_tol, c->mag_tol);
43 PUT(p0_att, c->p0_att); PUT(p0_bias, c->p0_bias);
44 PUT(acc_nis_gate, c->acc_nis_gate); PUT(mag_nis_gate, c->mag_nis_gate);
45 PUT(infl_decay, c->infl_decay); PUT(dip_tol, c->dip_tol);
46 PUT(infl_max, c->infl_max); PUT(lockout_p_bump, c->lockout_p_bump);
47 PUT(persist_decay, c->persist_decay); PUT(persist_ratio, c->persist_ratio);
48 PUT(persist_min, c->persist_min);
49#undef PUT
50 {
51 uint16_t u = c->lockout_updates; memcpy(&p.lockout_updates, &u, 2);
52 u = c->grace_updates; memcpy(&p.grace_updates, &u, 2);
53 }
54 p.flags = (uint8_t)((c->estimate_bias ? TLM_I_EST_BIAS : 0u) |
55 (c->adaptive ? TLM_I_ADAPTIVE : 0u) |
56 (c->tilt_comp_mag ? TLM_I_TILT_COMP : 0u) |
57 (c->decouple ? TLM_I_DECOUPLE : 0u) |
59 (c->tangent_innov ? TLM_I_TANGENT : 0u));
60 return tlm_encode(TLM_TYPE_INIT, &p, sizeof p, frame, cap);
61}
62
63size_t tlm_build_replay(const est_t *e, uint8_t *frame, size_t cap)
64{
65 uint8_t pl[TLM_REPLAY_MAX];
66 size_t n = 0;
67 const uint32_t win = e->win_count;
68 memcpy(&pl[n], &win, 4); n += 4;
69 pl[n++] = e->trace.nops;
70 pl[n++] = e->trace.overflow ? 1u : 0u;
71 memcpy(&pl[n], e->trace.buf, e->trace.len); n += e->trace.len;
72
73 float tail[15];
74 iekf_get_quat(&e->f, &tail[0]);
75 for (int i = 0; i < 3; ++i) tail[4 + i] = e->f.b[i];
76 for (int i = 0; i < 6; ++i) tail[7 + i] = e->f.P[i*IEKF_NX + i];
77 tail[13] = e->f.acc_infl;
78 tail[14] = e->f.mag_infl;
79 memcpy(&pl[n], tail, sizeof tail); n += sizeof tail;
80 return tlm_encode(TLM_TYPE_REPLAY, pl, (uint8_t)n, frame, cap);
81}
uint32_t n
Definition calib_mgr.c:35
float cap[6][3]
Definition calib_mgr.c:36
void iekf_get_quat(const iekf_t *f, float q[4])
Definition iekf.c:408
#define IEKF_NX
Definition iekf.h:29
void so3_to_quat(const float R[9], float q[4])
Definition so3.c:80
Single-precision SO(3) Lie-group utilities (port of expSO3.m / skewSym.m + firmware helpers).
iekf_seed_t seed
Definition calib.h:31
float mag_tol
Definition iekf.h:38
float sigma_mag
Definition iekf.h:36
uint8_t adaptive
Definition iekf.h:42
uint8_t decouple
1: acc corrects only roll/pitch, mag only yaw
Definition iekf.h:56
float infl_max
— protection against "lockout" of the NIS inflation — If the estimate is truly wrong,...
Definition iekf.h:77
uint8_t reset_jacobian
1: transport P after the retraction (default)
Definition iekf.h:57
float sigma_bias
rad/s^2, bias random walk
Definition iekf.h:34
float p0_att
initial attitude variance [rad^2]
Definition iekf.h:39
uint16_t grace_updates
e.g.
Definition iekf.h:80
float acc_nis_gate
— robustness to external accelerations / magnetic disturbances —
Definition iekf.h:45
float dip_tol
Definition iekf.h:50
float persist_ratio
|mean|^2 / mean(|e|^2) above which it is persistent, e.g.
Definition iekf.h:82
float sigma_acc
per-component std of the normalised vector
Definition iekf.h:35
uint8_t tilt_comp_mag
Definition iekf.h:43
float p0_bias
initial bias variance [(rad/s)^2]
Definition iekf.h:40
float sigma_gyro
rad/s, gyro white noise
Definition iekf.h:33
float persist_decay
moving mean of the innovation: exp(-dt/tau), tau ~ 1 s
Definition iekf.h:81
uint16_t lockout_updates
e.g.
Definition iekf.h:78
uint8_t estimate_bias
Definition iekf.h:41
uint8_t tangent_innov
Definition iekf.h:58
float acc_tol
relative tolerance on the magnitude (gating)
Definition iekf.h:37
float mag_nis_gate
Definition iekf.h:47
float lockout_p_bump
rad^2, e.g.
Definition iekf.h:79
float infl_decay
Definition iekf.h:54
float persist_min
minimum |mean| (sine of the error), e.g.
Definition iekf.h:83
float m_ref[3]
magnetic field direction, world frame
Definition iekf.h:91
float b0[3]
Definition iekf.h:89
float R0[9]
Definition iekf.h:88
float g_ref[3]
accelerometer direction at rest, world frame
Definition iekf.h:90
float nom_acc
nominal magnitudes for the adaptive gating
Definition iekf.h:92
float nom_mag
Definition iekf.h:93
float m_ref[3]
Definition telemetry.h:69
uint8_t flags
Definition telemetry.h:79
float q0[4]
Definition telemetry.h:67
float g_ref[3]
Definition telemetry.h:68
uint16_t lockout_updates
Definition telemetry.h:78
float b0[3]
Definition telemetry.h:70
uint16_t grace_updates
Definition telemetry.h:78
uint8_t flags
Definition telemetry.h:63
float acc[3]
g, body frame
Definition telemetry.h:60
float q[4]
body->world, [w x y z]
Definition telemetry.h:58
float gyro[3]
rad/s
Definition telemetry.h:61
float mag[3]
uT, body frame, hard-iron already removed
Definition telemetry.h:62
float bias[3]
rad/s
Definition telemetry.h:59
uint16_t seq
filter sample index (0 = initial state R0)
Definition telemetry.h:56
uint32_t t_us
filter time: sum of the dt actually used
Definition telemetry.h:57
size_t tlm_encode(uint8_t type, const void *payload, uint8_t len, uint8_t *out, size_t cap)
Writes the complete frame into out; returns its length, 0 if cap is too small.
Definition telemetry.c:18
#define TLM_I_TANGENT
tangential vector innovation (firmware 0.6.0)
Definition telemetry.h:47
#define TLM_I_EST_BIAS
Definition telemetry.h:42
#define TLM_TYPE_INIT
Definition telemetry.h:29
#define TLM_REPLAY_MAX
Definition telemetry.h:115
#define TLM_I_TILT_COMP
Definition telemetry.h:44
#define TLM_TYPE_STATE
Definition telemetry.h:28
#define TLM_I_ADAPTIVE
Definition telemetry.h:43
#define TLM_I_RESET_JAC
Definition telemetry.h:46
#define TLM_TYPE_REPLAY
trace of the filter calls + resulting state (parity)
Definition telemetry.h:31
#define TLM_I_DECOUPLE
Definition telemetry.h:45
size_t tlm_build_init(const est_t *e, float fs_state_hz, uint8_t *frame, size_t cap)
Definition tlm_build.c:26
size_t tlm_build_replay(const est_t *e, uint8_t *frame, size_t cap)
Definition tlm_build.c:63
size_t tlm_build_state(const est_t *e, uint8_t *frame, size_t cap)
Definition tlm_build.c:10
#define PUT(field, val)
Builds telemetry frames from the pipeline state.