14 p.
seq = (uint16_t)(e->step / e->cfg.steps_per_acc);
15 p.
t_us = (uint32_t)(e->t * 1e6f);
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);
33 memcpy(p.
q0, q0,
sizeof q0);
37#define PUT(field, val) do { v = (val); memcpy(&p.field, &v, sizeof v); } while (0)
41 PUT(fs_hz, fs_state_hz);
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;
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;
void iekf_get_quat(const iekf_t *f, float q[4])
void so3_to_quat(const float R[9], float q[4])
Single-precision SO(3) Lie-group utilities (port of expSO3.m / skewSym.m + firmware helpers).
uint8_t decouple
1: acc corrects only roll/pitch, mag only yaw
float infl_max
— protection against "lockout" of the NIS inflation — If the estimate is truly wrong,...
uint8_t reset_jacobian
1: transport P after the retraction (default)
float sigma_bias
rad/s^2, bias random walk
float p0_att
initial attitude variance [rad^2]
uint16_t grace_updates
e.g.
float acc_nis_gate
— robustness to external accelerations / magnetic disturbances —
float persist_ratio
|mean|^2 / mean(|e|^2) above which it is persistent, e.g.
float sigma_acc
per-component std of the normalised vector
float p0_bias
initial bias variance [(rad/s)^2]
float sigma_gyro
rad/s, gyro white noise
float persist_decay
moving mean of the innovation: exp(-dt/tau), tau ~ 1 s
uint16_t lockout_updates
e.g.
float acc_tol
relative tolerance on the magnitude (gating)
float lockout_p_bump
rad^2, e.g.
float persist_min
minimum |mean| (sine of the error), e.g.
float m_ref[3]
magnetic field direction, world frame
float g_ref[3]
accelerometer direction at rest, world frame
float nom_acc
nominal magnitudes for the adaptive gating
float acc[3]
g, body frame
float q[4]
body->world, [w x y z]
float mag[3]
uT, body frame, hard-iron already removed
uint16_t seq
filter sample index (0 = initial state R0)
uint32_t t_us
filter time: sum of the dt actually used
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.
#define TLM_I_TANGENT
tangential vector innovation (firmware 0.6.0)
#define TLM_TYPE_REPLAY
trace of the filter calls + resulting state (parity)
size_t tlm_build_init(const est_t *e, float fs_state_hz, uint8_t *frame, size_t cap)
size_t tlm_build_replay(const est_t *e, uint8_t *frame, size_t cap)
size_t tlm_build_state(const est_t *e, uint8_t *frame, size_t cap)
Builds telemetry frames from the pipeline state.