Expand description
§ados-rtcm
RTCM3 framing, CRC-24Q and MAVLink GPS_RTCM_DATA fragmentation for injecting RTK corrections into a flight controller.
An RTK rover needs a steady stream of RTCM3 correction messages from a base station, and a flight controller running ArduPilot or PX4 accepts them over MAVLink as GPS_RTCM_DATA messages of at most 180 bytes each. This crate finds whole, CRC-checked RTCM3 frames in a byte stream that arrives in arbitrary pieces, and splits each frame into the fragments and flag bits the firmware reassembles. Reach for it when you forward corrections from a base receiver, an NTRIP client or a file to a vehicle.
use ados_rtcm::{crc24q, encode_rtcm3, split_rtcm3, Fragmenter, Rtcm3Splitter};
// Frame a 394-byte RTCM3 payload: preamble, 10-bit length, payload, CRC-24Q.
let payload: Vec<u8> = (0..394).map(|i| i as u8).collect();
let frame = encode_rtcm3(&payload);
assert_eq!(frame.len(), 400);
// The trailing three bytes are the CRC-24Q of everything before them.
let (body, crc) = frame.split_at(frame.len() - 3);
assert_eq!(crc24q(body).to_be_bytes()[1..], *crc);
// Junk before the frame is skipped; a stream cut in two still yields one frame.
let mut stream = vec![0x00, 0x11];
stream.extend_from_slice(&frame);
assert_eq!(split_rtcm3(&stream), vec![&frame[..]]);
let mut splitter = Rtcm3Splitter::default();
assert!(splitter.push(&stream[..100]).is_empty());
let frames = splitter.push(&stream[100..]);
// Fragment into GPS_RTCM_DATA payloads: 180 + 180 + 40 bytes.
let mut fragmenter = Fragmenter::default();
let fragments = fragmenter.fragment(&frames[0]).unwrap();
let lens: Vec<u8> = fragments.iter().map(|f| f.len).collect();
assert_eq!(lens, [180, 180, 40]);
assert_eq!(fragments[1].flags, 1 | (1 << 1)); // fragmented, id 1, sequence 0§Highlights
- Zero dependencies, standard library only.
- Stream splitter with resync: junk bytes and frames with a bad CRC are skipped, and the carried partial frame is bounded by one maximum RTCM3 frame (1029 bytes).
- Fragment flags and end-of-message rules match the
GPS_RTCM_DATAreassembly in flight-controller firmware, including the zero-length closing fragment. - Unit tests cover fragment counts at every boundary, sequence id wraparound, CRC check values and splitting at every cut point of a frame.
§How it works
RTCM3 frames. A frame is the preamble 0xD3, 6 reserved bits, a 10-bit payload length, the payload (at most 1023 bytes) and a 24-bit CRC-24Q (polynomial 0x1864CFB, initial value 0) over everything before it. encode_rtcm3 builds one and crc24q computes the check.
Splitting. split_rtcm3 returns every whole CRC-valid frame in one buffer and drops an incomplete tail. Rtcm3Splitter does the same for a stream delivered in pieces, keeping the partial frame for the next push. A preamble whose frame fails its CRC is skipped by one byte so the scan resyncs on the next preamble.
Fragmentation. GPS_RTCM_DATA carries at most 180 bytes (FRAGMENT_LEN). A message of up to 180 bytes goes out whole with flags = 0. A longer one is split into 180-byte fragments with flags = 1 | fragment_id << 1 | (sequence_id & 0x1f) << 3, and Fragmenter advances its 5-bit sequence id once per fragmented message, so keep one Fragmenter per output link. The receiver treats a fragmented message as complete at the first fragment shorter than 180 bytes, or once all four fragments arrived. A message that is an exact multiple of 180 bytes below 720 therefore ends with a zero-length fragment, and 720 bytes (MAX_MESSAGE_LEN) is four full fragments. Longer messages return TooLong. message_fragments and fragment_count count the messages ahead of sending.
§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-crsf-codec | no_std CRSF / ExpressLRS codec for RC channels, telemetry and parameter frames. | 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-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.
Structs§
- Fragment
- One
GPS_RTCM_DATAmessage body. - Fragmenter
- Splits RTCM messages into
GPS_RTCM_DATAfragments, owning the 5-bit sequence id. - Rtcm3
Splitter - Splits an RTCM3 byte stream delivered in arbitrary pieces into whole
CRC-valid frames, carrying a partial frame over to the next push. The
carried tail is bounded by one maximum frame; junk and corrupt frames are
skipped with the same resync as
split_rtcm3. - TooLong
- A message too long to carry in four fragments.
Constants§
- FRAGMENT_
LEN - Payload capacity of one
GPS_RTCM_DATAmessage. - MAX_
FRAGMENTS - Fragments one message may span (two-bit fragment id).
- MAX_
MESSAGE_ LEN - Longest message the fragments can carry.
Functions§
- crc24q
- CRC-24Q (polynomial 0x1864CFB, initial value 0), the RTCM3 frame check.
- encode_
rtcm3 - Wrap
payload(at most 1023 bytes) in an RTCM3 frame: preamble, length, payload, CRC-24Q. - fragment_
count - Number of
GPS_RTCM_DATAmessages a byte stream produces aftersplit_rtcm3. - message_
fragments - The number of
GPS_RTCM_DATAmessages one RTCM message oflenbytes becomes. - split_
rtcm3 - Split one byte buffer into its whole CRC-valid RTCM3 frames (see
Rtcm3Splitterfor a stream that arrives in pieces). An incomplete frame at the end is dropped.