mirror of
https://github.com/azaion/autopilot.git
synced 2026-06-22 16:41:10 +00:00
[AZ-649] [AZ-674] [AZ-667] telemetry + vlm schema + mapobjects hydrate batch 6
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>
This commit is contained in:
@@ -33,6 +33,9 @@ use shared::models::mission::{Coordinate, MissionItem, MissionWaypoint};
|
||||
mod internal;
|
||||
|
||||
pub use internal::driver::{DriverError, MissionDriver};
|
||||
pub use internal::telemetry::{
|
||||
Consumer, DropCountingReceiver, MavlinkProjection, TelemetryForwarder,
|
||||
};
|
||||
pub use internal::types::{
|
||||
MissionState, StepOutcome, Telemetry, TransitionEvent, TransitionKey, Variant,
|
||||
};
|
||||
@@ -267,6 +270,49 @@ impl HealthDetail for ComponentHealth {
|
||||
}
|
||||
}
|
||||
|
||||
/// Spawn a task that subscribes to `mavlink_handle.subscribe_inbound()`
|
||||
/// and republishes every telemetry-bearing message through
|
||||
/// `forwarder`. Returns the task handle.
|
||||
///
|
||||
/// Non-telemetry MAVLink messages (mission protocol, command acks,
|
||||
/// status text, etc.) are intentionally ignored — they are consumed
|
||||
/// by other paths inside `mavlink_layer` (`send_command` demux,
|
||||
/// `mission_client` pull, …).
|
||||
///
|
||||
/// `RecvError::Lagged(n)` on the inbound subscription is treated as
|
||||
/// a hard drop on this side too: we log `n` skipped frames at warn
|
||||
/// level (the forwarder doesn't even see them) and continue. The
|
||||
/// forwarder's downstream channels are independent and unaffected.
|
||||
pub fn spawn_mavlink_pump(
|
||||
mavlink_handle: mavlink_layer::MavlinkHandle,
|
||||
forwarder: Arc<TelemetryForwarder>,
|
||||
) -> JoinHandle<()> {
|
||||
let mut rx = mavlink_handle.subscribe_inbound();
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
match rx.recv().await {
|
||||
Ok(inbound) => {
|
||||
if let Some(projection) = MavlinkProjection::from_mavlink(&inbound.message) {
|
||||
forwarder.publish_from_mavlink(&projection);
|
||||
}
|
||||
}
|
||||
Err(tokio::sync::broadcast::error::RecvError::Lagged(n)) => {
|
||||
tracing::warn!(
|
||||
skipped = n,
|
||||
"mission_executor telemetry pump lagged on mavlink inbound stream"
|
||||
);
|
||||
}
|
||||
Err(tokio::sync::broadcast::error::RecvError::Closed) => {
|
||||
tracing::info!(
|
||||
"mission_executor telemetry pump: mavlink inbound stream closed"
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user