mirror of
https://github.com/dragonpilot/dragonpilot.git
synced 2026-08-23 09:13:47 +08:00
openpilot v0.9.5 release
date: 2023-11-17T23:53:40
master commit: d3aad9ca46
This commit is contained in:
@@ -8,17 +8,14 @@ from typing import Optional, Callable, List, ValuesView
|
||||
from abc import ABC, abstractmethod
|
||||
from multiprocessing import Process
|
||||
|
||||
from setproctitle import setproctitle # pylint: disable=no-name-in-module
|
||||
from setproctitle import setproctitle
|
||||
|
||||
from cereal import car, log
|
||||
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
|
||||
from system.swaglog import cloudlog
|
||||
from system.hardware import HARDWARE
|
||||
from cereal import log
|
||||
import openpilot.selfdrive.sentry as sentry
|
||||
from openpilot.common.basedir import BASEDIR
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.system.swaglog import cloudlog
|
||||
|
||||
WATCHDOG_FN = "/dev/shm/wd_"
|
||||
ENABLE_WATCHDOG = os.getenv("NO_WATCHDOG") is None
|
||||
@@ -40,7 +37,7 @@ def launcher(proc: str, name: str) -> None:
|
||||
sentry.set_tag("daemon", name)
|
||||
|
||||
# exec the process
|
||||
getattr(mod, 'main')()
|
||||
mod.main()
|
||||
except KeyboardInterrupt:
|
||||
cloudlog.warning(f"child {proc} got SIGINT")
|
||||
except Exception:
|
||||
@@ -67,12 +64,9 @@ def join_process(process: Process, timeout: float) -> None:
|
||||
|
||||
|
||||
class ManagerProcess(ABC):
|
||||
unkillable = False
|
||||
daemon = False
|
||||
sigkill = False
|
||||
onroad = True
|
||||
offroad = False
|
||||
callback: Optional[Callable[[bool, Params, car.CarParams], bool]] = None
|
||||
should_run: Callable[[bool, Params, car.CarParams], bool]
|
||||
proc: Optional[Process] = None
|
||||
enabled = True
|
||||
name = ""
|
||||
@@ -102,11 +96,11 @@ class ManagerProcess(ABC):
|
||||
fn = WATCHDOG_FN + str(self.proc.pid)
|
||||
with open(fn, "rb") as f:
|
||||
# TODO: why can't pylint find struct.unpack?
|
||||
self.last_watchdog_time = struct.unpack('Q', f.read())[0] # pylint: disable=no-member
|
||||
self.last_watchdog_time = struct.unpack('Q', f.read())[0]
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
dt = sec_since_boot() - self.last_watchdog_time / 1e9
|
||||
dt = time.monotonic() - self.last_watchdog_time / 1e9
|
||||
|
||||
if dt > self.watchdog_max_dt:
|
||||
if self.watchdog_seen and ENABLE_WATCHDOG:
|
||||
@@ -132,22 +126,11 @@ class ManagerProcess(ABC):
|
||||
|
||||
join_process(self.proc, 5)
|
||||
|
||||
# If process failed to die send SIGKILL or reboot
|
||||
# If process failed to die send SIGKILL
|
||||
if self.proc.exitcode is None and retry:
|
||||
if self.unkillable:
|
||||
cloudlog.critical(f"unkillable process {self.name} failed to exit! rebooting in 15 if it doesn't die")
|
||||
join_process(self.proc, 15)
|
||||
|
||||
if self.proc.exitcode is None:
|
||||
cloudlog.critical(f"unkillable process {self.name} failed to die!")
|
||||
os.system("date >> /data/unkillable_reboot")
|
||||
os.sync()
|
||||
HARDWARE.reboot()
|
||||
raise RuntimeError
|
||||
else:
|
||||
cloudlog.info(f"killing {self.name} with SIGKILL")
|
||||
self.signal(signal.SIGKILL)
|
||||
self.proc.join()
|
||||
cloudlog.info(f"killing {self.name} with SIGKILL")
|
||||
self.signal(signal.SIGKILL)
|
||||
self.proc.join()
|
||||
|
||||
ret = self.proc.exitcode
|
||||
cloudlog.info(f"{self.name} is dead with {ret}")
|
||||
@@ -185,17 +168,15 @@ class ManagerProcess(ABC):
|
||||
|
||||
|
||||
class NativeProcess(ManagerProcess):
|
||||
def __init__(self, name, cwd, cmdline, enabled=True, onroad=True, offroad=False, callback=None, unkillable=False, sigkill=False, watchdog_max_dt=None):
|
||||
def __init__(self, name, cwd, cmdline, should_run, enabled=True, sigkill=False, watchdog_max_dt=None):
|
||||
self.name = name
|
||||
self.cwd = cwd
|
||||
self.cmdline = cmdline
|
||||
self.should_run = should_run
|
||||
self.enabled = enabled
|
||||
self.onroad = onroad
|
||||
self.offroad = offroad
|
||||
self.callback = callback
|
||||
self.unkillable = unkillable
|
||||
self.sigkill = sigkill
|
||||
self.watchdog_max_dt = watchdog_max_dt
|
||||
self.launcher = nativelauncher
|
||||
|
||||
def prepare(self) -> None:
|
||||
pass
|
||||
@@ -210,23 +191,21 @@ class NativeProcess(ManagerProcess):
|
||||
|
||||
cwd = os.path.join(BASEDIR, self.cwd)
|
||||
cloudlog.info(f"starting process {self.name}")
|
||||
self.proc = Process(name=self.name, target=nativelauncher, args=(self.cmdline, cwd, self.name))
|
||||
self.proc = Process(name=self.name, target=self.launcher, args=(self.cmdline, cwd, self.name))
|
||||
self.proc.start()
|
||||
self.watchdog_seen = False
|
||||
self.shutting_down = False
|
||||
|
||||
|
||||
class PythonProcess(ManagerProcess):
|
||||
def __init__(self, name, module, enabled=True, onroad=True, offroad=False, callback=None, unkillable=False, sigkill=False, watchdog_max_dt=None):
|
||||
def __init__(self, name, module, should_run, enabled=True, sigkill=False, watchdog_max_dt=None):
|
||||
self.name = name
|
||||
self.module = module
|
||||
self.should_run = should_run
|
||||
self.enabled = enabled
|
||||
self.onroad = onroad
|
||||
self.offroad = offroad
|
||||
self.callback = callback
|
||||
self.unkillable = unkillable
|
||||
self.sigkill = sigkill
|
||||
self.watchdog_max_dt = watchdog_max_dt
|
||||
self.launcher = launcher
|
||||
|
||||
def prepare(self) -> None:
|
||||
if self.enabled:
|
||||
@@ -242,7 +221,7 @@ class PythonProcess(ManagerProcess):
|
||||
return
|
||||
|
||||
cloudlog.info(f"starting python {self.module}")
|
||||
self.proc = Process(name=self.name, target=launcher, args=(self.module, self.name))
|
||||
self.proc = Process(name=self.name, target=self.launcher, args=(self.module, self.name))
|
||||
self.proc.start()
|
||||
self.watchdog_seen = False
|
||||
self.shutting_down = False
|
||||
@@ -256,10 +235,12 @@ class DaemonProcess(ManagerProcess):
|
||||
self.module = module
|
||||
self.param_name = param_name
|
||||
self.enabled = enabled
|
||||
self.onroad = True
|
||||
self.offroad = True
|
||||
self.params = None
|
||||
|
||||
@staticmethod
|
||||
def should_run(started, params, CP):
|
||||
return True
|
||||
|
||||
def prepare(self) -> None:
|
||||
pass
|
||||
|
||||
@@ -280,7 +261,7 @@ class DaemonProcess(ManagerProcess):
|
||||
pass
|
||||
|
||||
cloudlog.info(f"starting daemon {self.name}")
|
||||
proc = subprocess.Popen(['python', '-m', self.module], # pylint: disable=subprocess-popen-preexec-fn
|
||||
proc = subprocess.Popen(['python', '-m', self.module],
|
||||
stdin=open('/dev/null'),
|
||||
stdout=open('/dev/null', 'w'),
|
||||
stderr=open('/dev/null', 'w'),
|
||||
@@ -299,21 +280,7 @@ def ensure_running(procs: ValuesView[ManagerProcess], started: bool, params=None
|
||||
|
||||
running = []
|
||||
for p in procs:
|
||||
# Conditions that make a process run
|
||||
run = any((
|
||||
p.offroad and not started,
|
||||
p.onroad and started,
|
||||
))
|
||||
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((
|
||||
not p.enabled,
|
||||
p.name in not_run,
|
||||
))
|
||||
|
||||
if run:
|
||||
if p.enabled and p.name not in not_run and p.should_run(started, params, CP):
|
||||
p.start()
|
||||
running.append(p)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user