mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-08 23:22:04 +08:00
244 lines
11 KiB
Python
244 lines
11 KiB
Python
import os
|
|
import operator
|
|
import platform
|
|
import sys
|
|
|
|
from types import SimpleNamespace
|
|
|
|
from cereal import car
|
|
from openpilot.common.params import Params
|
|
from openpilot.system.hardware import HARDWARE, PC, TICI
|
|
from openpilot.system.manager.process import PythonProcess, NativeProcess, DaemonProcess
|
|
|
|
WEBCAM = os.getenv("USE_WEBCAM") is not None
|
|
UI_WATCHDOG_MAX_DT = int(os.getenv("UI_WATCHDOG_MAX_DT", "10"))
|
|
|
|
def driverview(started: bool, params: Params, CP: car.CarParams, starpilot_toggles: SimpleNamespace) -> bool:
|
|
return started or params.get_bool("IsDriverViewEnabled")
|
|
|
|
def notcar(started: bool, params: Params, CP: car.CarParams, starpilot_toggles: SimpleNamespace) -> bool:
|
|
return started and CP.notCar
|
|
|
|
def iscar(started: bool, params: Params, CP: car.CarParams, starpilot_toggles: SimpleNamespace) -> bool:
|
|
return started and not CP.notCar
|
|
|
|
def logging(started: bool, params: Params, CP: car.CarParams, starpilot_toggles: SimpleNamespace) -> bool:
|
|
run = (not CP.notCar) or not params.get_bool("DisableLogging")
|
|
return started and run
|
|
|
|
def ublox_available() -> bool:
|
|
return os.path.exists('/dev/ttyHS0') and not os.path.exists('/persist/comma/use-quectel-gps')
|
|
|
|
def ublox(started: bool, params: Params, CP: car.CarParams, starpilot_toggles: SimpleNamespace) -> bool:
|
|
use_ublox = ublox_available()
|
|
if use_ublox != params.get_bool("UbloxAvailable"):
|
|
params.put_bool("UbloxAvailable", use_ublox)
|
|
return started and use_ublox
|
|
|
|
def joystick(started: bool, params: Params, CP: car.CarParams, starpilot_toggles: SimpleNamespace) -> bool:
|
|
return started and params.get_bool("JoystickDebugMode")
|
|
|
|
def not_joystick(started: bool, params: Params, CP: car.CarParams, starpilot_toggles: SimpleNamespace) -> bool:
|
|
return started and not params.get_bool("JoystickDebugMode")
|
|
|
|
def long_maneuver(started: bool, params: Params, CP: car.CarParams, starpilot_toggles: SimpleNamespace) -> bool:
|
|
return started and params.get_bool("LongitudinalManeuverMode") and not params.get_bool("LateralManeuverMode")
|
|
|
|
def lat_maneuver(started: bool, params: Params, CP: car.CarParams, starpilot_toggles: SimpleNamespace) -> bool:
|
|
return started and params.get_bool("LateralManeuverMode") and not params.get_bool("LongitudinalManeuverMode")
|
|
|
|
def not_long_maneuver(started: bool, params: Params, CP: car.CarParams, starpilot_toggles: SimpleNamespace) -> bool:
|
|
return started and not params.get_bool("LongitudinalManeuverMode")
|
|
|
|
def qcomgps(started: bool, params: Params, CP: car.CarParams, starpilot_toggles: SimpleNamespace) -> bool:
|
|
return started and not ublox_available()
|
|
|
|
def always_run(started: bool, params: Params, CP: car.CarParams, starpilot_toggles: SimpleNamespace) -> bool:
|
|
return True
|
|
|
|
def only_onroad(started: bool, params: Params, CP: car.CarParams, starpilot_toggles: SimpleNamespace) -> bool:
|
|
return started
|
|
|
|
def only_offroad(started: bool, params: Params, CP: car.CarParams, starpilot_toggles: SimpleNamespace) -> bool:
|
|
return not started
|
|
|
|
def or_(*fns):
|
|
return lambda *args: operator.or_(*(fn(*args) for fn in fns))
|
|
|
|
def and_(*fns):
|
|
return lambda *args: operator.and_(*(fn(*args) for fn in fns))
|
|
|
|
# StarPilot variables
|
|
def allow_logging(started: bool, params: Params, CP: car.CarParams, starpilot_toggles: SimpleNamespace) -> bool:
|
|
return not starpilot_toggles.no_logging
|
|
|
|
def allow_uploads(started: bool, params: Params, CP: car.CarParams, starpilot_toggles: SimpleNamespace) -> bool:
|
|
return params.get_bool("AlwaysAllowUploads") or not starpilot_toggles.no_uploads or starpilot_toggles.no_onroad_uploads
|
|
|
|
def run_speed_limit_filler(started: bool, params: Params, CP: car.CarParams, starpilot_toggles: SimpleNamespace) -> bool:
|
|
return starpilot_toggles.speed_limit_filler
|
|
|
|
def run_speed_limit_vision(started: bool, params: Params, CP: car.CarParams, starpilot_toggles: SimpleNamespace) -> bool:
|
|
return starpilot_toggles.vision_speed_limit_detection
|
|
|
|
def run_navigationd(started: bool, params: Params, CP: car.CarParams, starpilot_toggles: SimpleNamespace) -> bool:
|
|
return started and params.get("NavDestination") is not None
|
|
|
|
|
|
class BigDeviceUIProcess:
|
|
name = "ui"
|
|
enabled = True
|
|
sigkill = False
|
|
daemon = False
|
|
|
|
def __init__(self, should_run, watchdog_max_dt=None):
|
|
self.should_run_fn = should_run
|
|
self.watchdog_max_dt = watchdog_max_dt
|
|
self._started = False
|
|
self._params = None
|
|
self._active_process = None
|
|
self._qt_process = NativeProcess("ui", "selfdrive/ui", ["./ui"], should_run, watchdog_max_dt=watchdog_max_dt)
|
|
self._raylib_process = NativeProcess(
|
|
"ui",
|
|
".",
|
|
["/usr/bin/env", "BIG=1", sys.executable, "-m", "openpilot.selfdrive.ui.ui"],
|
|
should_run,
|
|
watchdog_max_dt=watchdog_max_dt,
|
|
)
|
|
|
|
@property
|
|
def proc(self):
|
|
return self._active_process.proc if self._active_process is not None else None
|
|
|
|
@property
|
|
def shutting_down(self):
|
|
return self._active_process.shutting_down if self._active_process is not None else False
|
|
|
|
def prepare(self) -> None:
|
|
self._qt_process.prepare()
|
|
|
|
def should_run(self, started: bool, params: Params, CP: car.CarParams, starpilot_toggles: SimpleNamespace) -> bool:
|
|
self._started = started
|
|
self._params = params
|
|
return self.should_run_fn(started, params, CP, starpilot_toggles)
|
|
|
|
def _desired_process(self):
|
|
return self._raylib_process if self._params is not None and self._params.get_bool("TryRaylibUI") else self._qt_process
|
|
|
|
def start(self) -> None:
|
|
desired_process = self._desired_process()
|
|
|
|
# Never swap UI implementations mid-drive. Direct param writes while onroad
|
|
# take effect the next time the device is offroad.
|
|
if self._started and self._active_process is not None and self._active_process is not desired_process:
|
|
desired_process = self._active_process
|
|
|
|
if self._active_process is not None and self._active_process is not desired_process:
|
|
self._active_process.stop()
|
|
|
|
for process in (self._qt_process, self._raylib_process):
|
|
if process is not desired_process and process.proc is not None:
|
|
process.stop()
|
|
|
|
self._active_process = desired_process
|
|
self._active_process.start()
|
|
|
|
def stop(self, retry: bool = True, block: bool = True, sig=None):
|
|
ret = None
|
|
for process in (self._qt_process, self._raylib_process):
|
|
process_ret = process.stop(retry=retry, block=block, sig=sig)
|
|
if process is self._active_process:
|
|
ret = process_ret
|
|
return ret
|
|
|
|
def restart(self) -> None:
|
|
self.stop()
|
|
self.start()
|
|
|
|
def check_watchdog(self, started: bool) -> None:
|
|
if self._active_process is not None:
|
|
self._active_process.check_watchdog(started)
|
|
|
|
def get_process_state_msg(self):
|
|
process = self._active_process or self._qt_process
|
|
return process.get_process_state_msg()
|
|
|
|
|
|
procs = [
|
|
DaemonProcess("manage_athenad", "system.athena.manage_athenad", "AthenadPid"),
|
|
|
|
NativeProcess("loggerd", "system/loggerd", ["./loggerd"], and_(allow_logging, logging)),
|
|
NativeProcess("encoderd", "system/loggerd", ["./encoderd"], and_(allow_logging, only_onroad)),
|
|
NativeProcess("stream_encoderd", "system/loggerd", ["./encoderd", "--stream"], notcar),
|
|
PythonProcess("logmessaged", "system.logmessaged", always_run),
|
|
|
|
NativeProcess("camerad", "system/camerad", ["./camerad"], driverview, enabled=not WEBCAM),
|
|
PythonProcess("webcamerad", "tools.webcam.camerad", driverview, enabled=WEBCAM),
|
|
PythonProcess("proclogd", "system.proclogd", and_(allow_logging, only_onroad), enabled=platform.system() != "Darwin"),
|
|
PythonProcess("journald", "system.journald", and_(allow_logging, only_onroad), platform.system() != "Darwin"),
|
|
PythonProcess("micd", "system.micd", iscar),
|
|
PythonProcess("timed", "system.timed", always_run, enabled=not PC),
|
|
|
|
PythonProcess("modeld", "selfdrive.modeld.modeld", only_onroad),
|
|
PythonProcess("dmonitoringmodeld", "selfdrive.modeld.dmonitoringmodeld", driverview, enabled=(WEBCAM or not PC)),
|
|
|
|
PythonProcess("sensord", "system.sensord.sensord", only_onroad, enabled=not PC),
|
|
PythonProcess("soundd", "selfdrive.ui.soundd", driverview),
|
|
PythonProcess("locationd", "selfdrive.locationd.locationd", only_onroad),
|
|
NativeProcess("_pandad", "selfdrive/pandad", ["./pandad"], always_run, enabled=False),
|
|
PythonProcess("calibrationd", "selfdrive.locationd.calibrationd", only_onroad),
|
|
PythonProcess("torqued", "selfdrive.locationd.torqued", only_onroad),
|
|
PythonProcess("controlsd", "selfdrive.controls.controlsd", and_(not_joystick, iscar)),
|
|
PythonProcess("joystickd", "tools.joystick.joystickd", or_(joystick, notcar)),
|
|
PythonProcess("selfdrived", "selfdrive.selfdrived.selfdrived", only_onroad),
|
|
PythonProcess("card", "selfdrive.car.card", only_onroad),
|
|
PythonProcess("deleter", "system.loggerd.deleter", always_run),
|
|
PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", driverview, enabled=(WEBCAM or not PC)),
|
|
PythonProcess("qcomgpsd", "system.qcomgpsd.qcomgpsd", qcomgps, enabled=TICI),
|
|
PythonProcess("pandad", "selfdrive.pandad.pandad", always_run),
|
|
PythonProcess("paramsd", "selfdrive.locationd.paramsd", only_onroad),
|
|
PythonProcess("lagd", "selfdrive.locationd.lagd", only_onroad),
|
|
PythonProcess("ubloxd", "system.ubloxd.ubloxd", ublox, enabled=TICI),
|
|
PythonProcess("pigeond", "system.ubloxd.pigeond", ublox, enabled=TICI),
|
|
PythonProcess("plannerd", "selfdrive.controls.plannerd", not_long_maneuver),
|
|
PythonProcess("maneuversd", "tools.longitudinal_maneuvers.maneuversd", long_maneuver),
|
|
PythonProcess("lateral_maneuversd", "tools.lateral_maneuvers.lateral_maneuversd", lat_maneuver),
|
|
PythonProcess("radard", "selfdrive.controls.radard", only_onroad),
|
|
PythonProcess("hardwared", "system.hardware.hardwared", always_run),
|
|
PythonProcess("tombstoned", "system.tombstoned", always_run, enabled=not PC),
|
|
PythonProcess("updated", "system.updated.updated", always_run, enabled=not PC),
|
|
PythonProcess("uploader", "system.loggerd.uploader", allow_uploads),
|
|
PythonProcess("statsd", "system.statsd", always_run),
|
|
PythonProcess("feedbackd", "selfdrive.ui.feedback.feedbackd", only_onroad),
|
|
|
|
# debug procs
|
|
NativeProcess("bridge", "cereal/messaging", ["./bridge"], notcar),
|
|
PythonProcess("webrtcd", "system.webrtc.webrtcd", notcar),
|
|
PythonProcess("webjoystick", "tools.bodyteleop.web", notcar),
|
|
PythonProcess("joystick", "tools.joystick.joystick_control", and_(joystick, iscar)),
|
|
]
|
|
|
|
# StarPilot variables
|
|
procs += [
|
|
PythonProcess("the_galaxy", "starpilot.system.the_galaxy.the_galaxy", always_run, nice=19),
|
|
PythonProcess("galaxy", "starpilot.system.galaxy.galaxy", always_run, nice=19),
|
|
]
|
|
|
|
device_type = HARDWARE.get_device_type()
|
|
if device_type in ("tici", "tizi"):
|
|
procs.append(BigDeviceUIProcess(always_run, watchdog_max_dt=UI_WATCHDOG_MAX_DT))
|
|
else:
|
|
# C4 (mici) already runs the Python raylib UI path; TryRaylibUI must not affect it.
|
|
procs.append(PythonProcess("ui", "selfdrive.ui.ui", always_run, watchdog_max_dt=UI_WATCHDOG_MAX_DT))
|
|
|
|
procs += [
|
|
PythonProcess("device_syncd", "starpilot.system.device_syncd", always_run),
|
|
PythonProcess("starpilot_process", "starpilot.starpilot_process", always_run),
|
|
PythonProcess("mapd", "starpilot.navigation.mapd_wrapper", always_run, nice=19),
|
|
PythonProcess("navigationd", "starpilot.navigation.navigationd", run_navigationd, nice=19),
|
|
PythonProcess("speed_limit_filler", "starpilot.system.speed_limit_filler", run_speed_limit_filler, nice=19),
|
|
PythonProcess("speed_limit_vision", "starpilot.system.speed_limit_vision", run_speed_limit_vision, nice=19),
|
|
]
|
|
|
|
managed_processes = {p.name: p for p in procs}
|