15#define DEG2RAD 0.017453292519943295f
123 for (
int tries = 0; tries < 8; ++tries) {
125 if (s0 & 1u)
continue;
135static void event(uint8_t level, uint16_t code, int32_t arg)
142static uint8_t
has(uint16_t bits) {
return (uint8_t)((
s_sensors & bits) != 0u); }
148static float clampf(
float v,
float lo,
float hi) {
return v < lo ? lo : (v > hi ? hi : v); }
158 if (ci < c) { c = ci; k = 1; }
217 const int a = (int)(
PARAM(p_idx) + 0.5f);
233#define OK() result(c, PV2_ACK_OK, PV2_R_NONE)
234#define REJ(why) result(c, PV2_ACK_REJECTED, (why))
235#define INVALID(w) result(c, PV2_ACK_INVALID, (w))
236 const uint8_t *p = c->
p;
289 float alt = (c->
len >= 2u) ? (
float)
pv2_rd_u16(p) / 100.0f : 0.0f;
291 if (alt < 0.5f) alt = 0.5f;
292 if (alt > 3.0f) alt = 3.0f;
329 if (c->
len < 4u || p[0] != 0x4Bu || p[1] != 0x49u || p[2] != 0x4Cu || p[3] != 0x4Cu) {
341 const uint8_t m = p[0];
356 const uint8_t m = p[0], pct = p[1];
540 else descending = (uint8_t)(
s_stick[0] < -0.9f);
576 static uint8_t prev_auto;
577 const float dt = (float)dt_ms * 1e-3f;
580 memset(&
sp, 0,
sizeof sp);
593 sp.pitch_rate =
s_stick[2] * 4.0f * yawr;
637 if (
s_v.
h >= ceil && vz > 0.0f) {
638 vz = (
s_v.
h > ceil + 0.3f) ? -0.3f : 0.0f;
656 const float ramp = 0.10f + 0.40f * (float)(now -
s_to_t0) * 1e-3f;
688 const float w =
clampf(
s_v.
vz * 100.0f, -32767.0f, 32767.0f);
708 while (
spsc_pop(&s_cmdq, &c))
exec(&c, now, est_running);
float alt_ctrl_vz_sp(const alt_ctrl_t *c, float h_sp, float h, float up, float dn)
void alt_ctrl_reset(alt_ctrl_t *c, float integ)
void alt_ctrl_init(alt_ctrl_t *c, float hover)
float alt_ctrl_step(alt_ctrl_t *c, float vz_sp, float vz, float ct, float dt)
Vertical control: height -> climb rate -> collective thrust.
uint32_t appl_silence_ms(uint32_t now_ms, uint32_t down_floor_ms)
Silence seen by the failsafe: now - last CMD frame, at least 'down_floor_ms' while the link is report...
int appl_rc_read(appl_rc_t *out, uint32_t *t_ms)
Latest RC values and their arrival time.
Receive side of the ACwing Pilot link (HANDOVER_FW.md ยง2 and ยง6).
static uint8_t s_batt_level
static void setpoints(uint32_t now, uint32_t dt_ms)
int fc_batt_signal(const fc_batt_sig_t *b)
0 = queued, -1 = full
static uint32_t s_last_ms
uint8_t fc_is_core_op(uint8_t op)
ops executed by the core
static uint8_t s_failsafe
void fc_service(uint32_t now, uint8_t est_running, const fc_vert_t *v)
v: NULL = no vertical estimate (in air only via g_fc_dbg_in_air)
void fc_set_ground_info(uint8_t ready, uint8_t batt_fail, uint8_t calibrating)
ground information computed by the AppTask (atomic byte stores)
static uint8_t gnss(void)
static uint8_t has(uint16_t bits)
static uint8_t s_test_pct
static void app_link_failsafe(uint32_t now)
int fc_take_result(fc_res_t *r)
1 if a result was taken
static uint8_t batt_owns_auto(void)
static uint32_t s_landed_ms
static uint8_t s_batt_have_hb
static void event(uint8_t level, uint16_t code, int32_t arg)
static uint8_t s_took_off
static fc_setpoint_t s_sp
static void flow_failsafe(uint32_t dt)
static uint8_t batt_unusable(void)
void fc_setpoint(fc_setpoint_t *out)
last setpoints, same context
static uint8_t home_set(void)
static void publish(void)
static uint8_t s_batt_lock
void fc_batt_heartbeat(uint32_t now)
every BattTask step
static uint8_t alt_sensor(void)
static uint32_t s_silence
static uint8_t s_batt_present
static void update_sticks(uint32_t now)
static uint8_t s_have_last
static int stick_moved(void)
static uint32_t s_flow_bad_ms
static void test_stop(void)
static uint32_t s_flight_ms
static volatile uint8_t s_checks_ready
static void exec(const fc_cmd_t *c, uint32_t now, uint8_t est_running)
static volatile uint32_t s_batt_hb_ms
static uint8_t s_geofence_ev
static uint8_t s_fs_short_hold
static void battery(uint32_t now)
static void air_ground(uint32_t now, uint32_t dt)
static float ceiling_h_kind(int32_t *kind)
static void lift_off(void)
static uint32_t s_test_until
static void touch_down(uint32_t now)
static volatile uint8_t s_batt_hb_set
static uint8_t s_dbg_forced
static uint8_t fs_action(int p_idx)
int fc_post(const fc_cmd_t *c)
0 = queued, -1 = full
static uint8_t s_geofence
static uint8_t indoor(void)
void fc_init(const fc_config_t *cfg)
static volatile uint8_t s_batt_fail
static volatile uint8_t s_calibrating
static uint8_t s_test_motor
static uint8_t hold_mode(void)
static uint8_t s_batt_stale
void fc_set_sensors(uint16_t sensors)
sensors detected at run time (a late expansion board): atomic store
static float ceiling_h(void)
void fc_snapshot(fc_state_t *out)
static void result(const fc_cmd_t *c, uint8_t res, uint8_t why)
static uint32_t s_touch_ms
static volatile uint16_t s_sensors
int fc_take_event(fc_event_t *e)
volatile uint8_t g_fc_dbg_in_air
static uint8_t s_rc_stale
static float clampf(float v, float lo, float hi)
static uint8_t alt_ok(void)
static uint8_t s_to_lifted
static volatile uint32_t s_snap_seq
Flight core: arming, modes, automatic actions, failsafes, motor test (HANDOVER_FW....
#define FC_FS_LONG_MS
fsAppLong + EVENT 20
#define FC_FS_SHORT_MS
fsAppShort
#define FC_LIFTOFF_TIMEOUT_MS
no lift-off -> TAKEOFF aborted
#define FC_ARM_RC_FRESH_MS
throttle rule applies to RC this recent
#define FC_LIFTOFF_DH
m above the ground level = airborne
#define FC_FLOW_LOST_Q
flow quality below this ...
#define FC_TOUCH_MS
... for this long (descent commanded)
#define FC_GROUND_DISARM_MS
armed on the ground, app silent
#define FC_NO_TAKEOFF_MS
auto-disarm if not taken off
#define FC_LINK_BACK_MS
link considered back
#define FC_TOUCH_MS_NO_TOF
#define FC_OP_MOTOR_STOP
stop a running motor test
#define FC_TOUCH_VZ
|vz| below this ...
#define FC_BATT_STALE_MS
no BattTask heartbeat: battery unknown
#define FC_STICK_CANCEL
30 % of the stick
#define FC_RC_STALE_MS
stop using the last RC values
#define FC_LAND_SLOW_VZ
m/s below 1 m with ToF
#define FC_TAKEOFF_VZ
m/s, climb during TAKEOFF
Drone parameters of protocol v2 (HANDOVER_FW.md ยง8, ids.ts PARAMS).
ACwing Pilot app protocol v2: identifiers and frame layouts.
static uint16_t pv2_rd_u16(const uint8_t *p)
little-endian readers for command payloads (unaligned-safe)
@ PV2_R_USB_CONNECTED
ARM / TAKEOFF / MOTOR_TEST while a USB host is connected (ADR 0009)
@ PV2_R_PROPS_CONFIRM_MISSING
#define PV2_PROPS_OFF_MAGIC
'P'
#define PV2_OP_MOTOR_TEST
@ PV2_E_BATTERY_EMERGENCY
@ PV2_E_TAKEOFF_ABORTED
firmware extension (WARN): no lift-off; the app shows the text
@ PV2_E_FAILSAFE_APP_LINK
@ PV2_E_BATTERY_MONITOR_LOST
firmware extension (ERROR): BattTask silent, battery unknown
Lock-free single-producer single-consumer queue of fixed-size items.
#define SPSC_DEFINE(name, type, n)
static int spsc_push(spsc_t *q, const void *it)
static void spsc_reset(spsc_t *q)
static int spsc_pop(spsc_t *q, void *it)
int16_t roll
-1000..1000: thr -1000 = stick bottom
battery signal (BattTask -> core): sent when the level or presence changes
uint8_t len
len = payload bytes after seq
void(* motor_test)(uint8_t motor, float duty)
motor 0 = all off
uint8_t batt_monitor
a BattTask measures the battery
uint8_t motors_built
0: MOTOR_TEST -> UNSUPPORTED
uint8_t n_motors
4, 6 or 8
uint8_t(* usb_host)(void)
1 while a USB host is connected: ARM, TAKEOFF and MOTOR_TEST are refused (USB_CONNECTED,...
void(* on_event)(const fc_event_t *e)
every event also goes here (flight-control context), e.g.
void(* motors_arm)(uint8_t armed)
outputs (ImuTask context); may be NULL on the host
uint16_t sensors
CAPS bits detected at boot
setpoints for the attitude / rate loops (phase 3) and the motor mixer
published state (AppTask builds FLIGHT / MOTORS from it)
uint8_t geofence
a limit is active
int32_t alt_rel_cm
above the take-off point
uint8_t fs_long
the long app-link action fired
uint8_t batt_stale
BattTask silent: battery state unknown
float stick[4]
setpoint inputs -1..1: thr, yaw, pitch, roll
uint8_t landed
touched down after a flight (until disarm)
uint8_t batt_level
last level signalled by the BattTask
uint32_t silence_ms
app link silence seen by the failsafe
uint8_t test_motor
motor under test (1..n), 0 none
uint8_t rc_stale
RC older than FC_RC_STALE_MS: neutral sticks in use.
vertical state from the estimator (flight-control context)
uint8_t valid
an altitude source is running (baro and/or ToF)
float vz
m, m/s, + up (alt_est)
float cos_tilt
R33 of the attitude
uint8_t tof_ground
ToF used / ToF below its minimum range
float tof_h
m above the floor
uint8_t flow_q
0..100, 0xFF n/a