# RoboVision — camera/motion detection (robot-side)

Runs on the robot. A Flask server (`app_pi_clean.py`, port 5000 by default)
that:

- Streams the camera at `/video_feed` (MJPEG, with OpenCV-drawn bounding
  boxes/labels baked into the frame) — this is what the Park dashboard's
  "Show overlay" button in the camera drawer points at directly.
- Runs OpenCV DNN object detection (MobileNet SSD) on every frame —
  `/api/detections` for the latest results.
- Runs frame-diff motion detection, toggled via `POST /api/motion/toggle
  {"active": true}` — when motion is detected it POSTs a JPEG snapshot to a
  configurable webhook (`POST /api/motion/webhook {"url": "..."}`).

## Wiring it to an actual session (the production trigger)

RoboVision only *detects*; it doesn't itself start a robot session. The
scheduler's `preview_agent.py` (in `../scheduler/`) now runs a small built-in
listener for exactly this webhook and turns a motion event into a real,
presence-triggered session (`POST /api/devices/{id}/request-session`),
publishing camera + mic into the resulting LiveKit room. Point RoboVision at
it:

Both of these calls go to RoboVision's own server (port 5000 by default —
NOT the scheduler on 8080):

```
curl -X POST http://localhost:5000/api/motion/webhook \
  -H "Content-Type: application/json" \
  -d '{"url": "http://localhost:5057/"}'
curl -X POST http://localhost:5000/api/motion/toggle \
  -H "Content-Type: application/json" -d '{"active": true}'
```

(`5057` is `preview_agent.py`'s default `--vision-webhook-port`; override with
`--vision-webhook-port` if RoboVision runs on a different host than the
preview agent.)

## Required model files (NOT bundled)

`app_pi_clean.py` needs two Caffe model files that are **not shipped** in this
npm package (the weights are ~23MB and would bloat every `infinicode`/
`robopark` install, including installs that never touch RoboPark):

```
deploy.prototxt
mobilenet_iter_73000.caffemodel
```

Download the standard MobileNet-SSD (VOC) weights (e.g. from
chuanqi305/MobileNet-SSD) into this directory before running. Without them,
`app_pi_clean.py` still runs — object detection is silently disabled, motion
detection still works.

## Running

Pure Python + OpenCV (Flask, cv2, numpy) — cross-platform, no bash required:

```
pip install -r requirements_pi_unified.txt
python app_pi_clean.py
```

`install.sh`/`run.sh` are Linux/Pi convenience wrappers (venv + systemd-style
process management) — not required on Windows/macOS, just run the script
directly.
