- Re-enable FrogPilot OMX screen recorder (H.264 MP4, 1440x720, 2Mbps) - Auto-start recording when car is on, auto-stop when off - Hide all recorder UI elements (invisible to driver) - Add ScreenRecorderDebug param for bench testing without car - Disable encoderd (camera .hevc files) — CAN/sensor logs still recorded - Raise deleter free space threshold from 5GB to 9GB - Deleter rotates oldest videos before log segments - Add CLAUDE.md project documentation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
12 KiB
ClearPilot — CLAUDE.md
Project Overview
ClearPilot is a custom fork of FrogPilot (itself a fork of comma.ai's openpilot), based on a 2024 release. It is purpose-built for Brian Hanson's Hyundai Tucson (HDA2 equipped). The vehicle's HDA2 system has specific quirks around how it synchronizes driving state with openpilot that require careful handling.
Key Customizations in This Fork
- UI changes to the onroad driving interface
- Lane change behavior: brief disengage when turn signal is active during lane changes
- Lateral control disabled: the car's own radar cruise control handles lateral; openpilot handles longitudinal only
- Driver monitoring timeouts: modified safety timeouts for the driver monitoring system
- Custom driving models:
duck-amigo.thneed,farmville.onnx,wd-40.thneedinselfdrive/clearpilot/models/ - ClearPilot service: Node.js service at
selfdrive/clearpilot/with behavior scripts for lane change and longitudinal control
Short-Term Goals
Fix the dashcam/screen recorder feature(done — see Dashcam section below)- Fix GPS tracking feature
- Add a safe-speed-exceeded chime
- Implement interactions for the "debug function button"
Working Rules
CRITICAL: Change Control
This is self-driving software. All changes must be deliberate and well-understood.
- NEVER make changes outside of what is explicitly requested
- Always explain proposed changes first — describe the change, the logic, and the architecture; let Brian review and approve before writing any code
- Brian is an expert on this software — do not override his judgment or assume responsibility for changes he doesn't understand
- Every line must be understood — work slowly and deliberately
- Test everything thoroughly — Brian must always be in the loop
- Do not refactor, clean up, or "improve" code beyond the specific request
File Ownership
We operate as root on this device, but openpilot runs as the comma user (uid=1000, gid=1000). After any code changes that touch multiple files or before testing:
chown -R comma:comma /data/openpilot
Git
- Remote:
git@git.internal.hanson.xyz:brianhansonxyz/comma.git - Branch:
clearpilot - Large model files are tracked in git (intentional — this is a backup)
Samba Share
- Share name:
openpilot(e.g.\\comma-3889765b\openpilot) - Path:
/data/openpilot - Username:
comma - Password:
i-like-to-drive-cars - Runs as
comma:commavia force user/group — files created over SMB are owned correctly - Enabled at boot (
smbd+nmbd)
Testing Changes
To restart the full openpilot stack after making changes:
# Fix ownership first (we edit as root, openpilot runs as comma)
chown -R comma:comma /data/openpilot
# Kill existing stack — use pgrep/kill to avoid pkill matching our own shell
kill $(pgrep -f 'python.*manager') 2>/dev/null; sleep 2
# Must use a login shell as comma — sudo -u won't set up the right Python/env
su - comma -c "bash /data/openpilot/launch_openpilot.sh"
Note: pkill -f manager or pkill -f launch_openpilot will match the invoking shell's own command line and kill the launch process itself. Use pgrep+kill or run the kill as a separate step before launching.
Adding new params: The params system uses a C++ whitelist. Adding a new param name in manager.py alone will crash with UnknownKeyName. You must also register the key in common/params.cc in the key list (alphabetically, with PERSISTENT or CLEAR_ON_* flag), then rebuild. The rebuild will recompile params.cc -> libcommon.a and re-link all binaries that use it.
The prebuilt marker file skips compilation. It is recreated automatically after each successful build, so you must remove it every time you want to recompile:
rm -f /data/openpilot/prebuilt
Dashcam / Screen Recorder
Architecture
The dashcam is the FrogPilot ScreenRecorder — it captures the onroad UI screen (with overlays) and encodes to MP4 using the Qualcomm OMX H.264 hardware encoder.
- Codec: H.264 AVC (hardware accelerated via
OMX.qcom.video.encoder.avc) - Resolution: 1440x720 (downscaled from 2160x1080)
- Bitrate: 2 Mbps
- Container: MP4
- Segment length: 3 minutes per file
- Save path:
/data/media/0/videos/YYYYMMDD-HHMMSS.mp4
Changes Made (2026-04-11)
-
Disabled comma training data video (
selfdrive/manager/process_config.py): commented outencoderdandstream_encoderd. CAN/sensor logs (rlog/qlog) are still recorded byloggerd. -
Re-enabled screen recorder (
selfdrive/ui/qt/onroad.cc): uncommented theQTimerthat feeds frames to the encoder at UI_FREQ rate. -
Auto-start recording (
selfdrive/frogpilot/screenrecorder/screenrecorder.cc): modifiedupdate_screen()to automatically start recording when the car is on (scene.started) and stop when off. No button press needed. -
Hidden UI elements: the record button is constructed but never made visible or added to layout. Recording is invisible to the driver.
-
Debug flag (
ScreenRecorderDebugparam): when set to"1", recording starts even without a car connected. Used for bench testing. Read viascene.screen_recorder_debuginui.h/ui.cc. -
Deleter updated (
system/loggerd/deleter.py): free space threshold raised from 5 GB to 9 GB. Oldest videos in/data/media/0/videos/are deleted first before falling back to log segments.
Key Files
| File | Role |
|---|---|
selfdrive/frogpilot/screenrecorder/screenrecorder.cc |
Screen capture and auto-start/stop logic |
selfdrive/frogpilot/screenrecorder/omx_encoder.cc |
OMX H.264 hardware encoder wrapper |
selfdrive/ui/qt/onroad.cc |
Timer that drives frame capture |
selfdrive/ui/ui.h |
screen_recorder_debug scene flag |
selfdrive/ui/ui.cc |
Reads ScreenRecorderDebug param |
selfdrive/manager/manager.py |
Default params |
selfdrive/manager/process_config.py |
encoderd disabled here |
system/loggerd/deleter.py |
Storage rotation (9 GB threshold, videos + logs) |
Device: comma 3x
Hardware
- Qualcomm Snapdragon SoC (aarch64)
- Serial: comma-3889765b
- Connects to the car via comma panda (CAN bus interface)
Operating System
- Ubuntu 20.04.6 LTS (Focal Fossa) on aarch64
- Kernel: 4.9.103+ (custom comma.ai PREEMPT build, Feb 2024) — very old, vendor-patched Qualcomm kernel
- AGNOS version: 9.7 (comma's custom OS layer on top of Ubuntu)
- Display server: Weston (Wayland compositor) on tty1
- SELinux: mounted (enforcement status varies)
Users
comma(uid=1000) — the user openpilot runs as; member of root, sudo, disk, gpu, gpio groupsroot— what we SSH in as; files must be chowned back to comma before running openpilot
Filesystem / Mount Quirks
| Mount | Device | Type | Notes |
|---|---|---|---|
/ |
/dev/sda7 | ext4 | Root filesystem, read-write |
/data |
/dev/sda12 | ext4 | Persistent. Openpilot lives here. Survives reboots. |
/home |
overlay | overlayfs | VOLATILE — upperdir on tmpfs, changes lost on reboot |
/tmp |
tmpfs | tmpfs | Volatile, 150 MB |
/var |
tmpfs | tmpfs | Volatile, 128 MB (fstab) / 1.5 GB (actual) |
/systemrw |
/dev/sda10 | ext4 | Writable system overlay, noexec |
/persist |
/dev/sda2 | ext4 | Persistent config/certs, noexec |
/cache |
/dev/sda11 | ext4 | Android-style cache partition |
/dsp |
/dev/sde26 | ext4 | Read-only Qualcomm DSP firmware |
/firmware |
/dev/sde4 | vfat | Read-only firmware blobs |
/data/media |
NVMe | auto | 69 GB dashcam video storage |
Unusual Packages / Services
vnstat— network traffic monitorcdsprpcd,qseecomd— Qualcomm DSP and secure execution daemonstftp_server— TFTP server running (Qualcomm firmware access)- armhf multiarch libraries present (32-bit binary support)
- Reverse SSH tunnel running via screen (
/data/brian/reverse_ssh.sh) phantom_touch_logger.py,power_drop_monitor.py— comma hardware monitors
Large Files on Device
/data/media— ~69 GB (dashcam video segments)/data/scons_cache— ~1.9 GB (build cache)/data/safe_staging— ~1.5 GB (OTA update staging)- Model files in repo: ~238 MB total (see models section below)
Boot Sequence
Power On
-> systemd: comma.service (runs as comma user)
-> /usr/comma/comma.sh (waits for Weston, handles factory reset)
-> /data/continue.sh (exec bridge to openpilot)
-> /data/openpilot/launch_openpilot.sh
-> Sources launch_env.sh (thread counts, AGNOS_VERSION)
-> Runs agnos_init (marks boot slot, GPU perms, checks OS update)
-> Sets PYTHONPATH, symlinks /data/pythonpath
-> Runs build.py if no `prebuilt` marker
-> Launches selfdrive/manager/manager.py
-> manager_init() sets default params
-> ensure_running() loop starts all managed processes
Openpilot Architecture
Process Manager
selfdrive/manager/manager.py orchestrates all processes defined in selfdrive/manager/process_config.py.
Always-Running Processes (offroad + onroad)
thermald— thermal management, high CPU (~5.6%)pandad— panda CAN bus interfaceui— Qt-based onroad/offroad UIdeleter— storage cleanupstatsd,timed,logmessaged,tombstoned— telemetry/loggingmanage_athenad— comma cloud connectivity
Onroad-Only Processes (when driving)
controlsd— main vehicle control loopplannerd— path planningradard— radar processingmodeld— driving model inferencedmonitoringmodeld— driver monitoring modellocationd— positioning/localizationcalibrationd— camera calibrationparamsd,torqued— parameter estimationsensord— IMU/sensor datasoundd— alert soundscamerad— camera captureloggerd,encoderd— video logging/encodingboardd— board communication
GPS
ubloxd+pigeondfor u-blox GPS hardwareqcomgpsd,ugpsd,navdcurrently commented out in process_config
FrogPilot Additions
selfdrive/frogpilot/frogpilot_process.py— FrogPilot main processselfdrive/frogpilot/controls/— custom planner, control librariesselfdrive/frogpilot/fleetmanager/— fleet management web UIselfdrive/frogpilot/screenrecorder/— C++ OMX-based screen recorder (dashcam)selfdrive/frogpilot/ui/qt/— custom UI widgets and settings panelsselfdrive/frogpilot/assets/— custom assets
ClearPilot Additions
selfdrive/clearpilot/clearpilot.js— Node.js serviceselfdrive/clearpilot/behavior/— lane change, longitudinal control mode scriptsselfdrive/clearpilot/models/— custom driving models (duck-amigo, farmville, wd-40)selfdrive/clearpilot/manager/api.js— manager APIselfdrive/clearpilot/theme/,selfdrive/clearpilot/resource/— theming and assets
Car Interface (Hyundai)
selfdrive/car/hyundai/interface.py— main car interfaceselfdrive/car/hyundai/carcontroller.py— actuator commandsselfdrive/car/hyundai/carstate.py— vehicle state parsingselfdrive/car/hyundai/radar_interface.py— radar dataselfdrive/car/hyundai/hyundaicanfd.py— CAN-FD message definitions (HDA2 uses CAN-FD)selfdrive/car/hyundai/values.py,fingerprints.py— car-specific constants
UI Code
selfdrive/ui/— Qt/C++ basedselfdrive/ui/qt/onroad.cc— main driving screen (contains uiDebug publish, screen recorder integration)selfdrive/ui/qt/home.cc— home/offroad screenselfdrive/ui/qt/sidebar.cc— sidebarselfdrive/ui/ui.cc,ui.h— UI state management
Key Dependencies
- Python 3.11 with: numpy, casadi, onnx/onnxruntime, pycapnp, pyzmq, sentry-sdk, sympy, Cython
- capnp (Cap'n Proto) — IPC message serialization between all processes
- ZeroMQ — IPC transport layer
- Qt 5 — UI framework
- OpenMAX (OMX) — hardware video encoding (screen recorder)
- SCons — build system for native C++ components