Skip to main content

ados_protocol/
lib.rs

1#![doc = include_str!("../README.md")]
2
3pub mod ap_country;
4pub mod armed;
5pub mod aux_egress;
6pub mod aux_mux;
7pub mod aux_ports;
8pub mod aux_rpc;
9pub mod aux_rpc_proxy;
10pub mod buttons;
11pub mod camera_control;
12pub mod capabilities;
13pub mod cloud_link;
14pub mod cloud_publish;
15#[cfg(feature = "mavlink")]
16pub mod config_tunnel;
17pub mod config_tunnel_ingest;
18pub mod contracts;
19#[cfg(feature = "tls")]
20pub mod crypto;
21pub mod dashboard_session;
22pub mod dispatch;
23pub mod fleet_identity;
24pub mod flight_modes;
25pub mod frame;
26pub mod framebus;
27pub mod hwcaps;
28pub mod identity;
29pub mod ipc;
30pub mod launchd;
31pub mod link_feedback;
32pub mod logd;
33#[cfg(feature = "mavlink")]
34pub mod mavlink;
35pub mod mavlink_ingest;
36pub mod mavlink_socket;
37pub mod mcp_token;
38pub mod media_relay;
39pub mod msp;
40pub mod netif;
41pub mod node_info;
42pub mod node_presence;
43pub mod node_status;
44pub mod nonce_cache;
45pub mod offload_link;
46pub mod pair_proof;
47pub mod pairing_posture;
48pub mod panel_ui;
49pub mod param_codec;
50pub mod paths;
51pub mod plugin;
52pub mod plugin_loopback_guard;
53pub mod plugin_mdns;
54pub mod radio_adapters;
55pub mod reach;
56pub mod relay_ticket;
57pub mod rest;
58pub mod retry;
59pub mod secret_gen;
60pub mod shutdown;
61pub mod sidecar;
62pub mod state;
63pub mod tap;
64pub mod units;
65pub mod vision_rpc;
66pub mod vision_status;
67pub mod wfb_status;
68pub mod wfb_tables;
69pub mod ws_ticket;
70
71/// Whether a flight-mode name is one that accepts offboard position setpoints.
72///
73/// Which mode a vehicle must be in to be commanded is firmware-specific, and the
74/// name is all that survives the decode: ArduPilot calls it GUIDED, PX4 calls it
75/// OFFBOARD, and PX4's mode table contains no GUIDED entry at all. A gate that
76/// compared against the single string "GUIDED" could therefore never be
77/// satisfied by a PX4 vehicle no matter what its operator did.
78///
79/// Deliberately NOT widened to the AUTO modes. PX4 rejects offboard setpoints
80/// under those, so admitting them would move the failure from commanding
81/// nothing to commanding something that is quietly ignored, which is worse
82/// because it looks like it is working.
83pub fn accepts_offboard_setpoints(mode: &str) -> bool {
84    matches!(mode, "GUIDED" | "GUIDED_NOGPS" | "OFFBOARD")
85}
86
87#[cfg(test)]
88mod offboard_mode_tests {
89    use super::accepts_offboard_setpoints;
90
91    #[test]
92    fn each_firmware_names_the_commandable_mode_differently() {
93        assert!(accepts_offboard_setpoints("GUIDED"), "ArduPilot");
94        assert!(
95            accepts_offboard_setpoints("GUIDED_NOGPS"),
96            "ArduPilot without GPS"
97        );
98        assert!(accepts_offboard_setpoints("OFFBOARD"), "PX4");
99    }
100
101    #[test]
102    fn a_px4_auto_mode_is_not_commandable() {
103        // PX4 ignores offboard setpoints under AUTO. Admitting these would turn
104        // a visible refusal into a silent no-op.
105        for mode in ["AUTO.LOITER", "AUTO.MISSION", "AUTO.RTL", "AUTO.TAKEOFF"] {
106            assert!(!accepts_offboard_setpoints(mode), "{mode}");
107        }
108    }
109
110    #[test]
111    fn a_pilot_flown_mode_is_not_commandable() {
112        for mode in ["MANUAL", "STABILIZED", "ACRO", "POSCTL", "ALTCTL", "LOITER"] {
113            assert!(!accepts_offboard_setpoints(mode), "{mode}");
114        }
115    }
116}