mirror of
https://github.com/azaion/detections-semantic.git
synced 2026-04-23 03:36:38 +00:00
Initial commit
Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
# 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/` |
|
||||
Reference in New Issue
Block a user