Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/commaai/openpilot/llms.txt

Use this file to discover all available pages before exploring further.

openpilot runs as a set of independent daemons managed by system/manager/manager.py. The manager process starts and stops processes depending on ignition state, device type, and user configuration. Each process communicates exclusively through cereal pub/sub sockets — there is no direct function-call coupling between daemons. Process lifecycle conditions are defined in system/manager/process_config.py. A process flagged as only_onroad runs only while the car is started (deviceState.started == true). Processes marked always_run are active from boot. The managerState message reports whether each registered process is alive and whether it should be running; selfdrived monitors this and raises a processNotRunning event if a required process exits unexpectedly.
Source paths below are relative to the openpilot repository root.
Source: system/manager/manager.pyRuns: always (it is the parent of all other processes)Purpose: manager is the init daemon for openpilot. On startup it initialises logging, registers the device with comma’s servers, clears stale params, and then enters a 1 Hz supervision loop. In the loop it calls ensure_running to start or stop processes based on the current ignition state and publishes a managerState heartbeat. On shutdown it stops all processes and optionally calls the hardware layer to reboot, shutdown, or uninstall.
DirectionTopics
SubscribesdeviceState, carParams, pandaStates
PublishesmanagerState
Source: selfdrive/selfdrived/selfdrived.pyRuns: onroad onlyPurpose: selfdrived is the engagement state machine. It runs at 100 Hz and is responsible for deciding whether openpilot is enabled, active, or disabled. On each cycle it calls data_sample to collect the latest messages, update_events to evaluate all system health signals (camera liveness, panda safety model match, driver monitoring status, CAN validity, sensor data freshness, GPS availability, and more), and then advances the StateMachine defined in selfdrive/selfdrived/state.py. States are: disabled, preEnabled, enabled, softDisabling, and overriding. The alert manager is updated and the result is published as selfdriveState.
DirectionTopics
SubscribesdeviceState, pandaStates, peripheralState, modelV2, liveCalibration, carOutput, driverMonitoringState, longitudinalPlan, livePose, liveDelay, managerState, liveParameters, radarState, liveTorqueParameters, controlsState, carControl, driverAssistance, alertDebug, userBookmark, audioFeedback, lateralManeuverPlan, roadCameraState, driverCameraState, wideRoadCameraState, accelerometer, gyroscope, GPS location service
PublishesselfdriveState, onroadEvents
Source: selfdrive/controls/controlsd.pyRuns: onroad, car only (not active in joystick debug mode)Purpose: controlsd translates the planner’s intentions into physical actuator commands at 100 Hz. It instantiates the vehicle model (VehicleModel) and a lateral controller (PID, angle, or torque depending on CarParams.lateralTuning). On each step it reads selfdriveState.enabled and selfdriveState.active to decide whether lateral and longitudinal control loops should run, executes the PID loops, clips the desired curvature to safe limits, and assembles a CarControl message. It also populates controlsState with internal loop diagnostics (PID terms, curvature, long control state) for logging and monitoring.
DirectionTopics
SubscribesliveDelay, liveParameters, liveTorqueParameters, modelV2, selfdriveState, liveCalibration, livePose, longitudinalPlan, lateralManeuverPlan, carState, carOutput, driverMonitoringState, onroadEvents, driverAssistance
PublishescarControl, controlsState
Source: selfdrive/controls/plannerd.pyRuns: onroad only (replaced by maneuversd in longitudinal maneuver mode)Purpose: plannerd converts model predictions into a longitudinal trajectory at 20 Hz, polling on modelV2. It runs LongitudinalPlanner which uses model velocity/acceleration predictions from modelV2 and lead vehicle data from radarState to produce a target acceleration profile. It also runs LaneDepartureWarning and publishes driverAssistance with left/right lane departure flags.
DirectionTopics
SubscribescarControl, carState, controlsState, liveParameters, radarState, modelV2, selfdriveState
PublisheslongitudinalPlan, driverAssistance
Source: selfdrive/modeld/modeld.pyRuns: onroad onlyPurpose: modeld runs the supercombo driving model (a neural network compiled with tinygrad). It connects to the VisionIPC shared-memory ring buffer from camerad, receiving road camera frames (and optionally wide-road frames). On each frame it applies a calibration warp transform, feeds the frame and auxiliary inputs (desire, traffic convention) through the vision and policy sub-networks, and publishes the decoded outputs. Outputs include predicted path, lane lines, lead vehicle positions, velocity estimates, and the desired curvature/acceleration action for the current time step. The model runs at the camera frame rate (~20 Hz).
DirectionTopics
Subscribes (messaging)deviceState, carState, roadCameraState, liveCalibration, driverMonitoringState, carControl, liveDelay
Subscribes (VisionIPC)VISION_STREAM_ROAD, VISION_STREAM_WIDE_ROAD
PublishesmodelV2, drivingModelData, cameraOdometry
Source: selfdrive/modeld/dmonitoringmodeld.pyRuns: whenever the driver camera view is active (onroad or driver view enabled)Purpose: dmonitoringmodeld runs the driver monitoring neural network. It receives driver camera frames from VisionIPC, applies a calibration transform, and runs the model to estimate face orientation, eye openness, blink probability, phone usage, and whether the driver is asleep. Results are published as driverStateV2 at the camera frame rate (~20 Hz). The downstream dmonitoringd process reads this output and applies policy logic to decide distraction alert levels.
DirectionTopics
Subscribes (messaging)liveCalibration
Subscribes (VisionIPC)VISION_STREAM_DRIVER
PublishesdriverStateV2
Source: selfdrive/monitoring/dmonitoringd.pyRuns: whenever the driver camera view is activePurpose: dmonitoringd applies the driver monitoring policy on top of the raw model output from dmonitoringmodeld. It runs DriverMonitoring which accumulates distraction evidence and computes an alert level (none, one, two, three). It also detects right-hand-drive automatically and saves the result to params. The output driverMonitoringState is consumed by selfdrived to gate engagement and trigger distraction alerts.
DirectionTopics
SubscribesdriverStateV2, liveCalibration, carState, selfdriveState, modelV2
PublishesdriverMonitoringState
Source: selfdrive/pandad/pandad.py (Python wrapper), selfdrive/pandad/pandad.cc (native daemon)Runs: alwaysPurpose: pandad manages the connection to the panda hardware. The Python wrapper (pandad.py) checks the panda’s firmware signature on startup and flashes an update if needed before launching the native pandad binary. The native daemon reads raw CAN frames from the panda at 100 Hz and publishes them on the can socket. It also publishes pandaStates (ignition line status, safety model in use, fault flags) and peripheralState (fan speed, panda type). In the other direction it reads sendcan messages written by the car interface and forwards them to the panda. A separate safety setter thread applies the correct safety model from CarParams to the panda firmware when the car goes onroad.
DirectionTopics
SubscribesselfdriveState, carParams (for safety model), sendcan
Publishescan, pandaStates, peripheralState
Source: system/loggerd/loggerd.ccRuns: onroad (logging condition: car trips only, unless DisableLogging is unset for non-car devices)Purpose: loggerd subscribes to every service in the SERVICE_LIST and writes all messages to compressed log files on the device storage. Logs are segmented into approximately one-minute chunks. Camera streams are encoded separately by encoderd (H.265) and referenced via encode index messages. Completed segments are uploaded to comma’s servers by the uploader process. loggerd also monitors free disk space; selfdrived raises an outOfSpace event when free space drops below 7%.
DirectionTopics
SubscribesAll services marked should_log: true in cereal/services.py
Publishes(none — writes to disk)
Source: system/camerad/main.cc, system/camerad/cameras/Runs: whenever the driver view is active (onroad or IsDriverViewEnabled)Purpose: camerad initialises the ISP (image signal processor) and camera sensors on the comma four hardware. It captures frames from the road, wide-road, and driver cameras, applies ISP processing, and places YUV frames into shared-memory ring buffers via VisionIPC. Downstream processes (modeld, dmonitoringmodeld, encoderd) connect to these ring buffers directly without copying data through the messaging layer. camerad also publishes camera state messages (roadCameraState, wideRoadCameraState, driverCameraState) containing frame metadata such as frame ID, gain, and exposure.
DirectionTopics
SubscribesselfdriveState (for exposure adjustments)
Publishes (VisionIPC)VISION_STREAM_ROAD, VISION_STREAM_WIDE_ROAD, VISION_STREAM_DRIVER
Publishes (cereal)roadCameraState, wideRoadCameraState, driverCameraState
Source: system/sensord/sensord.pyRuns: onroad onlyPurpose: sensord reads the LSM6DS3 IMU over I²C on the comma four hardware. The accelerometer and gyroscope share a GPIO interrupt line; sensord uses an interrupt-driven loop to read samples at 104 Hz with hardware timestamps. Data is published as accelerometer and gyroscope messages. selfdrived monitors these sockets and raises a sensorDataInvalid event if either goes stale for more than 10 seconds while driving.
DirectionTopics
Subscribes(none)
Publishesaccelerometer, gyroscope
Source: system/updated/updated.pyRuns: offroad only (does not run while the car is started)Purpose: updated manages over-the-air software updates for openpilot. It checks for new releases on comma’s update server, fetches them using casync (a content-addressed sync protocol), and stages the update in an overlay filesystem at /data/safe_staging. The update is only applied on the next reboot; there is no in-place patching. updated enforces a connectivity requirement: if the device has been online for more than 27 hours of onroad time without a successful update check, openpilot will refuse to engage. updated communicates its status through the Params key-value store rather than cereal sockets.
DirectionTopics
Subscribes(uses Params, not cereal sockets)
Publishes(uses Params, not cereal sockets)

Process scheduling summary

The table below summarises the run condition and approximate cycle rate for each major process.
ProcessRun conditionFrequency
manageralways1 Hz supervision loop
selfdrivedonroad100 Hz
controlsdonroad, car only100 Hz
plannerdonroad20 Hz (polls modelV2)
modeldonroad~20 Hz (camera frame rate)
dmonitoringmodelddriver view~20 Hz (camera frame rate)
dmonitoringddriver view20 Hz (polls driverStateV2)
pandadalways100 Hz CAN I/O
loggerdonroadcontinuous
cameraddriver viewcamera hardware rate
sensordonroad104 Hz interrupt-driven
updatedoffroadperiodic, background

Build docs developers (and LLMs) love