docs: update CLAUDE.md for display modes, dashcam trips, ClearPilot menu
Document 5-state display mode system with auto day/night switching, nightrider rendering, and button behavior. Update dashcam section for trip directories, 2500kbps bitrate, SRT subtitles, graceful shutdown. Update offroad UI section for new ClearPilot menu panels. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
115
CLAUDE.md
115
CLAUDE.md
@@ -228,12 +228,14 @@ A single `session.log` in each session directory records major events:
|
||||
|
||||
- **Codec**: H.264 AVC (hardware accelerated via `OMX.qcom.video.encoder.avc`)
|
||||
- **Resolution**: 1928x1208 (full camera resolution, no downscaling)
|
||||
- **Bitrate**: 4 Mbps
|
||||
- **Container**: MP4 (remuxed via libavformat)
|
||||
- **Bitrate**: 2500 kbps
|
||||
- **Container**: MP4 (remuxed via libavformat) + SRT subtitle sidecar
|
||||
- **Segment length**: 3 minutes per file
|
||||
- **Save path**: `/data/media/0/videos/YYYYMMDD-HHMMSS.mp4`
|
||||
- **Standstill timeout**: suspends recording after 10 minutes of standstill, resumes when car moves
|
||||
- **Storage**: ~90 MB per 3-minute segment, ~43 hours of footage in 78 GB free space
|
||||
- **Save path**: `/data/media/0/videos/YYYYMMDD-HHMMSS/YYYYMMDD-HHMMSS.mp4` (trip directories)
|
||||
- **GPS subtitles**: companion `.srt` file per segment with 1Hz entries (speed MPH, lat/lon, UTC timestamp)
|
||||
- **Trip lifecycle**: starts recording on launch with 10-min idle timer; car in drive cancels timer; park/off restarts timer; ignition cycle = new trip
|
||||
- **Graceful shutdown**: thermald sets `DashcamShutdown` param, dashcamd closes segment and acks within 15s
|
||||
- **Storage**: ~56 MB per 3-minute segment at 2500 kbps
|
||||
- **Storage device**: WDC SDINDDH4-128G UFS 2.1 — automotive grade, ~384 TB write endurance, no concern for continuous writes
|
||||
|
||||
### Key Differences from Old Screen Recorder
|
||||
@@ -254,13 +256,13 @@ A single `session.log` in each session directory records major events:
|
||||
| `selfdrive/clearpilot/SConscript` | Build config for dashcamd |
|
||||
| `selfdrive/frogpilot/screenrecorder/omx_encoder.cc` | OMX encoder (added `encode_frame_nv12` method) |
|
||||
| `selfdrive/frogpilot/screenrecorder/omx_encoder.h` | Encoder header |
|
||||
| `selfdrive/manager/process_config.py` | dashcamd registered as NativeProcess, encoderd disabled |
|
||||
| `system/loggerd/deleter.py` | Storage rotation (9 GB threshold, oldest videos deleted first) |
|
||||
| `selfdrive/manager/process_config.py` | dashcamd registered as NativeProcess, camerad always_run, encoderd disabled |
|
||||
| `system/loggerd/deleter.py` | Trip-aware storage rotation (oldest trip first, then segments within active trip) |
|
||||
|
||||
### Params
|
||||
|
||||
- `DashcamDebug` — when `"1"`, dashcamd runs even without car connected (for bench testing)
|
||||
- `IsDriverViewEnabled` — must be `"1"` to start camerad on bench (no car ignition)
|
||||
- `DashcamShutdown` — set by thermald before power-off, dashcamd acks by clearing it
|
||||
|
||||
## Standstill Power Saving
|
||||
|
||||
@@ -279,63 +281,88 @@ When `carState.standstill` is true:
|
||||
| `selfdrive/thermald/fan_controller.py` | Standstill-aware fan clamps |
|
||||
| `selfdrive/thermald/thermald.py` | Passes standstill to fan controller via carState |
|
||||
|
||||
## Debug Function Button (LFA/LKAS Steering Wheel Button)
|
||||
## Display Modes (LFA/LKAS Debug Button)
|
||||
|
||||
The Hyundai Tucson's LFA (Lane Following Assist) steering wheel button is repurposed as a general-purpose UI control button. It has no driving function in ClearPilot since lateral control is disabled.
|
||||
The Hyundai Tucson's LFA steering wheel button cycles through 5 display modes via `ScreenDisplayMode` param (`/dev/shm/params`, CLEAR_ON_MANAGER_START, default 0).
|
||||
|
||||
### Display States
|
||||
|
||||
| State | Name | Display | Camera | Path Drawing |
|
||||
|-------|------|---------|--------|-------------|
|
||||
| 0 | auto-normal | on | yes | filled (normal) |
|
||||
| 1 | auto-nightrider | on | black | 2px outline only |
|
||||
| 2 | normal (manual) | on | yes | filled (normal) |
|
||||
| 3 | screen off | GPIO off | n/a | n/a |
|
||||
| 4 | nightrider (manual) | on | black | 2px outline only |
|
||||
|
||||
### Auto Day/Night Switching
|
||||
|
||||
- `gpsd.py` computes `is_daylight(lat, lon, utc_dt)` using NOAA solar position algorithm
|
||||
- First calculation immediately on GPS fix + valid clock, then every 30 seconds
|
||||
- State 0 + sunset → auto-switch to 1; State 1 + sunrise → auto-switch to 0
|
||||
- States 2/3/4 are never touched by auto logic
|
||||
- `IsDaylight` param written to `/dev/shm/params` for reference
|
||||
|
||||
### Button Behavior
|
||||
|
||||
**Onroad (car in drive gear):** 0→4, 1→2, 2→3, 3→4, 4→2 (never back to auto via button)
|
||||
|
||||
**Not in drive (parked/off):** any except 3 → 3 (screen off), state 3 → 0 (auto-normal)
|
||||
|
||||
### Nightrider Mode
|
||||
|
||||
- Camera feed suppressed (OpenGL clears to black instead of rendering camera texture)
|
||||
- All HUD elements (speed, alerts, telemetry indicator) still visible
|
||||
- Path/lane polygons drawn as 2px outlines only (no gradient fill)
|
||||
- Lane lines, road edges, blind spot paths, adjacent paths all use outline rendering
|
||||
|
||||
### Signal Chain
|
||||
|
||||
```
|
||||
Steering wheel LFA button press
|
||||
-> CAN-FD message: cruise_btns_msg_canfd["LFA_BTN"]
|
||||
[selfdrive/car/hyundai/carstate.py:332-339]
|
||||
-> Edge detection: lkas_enabled vs lkas_previously_enabled
|
||||
-> create_button_events() -> ButtonEvent(type=FrogPilotButtonType.lkas)
|
||||
[selfdrive/car/hyundai/interface.py:168]
|
||||
-> controlsd.update_clearpilot_events(CS)
|
||||
[selfdrive/controls/controlsd.py:1235-1239]
|
||||
-> events.add(EventName.clpDebug)
|
||||
-> controlsd.clearpilot_state_control(CC, CS)
|
||||
[selfdrive/controls/controlsd.py:1241-1258]
|
||||
-> Toggles ScreenDisaplayMode param (0=on, 1=off) in /dev/shm/params
|
||||
-> UI reads ScreenDisaplayMode in drawHud()
|
||||
[selfdrive/ui/qt/onroad.cc:390-403]
|
||||
-> mode=1 and no alert: Hardware::set_display_power(false)
|
||||
-> mode=0 or alert visible: Hardware::set_display_power(true)
|
||||
-> CAN-FD: cruise_btns_msg_canfd["LFA_BTN"]
|
||||
-> Edge detection → ButtonEvent(type=FrogPilotButtonType.lkas)
|
||||
-> controlsd.clearpilot_state_control()
|
||||
-> Reads ScreenDisplayMode, applies transition table based on driving_gear
|
||||
-> Writes new ScreenDisplayMode to /dev/shm/params
|
||||
-> UI reads ScreenDisplayMode in paintEvent() (for camera/nightrider)
|
||||
and drawHud() (for display power on/off)
|
||||
```
|
||||
|
||||
### Current Behavior
|
||||
|
||||
- Each press toggles the display on/off instantly (debug alert suppressed)
|
||||
- `ScreenDisaplayMode` is in-memory params (`/dev/shm/params`), resets on reboot
|
||||
- `max_display_mode = 1` — currently only two states (on/off); can be extended for future modes
|
||||
|
||||
### Key Files
|
||||
|
||||
| File | Role |
|
||||
|------|------|
|
||||
| `selfdrive/car/hyundai/carstate.py` | Reads LFA_BTN from CAN-FD |
|
||||
| `selfdrive/car/hyundai/interface.py` | Creates ButtonEvent with FrogPilotButtonType.lkas |
|
||||
| `selfdrive/controls/controlsd.py` | Fires clpDebug event, toggles ScreenDisaplayMode |
|
||||
| `selfdrive/controls/lib/events.py` | clpDebug event definition (alert suppressed) |
|
||||
| `selfdrive/ui/qt/onroad.cc` | Reads ScreenDisaplayMode, controls display power |
|
||||
| `selfdrive/controls/controlsd.py` | Button state machine, writes ScreenDisplayMode |
|
||||
| `selfdrive/ui/qt/onroad.cc` | Nightrider rendering, display power control |
|
||||
| `selfdrive/ui/qt/home.cc` | Display power for park/splash state |
|
||||
| `system/clearpilot/gpsd.py` | Sunset/sunrise calc, auto day/night transitions |
|
||||
| `selfdrive/clearpilot/bench_cmd.py` | `debugbutton` command simulates button press |
|
||||
|
||||
## Screen Timeout / Display Power
|
||||
|
||||
Display power is managed by `Device::updateWakefulness()` in `selfdrive/ui/ui.cc`.
|
||||
|
||||
- **Ignition off (offroad)**: screen blanks after `ScreenTimeout` seconds (default 120) of no touch. Tapping wakes it.
|
||||
- **Ignition on (onroad)**: screen stays on unconditionally — `setAwake(s.scene.ignition || interactive_timeout > 0)` means ignition=true always keeps the screen awake. The FrogPilot `ScreenTimeoutOnroad` param (default 10s) has no effect because ignition being true short-circuits the timeout check.
|
||||
- **Debug button (LFA)**: the only way to turn off the screen while driving. Toggles `ScreenDisaplayMode` param which is checked in `drawHud()` (onroad) and `updateState()` (park splash). Independent of the timeout system.
|
||||
- **Ignition on (onroad)**: screen stays on unconditionally — ignition=true short-circuits the timeout check.
|
||||
- **Debug button (LFA)**: cycles through display modes including screen off (state 3). Only state 3 calls `Hardware::set_display_power(false)`.
|
||||
|
||||
## Offroad UI
|
||||
## Offroad UI (ClearPilot Menu)
|
||||
|
||||
The offroad home screen (`selfdrive/ui/qt/home.cc`) was replaced with a clean grid launcher. Stock FrogPilot widgets (date, version, update/alert notifications) were removed.
|
||||
The offroad home screen (`selfdrive/ui/qt/home.cc`) is a sidebar settings panel replacing the stock home screen. The original system settings are no longer accessible — the ClearPilot menu is the only settings interface.
|
||||
|
||||
- **Settings button**: opens the original comma/FrogPilot settings (backdoor to all original settings)
|
||||
- **Dashcam button**: placeholder for future dashcam footage viewer
|
||||
- Tapping the splash screen (ReadyWindow) goes directly to the grid launcher (no sidebar)
|
||||
- Sidebar with metrics (TEMP, VEHICLE, CONNECT) is hidden but still accessible via settings path
|
||||
### Panels
|
||||
|
||||
- **General**: Status window, Reset Calibration, Shutdown Timer, Reboot/Soft Reboot/Power Off
|
||||
- **Network**: WiFi management, tethering, roaming, hidden networks (APN settings removed)
|
||||
- **Dashcam**: placeholder for future dashcam footage viewer
|
||||
- **Debug**: Telemetry logging toggle
|
||||
|
||||
### Navigation
|
||||
|
||||
- Tapping the splash screen (ReadyWindow) opens the ClearPilot menu
|
||||
- "← Back" button returns to splash or onroad view
|
||||
- Sidebar with stock metrics (TEMP, VEHICLE, CONNECT) is hidden
|
||||
|
||||
## Device: comma 3x
|
||||
|
||||
|
||||
Reference in New Issue
Block a user