From cdf6338388c4f2e054de0e76eb1401a2993360ce Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 3 May 2022 23:30:35 -0700 Subject: [PATCH] manager: start process by callback (#24417) --- selfdrive/manager/manager.py | 7 +++---- selfdrive/manager/process.py | 22 ++++++++++------------ selfdrive/manager/process_config.py | 19 ++++++++++++++----- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/selfdrive/manager/manager.py b/selfdrive/manager/manager.py index 1934da6701..cd7817fa97 100755 --- a/selfdrive/manager/manager.py +++ b/selfdrive/manager/manager.py @@ -128,17 +128,16 @@ def manager_thread() -> None: ignore.append("pandad") ignore += [x for x in os.getenv("BLOCK", "").split(",") if len(x) > 0] - ensure_running(managed_processes.values(), started=False, not_run=ignore) - sm = messaging.SubMaster(['deviceState', 'carParams'], poll=['deviceState']) pm = messaging.PubMaster(['managerState']) + ensure_running(managed_processes.values(), False, params=params, CP=sm['carParams'], not_run=ignore) + while True: sm.update() started = sm['deviceState'].started - driverview = params.get_bool("IsDriverViewEnabled") - ensure_running(managed_processes.values(), started=started, driverview=driverview, notcar=sm['carParams'].notCar, not_run=ignore) + ensure_running(managed_processes.values(), started, params=params, CP=sm['carParams'], not_run=ignore) running = ' '.join("%s%s\u001b[0m" % ("\u001b[32m" if p.proc.is_alive() else "\u001b[31m", p.name) for p in managed_processes.values() if p.proc) diff --git a/selfdrive/manager/process.py b/selfdrive/manager/process.py index 8bb160961f..e2bb41c217 100644 --- a/selfdrive/manager/process.py +++ b/selfdrive/manager/process.py @@ -4,7 +4,7 @@ import signal import struct import time import subprocess -from typing import Optional, List, ValuesView +from typing import Optional, Callable, List, ValuesView from abc import ABC, abstractmethod from multiprocessing import Process @@ -12,6 +12,7 @@ from setproctitle import setproctitle # pylint: disable=no-name-in-module import cereal.messaging as messaging import selfdrive.sentry as sentry +from cereal import car from common.basedir import BASEDIR from common.params import Params from common.realtime import sec_since_boot @@ -71,8 +72,7 @@ class ManagerProcess(ABC): sigkill = False onroad = True offroad = False - driverview = False - notcar = False + callback: Optional[Callable[[bool, Params, car.CarParams], bool]] = None proc: Optional[Process] = None enabled = True name = "" @@ -184,15 +184,14 @@ class ManagerProcess(ABC): class NativeProcess(ManagerProcess): - def __init__(self, name, cwd, cmdline, enabled=True, onroad=True, offroad=False, driverview=False, notcar=False, unkillable=False, sigkill=False, watchdog_max_dt=None): + def __init__(self, name, cwd, cmdline, enabled=True, onroad=True, offroad=False, callback=None, unkillable=False, sigkill=False, watchdog_max_dt=None): self.name = name self.cwd = cwd self.cmdline = cmdline self.enabled = enabled self.onroad = onroad self.offroad = offroad - self.driverview = driverview - self.notcar = notcar + self.callback = callback self.unkillable = unkillable self.sigkill = sigkill self.watchdog_max_dt = watchdog_max_dt @@ -217,14 +216,13 @@ class NativeProcess(ManagerProcess): class PythonProcess(ManagerProcess): - def __init__(self, name, module, enabled=True, onroad=True, offroad=False, driverview=False, notcar=False, unkillable=False, sigkill=False, watchdog_max_dt=None): + def __init__(self, name, module, enabled=True, onroad=True, offroad=False, callback=None, unkillable=False, sigkill=False, watchdog_max_dt=None): self.name = name self.module = module self.enabled = enabled self.onroad = onroad self.offroad = offroad - self.driverview = driverview - self.notcar = notcar + self.callback = callback self.unkillable = unkillable self.sigkill = sigkill self.watchdog_max_dt = watchdog_max_dt @@ -291,7 +289,7 @@ class DaemonProcess(ManagerProcess): pass -def ensure_running(procs: ValuesView[ManagerProcess], started: bool, driverview: bool=False, notcar: bool=False, +def ensure_running(procs: ValuesView[ManagerProcess], started: bool, params=None, CP: car.CarParams=None, not_run: Optional[List[str]]=None) -> None: if not_run is None: not_run = [] @@ -301,9 +299,9 @@ def ensure_running(procs: ValuesView[ManagerProcess], started: bool, driverview: run = any(( p.offroad and not started, p.onroad and started, - p.driverview and driverview, - p.notcar and notcar, )) + if p.callback is not None and None not in (params, CP): + run = run or p.callback(started, params, CP) # Conditions that block a process from starting run = run and not any(( diff --git a/selfdrive/manager/process_config.py b/selfdrive/manager/process_config.py index 2e2747fecc..0979c67d70 100644 --- a/selfdrive/manager/process_config.py +++ b/selfdrive/manager/process_config.py @@ -1,16 +1,25 @@ import os +from cereal import car +from common.params import Params from selfdrive.hardware import TICI, PC from selfdrive.manager.process import PythonProcess, NativeProcess, DaemonProcess WEBCAM = os.getenv("USE_WEBCAM") is not None +def driverview(started: bool, params: Params, CP: car.CarParams) -> bool: + return params.get_bool("IsDriverViewEnabled") + +def notcar(started: bool, params: Params, CP: car.CarParams) -> bool: + return CP.notCar + + procs = [ DaemonProcess("manage_athenad", "selfdrive.athena.manage_athenad", "AthenadPid"), # due to qualcomm kernel bugs SIGKILLing camerad sometimes causes page table corruption - NativeProcess("camerad", "selfdrive/camerad", ["./camerad"], unkillable=True, driverview=True), + NativeProcess("camerad", "selfdrive/camerad", ["./camerad"], unkillable=True, callback=driverview), NativeProcess("clocksd", "selfdrive/clocksd", ["./clocksd"]), - NativeProcess("dmonitoringmodeld", "selfdrive/modeld", ["./dmonitoringmodeld"], enabled=(not PC or WEBCAM), driverview=True), + NativeProcess("dmonitoringmodeld", "selfdrive/modeld", ["./dmonitoringmodeld"], enabled=(not PC or WEBCAM), callback=driverview), NativeProcess("logcatd", "selfdrive/logcatd", ["./logcatd"]), NativeProcess("loggerd", "selfdrive/loggerd", ["./loggerd"]), NativeProcess("modeld", "selfdrive/modeld", ["./modeld"]), @@ -25,7 +34,7 @@ procs = [ PythonProcess("calibrationd", "selfdrive.locationd.calibrationd"), PythonProcess("controlsd", "selfdrive.controls.controlsd"), PythonProcess("deleter", "selfdrive.loggerd.deleter", offroad=True), - PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", enabled=(not PC or WEBCAM), driverview=True), + PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", enabled=(not PC or WEBCAM), callback=driverview), PythonProcess("logmessaged", "selfdrive.logmessaged", offroad=True), PythonProcess("pandad", "selfdrive.boardd.pandad", offroad=True), PythonProcess("paramsd", "selfdrive.locationd.paramsd"), @@ -38,8 +47,8 @@ procs = [ PythonProcess("uploader", "selfdrive.loggerd.uploader", offroad=True), PythonProcess("statsd", "selfdrive.statsd", offroad=True), - NativeProcess("bridge", "cereal/messaging", ["./bridge"], onroad=False, notcar=True), - PythonProcess("webjoystick", "tools.joystick.web", onroad=False, notcar=True), + NativeProcess("bridge", "cereal/messaging", ["./bridge"], onroad=False, callback=notcar), + PythonProcess("webjoystick", "tools.joystick.web", onroad=False, callback=notcar), # Experimental PythonProcess("rawgpsd", "selfdrive.sensord.rawgps.rawgpsd", enabled=os.path.isfile("/persist/comma/use-quectel-rawgps")),