openpilot runs as a set of independent daemons managed byDocumentation 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.
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.
manager
manager
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.| Direction | Topics |
|---|---|
| Subscribes | deviceState, carParams, pandaStates |
| Publishes | managerState |
selfdrived
selfdrived
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.| Direction | Topics |
|---|---|
| Subscribes | deviceState, 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 |
| Publishes | selfdriveState, onroadEvents |
controlsd
controlsd
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.| Direction | Topics |
|---|---|
| Subscribes | liveDelay, liveParameters, liveTorqueParameters, modelV2, selfdriveState, liveCalibration, livePose, longitudinalPlan, lateralManeuverPlan, carState, carOutput, driverMonitoringState, onroadEvents, driverAssistance |
| Publishes | carControl, controlsState |
plannerd
plannerd
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.| Direction | Topics |
|---|---|
| Subscribes | carControl, carState, controlsState, liveParameters, radarState, modelV2, selfdriveState |
| Publishes | longitudinalPlan, driverAssistance |
modeld
modeld
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).| Direction | Topics |
|---|---|
| Subscribes (messaging) | deviceState, carState, roadCameraState, liveCalibration, driverMonitoringState, carControl, liveDelay |
| Subscribes (VisionIPC) | VISION_STREAM_ROAD, VISION_STREAM_WIDE_ROAD |
| Publishes | modelV2, drivingModelData, cameraOdometry |
dmonitoringmodeld
dmonitoringmodeld
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.| Direction | Topics |
|---|---|
| Subscribes (messaging) | liveCalibration |
| Subscribes (VisionIPC) | VISION_STREAM_DRIVER |
| Publishes | driverStateV2 |
dmonitoringd
dmonitoringd
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.| Direction | Topics |
|---|---|
| Subscribes | driverStateV2, liveCalibration, carState, selfdriveState, modelV2 |
| Publishes | driverMonitoringState |
pandad
pandad
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.| Direction | Topics |
|---|---|
| Subscribes | selfdriveState, carParams (for safety model), sendcan |
| Publishes | can, pandaStates, peripheralState |
loggerd
loggerd
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%.| Direction | Topics |
|---|---|
| Subscribes | All services marked should_log: true in cereal/services.py |
| Publishes | (none — writes to disk) |
camerad
camerad
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.| Direction | Topics |
|---|---|
| Subscribes | selfdriveState (for exposure adjustments) |
| Publishes (VisionIPC) | VISION_STREAM_ROAD, VISION_STREAM_WIDE_ROAD, VISION_STREAM_DRIVER |
| Publishes (cereal) | roadCameraState, wideRoadCameraState, driverCameraState |
sensord
sensord
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.| Direction | Topics |
|---|---|
| Subscribes | (none) |
| Publishes | accelerometer, gyroscope |
updated
updated
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.| Direction | Topics |
|---|---|
| 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.| Process | Run condition | Frequency |
|---|---|---|
| manager | always | 1 Hz supervision loop |
| selfdrived | onroad | 100 Hz |
| controlsd | onroad, car only | 100 Hz |
| plannerd | onroad | 20 Hz (polls modelV2) |
| modeld | onroad | ~20 Hz (camera frame rate) |
| dmonitoringmodeld | driver view | ~20 Hz (camera frame rate) |
| dmonitoringd | driver view | 20 Hz (polls driverStateV2) |
| pandad | always | 100 Hz CAN I/O |
| loggerd | onroad | continuous |
| camerad | driver view | camera hardware rate |
| sensord | onroad | 104 Hz interrupt-driven |
| updated | offroad | periodic, background |
