Files
Oleksandr Bezdieniezhnykh 8e2ecf50fd Initial commit
Made-with: Cursor
2026-03-26 00:20:30 +02:00

3.8 KiB

OutputManager

1. High-Level Overview

Purpose: Handles all persistent output: detection logging (JSON-lines), frame recording (JPEG), health logging, gimbal command logging, and operator detection delivery. Manages NVMe write operations and circular buffer for storage.

Architectural Pattern: Facade over multiple output writers (async file I/O).

Upstream dependencies: Config helper (output paths, recording rates, storage limits), Types helper

Downstream consumers: ScanController

2. Internal Interfaces

Interface: OutputManager

Method Input Output Async Error Types
init(output_dir) str No IOError
log_detection(entry) DetectionLogEntry dict No (non-blocking write) WriteError
record_frame(frame, frame_id, level) numpy, uint64, int No (non-blocking write) WriteError
log_health(health) HealthLogEntry dict No WriteError
log_gimbal_command(cmd_str) str No WriteError
report_to_operator(detections) list[Detection] No
get_storage_status() StorageStatus No

StorageStatus:

nvme_free_pct: float (0-100)
frames_recorded: uint64
detections_logged: uint64
should_reduce_recording: bool — true if free < 20%

4. Data Access Patterns

Storage Estimates

Output Write Rate Per Hour Per 4h Flight
detections.jsonl ~1 KB/det, ~100 det/min ~6 MB ~24 MB
frames/ (L1, 2 FPS) ~100 KB/frame ~720 MB ~2.9 GB
frames/ (L2, 30 FPS) ~100 KB/frame ~10.8 GB ~43 GB
health.jsonl ~200 B/s ~720 KB ~3 MB
gimbal.log ~500 B/s ~1.8 MB ~7 MB

Circular Buffer Strategy

When NVMe free space < 20%:

  1. Signal ScanController via should_reduce_recording
  2. ScanController switches to L1 recording rate only
  3. If still < 10%: stop L1 frame recording, keep detection log only
  4. Never overwrite detection logs (most valuable data)

5. Implementation Details

File Writers:

  • Detection log: open file handle, append JSON line, flush periodically (every 10 entries or 5s)
  • Frame recorder: JPEG encode via OpenCV, write to sequential filename {frame_id}.jpg
  • Health log: append JSON line every 1s
  • Gimbal log: append text line per command

Operator Delivery: Format detections into existing YOLO output schema (centerX, centerY, width, height, classNum, label, confidence) and make available via the same interface the existing YOLO pipeline uses.

Key Dependencies:

Library Version Purpose
OpenCV 4.x JPEG encoding for frame recording
json (stdlib) JSON-lines serialization
os (stdlib) NVMe free space check (statvfs)

Error Handling Strategy:

  • WriteError: log to stderr, increment error counter, continue processing (recording failure must not block inference)
  • NVMe full: stop recording, log warning, continue detection-only mode

7. Caveats & Edge Cases

Known limitations:

  • Frame recording at 30 FPS (L2) writes ~3 MB/s — well within NVMe bandwidth but significant storage consumption
  • JSON-lines flush interval means up to 10 detections or 5s of data could be lost on hard crash

8. Dependency Graph

Must be implemented after: Config helper, Types helper Can be implemented in parallel with: Tier1Detector, Tier2SpatialAnalyzer, VLMClient, GimbalDriver Blocks: ScanController (needs OutputManager for logging)

9. Logging Strategy

Log Level When Example
ERROR NVMe write failure, disk full Frame write failed: No space left on device
WARN Storage low, reducing recording NVMe 18% free, reducing to L1 recording only
INFO Session started, stats Output session started: /data/output/2026-03-19T14:00/