Files
andrew f621ae86fb
ci / smoke (push) Canceled after 0s
fix(auto-batch): truck presence needs 50% polygon overlap, config-authoritative timers
Big docked truck bbox rests 1-2px past detection_polygon bottom edge, so
100%-containment made truck_in_area flicker False -> batch 15 split (6+276)
on 2026-09-29 while the truck never left. v4-best.engine detected it at
conf 0.92-0.97 in every replayed frame (no model miss, no retraining).

- truck gate: frac_inside >= 0.5 instead of contains(bbox)
- batch.truck_gone_tolerance_seconds (new, 30) authoritative; drop the
  hardcoded batch_mgr._truck_gone_tolerance = 30.0 override;
  batch.timeout_seconds documented as sack-idle pause only
- [TRUCK] truck_in_area transition debug log
2026-09-30 09:40:15 +07:00

5.3 KiB

AGENTS.md — karung (sack counter)

Repo: https://git.proit.id/andrew/karung-counting-feedmill-semarang (transferred from ervan/; old remote redirects, but git remote set-url origin to the new URL).

AI video analytics (Jetson) counting feed sacks loaded onto trucks. UI/log strings are Indonesian (karung=sack, truk=truck); YOLO class names are English (sack, box, truck, person). Details: README.md, docs/.

Which pipeline to touch

  • predict.py = production AND dev CLI (runs as karung-counter.service with zero args). Dev flags: --source VID --env .env --config YAML --model X --output-dir D --output-json F --sack-conf C --truck-conf C --box-conf C --box-model P --model-mode M --batch-timeout S --max-frames N --no-dashboard --no-db. Zero flags = systemd behaviour (config.yaml + .env). Model modes are DATA in config.yaml models.modes (engines + class filters only; conf/iou/min_bbox in models.detection_params): A=combined only; B=v4 truck + yolo11n sack+box; C=A + yolo11n box-only (default); D=v4 truck + best sack-only + yolo11n box-only. New modes need no code change. All modes load .engine files (2-3 coexist, ~24 MB peak); never mix load order assumptions — PyTorch .pt must load before TensorRT .engine.
  • src/ = shared library (detection/tracking/counting/batch). python -m src.main still works but prints a deprecation pointer to predict.py.
  • archive/ = retired experiments (predict_new.py, rpo_iki/, simple_predict.py, check/merge/test scripts). Git history preserved via git mv. Don't resurrect without asking.

Gotchas

  • Unified config: config.yaml is canonical (stream/models/counting/batch/do/ output/camera via src/config_loader.py); .env holds secrets + deployment only (RTSP_URL, dashboard host/ports/secret/site); zones.json holds geometry (polygons + left/right limits — knob keys there are ignored, warned); cfg/tracker.yaml holds tracker hyperparams. src/config.py (v3 keys like LOCAL_RTSP) is deprecated — don't add keys there. Dashboard mode switches write config.yaml models.active_mode (atomic, manual restart to apply); batch_mode.json keeps only batch flow mode (auto|do_manual|manual, default seed batch.default_mode: auto). Port split: mode / model_mode / require_plate / require_do POSTs → office :5721 only (403 on :5000); ocr_engine office-only too (default rapid). Discard batch only if both gross count==0 and box_loading==0 (nets kept in DB/API). DO helpers: src/do_batch.py, OCR: src/do_ocr.py; ERD: ERD.md (repo root).
  • Counting filters by class name, not ID: SackDetector/BoxDetector/ TruckDetector filter via BaseDetector(class_filter) (src/detection.py); tracker keeps ("sack", "truck", "box") (src/tracking.py); counting uses MultiClassLineCounter = dual LineCrossCounters on one shared line (src/counting.py). Same line geometry + 30px dedup for sacks and boxes.
  • All weights live in models/ (.pt/.onnx tracked; .engine gitignored — rebuild via export_model.py; per-mode detector/filter matrix in models/modelREADME.md). Verified classes: truck-detector={truck}, model_karung_truk/v4-best={sack,truck}, karung-dimuat-*-seg-200e= {person,sack} (seg; persons drawn, never counted), best={sack}, yolo11n-…-sack+box={sack,box}. predict.py auto-picks MODEL_PATH env, else models/v4-best.engine > .pt > v4-best (1).pt > models/model_karung_truk.*. src/config.py defaults: models/best.engine (sack) / models/truck-detector.engine.
  • Counting trigger is the bbox top edge (y1) vs a truck-anchored line band (src/counting.py, src/truck_roi.py); truck detect runs every 15th frame only.
  • Auto-mode batch timers (config.yaml batch:): timeout_seconds = sack-idle pause (→ WAITING_FOR_ACTIVITY), truck_gone_tolerance_seconds = truck-gone finalize (hardcoded 30 s override in predict.py removed). truck_in_area accepts ≥50 % bbox overlap of detection_polygon (100 % containment flickered False for big docked trucks → split batches); transitions log [TRUCK] truck_in_area.
  • Tests: python -m pytest tests/ -q (smoke tests for counting, batch, config, do_batch — pure-Python; Flask API tests skip if flask/openpyxl missing). Deps: requirements.txt (unpinned; never pip-install torch from PyPI on the Jetson — use the NVIDIA wheels already on device). For visual checks run on a video file (--source), not the live RTSP.
  • Don't commit state: .gitignore excludes *.engine (rebuildable), *.mp4/*.jpg/*.png, *.db, .env, batch_history_folder/. Videos and local DBs already sit untracked in the working tree — leave them alone.

Deploy (Jetson 192.168.192.96, user jetson)

  • deploy_to_jetson.py syncs predict.py, counter_dashboard.py, templates/{operator,monitoring,base}.html, .env, plus models/*.engine (skips missing local files; creates remote models/). .pt/.onnx stay local. Edits elsewhere (e.g. src/, zones.json) need manual sync.
  • Services: karung-counter (predict.py), karung-counter-dashboard (counter_dashboard.py, ports 5000/5721). TensorRT export: python export_model.py models/<name>.pt — run on the Jetson.