# Next Session: Hailo Camera-Only Servo Tracking

## TL;DR

HailoTracking.py is deployed and detecting objects. Camera settings are locked
(sat=40, WB=3300K). Servo tracking was observed (camera moved in debug frames)
but never explicitly tested with the user watching. This session: test camera-only
servo tracking (no wheels), tune PID if needed, then optionally enable wheels.

## What's working

- Hailo YOLO inference: `quantized=True`, uint8 input, detects "person" and sometimes "ball 0.48"
- Camera settings: `saturation=40, white_balance_automatic=0, white_balance_temperature=3300`
- Sonar LEDs: off at startup via `_init_hardware()`
- Telegram buttons: 4 Hailo Chase buttons live (any/red/blue/green)
- deploy-turbopi.sh: deploys Functions/ + _headless_runner.py

## What needs testing

**Camera-only servo tracking (no wheels).** The `move()` thread has PID servo
control that should pan/tilt to keep the detected object centered. The user
explicitly wants NO wheel movement — only camera head tracking.

### How to test

1. In `_headless_runner.py`, the HailoTracking init block currently calls
   `mod.setVehicleFollowing(True)`. Change to `False` for camera-only mode.

2. Start demo via Telegram (🎯 Hailo Chase) or API:
   ```bash
   curl -s -X POST http://localhost:8080/demo/start \
     -H 'Authorization: Bearer 8cX80yIBws1PfBjFuvPz0k9egPSZD0LvS02oUD6ijfg' \
     -H 'Content-Type: application/json' \
     -d '{"name": "HailoTracking", "color": ""}'
   ```

3. Hold ball in front of camera, move it left/right/up/down slowly.
   Camera head should follow.

4. Check debug frame: `scp pi:/tmp/hailo_debug.jpg .`
   Check logs: stop demo, then `journalctl -u turbopi-server --since '30 sec ago'`
   Look for `tracking: cx=... cy=... sx=... sy=...` lines.

### If servo doesn't track

The `move()` thread has error logging (`HailoTracking move() error: ...`).
Check stderr in the journal after stopping the demo (only printed on crash/stop).

Common issues:
- `board is None` → thread started before headless runner set `mod.board`
- PID output too small → increase `servo_x_pid` P gain (currently 0.06)
- Detection too intermittent → check frame rate, confidence threshold

### PID gains (current)

```python
servo_x_pid = PID.PID(P=0.06, I=0.0003, D=0.0006)  # pan
servo_y_pid = PID.PID(P=0.06, I=0.0003, D=0.0006)  # tilt
car_x_pid   = PID.PID(P=0.25, I=0.001,  D=0.0001)  # chassis X (disabled)
car_y_pid   = PID.PID(P=1.00, I=0.001,  D=0.0001)  # chassis Y (disabled)
```

These are copied from ColorTracking.py. May need tuning for Hailo's detection
rate (~10-15 FPS vs ColorTracking's ~30 FPS).

## Key bugs found in session 56

1. **Hailo quantized input:** `quantized=False` + float32/255 → zero detections
   in subprocess. Fix: `quantized=True` + uint8 input.
2. **v4l2-ctl after camera open:** OpenCV resets UVC controls on `VideoCapture()`.
3. **COCO class 32:** Small rubber balls rarely classified as "sports ball".
   Fallback: track highest-confidence detection of ANY class.
4. **deploy-turbopi.sh gap:** `_headless_runner.py` wasn't deployed to `/home/pi/TurboPi/`.
5. **Python name mangling:** `HailoTracking.__isRunning` in test class bodies
   gets mangled to `_TestClass__isRunning`. Fix: `setattr()` helpers.

## Files

| File | Location | Status |
|------|----------|--------|
| HailoTracking.py | `vendor/turbopi/Functions/` → Pi `/home/pi/TurboPi/Functions/` | Deployed (gitignored) |
| _headless_runner.py | `services/turbopi-server/pi-files/` → Pi `/home/pi/TurboPi/` | Committed + deployed |
| main.py | `services/turbopi-server/` | Committed (camera settings) |
| car_demo_handler.py | `services/telegram-bot/` | Committed (4 buttons) |
| deploy-turbopi.sh | `scripts/` | Committed (includes _headless_runner) |

## Git state

- Branch: `main` at `b6fb58d`
- 5 commits this session: `6e39312`, `5b6c408`, `ae82283`, `8c80401`, `b6fb58d`

## Prompt

```
Test Hailo camera-only servo tracking. Read docs/NEXT-SESSION-HAILO-CAMERA-TRACKING.md.

1. Change setVehicleFollowing(True) to False in _headless_runner.py
2. Deploy and start HailoTracking demo
3. Ask user to hold ball and move it — camera head should follow
4. Check debug frames and logs for tracking data
5. Tune PID if servo response is too slow/fast
```
