mirror of
https://github.com/azaion/autopilot.git
synced 2026-06-21 10:11:09 +00:00
e56d428753
AZ-649 mission_executor telemetry forwarding: - shared::models::telemetry::UavTelemetry canonical model - TelemetryForwarder with atomic ArcSwap snapshot + 3 lossy tokio::sync::broadcast channels (MissionExecutor, ScanController, MavlinkUplink) + per-consumer drop counters - MavlinkProjection::from_mavlink for HEARTBEAT/GLOBAL_POSITION_INT/ ATTITUDE/SYS_STATUS - spawn_mavlink_pump bridges mavlink_layer into the forwarder at the binary edge AZ-674 vlm_client schema validation + model_version tracking: - AssessmentParser owns schema validation + model-version state - wire::read_response_raw splits raw bytes from parsing so invalid payloads can be logged size-capped - VlmStatus gains an Inconclusive variant; exhaustive-match test guards downstream consumers - VlmPipelineStatus mirrors the new variant in shared::models::poi AZ-667 mapobjects_store hydrate + pending logs + cascade: - SyncState enum aligned with description.md (FreshBoot, Synced, CachedFallback, Degraded, Failed) - Store::hydrate(MapObjectsBundle) replaces in-memory map atomically; freshness=Stale -> CachedFallback - classify() + end_of_pass append MapObjectObservation events to pending_observations (New/Moved/Existing/RemovedCandidate) - apply_decline + LocalAppended ignored items append to pending_ignored - drain_pending() returns and clears both logs - cascade_mission(id) purges by_cell + IgnoredSet + pending logs - Health surface reports sync_state, pending_obs, pending_ign Co-authored-by: Cursor <cursoragent@cursor.com>
97 lines
3.0 KiB
Rust
97 lines
3.0 KiB
Rust
//! `UavTelemetry` — projection of decoded MAVLink telemetry into a
|
|
//! typed snapshot that downstream consumers (`scan_controller`,
|
|
//! `movement_detector`, `telemetry_stream`, BIT) consume.
|
|
//!
|
|
//! Authoritative projection rules:
|
|
//!
|
|
//! - `position` from `GLOBAL_POSITION_INT` (id 33). Latitude/longitude
|
|
//! are kept in their MAVLink-native E7 form so consumers that
|
|
//! compare against waypoints (also E7) don't re-introduce float
|
|
//! round-trip drift. Altitude is in metres (MSL + AGL relative).
|
|
//! Velocities are in m/s, heading in degrees [0, 360).
|
|
//! - `attitude` from `ATTITUDE` (id 30). Angles in radians per the
|
|
//! MAVLink convention.
|
|
//! - `mode` from `HEARTBEAT` (id 0). The `(base_mode, custom_mode)`
|
|
//! pair is the canonical (vehicle-type-specific) discriminator;
|
|
//! `system_status` is the MAV_STATE enum (`MAV_STATE_ACTIVE` etc.).
|
|
//! - `sys_status` from `SYS_STATUS` (id 1). Battery + comms + sensor
|
|
//! health bitfield — the bits consumers actually read are
|
|
//! documented in `architecture.md §5.6`.
|
|
//! - `monotonic_ts_ns` is the host monotonic timestamp captured the
|
|
//! moment the originating MAVLink message was decoded. Strictly
|
|
//! non-decreasing across snapshots. Boot-time-relative fields
|
|
//! (`ts_boot_ms`) are kept on each sub-struct so consumers that
|
|
//! already correlate against MAVLink time-bases (e.g. EKF logs)
|
|
//! don't lose them.
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
|
pub struct UavPosition {
|
|
pub lat_e7: i32,
|
|
pub lon_e7: i32,
|
|
pub alt_m: f32,
|
|
pub relative_alt_m: f32,
|
|
pub vx_mps: f32,
|
|
pub vy_mps: f32,
|
|
pub vz_mps: f32,
|
|
pub heading_deg: f32,
|
|
pub ts_boot_ms: u32,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
|
pub struct UavAttitude {
|
|
pub roll: f32,
|
|
pub pitch: f32,
|
|
pub yaw: f32,
|
|
pub rollspeed: f32,
|
|
pub pitchspeed: f32,
|
|
pub yawspeed: f32,
|
|
pub ts_boot_ms: u32,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub struct UavMode {
|
|
pub base_mode: u8,
|
|
pub custom_mode: u32,
|
|
pub system_status: u8,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub struct UavSysStatus {
|
|
pub voltage_battery_mv: u16,
|
|
pub current_battery_ca: i16,
|
|
pub battery_remaining: i8,
|
|
pub onboard_sensors_health: u32,
|
|
pub errors_comm: u16,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
|
pub struct UavTelemetry {
|
|
pub position: Option<UavPosition>,
|
|
pub attitude: Option<UavAttitude>,
|
|
pub mode: Option<UavMode>,
|
|
pub sys_status: Option<UavSysStatus>,
|
|
pub monotonic_ts_ns: u64,
|
|
}
|
|
|
|
impl UavTelemetry {
|
|
/// Empty snapshot used as the initial value before any telemetry
|
|
/// has arrived.
|
|
pub fn empty() -> Self {
|
|
Self {
|
|
position: None,
|
|
attitude: None,
|
|
mode: None,
|
|
sys_status: None,
|
|
monotonic_ts_ns: 0,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for UavTelemetry {
|
|
fn default() -> Self {
|
|
Self::empty()
|
|
}
|
|
}
|