mirror of
https://github.com/azaion/autopilot.git
synced 2026-06-21 14:21:10 +00:00
[AZ-626] Decompose complete: 47 tasks + docs + module layout
Greenfield Steps 1-6 baseline for the autopilot rewrite from legacy Qt/C++ to a Rust workspace. - Remove legacy Qt/C++ tree (ai_controller, drone_controller, misc/camera, python_scaffold, root Dockerfile, autopilot.pro, legacy main.py / requirements.txt). - Add _docs/00_problem (problem, restrictions, acceptance criteria, security approach, input data + fixtures). - Add _docs/01_solution/solution_draft01. - Add _docs/02_document (architecture, system-flows, data_model, glossary, decision-rationale, deployment, 13 component descriptions, tests/ specs, FINAL_report, module-layout). - Add _docs/02_tasks/todo with 47 task specs (AZ-640..AZ-686, one bootstrap + 46 component tasks) and _dependencies_table.md. - Add .cursor/rules/artifact-srp.mdc (single-responsibility rule for canonical _docs artifacts). - Track autodev state in _docs/_autodev_state.md (Step 6 completed, ready for Step 7 Implement). Jira: bootstrap AZ-626; component epics AZ-627..AZ-639; tasks AZ-640..AZ-686. Total complexity 173 points across 12 epics. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
# Component — `scan_controller`
|
||||
|
||||
**Layer**: Decision + Memory
|
||||
**Status**: forward-looking design (Rust)
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
The system's brain. A deterministic typed state machine — `ZoomedOut`, `ZoomedIn { roi, hold_started_at }`, and `TargetFollow { target_id, started_at }`. Owns the POI queue, timeouts, the ≤5 POIs/min operator-review cap, the confidence-scaled operator-decision window, gimbal command issuance, and the new/moved/existing/removed dispatch into `mapobjects_store`.
|
||||
|
||||
The full behaviour-tree spec — including tick scenarios and the 15 fixed-wing rules — lives in `system-flows.md §F4`.
|
||||
|
||||
## 2. Inputs
|
||||
|
||||
| Input | Source | Cadence | Notes |
|
||||
|---|---|---|---|
|
||||
| `DetectionBatch` | `detection_client` | per frame | Tier 1 primitives. |
|
||||
| `MovementCandidate` | `movement_detector` | per frame at both zoom-out and zoom-in (suppressed only during `TargetFollow`) | Each candidate carries `source_zoom_band`. |
|
||||
| `Tier2Evidence` | `semantic_analyzer` | per zoom-in hold | Path / endpoint / concealment scoring. |
|
||||
| `VlmAssessment` | `vlm_client` (optional) | per zoom-in endpoint hold | `status: disabled` if VLM is off. |
|
||||
| Operator commands | `operator_bridge` | event | confirm / decline / target-follow start / target-follow release. Authenticated, signed, replay-protected upstream of this component. |
|
||||
| UAV telemetry | `mavlink_layer` (via `mission_executor`) | 10 Hz target | Position used for proximity-weighted POI priority and middle-waypoint computation. |
|
||||
| Mission state | `mission_executor` | event | Current waypoint, mission progress; used for sweep-vs-route alignment. |
|
||||
| MapObjects sync state | `mapobjects_store` | event at startup + post-flight | `synced` / `cached_fallback` / `degraded` — surfaces a health flag and (for `degraded`) suppresses MapObject diff classifications until corrected. |
|
||||
|
||||
## 3. Outputs
|
||||
|
||||
| Output | Consumer | Shape |
|
||||
|---|---|---|
|
||||
| `GimbalCommand` (yaw / pitch / zoom) | `gimbal_controller` | per state-machine tick or per zoom-in plan step |
|
||||
| `POI` to operator | `operator_bridge` (then `telemetry_stream`) | enqueue / dequeue events |
|
||||
| Middle-waypoint hint | `mission_executor` | event on operator-confirmed target |
|
||||
| MapObjects update | `mapobjects_store` | new / moved / existing / removed dispatch |
|
||||
| Health metric | health aggregator | `state`, `pois_in_queue`, `pois_per_min`, `tick_latency_p99`, `last_state_change_ts`, `mapobjects_sync_state`. |
|
||||
|
||||
## 4. Key Responsibilities
|
||||
|
||||
- Run the `ZoomedOut` / `ZoomedIn` / `TargetFollow` state machine. Transitions are explicit, typed, and fully enumerated; no ad-hoc booleans.
|
||||
- Maintain the POI queue ordered by `confidence × proximity_to_current_camera × age_factor`. Hard-cap output to ≤5 POIs/min surfaced to the operator.
|
||||
- Apply the confidence-scaled operator decision window (40 % → 30 s, 100 % → 120 s, linear; below 40 % the POI is not surfaced). Timeout = forget; decline = `IgnoredItem` entry via `mapobjects_store`.
|
||||
- Suppress new POIs whose `(MGRS, class_group)` matches an existing `IgnoredItem`.
|
||||
- For each new detection or movement candidate: compute the H3 cell, ask `mapobjects_store` to classify as new / moved / existing, and only surface non-existing entries.
|
||||
- **Zoom-in candidate handling.** When a `MovementCandidate` arrives with `source_zoom_band = zoomed_in`, evaluate against the current ROI: if inside, bump current-ROI confidence; if outside the ROI but inside the broader zoomed FOV, enqueue as a candidate-POI; only interrupt the current zoom-in hold if the candidate's priority exceeds the current hold's priority.
|
||||
- On operator confirmation: hand a middle-waypoint hint to `mission_executor`, transition to `TargetFollow`, and command `gimbal_controller` to keep the target in the centre 25 % of frame.
|
||||
- On operator decline / timeout / target loss: append (decline only) an `IgnoredItem` and return to `ZoomedOut`.
|
||||
- On `mapobjects_store` reporting `sync_state = degraded`, surface health → red and **do not** classify new detections (avoid corrupting the central observation log on next push); continue to surface POIs to the operator on Tier-1 + movement evidence alone.
|
||||
|
||||
## 5. Internal State
|
||||
|
||||
The state machine lives entirely in this component. State variables:
|
||||
|
||||
- Current state: `ZoomedOut | ZoomedIn { roi, hold_started_at } | TargetFollow { target_id, started_at }`.
|
||||
- POI queue: ordered, with per-entry priority and queue position.
|
||||
- Per-class operator-decision-window thresholds.
|
||||
- Last-N tick timestamps for tick-latency observability.
|
||||
- Frame-rate floor monitor: when sustained FPS < 10, suppress `ZoomedOut → ZoomedIn` transitions and surface health → yellow.
|
||||
|
||||
State is in-process only; restart starts in `ZoomedOut` with an empty queue.
|
||||
|
||||
## 6. Failure Modes
|
||||
|
||||
| Failure | Detection | Behaviour |
|
||||
|---|---|---|
|
||||
| `detection_client` health red | health input | Continue zoom-out sweep; emit no new POIs from Tier 1; movement candidates still flow. |
|
||||
| `movement_detector` health red | health input | Continue; lose movement-candidate enqueueing. |
|
||||
| `semantic_analyzer` health red | health input | Skip Tier 2; surface POIs with Tier-1-only evidence; flag in operator overlay. |
|
||||
| `vlm_client` returns `status: disabled \| timeout \| ipc_error \| schema_invalid` | per-call status | Surface POI without VLM evidence (fail-closed). |
|
||||
| `gimbal_controller` not ready | health input | Stay in current state; alert; do not silently drop scan steps. |
|
||||
| `operator_bridge` disconnected | health input | Continue zoom-out (operator UI is unreachable, but the system must not crash); pause POI surfacing; resume on reconnect. F10 lost-link ladder owns the larger response. |
|
||||
| `mapobjects_store` sync degraded | sync_state input | Suppress diff classifications; surface POIs on Tier-1 + movement only; health → red. |
|
||||
| Sustained FPS < 10 | self-instrumented | Suppress zoom-in transitions; health → yellow. |
|
||||
| Tick-latency above budget | self-instrumented | Health → yellow; investigate (likely upstream consumer slowness). |
|
||||
|
||||
## 7. Dependencies
|
||||
|
||||
**In-process** (input): `detection_client`, `movement_detector`, `semantic_analyzer`, `vlm_client`, `operator_bridge`, `mission_executor`, `mapobjects_store`.
|
||||
**In-process** (output): `gimbal_controller`, `operator_bridge`, `mission_executor`, `mapobjects_store`.
|
||||
|
||||
**External**: none directly. All external integrations are mediated by other components.
|
||||
|
||||
## 8. Non-Functional Targets
|
||||
|
||||
| Concern | Target |
|
||||
|---|---|
|
||||
| Tick latency | ≤10 ms p99 |
|
||||
| POI enqueue → operator surface | ≤1 s in normal load |
|
||||
| POI rate to operator | ≤5 POIs/min (hard cap) |
|
||||
| Zoom-out → zoom-in transition | ≤2 s including physical zoom |
|
||||
| Zoom-in hold duration | configurable; default 5 s/POI |
|
||||
| Target-follow centre-window | target inside centre 25 % of frame while visible |
|
||||
| Frame-rate floor | ≥10 fps sustained; below this, suppress zoom-in transitions |
|
||||
|
||||
## 9. References
|
||||
|
||||
- `architecture.md §3`, `§5 Architectural Principles`, `§6 NFR`, `§7.6 Scan controller and POI queue`, `§7.12 New vs Existing / Moved / Removed Object Detection`, `§7.13 MapObjects Sync`.
|
||||
- `system-flows.md §F4 Scan controller behaviour tree` (full BT spec, tick scenarios, 15 fixed-wing rules).
|
||||
- `data_model.md §POI`, `§IgnoredItem`, `§MapObject`.
|
||||
Reference in New Issue
Block a user