# Next Session: SLAM Drive Tuning & E2E Navigation

## Context

Session 65 implemented SLAM odometry (commanded-velocity prediction) and fixed several
hardware mapping issues. The SLAM heading is now stable (0.7° drift for straight drives).
Safety daemon has been restored to production settings.

## What Was Done (Session 65)

1. **SLAM odometry** — OdometryHint class, body velocity, /drive timing (56 new tests, 273 total)
2. **Heading prior** — HEADING_PRIOR_WEIGHT=5000 in Gauss-Newton scan matcher
3. **Theta clamp** — MATCH_MAX_STEP_THETA=5° (was 30°)
4. **LIDAR_CCW=False** — hand test proved C1 outputs CW natively, not CCW
5. **Strafe L/R swapped** — strafe_left 180→0°, strafe_right 0→180°, drifts too
6. **Motor trim** — MOTOR_TRIM_FL=1.15, MOTOR_TRIM_RL=1.15 (left motors +15%)
7. **Calibrated** — DUTY_TO_MPS=0.002750, DUTY_TO_RPS=0.047000 (in systemd)
8. **DISABLE_SAFETY env var** — added for dark room testing (now set to 0)

## Current State

- **Git:** main at `3b49330`
- **Pi systemd:** safety restored (SAFETY_DISTANCE_CM=30, HAILO on, SIDE_CLEARANCE=400mm)
- **Health:** all green (safety=true, slam=running, imu=true, lidar=true, odom_calibrated=true)

## Known Issues

1. **Wheel slip on smooth floor** — speed 50 sometimes barely moves car at startup.
   Ramp-up helps (0.3s at speed 25, then full speed). Consider baking into /drive.
2. **Left drift** — front-left motor trim helps but car still pulls left slightly.
   Battery weight distribution causes uneven traction.
3. **SLAM displacement** — varies due to wheel slip (0.05-0.43m for ~0.45m predicted).
   Heading is stable (0.7-5.9°). Displacement will improve in rooms with features.
4. **Turn directions** — left/right angular turns NOT yet verified after lidar flip.
   May also need swapping like strafe was.

## What To Do Next

### 1. Verify Turns
Drive `left` and `right` actions, check if they rotate the correct direction.
If swapped, swap the angular_rate signs in ACTION_MAP.

### 2. Straight-Line Drive Test
Place car in open area (no curtain). Drive forward 1m (speed 50, ~7s).
Measure actual distance. Compare with SLAM pose.
Target: SLAM within 2x of actual, heading < 10°.

### 3. Full E2E Navigation
Via Telegram: "Annie, explore this room"
Watch: map builds progressively, pose tracks, no wild jumps.
Navigation uses 1s drives (was 2s), max 20 cycles (was 10).

### 4. Auto-Ramp (Optional)
If wheel slip persists, add 0.3s ramp-up at half speed before full drive.
Modify `_drive_sync` or add ramp logic in `/drive` handler.

## Files Reference

| File | What |
|------|------|
| `services/turbopi-server/odometry.py` | OdometryHint class |
| `services/turbopi-server/slam.py` | SLAM with odometry + heading prior + confidence gate |
| `services/turbopi-server/main.py` | /drive timing, body velocity, motor trim, DISABLE_SAFETY |
| `services/turbopi-server/lidar.py` | LIDAR_CCW=False, bearing conversion |
| `services/annie-voice/robot_tools.py` | duration 1s, max_cycles 15/20 |
| `scripts/calibrate_odometry.py` | Calibration script |
