ACwing FC firmware
STM32WB55: attitude IEKF, altitude Kalman filter, flight core, protocol v2
Loading...
Searching...
No Matches
app_config.h
Go to the documentation of this file.
1
7
#ifndef APP_CONFIG_H
8
#define APP_CONFIG_H
9
10
#define DEG2RAD_F 0.017453292519943295f
11
12
/* ---------------- IMU ---------------- */
13
/* Bring-up: 960 Hz with I2C at 400 kHz. 1920 Hz requires Fast-mode Plus (1 MHz);
14
* try it only after checking the bus edges with an oscilloscope: the IKS4A1 has
15
* level translators and 4k7 pull-ups. The pipeline adapts automatically. */
16
#define APP_IMU_ODR IMU_ODR_960HZ
17
#define APP_IMU_WATERMARK 4u
18
#define APP_GY_LPF1_BW LSM6DSV16X_GY_LIGHT
19
#define APP_XL_LPF2_ENABLE 1
20
#define APP_XL_LPF2_BW LSM6DSV16X_XL_STRONG
21
#define APP_MAG_FAST 1
22
/* ---------------- rates (derived) ---------------- */
23
#define APP_STEP_HZ 960u
24
#define APP_STEPS_PER_ACC 4u
25
/* ---------------- static calibration ---------------- */
26
#define APP_CALIB_SAMPLES 100u
27
#define APP_CALIB_GYRO_STILL (5.0f * DEG2RAD_F)
28
29
/* ---------------- IEKF ----------------
30
* State: attitude (3) + gyro bias (3). IEKF_ESTIMATE_BIAS = 0 -> 3 states.
31
* sigma_gyro is the EFFECTIVE gyro process noise (Q = sigma^2 * dt).
32
* It must cover not only the sensor noise (~0.003 deg/s/rtHz from the datasheet)
33
* but also what the model ignores: scale-factor error, misalignment,
34
* acceleration sensitivity. In simulation with 1% scale error and 1 deg of
35
* misalignment: sigma 0.1 -> RMSE 1.17 deg, sigma 0.5 -> 0.42 deg.
36
* Hence 0.5: it can be lowered only after calibrating gyro scale and
37
* misalignment (see 03 - Docs/theory/iekf-embedded.md). */
38
#define IEKF_SIGMA_GYRO (0.5f * DEG2RAD_F)
39
#define IEKF_SIGMA_BIAS 1e-4f
40
#define IEKF_SIGMA_VEC_MIN 0.01f
41
#define IEKF_ACC_TOL 0.08f
42
#define IEKF_MAG_TOL 0.08f
43
#define IEKF_P0_ATT ((2.0f * DEG2RAD_F) * (2.0f * DEG2RAD_F))
44
#define IEKF_P0_BIAS ((0.2f * DEG2RAD_F) * (0.2f * DEG2RAD_F))
45
#define IEKF_ESTIMATE_BIAS 1
46
#define IEKF_ADAPTIVE 1
47
#define IEKF_TILT_COMP_MAG 1
48
49
/* ---------------- robustness (external accelerations / magnetic disturbances) ----
50
* Accelerometer: R inflated by NIS/gate when the innovation is inconsistent with
51
* the covariance (this also catches accelerations PERPENDICULAR to gravity, which
52
* the magnitude check barely sees), with a memory of IEKF_INFL_TAU_S.
53
* Magnetometer: de-weighted when the measured field-gravity angle departs from
54
* the calibration value (independent of the estimate: it does not slow down yaw
55
* recovery).
56
* Stillness detector: board at rest -> the accelerometer is trusted again at once. */
57
#define IEKF_ACC_NIS_GATE 4.0f
58
#define IEKF_MAG_NIS_GATE 0.0f
59
#define IEKF_INFL_TAU_S 0.5f
60
#define IEKF_DIP_TOL (5.0f * DEG2RAD_F)
61
#define IEKF_DECOUPLE 0
62
/* "Lockout" protection: without it, a true attitude error during motion inflates
63
* R_acc forever (recovery > 20 s). The inflation is capped and, if the innovation
64
* is persistent in the world frame (a true error, not shaking), after
65
* IEKF_LOCKOUT_S the covariance is reopened and the accelerometer trusted again. */
66
#define IEKF_RESET_JACOBIAN 1
67
/* Tangential vector innovation: the radial part of y - yhat (along yhat) is
68
* dropped, it is outside the range of H and only inflated the NIS of large
69
* errors (see 03 - Docs/theory/iekf-embedded.md, "Tangential innovation"). */
70
#define IEKF_TANGENT_INNOV 1
71
#define IEKF_INFL_MAX 100.0f
72
#define IEKF_LOCKOUT_S 0.5f
73
#define IEKF_LOCKOUT_BUMP ((10.0f * DEG2RAD_F) * (10.0f * DEG2RAD_F))
74
#define IEKF_GRACE_S 0.25f
75
#define IEKF_PERSIST_TAU_S 1.0f
76
#define IEKF_PERSIST_RATIO 0.6f
77
#define IEKF_PERSIST_MIN 0.02f
78
79
/* ---------------- diagnostic comparison profile ----------------
80
* 1 = filter as in the earlier "works better" version: no inflation cap,
81
* no lockout protection, no error reset. */
82
#define APP_PROFILE_PREVIOUS 0
83
#if APP_PROFILE_PREVIOUS
84
#undef IEKF_RESET_JACOBIAN
85
#define IEKF_RESET_JACOBIAN 0
86
#undef IEKF_INFL_MAX
87
#define IEKF_INFL_MAX 1e4f
88
#undef IEKF_LOCKOUT_S
89
#define IEKF_LOCKOUT_S 0.0f
90
#endif
91
#define APP_STILL_ACC_TOL 0.02f
92
#define APP_STILL_GYRO_THR (3.0f * DEG2RAD_F)
93
#define APP_STILL_TIME_S 0.3f
94
95
/* ---------------- comparison with the original MATLAB filter ----------------
96
* 1 = disables the extensions that the original iekfAttitude.m does not have
97
* (NIS inflation, dip check, stillness detector, variance due to the age of
98
* the mag sample, error reset). The embedded filter must then match the
99
* original up to float32 precision: this proves that the C code implements
100
* the equations validated in MATLAB.
101
* 0 = full configuration: the comparison quantifies the effect of the extensions. */
102
#define APP_COMPARE_ORIGINAL 0
103
104
/* ---------------- magnetometer -> body (LSM6DSV16X frame) ----------------
105
* Calibration of 2026-10-07 (calibMagAxes.m on the board): LIS2MDL axes rotated
106
* by 180 deg about x w.r.t. the LSM6DSV16X (y and z flipped).
107
* Large hard-iron (~194 uT, ~4x the Earth field): recalibrate whenever anything
108
* near the sensor changes (cables, battery, screws, motors). */
109
#define MAG_AXIS_MAP { 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f }
110
#define MAG_HARD_IRON { 31.61f, 16.44f, -26.23f }
111
/* ---------------- telemetry (phase 1: ST-LINK virtual COM port) ---------------- */
112
#define APP_TLM_DECIMATION 1u
113
#define APP_TLM_DECIM_REPLAY 8u
/* with REPLAY on, STATE drops to 30 Hz:
114
REPLAY already carries q and bias at 240 Hz */
115
#define APP_TLM_TX_TIMEOUT_MS 20u
116
#define APP_INIT_EVERY_N 480u
117
#define APP_TLM_REPLAY 0
/* 1 only for the MATLAB comparison: raises the
118
telemetry from ~19 to ~44 kB/s, too much for
119
the real-time viewer -> record with
120
tlmCapture.m and analyse offline */
121
122
/* ---------------- telemetry over BLE (phase 2, see 03 - Docs/firmware/ble.md) ----------------
123
* Same frames as the UART, as a byte stream on a GATT notification. The UART
124
* keeps working unchanged (REPLAY and comparison stay USB-only). */
125
#define APP_TLM_BLE 1
/* 1 once STM32_WPAN (BLE) is enabled in CubeMX
126
and the CPU2 wireless stack is flashed */
127
#define APP_BLE_STATE_DECIM 4u
/* STATE over BLE: 240/4 = 60 Hz (~5.4 kB/s in
128
total with STATUS and INIT). Changeable at run
129
time with the CMD characteristic. */
130
#define APP_BLE_FLUSH_MS 10u
/* TX thread period: groups frames in one
131
notification when the MTU allows it */
132
#define APP_BLE_CONN_INT_MIN 12u
133
#define APP_BLE_CONN_INT_MAX 24u
134
#define APP_BLE_SUPERV_TIMEOUT 400u
135
/* ---------------- ACwing Pilot protocol v2 ---------------- */
136
#define APP_HW_REV 'N'
137
/* ACwing Flow: PMW3901 counts -> body axes (frame C2: board t forward, s left).
138
* To be confirmed on the first build (FLOW_TOF calibration, "match"). */
139
#define APP_FLOW_SIGN_X (1.0f)
140
#define APP_FLOW_SIGN_Y (1.0f)
141
/* PMW3901 minimum working distance (datasheet: 80 mm). Landed, the lens is
142
* ~11 mm above the floor (frame C2): below this height the flow is not used
143
* (no velocity, no POS_HOLD, no FLOW_LOST failsafe); usable again 20 mm above. */
144
#define APP_FLOW_MIN_H 0.08f
145
146
/* ---------------- battery (BattTask) ---------------- */
147
/* ADC1 injected group, VBAT + CUR + VREFINT, 16x oversampling.
148
* ACwing FC rev A: PA5 = VBAT_SNS (ADC1_IN10, 100k/10k), PA4 = ESC_CUR (ADC1_IN9).
149
* Bench (NUCLEO-WB55): off by default -- nothing is wired. To try it, wire a
150
* 100k/10k divider from a bench supply to A0 (PC0, ADC1_IN1) and optionally a
151
* voltage for the current to A1 (PC1, ADC1_IN2), then set APP_BATT_ADC 1. */
152
#if APP_HW_REV == 'A'
153
#define APP_BATT_ADC 1
154
#define APP_BATT_VBAT_CH 10u
155
#define APP_BATT_VBAT_PORT GPIOA
156
#define APP_BATT_VBAT_PIN (1u << 5)
157
#define APP_BATT_CUR_CH 9u
158
#define APP_BATT_CUR_PORT GPIOA
159
#define APP_BATT_CUR_PIN (1u << 4)
160
#else
161
#define APP_BATT_ADC 0
162
#define APP_BATT_VBAT_CH 1u
163
#define APP_BATT_VBAT_PORT GPIOC
164
#define APP_BATT_VBAT_PIN (1u << 0)
165
#define APP_BATT_CUR_CH 2u
166
#define APP_BATT_CUR_PORT GPIOC
167
#define APP_BATT_CUR_PIN (1u << 1)
168
#endif
169
#define APP_BATT_CURRENT 1
170
#define APP_BATT_SENS_V_A 0.1f
172
/* ---------------- flight log (LogTask) ---------------- */
173
/* 0 none, 1 RAM (bench: the log is lost at power-off), 2 W25Q128JV on SPI1 (rev A) */
174
#if APP_HW_REV == 'A'
175
#define APP_LOG_FLASH 2
176
#else
177
#define APP_LOG_FLASH 1
178
#endif
179
#define APP_LOG_RAM_KB 48u
181
/* ---------------- USB device (CDC: ground link, ADR 0009) ---------------- */
182
#define APP_USB_CDC 1
183
/* The USB link carries the flight log, parameters, calibrations and telemetry,
184
* never flight commands; ARM, TAKEOFF and MOTOR_TEST are refused while a USB
185
* host is connected. With a program on the port it also gets the PC telemetry
186
* (STATE, INIT, STATUS, and REPLAY when enabled) that the UART carries: on the
187
* ACwing FC there is no ST-LINK virtual COM port. */
188
#define APP_USB_TLM 1
189
190
#endif
/* APP_CONFIG_H */
app
app_config.h
Generated by
1.9.8