Files
clearpilot/CLAUDE.md
Brian Hanson 8ae7ef6eaf dashcam: re-enable screen recorder, disable training data video
- 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>
2026-04-11 07:28:30 +00:00

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.thneed in selfdrive/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:comma via 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)

  1. Disabled comma training data video (selfdrive/manager/process_config.py): commented out encoderd and stream_encoderd. CAN/sensor logs (rlog/qlog) are still recorded by loggerd.

  2. Re-enabled screen recorder (selfdrive/ui/qt/onroad.cc): uncommented the QTimer that feeds frames to the encoder at UI_FREQ rate.

  3. Auto-start recording (selfdrive/frogpilot/screenrecorder/screenrecorder.cc): modified update_screen() to automatically start recording when the car is on (scene.started) and stop when off. No button press needed.

  4. Hidden UI elements: the record button is constructed but never made visible or added to layout. Recording is invisible to the driver.

  5. Debug flag (ScreenRecorderDebug param): when set to "1", recording starts even without a car connected. Used for bench testing. Read via scene.screen_recorder_debug in ui.h/ui.cc.

  6. 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 groups
  • root — 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 monitor
  • cdsprpcd, qseecomd — Qualcomm DSP and secure execution daemons
  • tftp_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 interface
  • ui — Qt-based onroad/offroad UI
  • deleter — storage cleanup
  • statsd, timed, logmessaged, tombstoned — telemetry/logging
  • manage_athenad — comma cloud connectivity

Onroad-Only Processes (when driving)

  • controlsd — main vehicle control loop
  • plannerd — path planning
  • radard — radar processing
  • modeld — driving model inference
  • dmonitoringmodeld — driver monitoring model
  • locationd — positioning/localization
  • calibrationd — camera calibration
  • paramsd, torqued — parameter estimation
  • sensord — IMU/sensor data
  • soundd — alert sounds
  • camerad — camera capture
  • loggerd, encoderd — video logging/encoding
  • boardd — board communication

GPS

  • ubloxd + pigeond for u-blox GPS hardware
  • qcomgpsd, ugpsd, navd currently commented out in process_config

FrogPilot Additions

  • selfdrive/frogpilot/frogpilot_process.py — FrogPilot main process
  • selfdrive/frogpilot/controls/ — custom planner, control libraries
  • selfdrive/frogpilot/fleetmanager/ — fleet management web UI
  • selfdrive/frogpilot/screenrecorder/ — C++ OMX-based screen recorder (dashcam)
  • selfdrive/frogpilot/ui/qt/ — custom UI widgets and settings panels
  • selfdrive/frogpilot/assets/ — custom assets

ClearPilot Additions

  • selfdrive/clearpilot/clearpilot.js — Node.js service
  • selfdrive/clearpilot/behavior/ — lane change, longitudinal control mode scripts
  • selfdrive/clearpilot/models/ — custom driving models (duck-amigo, farmville, wd-40)
  • selfdrive/clearpilot/manager/api.js — manager API
  • selfdrive/clearpilot/theme/, selfdrive/clearpilot/resource/ — theming and assets

Car Interface (Hyundai)

  • selfdrive/car/hyundai/interface.py — main car interface
  • selfdrive/car/hyundai/carcontroller.py — actuator commands
  • selfdrive/car/hyundai/carstate.py — vehicle state parsing
  • selfdrive/car/hyundai/radar_interface.py — radar data
  • selfdrive/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++ based
  • selfdrive/ui/qt/onroad.cc — main driving screen (contains uiDebug publish, screen recorder integration)
  • selfdrive/ui/qt/home.cc — home/offroad screen
  • selfdrive/ui/qt/sidebar.cc — sidebar
  • selfdrive/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