fix: harden v1.2 trajectory disposal matching

This commit is contained in:
Yoilun
2026-05-29 16:26:15 +08:00
parent 90aa5dd704
commit 100b949f1f
11 changed files with 248 additions and 36 deletions

View File

@@ -17,7 +17,7 @@ The `v1.2 轨迹识别` batch adds source-zone trajectory evidence for disposal
- `manage_api.py`: standard-library HTTP management API.
- `main.py`: RTSP runtime loop connecting frame capture, vision, state engine, and JSONL sinks.
- `vision.py`: heuristic ROI occupancy and trash-motion detection.
- v1.2 adds trajectory evidence between vision and engine: `MotionTrajectoryBackend` emits source-zone-to-trash evidence; `BatchEngine` consumes the backend-neutral `disposal_evidence` contract.
- v1.2 adds trajectory evidence between vision and engine: `TrajectoryTracker` emits source-zone-to-trash evidence; `BatchEngine` consumes the backend-neutral `disposal_evidence` contract.
- Frontend package: `web/`
- Vite + vanilla JavaScript management console.
- Default web port `23000`.
@@ -26,6 +26,7 @@ The `v1.2 轨迹识别` batch adds source-zone trajectory evidence for disposal
- Runtime data:
- Events JSONL default path `logs/events.jsonl`.
- Diagnostics JSONL default path `logs/runtime_diagnostics.jsonl`.
- v1.2 diagnostics include root-level `disposal_evidence` plus `diagnostics.trajectory`.
- Deployment:
- Root Python Docker image for API/runtime.
- `web/Dockerfile` for static web console.
@@ -52,9 +53,34 @@ The `v1.2 轨迹识别` batch adds source-zone trajectory evidence for disposal
- `trajectory_enabled`: enables source-zone trajectory evidence.
- `trajectory_window_seconds`: seconds after a zone clears where movement can confirm disposal.
- `trajectory_sample_interval_seconds`: faster runtime delay while a candidate is active.
- `trajectory_min_points`: minimum sampled motion points required before evidence can emit.
- `trajectory_min_confidence`: minimum confidence before evidence can close pending disposal.
- `trajectory_motion_delta`: frame-difference threshold for trajectory motion points.
- `trajectory_min_blob_area`: minimum connected motion area to keep as a point.
- `trajectory_max_blob_area_fraction`: rejects overly broad frame motion as ambiguous.
- `trajectory_trash_entry_margin`: margin for treating a track point as entering the trash ROI.
- `trajectory_backend`: first valid value is `"motion"`.
- `yolo_enabled`: defaults to `false`; reserved for a future trained model backend.
- `yolo_enabled`, `yolo_model_path`, `yolo_min_confidence`: reserved for a future trained model backend. Current v1.2 keeps YOLO disabled.
## v1.2 Runtime Flow
1. `RTSPFrameSource` captures a resized RGB frame.
2. `ZoneOccupancyDetector` updates per-zone binary occupancy and generic trash-motion count from calibrated ROIs.
3. `TrajectoryTracker` watches zones that just cleared, follows lightweight motion points toward the trash ROI, and emits source-specific `DisposalEvidence` when confidence passes the configured threshold.
4. `BatchEngine` processes `Observation(zone_counts, trash_deposit_count, disposal_evidence)`.
5. For pending disposal, matching `disposal_evidence.source_zone_id` confirms `batch_discarded` before generic FIFO `trash_deposit_count` fallback is used.
6. Runtime writes events to `logs/events.jsonl` and diagnostics to `logs/runtime_diagnostics.jsonl`.
The current tracker is a motion backend only. A later trained YOLO detector should plug in as another backend that enriches or replaces the evidence producer while preserving the same `disposal_evidence` contract consumed by the engine.
## Diagnostics
- Runtime diagnostics JSONL records one item per runtime iteration.
- Root `disposal_evidence` is the exact evidence list passed into the engine for that iteration.
- `diagnostics.zones` contains occupancy metrics used to derive `zone_counts`.
- `diagnostics.trash` contains generic trash-motion metrics and cooldown state.
- `diagnostics.trajectory` contains v1.2 candidate counts, emitted evidence count, motion point count, and per-candidate emitted/rejected/expired records.
- Capture failures still keep the v1.2 schema with root `disposal_evidence: []` and `diagnostics.trajectory.reason = "frame_capture_failed"`.
## Event Model
@@ -87,11 +113,17 @@ In v1.2, `batch_discarded` can be triggered by zone-scoped `disposal_evidence` b
- `scripts/run_runtime.sh`
- One-frame smoke test when camera and `ffmpeg` are available:
- `PYTHONPATH=src python3 -m cold_display_guard.main --config config/example.toml --once`
- v1.2 operating notes:
- Keep `trajectory_backend = "motion"` and `yolo_enabled = false` unless a trained YOLO backend has been explicitly deployed.
- Confirm `logs/runtime_diagnostics.jsonl` contains top-level `disposal_evidence` and `diagnostics.trajectory` before judging trajectory behavior from events alone.
- When `TrajectoryTracker` has active candidates, runtime sampling uses `trajectory_sample_interval_seconds`; this can temporarily be faster than the normal `sample_interval_seconds`.
- On remote deployments, preserve the remote `config/example.toml` calibration and stream settings when syncing code.
## Known Risks
- The current vision detector is heuristic and reports binary occupancy, not item counts.
- v1.2 motion tracking improves disposal matching but can still miss movement if the hand/object path is occluded or sampled too sparsely.
- v1.2 motion tracking improves disposal matching but can still miss movement if the hand/object path is occluded, too broad, too small, or sampled too sparsely.
- YOLO config fields are present for compatibility, but no trained YOLO model is part of the current runtime.
- If food is already present during baseline collection, those regions may be treated as empty baseline until visual changes occur.
- Changing calibration while the runtime process has active batches can create operational ambiguity; v1.1 should document or enforce a pause/restart expectation.
- Historical events must keep the zone index at the time of emission so later region reordering does not reinterpret old logs.