Oleksandr Bezdieniezhnykh 2bcd4a8059 [AZ-651] [AZ-668] lost-link failsafe ladder + mapobjects persistence (batch 7)
AZ-651 (mission_executor lost-link ladder):
- LostLinkLadder pure-logic state machine (LinkOk -> Degraded -> Lost
  -> LinkLostInFollow + MavlinkLost branch). Configurable thresholds
  via LostLinkConfig.
- LostLinkCommandIssuer trait + MavlinkCommandIssuer production impl
  emitting MAV_CMD_NAV_RETURN_TO_LAUNCH via MavlinkHandle::send_command.
- LostLinkDriver task wires the ladder to operator-link watch, MAVLink
  LinkEvent broadcast, and optional target-follow signal. On RTL,
  driver calls the issuer THEN MissionExecutorHandle::failsafe_trigger.
- failsafe_trigger(LinkLost | LinkLostInFollow) short-circuits FlyMission
  -> Land via direct FSM state mutation + TransitionEvent emission;
  Paused state is intentionally NOT overridden.
- Tests: 4/4 ACs locally green (degraded-no-rtl; lost-fires-once;
  follow-grace; mavlink-loss-no-rtl) plus driver + FSM integration.

AZ-668 (mapobjects_store persistence):
- Snapshot serializable shape + Store::{to_snapshot,from_snapshot}
  round trip.
- MapObjectsPersistence async trait + JsonSnapshotEngine default impl
  (write to .tmp, sync_all, atomic rename, best-effort parent fsync).
- PersistenceError::{Corrupt, SchemaMismatch} surfaces explicit errors
  on bad blob; PersistenceMetrics tracks last_snapshot_ts,
  snapshot_size_bytes, snapshot_errors_total.
- MapObjectsStore::from_snapshot factory for crash recovery from the
  composition root.
- Tests: 4/4 ACs locally green (round-trip; atomic rename ignores
  partial .tmp; crash recovery preserves pending; corruption returns
  explicit error) plus schema-mismatch + metrics smoke checks.

Quality gates:
- cargo fmt: clean.
- cargo clippy -p mission_executor -p mapobjects_store --tests: 0 warns.
- cargo test --workspace: all green.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 18:59:28 +03:00

autopilot

Onboard mission executor for the AZAION reconnaissance UAV. Single Rust binary; runs on NVIDIA Jetson Orin Nano Super (aarch64). See _docs/02_document/architecture.md for the authoritative system design.

Layout

crates/
  shared/                # canonical DTOs, config, error, health, observability, clock, contracts
  autopilot/             # binary crate — runtime composition root + /health endpoint
  mavlink_layer/         # hand-rolled MAVLink v2 transport
  mission_client/        # missions API REST client + MapObjects sync
  frame_ingest/          # RTSP pull + decode
  detection_client/      # bi-directional gRPC to ../detections
  movement_detector/     # ego-motion-compensated residual-motion clustering
  semantic_analyzer/     # Tier 2 — primitive graph + ROI CNN
  vlm_client/            # Tier 3 — optional NanoLLM/VILA local IPC
  mapobjects_store/      # H3-indexed on-device map + ignored items
  gimbal_controller/     # ViewPro A40 UDP control
  scan_controller/       # central typed state machine (ZoomedOut/ZoomedIn/TargetFollow)
  operator_bridge/       # POI surface + operator command authentication
  mission_executor/      # multirotor + fixed-wing FSMs + geofence + failsafe
  telemetry_stream/      # always-on uplink to Ground Station

config/                  # TOML config per environment (dev / staging / prod)
deploy/systemd/          # on-airframe native systemd unit (Option A)
fixtures/                # replay clips (RTSP, MAVLink, missions, detections)
tests/e2e/               # workspace-level blackbox scenarios
benches/                 # NFR benchmark-gate harness

Build

# Host-arch build + tests
cargo build --workspace
cargo test  --workspace --locked

# Optional VLM feature path
cargo build --workspace --features vlm

# No-default-features path (enforces the VLM optionality contract)
cargo build --workspace --no-default-features
cargo test  --workspace --no-default-features

# aarch64 cross-build (CI uses cargo-zigbuild; locally `cross` also works)
cargo install --locked cargo-zigbuild
rustup target add aarch64-unknown-linux-gnu
cargo zigbuild --release --target aarch64-unknown-linux-gnu --workspace

Run (dev)

cp .env.example .env
docker compose up -d
# Then inspect:
curl -s http://127.0.0.1:8080/health | jq

Documentation

The full document tree lives under _docs/. Start with:

  • _docs/00_problem/problem.md — the problem statement
  • _docs/02_document/architecture.md — system architecture
  • _docs/02_document/system-flows.md — sequence diagrams
  • _docs/02_document/components/<name>/description.md — per-component specs
  • _docs/02_document/deployment/{containerization,ci_cd_pipeline,observability}.md

CI

.woodpecker.yml drives the pipeline. Stages: fetch → lint → unit-test → build-arm64 → build-no-vlm → integration-test → sitl-conformance → security-scan → package → sign → publish → benchmark-gate (opt-in).

S
Description
No description provided
Readme 58 MiB
Languages
C 58.6%
C++ 40%
QMake 1%
CMake 0.3%