Expand description
§ados-crsf-codec
no_std CRSF (Crossfire / ExpressLRS) codec: frames, packed RC channels, telemetry and parameter frames, axis scaling and link liveness.
CRSF is the serial protocol spoken by Crossfire and ExpressLRS radio modules, receivers and flight controllers. This crate encodes and decodes it: build an RC channels frame for a transmitter module, hunt frames out of a noisy byte stream, decode the telemetry a module sends back, and decide from link statistics whether the radio link is actually up. It is pure data handling with no I/O, so it runs the same on a microcontroller and on a Linux host.
use ados_crsf_codec::channels::{build_rc_frame, unpack_channels, CHANNEL_COUNT, CHANNEL_MID, PACKED_SIZE};
use ados_crsf_codec::frame::{Parser, ADDR_FLIGHT_CONTROLLER, TYPE_RC_CHANNELS_PACKED};
// 16 channels at center, with throttle low and one switch high.
let mut channels = [CHANNEL_MID; CHANNEL_COUNT];
channels[2] = 172;
channels[4] = 1811;
// One complete wire frame: sync, length, type, 22-byte payload, CRC-8.
let wire = build_rc_frame(&channels).unwrap();
assert_eq!(wire.len(), 26);
// Feed the bytes to the stream parser, split across two reads and
// preceded by line noise.
let mut parser = Parser::new();
assert!(parser.push(&[0x00, 0x42]).is_empty());
let mut frames = parser.push(&wire[..10]);
frames.extend(parser.push(&wire[10..]));
assert_eq!(frames.len(), 1);
let frame = &frames[0];
assert_eq!(frame.sync, ADDR_FLIGHT_CONTROLLER);
assert_eq!(frame.frame_type, TYPE_RC_CHANNELS_PACKED);
let payload: &[u8; PACKED_SIZE] = frame.payload.as_slice().try_into().unwrap();
assert_eq!(unpack_channels(payload), channels);§Highlights
#![no_std]withalloc; zero dependencies. Builds for bare-metal targets such asthumbv7em-none-eabihf.- The stream parser never panics on garbage: it resyncs byte by byte and counts the bytes it skipped.
- Codecs round-trip: every typed frame has an encoder and a decoder, and 61 unit tests check wire layouts and round trips.
- Payload sizes are validated against the frame type before decoding, so a short or long payload is an error, not a panic.
- Link liveness is a pure function: no clocks, no threads, just durations in and a state out.
§How it works
The crate has seven modules.
frameis the byte framing. Every frame is[sync] [len] [type] [payload...] [crc8].lencounts the bytes after it (type, payload and CRC, so 2..=62). The CRC-8 uses the DVB-S2 polynomial0xD5(init 0, no reflection, no xor-out) and covers the type and payload only. The sync byte is a device address:0xC8(flight controller),0xEE(transmitter module) or0xEA(radio handset); anything else is rejected.Parserbuffers partial input and returns every complete, CRC-valid frame.channelspacks 16 channels of 11 bits each, LSB first, into the 22-byteRC_CHANNELS_PACKED(0x16) payload.172is full low,992center and1811full high. The codec round-trips any 11-bit value; clamping to the usable range is the caller’s choice.bankis a validated set of 16 channel values: writes outside 172..=1811 are rejected, and a bulk write is all or nothing.scalemaps a signed 16-bit axis onto the channel range (with an exact 992 center) and an N-position switch onto evenly spaced channel values.telemetrydecodes and encodes link statistics (0x14), GPS (0x02), battery (0x08), attitude (0x1E) and flight mode (0x21). Multi-byte fields are big-endian.paramscarries the parameter protocol: read (0x2E), write (0x2F) and settings entry (0x2D) frames.linkderives a link state from what was observed. Bytes accepted by a serial driver prove nothing about the radio, so the verdict keys on fresh link-statistics telemetry and its uplink link quality. Transmitting with no fresh statistics past a grace window, or with uplink quality at zero, readsRfUnverified; onlyLinkOkandDegradedcount as flyable.
§Part of ADOS
Used in production by the ADOS Drone Agent, the onboard software of the ADOS software-defined drone platform. All ADOS crates · Docs · Discord
§Other ADOS crates
Platform (versioned with the ADOS Drone Agent)
| Crate | What it does | Docs |
|---|---|---|
ados-protocol | Wire contracts of the ADOS Drone Agent: IPC framing, plugin RPC envelope, capability tokens and the vision frame bus. | docs.rs |
ados-sdk | Write Rust plugins for the ADOS Drone Agent: IPC client, plugin context, driver traits and lifecycle runner. | docs.rs |
ados-vision | Single-object visual tracker: Kalman motion model, appearance re-identification and YOLOv8 head decoding. | docs.rs |
ados-gpio | Drive status buzzers and LEDs on Linux GPIO lines, with bounded software-PWM beep patterns. | docs.rs |
ados-hal-probe | Find out what a board’s hardware can really do by probing it, plus bundled board profiles. | docs.rs |
Standalone
| Crate | What it does | Docs |
|---|---|---|
ados-sensorhub | Sensor hub wire protocol: COBS framing, CRC-16 and fixed-layout IMU, baro, mag and GNSS packets. no_std. | docs.rs |
ados-offload | Choose where perception runs (onboard, offloaded or hybrid) and hold the vehicle when results go stale. | docs.rs |
ados-macpin | Stable MAC addresses for Linux network adapters that randomize theirs every boot. | docs.rs |
ados-lora | LoRa transmit governor with cited regional band plans, duty cycle, dwell time and airtime accounting. | docs.rs |
ados-positioning | Split mixed UBX, NMEA and RTCM3 GNSS streams, configure u-blox receivers and run an RTK base survey-in. | docs.rs |
ados-rtcm | RTCM3 framing, CRC-24Q and MAVLink GPS_RTCM_DATA fragmentation for RTK corrections. | docs.rs |
ados-clock | Map remote clocks onto the host clock: least-squares and envelope fits, TIMESYNC and a chrony sink. | docs.rs |
ados-swarm | Swarm control laws: separation, flocking, formations, CBBA task allocation and a point-mass simulator. | docs.rs |
ados-mavlink-tunnel | Send large messages over MAVLink TUNNEL frames with chunking and bounded reassembly. | docs.rs |
ados-display-driver | Small-display output on Linux: SSD1306/SH1106 OLED over I2C, pixel packers and a framebuffer writer. | docs.rs |
ados-hmi | Front-panel input: touchscreen calibration and gestures, button presses and rotary encoders. | docs.rs |
§ADOS repositories
| Repo | Runs on | What it does | Link |
|---|---|---|---|
| ADOS Mission Control | Browser, desktop (Electron) | Ground control station: FC setup, mission planning, flight, 3D simulation, fleet | ADOSMissionControl |
| ADOS Drone Agent | Companion computer on the drone, or a ground node | Onboard agent: MAVLink routing, HD video, long-range radio link, plugins, remote control | ADOSDroneAgent |
| ADOS Android GCS | Android phones and tablets | Native ground control app for agents on the LAN, direct flight controllers and the cloud | ADOSAndroidGCS |
| ADOS Extensions | Drone Agent and Mission Control | First-party signed plugins, each with an agent half and a GCS half | ADOSExtensions |
| ADOS MCP | Your machine | Model Context Protocol server that lets AI clients operate ADOS drones under scopes and a safety gate | ADOS-MCP |
| Documentation | docs.altnautica.com | Public docs for every ADOS product | Documentation |
§License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Modules§
- bank
- A validated bank of 16 RC channel values.
- channels
- RC channel packing: 16 channels × 11 bits, little-endian LSB-first, the
payload of the
RC_CHANNELS_PACKED(0x16) frame. - frame
- CRSF frame layer: the byte framing, the CRC, and a sync-hunting stream parser that never panics on garbage.
- link
- Link state derivation: a pure function from observed inputs to a link
state and an
rf_unverifiedverdict. - params
- Parameter (configuration) frame codecs: settings entry (0x2D), read request (0x2E), and write command (0x2F).
- scale
- Input scaling: signed 16-bit axis and switch values → CRSF channel values.
- telemetry
- Telemetry frame codecs: link statistics (0x14), GPS (0x02), battery (0x08), attitude (0x1E), and flight mode (0x21).