How the OpenPilot Manager Orchestrates and Supervises All Self-Driving Services
The openpilot manager acts as a central watchdog that initializes the system, evaluates real-time vehicle state, and uses the ensure_running() method to start, restart, or gracefully stop services, publishing health statistics via the managerState message.
The openpilot manager serves as the orchestration backbone for the commaai/openpilot autonomous driving stack. Located in system/manager/manager.py, this Python process replaces traditional init systems by managing the complete lifecycle of every service—from vision algorithms to CAN bus interpreters—ensuring the correct subset of processes runs based on ignition state, user settings, and vehicle configuration.
The Four Phases of Manager Operation
The manager's lifecycle consists of four distinct phases implemented across manager_init(), manager_thread(), and manager_cleanup().
Phase 1: System Initialization
During startup, manager_init() in system/manager/manager.py (lines 25–94) performs critical system setup. It clears transient parameters, creates the shared-memory directory at /dev/shm, registers the device dongle, configures logging, and pre-loads all process classes. This pre-loading ensures the Python interpreter knows about every service before any subprocess actually starts, preventing import delays during runtime.
Phase 2: Real-Time Supervision Loop
The manager_thread() function (lines 107–152) implements the main supervision loop. It subscribes to deviceState, carParams, and pandaStates via a SubMaster, then determines which processes should run based on the vehicle's started state, ignition status, and environment variables. Each iteration calls ensure_running() on the managed_processes dictionary to align the actual system state with the desired state.
Phase 3: Process Configuration
Every service is defined in system/manager/process_config.py (lines 64–118) as a subclass of Process—either PythonProcess, NativeProcess, or DaemonProcess (implemented in system/manager/process.py). Each definition specifies the module or binary to launch, a run-condition predicate, and behavioral flags like restart_if_crash and enabled. These definitions are collected into the managed_processes dictionary at import time.
Phase 4: Graceful Shutdown
When the system receives a shutdown command—triggered by the DoReboot, DoShutdown, or DoUninstall parameters—manager_cleanup() (lines 95–104) sends stop signals to every process, waits for termination, and invokes hardware-specific shutdown helpers.
Internal Supervision Mechanics
The manager's core supervision logic evaluates run-conditions and manages OS process states through three key mechanisms.
Run-Condition Evaluation
Each Process subclass receives three arguments in its predicate: started, params, and CP (car parameters). Built-in conditions like only_onroad or driverview return boolean values indicating whether the service should be active. For example, a process might only run when started is True and a specific feature flag is enabled.
Process Lifecycle Management with ensure_running()
The ensure_running() function in system/manager/process.py iterates over managed_processes and checks proc.should_run(). It handles three transitions:
- Start: Launches processes that should run but aren't alive
- Restart: Recovers processes that crashed when
restart_if_crash=True - Stop: Terminates processes that are alive but no longer meet their run-condition
Health Reporting via managerState
Each loop constructs a managerState protobuf containing processes = [p.get_process_state_msg() ...] with fields for name, alive status, CPU percentage, and memory usage. This message publishes to the managerState channel, allowing the UI and monitoring tools to display real-time service health.
System Entry Point
The operating system starts the manager through the main guard, which flushes stdout buffering for immediate logging:
# In system/manager/manager.py
if __name__ == "__main__":
unblock_stdout() # Flush stdout buffering so log output is immediate
try:
main() # manager_init → manager_thread → cleanup
except KeyboardInterrupt:
print("got CTRL‑C, exiting")
Implementing Custom Services
To add a new diagnostic service, define a PythonProcess in process_config.py:
# In system/manager/process_config.py
from openpilot.system.manager.process import PythonProcess
def my_diag_condition(started, params, CP):
# Run only when on-road and feature flag is enabled
return started and params.get_bool("EnableMyDiag")
procs.append(
PythonProcess(
name="mydiagnosticd",
entry="my_package.my_diagnostic_daemon",
run_if=my_diag_condition,
enabled=True,
restart_if_crash=True,
)
)
The manager automatically detects the new service because managed_processes rebuilds from the procs list at import time.
Monitoring Manager State
External components can query service health by subscribing to the manager's output:
import cereal.messaging as messaging
sub = messaging.SubMaster(['managerState'])
while True:
sub.update()
state = sub['managerState']
for proc in state.processes:
print(f"{proc.name}: alive={proc.alive}, cpu={proc.cpuPerc}%")
Summary
- The openpilot manager in
system/manager/manager.pyserves as the central process orchestrator, replacing traditional init systems - It operates in four phases: initialization (lines 25–94), supervision loop (lines 107–152), process configuration, and shutdown cleanup (lines 95–104)
- Services define run-conditions that evaluate
started,params, andCPto determine activation - The
ensure_running()method insystem/manager/process.pyaligns the actual process set with desired states by starting, restarting, or stopping services - Health data publishes via
managerStatemessages for real-time monitoring
Frequently Asked Questions
What is the difference between PythonProcess and NativeProcess?
PythonProcess launches Python modules by importing the specified entry string and executing the module, while NativeProcess executes compiled binaries using a command-line array. Both inherit from the base Process class in system/manager/process.py and support identical run-condition predicates and restart behaviors.
How does the manager decide which services to start?
The manager evaluates the should_run() predicate for each process, which receives the current started state, persistent params, and carParams. If the predicate returns True, ensure_running() spawns the process; if False and the process is running, it sends a termination signal. This dynamic evaluation allows services like the driver monitoring camera to start only when specific vehicle conditions are met.
What happens when a service crashes?
If a process exits unexpectedly and its definition includes restart_if_crash=True, the next iteration of manager_thread() detects the non-zero exit code through proc.get_process_state_msg() and automatically respawns the service. Processes with restart_if_crash=False remain dead until the run-condition changes or the manager restarts.
Can I disable specific openpilot services?
Yes. Set the enabled=False flag in the process definition within process_config.py, or modify the run-condition to return False for specific vehicle states. During development, you can also set environment variables that the run-condition checks to selectively disable services without modifying code.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →