The definitive technical reference for deploying, operating, extending, and debugging comma.ai's openpilot advanced driver-assistance system. This guide covers the full architecture from process orchestration down to CAN bus messaging, every configuration lever, and every diagnostic tool available in the codebase.
For installation steps, vehicle compatibility lists, and everyday usage instructions, see the companion User Guide.
Table of Contents
- Architecture Overview
- System Requirements
- Configuration Reference
- Deployment & Scaling
- Operations
- Performance
- Security
- Developer Internals
- Integration Points
1. Architecture Overview
openpilot is a real-time ADAS stack that runs on comma hardware (comma 3X, comma four) installed in supported vehicles. The system architecture follows a process-manager pattern: a central manager daemon orchestrates approximately 40 specialized processes that communicate through a high-performance pub/sub messaging layer built on Cap'n Proto serialization and shared memory transport.
1.1 High-Level System Diagram
┌─────────────────────────────────────────────────────────────────┐
│ comma device │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ system/manager │ │
│ │ manager.py ──► ensure_running() @ 1Hz │ │
│ │ process_config.py defines ~40 processes + conditions │ │
│ └──────────┬───────────────────────────────────────────────┘ │
│ │ spawns/monitors │
│ ┌──────────▼───────────────────────────────────────────────┐ │
│ │ cereal messaging (pub/sub) │ │
│ │ SubMaster / PubMaster over msgq (shared memory) │ │
│ │ ~60 message types defined in cereal/services.py │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │ │ │ │
│ ┌────▼──┐ ┌─────▼────┐ ┌───▼───┐ ┌────▼─────┐ │
│ │camerad│ │ controlsd │ │modeld │ │selfdrived│ │
│ │sensord│ │ plannerd │ │dmond │ │ card │ │
│ │loggerd│ │ radard │ └───────┘ │ pandad │ │
│ └───────┘ └──────────┘ └──────────┘ │
│ │ │ │
│ ┌────▼────────────────────────────────────▼───────────────┐ │
│ │ Vehicle CAN Bus (via panda) │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│ ▲
▼ │
┌──────────────┐ ┌───────┴──────┐
│ comma cloud │ │ Vehicle ECU │
│ (athena WS) │ │ (CAN msgs) │
└──────────────┘ └──────────────┘
1.2 Process Manager
The process manager (system/manager/manager.py) is the root of the entire runtime. It provides supervised process lifecycle management with automatic restart on crash.
Initialization sequence (manager_init()):
- Save bootlog to persistent storage
- Register device with comma servers (obtain DongleId)
- Set params: Version, GitCommit, GitBranch, etc.
- Initialize Sentry error reporting and structured logging
- Pre-import all Python process modules to reduce cold-start latency
Main loop (manager_thread()):
- Polls
deviceState,carParams, andpandaStatesat 1Hz - Calls
ensure_running()each iteration to start processes whose conditions are met and stop those whose conditions are no longer met - Watches three shutdown params:
DoUninstall,DoShutdown,DoReboot
Manager environment variables:
| Variable | Effect |
|---|---|
NOBOARD |
Skip panda hardware detection (development mode) |
BLOCK |
Comma-separated list of process names to prevent from starting |
PREPAREONLY |
Exit after initialization without entering the main loop |
1.3 Process Types
Three process types are defined in system/manager/process.py:
| Type | Implementation | Use Case |
|---|---|---|
PythonProcess |
Python module loaded via importlib, runs in multiprocessing.Process |
Most daemons (controlsd, modeld, etc.) |
NativeProcess |
C++ binary executed via os.execvp |
Performance-critical paths (camerad, loggerd, encoderd) |
DaemonProcess |
Long-running process that survives manager restarts | athenad (cloud connection) |
1.4 Complete Process Map
The full process configuration lives in system/manager/process_config.py. Every managed process, its type, and its activation condition:
Always Running:
| Process | Type | Purpose |
|---|---|---|
| pandad | Native | CAN bus interface via panda hardware |
| ui | Python | Main display interface |
| logmessaged | Python | Log message routing |
| hardwared | Python | Hardware monitoring (thermals, power, network) |
| uploader | Python | Log upload to comma cloud |
| deleter | Python | Storage management — delete old logs |
| statsd | Python | Statistics collection |
| manage_athenad | Daemon | Cloud WebSocket connectivity |
Onroad (vehicle ignition on):
| Process | Type | Purpose |
|---|---|---|
| modeld | Python | Driving model inference |
| controlsd | Python | Main control loop (100Hz) |
| selfdrived | Python | State machine, event management |
| card | Python | Car interface, CAN read/write |
| radard | Python | Radar/vision fusion |
| plannerd | Python | Longitudinal planning, LDW |
| locationd | Python | EKF pose estimation |
| calibrationd | Python | Camera calibration |
| torqued | Python | Torque parameter estimation |
| paramsd | Python | Vehicle parameter learning |
| lagd | Python | Lateral lag estimation |
| dmonitoringd | Python | Driver monitoring logic |
| sensord | Native | IMU sensor reading |
| camerad | Native | Camera capture |
| encoderd | Native | Video encoding |
| loggerd | Native | Log recording |
| proclogd | Python | Process resource logging |
| soundd | Python | Audio alerts |
| feedbackd | Python | User feedback collection |
| micd | Python | Microphone capture |
| ubloxd | Native | u-blox GPS receiver |
| pigeond | Python | u-blox GPS configuration |
| qcomgpsd | Python | Qualcomm GPS (alternative) |
Offroad only:
| Process | Type | Purpose |
|---|---|---|
| updated | Python | OTA system updates |
Conditional:
| Process | Condition | Purpose |
|---|---|---|
| joystickd | JoystickDebugMode param set |
Joystick input for testing |
| webcamerad | USE_WEBCAM env var |
Webcam instead of device cameras |
| maneuversd | LongitudinalManeuverMode param set |
Longitudinal maneuver testing |
| lateral_maneuversd | LateralManeuverMode param set |
Lateral maneuver testing |
| bridge | Debug/notcar only | Simulator bridge |
| webrtcd | Debug/notcar only | WebRTC streaming |
| webjoystick | Debug/notcar only | Web-based joystick |
1.5 Messaging Architecture (cereal)
All inter-process communication uses the cereal messaging framework — Cap'n Proto serialization over shared memory (msgq) or ZMQ transport.
Core concepts:
- PubMaster: Publishes messages to named topics (services)
- SubMaster: Subscribes to one or more topics, provides
.updated[]and.valid[]checks - FrequencyTracker: Validates that messages arrive at their expected frequency
- Services: Defined in
cereal/services.pywithQueueSizeenum controlling buffer depth
Key message types:
| Message | Publisher | Frequency | Content |
|---|---|---|---|
carState |
card | 100Hz | Vehicle state (speed, steering, pedals) |
carControl |
controlsd | 100Hz | Actuator commands (steer, gas, brake) |
controlsState |
controlsd | 100Hz | Control system state, errors |
modelV2 |
modeld | 20Hz | Path predictions, lane lines, leads |
radarState |
radard | 20Hz | Fused radar/vision lead detections |
selfdriveState |
selfdrived | - | ADAS state machine status |
deviceState |
hardwared | 2Hz | Thermals, power, network |
pandaStates |
pandad | 2Hz | Panda hardware status |
liveCalibration |
calibrationd | - | Camera extrinsics |
livePose |
locationd | - | Vehicle pose (position, velocity, orientation) |
longitudinalPlan |
plannerd | 20Hz | Speed/acceleration profile |
driverMonitoringState |
dmonitoringd | - | Driver attention status |
Note
The messaging layer uses shared memory by default on device (msgq) for minimal latency. ZMQ transport is available for development and cross-machine debugging but adds measurable overhead.
1.6 Controls Pipeline
The controls pipeline is the safety-critical path from perception to vehicle actuation, running at 100Hz:
camerad (frames) → modeld (path prediction, 20Hz)
↓
radard (lead detection, 20Hz) → plannerd (longitudinal plan, 20Hz)
↓
card (vehicle state, 100Hz) ──────► controlsd (actuator commands, 100Hz)
│
├── Lateral: LatControlAngle / LatControlPID / LatControlTorque
├── Longitudinal: LongControl (PID)
└── VehicleModel (curvature calculations)
↓
card → pandad → CAN bus → Vehicle
Lateral control selection is determined by CP.steerControlType:
LatControlAngle— Direct angle control (supported by some vehicles)LatControlPID— PID-based steering controlLatControlTorque— Torque-based steering control (most common)
Longitudinal control uses a PID controller (LongControl) that tracks the speed/acceleration profile from plannerd.
1.7 State Machine (selfdrived)
selfdrive/selfdrived/selfdrived.py manages the high-level ADAS state:
┌──────────────────┐
│ disabled │◄──── Default state
└───────┬──────────┘
│ enable conditions met
┌───────▼──────────┐
│ preEnabled │ ← Transitional
└───────┬──────────┘
│ all checks pass
┌───────▼──────────┐
│ enabled │ ← Active driving assist
└───────┬──────────┘
│ soft disable event
┌───────▼──────────┐
│ softDisabling │ ← Grace period
└───────┬──────────┘
│ timeout
┌───────▼──────────┐
│ disabled │
└──────────────────┘
Events are the mechanism for state transitions. Each event has a priority (PERMANENT, IMMEDIATE, SOFT_DISABLE, PRE_ENABLE, NO_ENTRY, WARNING, USER_DISABLE) and triggers alerts displayed on the UI.
2. System Requirements
2.1 Hardware
Production deployment requires comma hardware:
| Device | Status | Notes |
|---|---|---|
| comma 3X | Supported | Current production device |
| comma four | Supported | Latest generation |
| comma 3 | Legacy | Still functional |
| comma two | Deprecated | No longer maintained |
The device connects to the vehicle via the comma harness, which interfaces with the OBD-II port and provides CAN bus access through the panda (USB CAN adapter).
Development on PC:
| Component | Minimum | Recommended |
|---|---|---|
| OS | Ubuntu 24.04 | Ubuntu 24.04 |
| Python | 3.12+ | 3.13 |
| RAM | 8 GB | 16 GB |
| GPU | - | NVIDIA (for model inference) |
| Storage | 10 GB | 50 GB (with logs) |
Important
The
Dockerfile.openpilotin the repository is for CI/testing only. There is no Docker-based deployment path for end users. openpilot runs natively on AGNOS (comma's embedded Linux) on device hardware.
2.2 Software Stack
On-device (AGNOS):
- Custom Linux distribution based on Ubuntu
- Python 3.12+
- tinygrad for neural network inference
- Qualcomm Spectra ISP for camera processing
- V4L2 for video capture
- FFmpeg for encoding
Development dependencies:
- SCons build system
- Cython (via
site_scons/site_tools/cython.py) - Cap'n Proto compiler
- clang/gcc for C++ components
- pytest for testing
2.3 Build System
openpilot uses SCons with a total of 2,705 build nodes:
# Full build
scons -j$(nproc)
# Build with retry (decreasing parallelism on failure)
# The CI system automatically retries: nproc → nproc/2 → 1
scons -j$(nproc) || scons -j$(($(nproc)/2)) || scons -j1
Build cache:
- Device (AGNOS):
/data/scons_cache(max 2 GB) - PC:
/tmp/scons_cache(max 4 GB)
Tip
When developing on PC, set
NOBOARD=1to skip panda hardware detection. Combine withBLOCKto disable processes you don't need:BLOCK=camerad,encoderd,loggerd.
3. Configuration Reference
3.1 Params System
The primary configuration mechanism is the params system (common/params.py and common/params.cc), a persistent key-value store backed by the filesystem.
Storage location: {Paths.persist_root}/params/d/ (typically /data/params/d/)
Param lifecycle flags (ParamKeyFlags):
| Flag | Behavior |
|---|---|
CLEAR_ON_MANAGER_START |
Reset when manager starts |
CLEAR_ON_ONROAD_TRANSITION |
Reset when vehicle goes onroad |
CLEAR_ON_OFFROAD_TRANSITION |
Reset when vehicle goes offroad |
CLEAR_ON_IGNITION_ON |
Reset when ignition detected |
DEVELOPMENT_ONLY |
Only available in development builds |
Key params:
| Param | Type | Purpose |
|---|---|---|
CarParams |
bytes | Serialized car parameters (fingerprint result) |
DongleId |
string | Unique device identifier |
Version |
string | openpilot version string |
GitCommit |
string | Current git commit hash |
GitBranch |
string | Current git branch |
IsOnroad |
bool | Vehicle is driving |
IsOffroad |
bool | Vehicle is parked |
RecordFront |
bool | Record driver-facing camera |
JoystickDebugMode |
bool | Enable joystick control |
LongitudinalManeuverMode |
bool | Enable longitudinal test maneuvers |
LateralManeuverMode |
bool | Enable lateral test maneuvers |
IsLdwEnabled |
bool | Lane departure warning enabled |
IsMetric |
bool | Use metric units |
OpenpilotEnabledToggle |
bool | Master enable toggle |
ExperimentalMode |
bool | Enable experimental features |
ExperimentalModeConfirmed |
bool | User confirmed experimental mode |
Programmatic access:
from openpilot.common.params import Params
params = Params()
# Read
dongle_id = params.get("DongleId", encoding="utf-8")
is_metric = params.get_bool("IsMetric")
# Write
params.put("RecordFront", "1")
params.put_bool("IsMetric", True)
# Block until available
car_params = params.get("CarParams", block=True)
Params are thread-safe and can be accessed from any process. They are the standard inter-process configuration mechanism.
3.2 Environment Variables — Complete Reference
All 57 environment variables recognized by the codebase:
Core System
| Variable | Default | Description |
|---|---|---|
NOBOARD |
unset | Skip panda hardware; PC development mode |
PREPAREONLY |
unset | Exit manager after initialization |
BLOCK |
unset | Comma-separated process names to prevent starting |
SIMULATION |
0 |
Enable simulation mode |
DEBUG |
0 |
Enable debug logging across all modules |
CI |
unset | Running in continuous integration |
LOGPRINT |
warning |
Log level for stdout (debug, info, warning, error) |
Cloud & Networking
| Variable | Default | Description |
|---|---|---|
ATHENA_HOST |
wss://athena.comma.ai |
WebSocket endpoint for cloud connection |
API_HOST |
https://api.commadotai.com |
REST API endpoint for comma services |
HANDLER_THREADS |
4 |
Number of athena handler threads |
FORCEWIFI |
unset | Force WiFi-only mode (skip cellular) |
PRIME_TYPE |
unset | Override Prime subscription type |
Upload & Storage
| Variable | Default | Description |
|---|---|---|
FAKEUPLOAD |
unset | Simulate uploads without sending data |
UPLOADER_SLEEP |
1 |
Seconds between upload attempts |
DISABLE_FILEREADER_CACHE |
0 |
Disable local file caching |
CACHE_ROOT |
system default | Override cache directory root |
DATA_ENDPOINT |
http://data-raw.comma.internal/ |
Data download endpoint |
Camera & Video
| Variable | Default | Description |
|---|---|---|
USE_WEBCAM |
unset | Use USB webcam instead of device cameras |
ROAD_CAM |
0 |
Road camera device index |
WIDE_CAM |
unset | Wide camera device index |
DRIVER_CAM |
unset | Driver camera device index |
UI Configuration
| Variable | Default | Description |
|---|---|---|
FPS |
unset | Override UI frame rate |
ENABLE_VSYNC |
0 |
Enable vertical sync |
SHOW_FPS |
unset | Display FPS counter |
SHOW_TOUCHES |
unset | Visualize touch events |
STRICT_MODE |
unset | Strict UI validation |
SCALE |
1.0 |
UI scale factor |
GRID |
0 |
Show layout grid |
PROFILE_RENDER |
0 |
Profile render performance |
PROFILE_STATS |
100 |
Render profiling sample count |
OFFSCREEN |
unset | Offscreen rendering (headless) |
DEBUG_SCROLL |
0 |
Debug scroll behavior |
HORIZONTAL |
unset | Horizontal layout for replay UI |
BIG |
0 |
Use large model variant |
Recording
| Variable | Default | Description |
|---|---|---|
RECORD |
unset | Enable screen recording |
RECORD_OUTPUT |
output |
Recording output directory |
RECORD_QUALITY |
23 |
H.264 CRF quality (lower = better) |
RECORD_BITRATE |
unset | Override recording bitrate |
RECORD_SPEED |
1 |
Recording playback speed |
Paths
| Variable | Default | Description |
|---|---|---|
LOG_ROOT |
platform-dependent | Override log storage root |
COMMA_CACHE |
platform-dependent | Override cache directory |
OPENPILOT_PREFIX |
unset | Prefix for isolated test environments |
Model & Inference
| Variable | Default | Description |
|---|---|---|
SEND_RAW_PRED |
unset | Publish raw model predictions |
REPLAY |
0 |
Running in replay mode |
OTA Updates
| Variable | Default | Description |
|---|---|---|
UPDATER_LOCK_FILE |
/tmp/safe_staging_overlay.lock |
Update overlay lock file |
UPDATER_STAGING_ROOT |
/data/safe_staging |
Staging area for OTA updates |
Replay Tool
| Variable | Default | Description |
|---|---|---|
PWR_ON |
unset | Simulated power-on event timestamp |
PWR_OFF |
unset | Simulated power-off event timestamp |
ON |
unset | Simulated ignition-on timestamp |
OFF |
unset | Simulated ignition-off timestamp |
Data Pipeline
| Variable | Default | Description |
|---|---|---|
COMMA_CAR_SEGMENTS_REPO |
unset | Override car segments repository |
COMMA_CAR_SEGMENTS_BRANCH |
unset | Override car segments branch |
COMMA_CAR_SEGMENTS_LFS_INSTANCE |
unset | Override LFS instance |
FFMPEG_THREADS |
0 |
FFmpeg thread count (0 = auto) |
GPS
| Variable | Default | Description |
|---|---|---|
QCOM_ALT_ASSISTANCE_PATH |
None |
Qualcomm GPS alternative assistance data path |
Warning
Setting
NOBOARD=1disables all panda safety checks. Never use this on a vehicle. It exists solely for PC-based development and simulation.
3.3 Filesystem Paths
The Paths class in system/hardware/hw.py defines all standard paths:
| Path | Default (Device) | Env Override | Purpose |
|---|---|---|---|
comma_home |
/data |
- | Root data directory |
log_root |
/data/media/0/realdata |
LOG_ROOT |
Drive log storage |
swaglog_root |
/data/media/0/swaglog |
- | System logs |
download_cache_root |
/tmp/comma_cache |
COMMA_CACHE |
Download cache |
persist_root |
/persist |
- | Persistent storage (params) |
stats_root |
/data/stats |
- | Statistics |
config_root |
/tmp/config |
- | Runtime config |
shm_path |
/dev/shm |
- | Shared memory |
On PC, these map to ~/.comma/ subdirectories unless overridden.
4. Deployment & Scaling
4.1 Device Deployment
openpilot is deployed to comma hardware through the following channels:
- Factory install: Devices ship with AGNOS and a stable openpilot release
- OTA updates: The
updatedprocess manages over-the-air updates using overlay filesystems and casync
OTA update mechanism (system/updated/updated.py):
- Checks for updates periodically when offroad
- Downloads incremental updates using casync (content-addressable storage)
- Stages updates in an overlay filesystem at
UPDATER_STAGING_ROOT(/data/safe_staging) - Atomic swap on next boot
- Lock file at
UPDATER_LOCK_FILEprevents concurrent updates
Current System (read-only base)
│
├── Overlay Filesystem (staging area)
│ └── Delta changes from casync
│
└── Atomic swap on reboot
4.2 Development Setup
# Clone
git clone https://github.com/commaai/openpilot.git
cd openpilot
git submodule update --init --recursive
# System dependencies (Ubuntu 24.04)
tools/ubuntu_setup.sh
# Build
scons -j$(nproc)
# Run in simulation mode
NOBOARD=1 SIMULATION=1 ./launch_openpilot.sh
Caution
Never run
launch_openpilot.shwithoutNOBOARD=1on a PC. Without panda hardware present and safety checks disabled, processes will crash in unpredictable ways or attempt to access nonexistent hardware devices.
4.3 Branch & Release Strategy
masterbranch is the development trunk; all PRs targetmaster- Release branches are cut for stable device deployments
- CI runs process replay tests on every PR to catch regressions
- Contributing priorities (in order): safety, stability, quality, features
5. Operations
5.1 Hardware Monitoring (hardwared)
system/hardware/hardwared.py monitors device health at 2Hz, publishing deviceState:
Thermal zones (ThermalConfig):
| Zone | Sensors |
|---|---|
| CPU | SoC temperature sensors |
| GPU | GPU die temperature |
| DSP | DSP core temperature |
| Memory | DRAM temperature |
Thermal management states:
- Green: Normal operation
- Yellow: Reduce non-critical workloads
- Red: Disable model inference, reduce camera FPS
- Danger: Emergency shutdown
Fan control (FanController): PID-based fan speed control targeting thermal equilibrium. Fan speed adjusts based on the highest temperature across all zones.
Power monitoring (PowerMonitoring): Tracks battery voltage, current draw, and estimates remaining runtime. Triggers graceful shutdown before battery depletion.
5.2 Storage Management
Logging (system/loggerd/):
- Drive logs recorded to
Paths.log_rootas rlog (cereal messages) + video segments - Each segment is ~60 seconds of driving data
- Video encoded as H.265 (HEVC) on device
Deletion (system/loggerd/deleter.py):
- Monitors available storage
- Deletes oldest log segments first when storage falls below threshold
- Preserves flagged/starred drives
Upload (system/loggerd/uploader.py):
- Uploads logs to comma servers over WiFi (or cellular if Prime subscriber)
- Configurable via
FAKEUPLOAD(dry run) andUPLOADER_SLEEP(rate limiting)
5.3 Cloud Connectivity (athenad)
system/athena/athenad.py maintains a persistent WebSocket connection to ATHENA_HOST (default: wss://athena.comma.ai):
Capabilities:
- Receive remote commands from comma connect
- File upload/download on demand
- Remote SSH tunneling
- Push notifications to device
Resilience:
- Runs as a
DaemonProcess— survives manager restarts - Automatic reconnection with exponential backoff
- Handler thread pool (configurable via
HANDLER_THREADS, default 4)
5.4 GPS Subsystem
Two GPS backends are available:
| Backend | Process | Hardware | Notes |
|---|---|---|---|
| u-blox | ubloxd + pigeond | u-blox M8 receiver | Default on comma 3X |
| Qualcomm | qcomgpsd | Qualcomm SoC GNSS | Alternative, uses QCOM_ALT_ASSISTANCE_PATH |
pigeond.py handles u-blox configuration: baud rate, message rates, GNSS constellation selection. ubloxd is a native C++ process that reads NMEA/UBX messages and publishes gpsLocation.
5.5 eSIM Management (LPA)
The device includes an eSIM for cellular connectivity. The LPA (Local Profile Assistant) in system/hardware/tici/ manages eSIM profiles:
- List installed profiles
- Switch active profile
- Delete profiles
- Download new profiles (via QR activation code)
5.6 Known Issues
Active issues from the GitHub tracker relevant to operations:
| Issue | Title | Impact |
|---|---|---|
| #37845 | Comma 4 Splash Screen Hang and Post-Restart Audio Delay | Device may hang on boot splash, audio delayed after restart |
| #37384 | comma four: no engage/disengage sound | Missing audio feedback on comma four |
| #37610 | comma four < 60 FPS while engaged | UI framerate drops below 60 FPS during active engagement |
| #36887 | comma four: camera view UI glitch | Visual artifacts in camera view |
| #37458 | paramsd is active while driving in reverse | Parameter learning incorrectly active in reverse gear |
6. Performance
6.1 Model Pipeline
Driving model (selfdrive/modeld/modeld.py):
- Inference engine: tinygrad with ONNX model loading
- Model files:
driving_vision.onnx,driving_policy.onnx(andbigvariants) - Runs at 20Hz on device DSP/GPU
ModelConstantsdefines input/output dimensions and temporal structure- Output parsing: categorical cross-entropy, binary cross-entropy, mixture density networks (
parse_model_outputs.py)
Driver monitoring model (selfdrive/modeld/dmonitoringmodeld.py):
- Model file:
dmonitoring_model.onnx - Detects driver face pose, eye state, distraction
- Lower frequency than driving model
Note
Set
BIG=1to use the larger model variants. This increases accuracy but requires more compute time and may not maintain real-time performance on all hardware.
6.2 Camera Pipeline
system/camerad/ (C++) handles camera capture using the Qualcomm Spectra ISP on device:
- Three camera streams: road (forward), wide (fish-eye forward), driver (cabin-facing)
- ISP handles debayering, tone mapping, noise reduction in hardware
- Frames published to shared memory for modeld consumption
- On PC, the
USE_WEBCAMpath uses V4L2 for USB cameras
6.3 Kalman Filters
The localization pipeline uses multiple Extended Kalman Filters:
| Filter | Module | Estimates |
|---|---|---|
PoseKalman |
locationd | Vehicle pose (position, velocity, orientation, angular velocity) |
| Calibration EKF | calibrationd | Camera-to-road extrinsic calibration |
paramsd |
paramsd | Vehicle parameters (stiffness factor, steer ratio, angle offset) |
torqued |
torqued | Torque-based steering parameters via PointBuckets |
lagd |
lagd | Lateral control lag estimation |
6.4 Build Performance
The SCons build system supports parallel compilation:
# Maximum parallelism
scons -j$(nproc)
# Conservative (for constrained systems)
scons -j4
# Single-threaded (debugging build issues)
scons -j1
Build cache is stored at:
/data/scons_cacheon device (AGNOS), max 2 GB/tmp/scons_cacheon PC, max 4 GB
7. Security
7.1 Safety Architecture
openpilot's safety model is built on multiple independent layers:
-
Panda firmware safety: The panda (CAN adapter) runs independent safety firmware that enforces physical limits regardless of what the host software commands. The panda will refuse to send CAN messages that exceed safe torque/acceleration bounds.
-
controlsd safety checks: Software-level validation of all actuator commands before transmission. Rate limiting on steering torque, acceleration bounds, and sanity checks on model outputs.
-
selfdrived state machine: The engagement state machine enforces preconditions (driver monitoring OK, vehicle state valid, no critical faults) before allowing the system to control the vehicle.
-
Driver monitoring: Continuous driver attention monitoring via the cabin camera. Disengages if the driver is not attentive.
Caution
The panda firmware safety layer is the final safety barrier. It operates independently of the main openpilot software. Modifying panda firmware or flashing custom firmware that relaxes safety limits is extremely dangerous and voids all safety guarantees.
7.2 Process Isolation
Each process runs in its own address space (separate OS process, not threads). Crashes in one process do not directly affect others:
- Manager restarts crashed processes automatically
- Cereal messaging provides natural isolation boundaries
- The
OPENPILOT_PREFIXenvironment variable enables fully isolated test environments with separate shared memory namespaces
7.3 OTA Update Security
Updates are delivered through comma's infrastructure:
- Update manifests are signed
- casync provides content-addressable chunk verification
- Overlay filesystem prevents corruption of the running system during download
- Atomic swap ensures the system either boots the new version or rolls back to the previous one
7.4 Cloud Communication Security
- athenad uses WSS (WebSocket Secure) with TLS
- Device authentication via DongleId (device-unique identifier)
- File transfers are authenticated through the athena protocol
- No inbound ports are opened on the device
7.5 CAN Bus Security
- All CAN messages are filtered through panda firmware safety
- Fingerprinting (
selfdrive/car/) identifies the vehicle before enabling any control - Unknown or unsupported vehicles are blocked at the fingerprint stage
- CAN message counters and checksums are validated where supported by the vehicle protocol
Important
openpilot does not expose any network services, REST APIs, or web interfaces in production. The
webrtcdandwebjoystickprocesses are debug-only and are not started on production devices unless explicitly enabled.
8. Developer Internals
8.1 Module Reference
8.1.1 selfdrive/controls/controlsd.py
The main control loop running at 100Hz. Reads vehicle state from card, model predictions from modeld, and longitudinal plan from plannerd. Computes steering and acceleration commands.
Lateral controllers (selected by CP.steerControlType):
LatControlAngle— sends desired steering angle directlyLatControlPID— PID controller on steering angle errorLatControlTorque— PID controller on steering torque (most vehicles)
Longitudinal controller (LongControl):
- PID controller tracking the longitudinal plan
- Manages gas/brake actuator split
- Respects vehicle-specific acceleration limits
VehicleModel: Kinematic bicycle model for curvature-to-steering calculations. Uses learned parameters from paramsd (steer ratio, tire stiffness).
8.1.2 selfdrive/controls/plannerd.py
Longitudinal planning and lane departure warning:
- Consumes
modelV2(path predictions) andradarState(lead vehicles) - Produces
longitudinalPlanwith speed/acceleration targets over a time horizon - Lane departure warning triggers alerts when the vehicle drifts toward lane boundaries without turn signal
8.1.3 selfdrive/controls/radard.py
Radar and vision fusion for lead vehicle detection:
- Fuses radar tracks with vision-based lead detections from
modelV2 - Kalman filtering for smooth lead distance/velocity estimation
- Publishes
radarStatewith up to 3 lead vehicles - Handles radar-only, vision-only, and fused modes
8.1.4 selfdrive/car/
Vehicle interface layer. Each supported car brand has a subdirectory:
selfdrive/car/
├── interfaces.py # CarInterfaceBase ABC
├── car_helpers.py # Fingerprint logic
├── fw_query_definitions.py # Firmware query definitions
├── honda/
│ ├── interface.py # HondaCarInterface
│ ├── carcontroller.py # Honda-specific CAN commands
│ ├── carstate.py # Honda CAN → carState parsing
│ ├── hondacan.py # CAN message builders
│ └── values.py # Honda car constants
├── toyota/
├── hyundai/
├── gm/
├── ford/
├── volkswagen/
├── subaru/
├── mazda/
├── chrysler/
├── nissan/
└── ... (additional brands)
Fingerprinting: When a vehicle is connected, car_helpers.py reads CAN messages and firmware versions to identify the exact car model. The result is stored as CarParams and determines which interface, controller, and safety parameters are used.
8.1.5 selfdrive/modeld/
Neural network inference:
| File | Purpose |
|---|---|
modeld.py |
Main driving model inference loop |
dmonitoringmodeld.py |
Driver monitoring model |
parse_model_outputs.py |
Decode model output tensors |
models/ |
ONNX model files |
ModelConstants defines the model's input/output contract:
- Input dimensions (camera frame size, temporal context length)
- Output dimensions (path predictions, lane lines, leads, traffic signals)
- Temporal structure (how many past frames feed into the current prediction)
8.1.6 selfdrive/selfdrived/
State machine and alert system:
| File | Purpose |
|---|---|
selfdrived.py |
Main state machine loop |
events.py |
Event definitions and alert mappings |
alertmanager.py |
Alert display priority and lifecycle |
Events drive all state transitions. Each event type maps to one or more alerts with priority levels determining which alert is shown when multiple events are active simultaneously.
8.1.7 selfdrive/monitoring/
Driver monitoring logic (dmonitoringd.py):
- Consumes face detection and pose estimation from
dmonitoringmodeld - Tracks driver awareness through gaze direction, eye openness, face presence
- Escalating alert sequence: distraction warning → distraction critical → disengage
- Awareness score decays when driver is not looking at the road, recovers when attentive
8.1.8 selfdrive/locationd/
Localization and parameter estimation:
| Module | Purpose |
|---|---|
locationd.py |
EKF-based pose estimation (PoseKalman) combining IMU, GPS, visual odometry |
calibrationd.py |
Online camera calibration from driving data — estimates pitch/yaw of camera relative to road |
paramsd.py |
Vehicle parameter learning (tire stiffness factor, steering ratio, angle offset) |
torqued.py |
Torque parameter estimation using PointBuckets — maps lateral acceleration to required steering torque |
lagd.py |
Estimates lateral control lag (delay between command and vehicle response) |
8.1.9 selfdrive/pandad/
Panda CAN interface daemon. Manages communication with the panda USB device:
- CAN message reading/writing
- Panda health monitoring (published as
pandaStates) - Safety mode management
- Firmware version checking
8.1.10 system/manager/
Process orchestration:
| File | Purpose |
|---|---|
manager.py |
Main entry point, init sequence, supervisor loop |
process.py |
PythonProcess, NativeProcess, DaemonProcess classes |
process_config.py |
Complete process list with activation conditions |
8.1.11 system/hardware/
Hardware abstraction layer:
| File | Purpose |
|---|---|
base.py |
HardwareBase ABC — defines hardware interface |
hw.py |
Paths class, TICI/AGNOS/PC detection flags |
tici/hardware.py |
comma device implementation |
tici/amplifier.py |
Audio amplifier control |
tici/lpa.py |
eSIM profile management |
pc/hardware.py |
PC development stub |
hardwared.py |
Hardware monitoring daemon |
fan_controller.py |
PID-based thermal fan control |
power_monitoring.py |
Battery/power tracking |
Platform detection:
from openpilot.system.hardware import TICI, AGNOS, PC
if TICI:
# Running on comma device hardware
elif PC:
# Running on development PC
Detection is based on filesystem markers: /TICI and /AGNOS files.
8.1.12 system/athena/
Cloud connectivity:
| File | Purpose |
|---|---|
athenad.py |
WebSocket client, command handler, file transfer |
registration.py |
Device registration (DongleId acquisition) |
manage_athenad.py |
Daemon management wrapper |
8.1.13 system/updated/
OTA update system:
- Overlay filesystem approach: current system stays read-only while updates download
- casync for efficient incremental updates (content-addressable deduplication)
- Atomic swap on reboot ensures consistency
8.1.14 system/loggerd/ and system/camerad/
Native C++ services for performance-critical logging and camera capture:
| Component | Language | Purpose |
|---|---|---|
| loggerd | C++ | Records cereal messages to rlog files |
| encoderd | C++ | H.265 video encoding from camera frames |
| camerad | C++ | Camera capture via Qualcomm Spectra ISP or V4L2 |
8.1.15 common/
Shared utilities:
| File | Purpose |
|---|---|
params.py / params.cc |
Persistent key-value param store |
realtime.py |
Thread priority, core affinity, timing |
filter_simple.py |
First-order IIR filter |
transformations/ |
Coordinate transformations (ECEF, NED, camera) |
numpy_fast.py |
Optimized numpy operations |
swaglog.py |
Structured logging (cloudlog) |
8.1.16 selfdrive/ui/
Python UI framework built on pyray (raylib bindings):
| Component | Purpose |
|---|---|
GuiApplication |
Singleton managing widget stack, render loop, touch input |
Widget |
Base class for all UI elements |
layouts/main_layout.py |
Root layout (HOME, SETTINGS, ONROAD states) |
layouts/settings/ |
Settings panels (Device, Toggles, Developer, Software, Firehose) |
onroad/ |
Driving HUD (path visualization, speed, alerts) |
mici/ |
Alternative compact UI variant |
EGL rendering with shader-based polygon drawing. Multilingual support via .po translation files (12 languages).
8.2 Debug Tools — Complete Reference
openpilot ships with an extensive collection of debug and diagnostic scripts. All paths are relative to the repository root.
Core Debug Scripts (selfdrive/debug/)
| Script | Purpose |
|---|---|
selfdrive/debug/can_printer.py |
Print live CAN messages |
selfdrive/debug/dump.py |
Dump cereal messages to stdout |
selfdrive/debug/filter_log_message.py |
Filter log messages by content |
selfdrive/debug/get_fingerprint.py |
Run vehicle fingerprinting |
selfdrive/debug/live_cpu_and_temp.py |
Real-time CPU usage and temperatures |
selfdrive/debug/check_freq.py |
Verify message publication frequencies |
selfdrive/debug/uiprof.py |
UI performance profiling |
selfdrive/debug/print_docs_diff.py |
Show car docs changes |
selfdrive/debug/format_fingerprints.py |
Format fingerprint data |
selfdrive/debug/check_car_params.py |
Validate CarParams consistency |
Replay & Analysis Tools (tools/)
| Tool | Purpose |
|---|---|
tools/replay/ |
Drive replay from recorded logs (C++) |
tools/cabana/ |
CAN bus analysis tool (C++) |
tools/plotjuggler/ |
Time-series plotting for cereal messages |
tools/jotpluggler/ |
Log plotting tool (C++) |
tools/clip/ |
Create video clips from drives |
tools/profiling/ |
Performance profiling utilities |
Joystick & Remote Control
| Tool | Purpose |
|---|---|
tools/joystick/joystickd.py |
Physical joystick input daemon |
tools/joystick/web_joystick.py |
Web-based virtual joystick |
tools/bodyteleop/ |
comma body teleoperation |
Simulation
| Tool | Purpose |
|---|---|
tools/sim/bridge/ |
Simulator bridge (CARLA/MetaDrive integration) |
tools/webcam/ |
Webcam-based development mode |
Car Porting
| Tool | Purpose |
|---|---|
tools/car_porting/auto_fingerprint.py |
Automated fingerprint generation |
tools/car_porting/ |
Utilities for adding new vehicle support |
Library Utilities (tools/lib/)
| Module | Purpose |
|---|---|
tools/lib/route.py |
Route/segment management |
tools/lib/logreader.py |
Read rlog/qlog files |
tools/lib/filereader.py |
Cached file reading (local + remote) |
tools/lib/url_file.py |
URL-based file access with caching |
tools/lib/comma_car_segments.py |
Car segment data access |
8.3 Testing Framework
Test runner: pytest with custom fixtures from conftest.py
Key fixtures:
OpenpilotPrefix: Creates an isolated environment per test with separate params, shared memory, and filesystem paths. UsesOPENPILOT_PREFIXunder the hood.tici_setup_fixture: Automatically added to tests marked with@pytest.mark.TICI
Process replay (selfdrive/test/process_replay/):
The core regression testing strategy. Records reference outputs from known-good code, then replays the same inputs through modified code and compares outputs.
# Run process replay tests
pytest selfdrive/test/process_replay/test_processes.py
Tested processes in process replay:
- controlsd
- radard
- plannerd
- calibrationd
- dmonitoringd
- locationd
- paramsd
- ubloxd
- torqued
Tip
When developing a new feature that touches the control pipeline, run process replay tests before submitting a PR. These are the primary regression gate and catch most unintended behavioral changes.
Test markers:
@pytest.mark.TICI— skip on PC, only run on comma device- Standard pytest markers for slow tests, integration tests, etc.
8.4 Code Intelligence
AST-extracted patterns:
The codebase uses several consistent patterns:
- Daemon pattern: Each process module exposes a
main()function that the process manager calls - SubMaster/PubMaster: Standard message subscription/publication
- Params for config: All runtime configuration goes through the params system
- cloudlog: Structured logging via
common/swaglog.py
Cython integration: Performance-critical Python code uses Cython for compiled extensions, managed by site_scons/site_tools/cython.py.
8.5 Contributing
From CONTRIBUTING.md:
PR requirements:
- Target the
masterbranch - Pass process replay tests
- Pass CI lint and type checks
- Priority ordering: safety > stability > quality > features
Good first contributions:
- Typo fixes
- Removing unused code
- Car model ports (adding support for new vehicles)
Contributing without code:
- Bug reports with logs
- Driving feedback through comma connect
- Camera uploads for model training
- comma10k image annotations
Bounties: Available at https://github.com/orgs/commaai/projects/26/views/1
9. Integration Points
9.1 Vehicle Integration (CAN Bus)
openpilot integrates with vehicles exclusively through the CAN bus via the panda hardware adapter:
openpilot ←USB→ panda ←CAN→ Vehicle ECU
Adding a new vehicle requires:
- CAN message reverse engineering (use
tools/cabana/for analysis) - Fingerprint definition (unique set of CAN message IDs)
CarInterfaceimplementation (extendingCarInterfaceBase)CarStateparser (CAN bytes → structured state)CarController(structured commands → CAN bytes)- Safety model definition in panda firmware
- Process replay reference logs
The tools/car_porting/ directory contains utilities to assist with this process.
9.2 Comma Cloud Integration
| Service | Protocol | Purpose |
|---|---|---|
| athena | WebSocket (WSS) | Bidirectional command/control |
| API | HTTPS | Device registration, route listing |
| Upload | HTTPS | Log/video upload |
Device identity is established through the DongleId param, obtained during first-boot registration via system/athena/registration.py.
9.3 Simulator Integration
openpilot supports simulation through bridge processes:
| Simulator | Bridge |
|---|---|
| CARLA | tools/sim/bridge/carla/ |
| MetaDrive | tools/sim/bridge/metadrive/ |
The bridge translates simulator sensor data into cereal messages and sends openpilot control commands back to the simulator. Enable with SIMULATION=1.
9.4 WebRTC Streaming
system/webrtc/webrtcd.py provides a WebRTC streaming server for remote camera viewing:
- Streams camera feeds over WebRTC protocol
- Used by comma connect for remote vehicle monitoring
- Debug/development only — not started in production by default
9.5 External Tool Integration
| Tool | Integration |
|---|---|
| PlotJuggler | tools/plotjuggler/ — real-time cereal message plotting |
| Cabana | tools/cabana/ — CAN bus signal analysis and DBC editing |
| Sentry | Crash reporting via common/sentry.py |
| mkdocs | docs/ — documentation site generation |
Note
openpilot is an embedded vehicle system, not a web service. It has no REST API, no Docker deployment for end users, and no server-side scaling considerations. "Deployment" means installing on comma hardware in a supported vehicle.
Appendix A: Error Messages Reference
Key error messages organized by module for troubleshooting:
Manager Errors
manager_init failed— Initialization sequence failed; check bootlog for specificsProcess {name} not running— Process crashed or failed to start; manager will auto-restart
Controls Errors
controlsd lagging— Control loop not maintaining 100Hz; check CPU loadActuators not ready— Car interface not initialized; verify panda connectionSteer rate limited— Steering command exceeded rate limits; normal safety behaviorBrake fault— Vehicle reported brake system fault; check vehicle diagnostics
Model Errors
Model lagging— Model inference not maintaining 20Hz; thermal throttling likelyVision model timeout— No model output received within deadlineCalibration invalid— Camera calibration not converged; requires more driving
Sensor Errors
GPS unavailable— No GPS fix; check antenna and sky visibilityIMU fault— Accelerometer/gyroscope reading failureCamera frame drop— Missed camera frames; ISP or thermal issue
Communication Errors
CAN error— CAN bus communication failure; check harness connectionsPanda not found— USB connection to panda lost; reseat USB connectorAthena connection lost— WebSocket to comma cloud disconnected; network issue
Appendix B: Quick Reference Cards
Process Lifecycle
# Check running processes
selfdrive/debug/live_cpu_and_temp.py
# Check message frequencies
selfdrive/debug/check_freq.py
# Print live CAN data
selfdrive/debug/can_printer.py
# Dump any cereal message
selfdrive/debug/dump.py <service_name>
# Vehicle fingerprinting
selfdrive/debug/get_fingerprint.py
Development Shortcuts
# Run without hardware
NOBOARD=1 ./launch_openpilot.sh
# Block specific processes
BLOCK=modeld,dmonitoringd NOBOARD=1 ./launch_openpilot.sh
# Simulation mode
SIMULATION=1 NOBOARD=1 ./launch_openpilot.sh
# Enable debug logging
DEBUG=1 LOGPRINT=debug ./launch_openpilot.sh
# Record screen
RECORD=1 RECORD_OUTPUT=my_recording ./launch_openpilot.sh
Param Manipulation
# From Python
python -c "
from openpilot.common.params import Params
p = Params()
print(p.get('DongleId', encoding='utf-8'))
print(p.get_bool('IsMetric'))
p.put_bool('RecordFront', True)
"