mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-07-09 12:02:06 +08:00
7021d2ce20
* UI: Debug: Tap on Ui to capture snapshot of debug data * UI: Debug UI: Toggle to display debug UI elements & UI prerequisites * UI: VisionTurnController Implementation * UI: Debug UI: Toggle to display debug UI elements * UI: LiveMapData: Implementation * UI: SpeedLimitControl: Implementation * UI: TurnSpeedController: Implementation * fixup! UI: SpeedLimitControl: Implementation * Add adjustable speed limit offset (in % or actual values) * fix * fix 2 * fix 3 * wrong value used * don't need this * needs this! * and this? * needs to be at the top * has to be public * take them off * gotta have this * wrong! * update this every time * try to update * hmm maybe it was this * missed this * Revert "missed this" This reverts commit 926b45410544e4f1bbc5174d0d7b03fafedf610f. * Revert "hmm maybe it was this" This reverts commit 7f75543db71d6f438f6473c66d4f94df317f16f2. * refresh them * update them in both places! * make them public please * don't forget this path * try this refresh? * Revert "make them public please" This reverts commit 669a3ee1d5607c84109294db7a567ca86cb91b0f. * revert these * try using signals to update * Revert "try using signals to update" This reverts commit f3ad02bde71467aa7fc27c0b95d03748345193e6. * update state after it's emitted * make it public * Revert "make it public" This reverts commit ddf431d198133359b8bd656dde9061ec671f2312. * Revert "update state after it's emitted" This reverts commit aad2876166843b63d889e90830bf3d32edaa2857. * try this out * fixup! try this out * fixup! try this out * fixup! try this out * fixup! try this out * don't need this * fixup! try this out * fixup! try this out * fixup! try this out * fixup! try this out * make sure we can see it * make it float * Try to update this way * fixup! Try to update this way * Revert "fixup! Try to update this way" This reverts commit f4725bcb070cc8e8ebeb6e37afeb930694e96e22. * Revert "Try to update this way" This reverts commit af72af8a4a193b24e99931200fac18c6625a2431. * new method to hide/show * fixup! new method to hide/show * fixup! new method to hide/show * fixup! new method to hide/show * fixup! new method to hide/show * fixup! new method to hide/show * omg it works?! * run these at 2Hz pls * UI: use comma speed limit design instead of move-fast * fixup! UI: use comma speed limit design instead of move-fast * fixup! UI: use comma speed limit design instead of move-fast * fixup! UI: use comma speed limit design instead of move-fast * UI: use comma speed limit design instead of move-fast * fixup! UI: use comma speed limit design instead of move-fast * fixup! UI: use comma speed limit design instead of move-fast * fixup! UI: use comma speed limit design instead of move-fast * garbage collection * redundant * gc attempt? * Revert "garbage collection" This reverts commit 127fc8bd9d1eaea7725cf775dc7034ac6aaf09f4. * garbage collection * catch exceptions * ignore mapd if crashed * copy dependencies after first download * changed dir * oops * proper termination before exiting * same class * Revert "same class" This reverts commit dda695477371bf259b89aae726210dfe9d5f913e. * Revert "proper termination before exiting" This reverts commit 95c039dac86a389c0be043aadf2a3e8cbd4515c8. * don't let accelerator press to re-engage SLC when NDOG is off * can we free them up? * Revert "can we free them up?" This reverts commit d7736524645376ffb43acb77678086f6ae3c4e0b. * fixup! don't let accelerator press to re-engage SLC when NDOG is off * introduce navInstruction speed limits into SLC * nuke UI for now - memory test * do this instead * Overpass: does not exist * Revert "nuke UI for now - memory test" This reverts commit fd81ffde0443917580ec4ad71095c178173883fe. * meh
289 lines
8.2 KiB
Python
Executable File
289 lines
8.2 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import datetime
|
|
import os
|
|
import signal
|
|
import subprocess
|
|
import sys
|
|
import traceback
|
|
from typing import List, Tuple, Union
|
|
|
|
import cereal.messaging as messaging
|
|
import selfdrive.sentry as sentry
|
|
from common.basedir import BASEDIR
|
|
from common.params import Params, ParamKeyType
|
|
from common.text_window import TextWindow
|
|
from selfdrive.boardd.set_time import set_time
|
|
from system.hardware import HARDWARE, PC
|
|
from selfdrive.manager.helpers import unblock_stdout
|
|
from selfdrive.manager.process import ensure_running
|
|
from selfdrive.manager.process_config import managed_processes
|
|
from selfdrive.sentry import CRASHES_DIR
|
|
from selfdrive.athena.registration import register, UNREGISTERED_DONGLE_ID
|
|
from system.swaglog import cloudlog, add_file_handler
|
|
from system.version import is_dirty, get_commit, get_version, get_origin, get_short_branch, \
|
|
terms_version, training_version, is_tested_branch, is_release_branch
|
|
|
|
|
|
sys.path.append(os.path.join(BASEDIR, "third_party/mapd"))
|
|
|
|
|
|
def manager_init() -> None:
|
|
# update system time from panda
|
|
set_time(cloudlog)
|
|
|
|
# save boot log
|
|
subprocess.call("./bootlog", cwd=os.path.join(BASEDIR, "selfdrive/loggerd"))
|
|
|
|
params = Params()
|
|
params.clear_all(ParamKeyType.CLEAR_ON_MANAGER_START)
|
|
|
|
default_params: List[Tuple[str, Union[str, bytes]]] = [
|
|
("CompletedTrainingVersion", "0"),
|
|
("DisengageOnAccelerator", "0"),
|
|
("GsmMetered", "1"),
|
|
("HasAcceptedTerms", "0"),
|
|
("LanguageSetting", "main_en"),
|
|
("OpenpilotEnabledToggle", "1"),
|
|
|
|
("AccMadsCombo", "1"),
|
|
("AutoLaneChangeTimer", "0"),
|
|
("BelowSpeedPause", "0"),
|
|
("BrakeLights", "0"),
|
|
("BrightnessControl", "0"),
|
|
("CustomTorqueLateral", "0"),
|
|
("CameraControl", "2"),
|
|
("CameraControlToggle", "0"),
|
|
("CameraOffset", "0"),
|
|
("CarModel", ""),
|
|
("CarModelText", ""),
|
|
("ChevronInfo", "1"),
|
|
("CustomBootScreen", "0"),
|
|
("CustomOffsets", "0"),
|
|
("DevUI", "1"),
|
|
("DevUIRow", "1"),
|
|
("DisableOnroadUploads", "0"),
|
|
("DisengageLateralOnBrake", "1"),
|
|
("DynamicLaneProfile", "2"),
|
|
("DynamicLaneProfileToggle", "1"),
|
|
("EnableMads", "1"),
|
|
("EndToEndLongAlert", "0"),
|
|
("EndToEndLongToggle", "1"),
|
|
("EnhancedScc", "0"),
|
|
("GapAdjustCruise", "1"),
|
|
("GapAdjustCruiseMode", "0"),
|
|
("GapAdjustCruiseTr", "4"),
|
|
("GpxDeleteAfterUpload", "1"),
|
|
("GpxDeleteIfUploaded", "1"),
|
|
("HandsOnWheelMonitoring", "0"),
|
|
("HideVEgoUi", "0"),
|
|
("LastSpeedLimitSignTap", "0"),
|
|
("MadsIconToggle", "1"),
|
|
("MaxTimeOffroad", "9"),
|
|
("OnroadScreenOff", "0"),
|
|
("OnroadScreenOffBrightness", "50"),
|
|
("PathOffset", "0"),
|
|
("ReverseAccChange", "0"),
|
|
("ShowDebugUI", "1"),
|
|
("SpeedLimitControl", "1"),
|
|
("SpeedLimitPercOffset", "1"),
|
|
("SpeedLimitStyle", "0"),
|
|
("SpeedLimitValueOffset", "0"),
|
|
("SpeedLimitOffsetType", "0"),
|
|
("StandStillTimer", "0"),
|
|
("StockLongToyota", "0"),
|
|
("TorqueDeadzoneDeg", "0"),
|
|
("TorqueFriction", "1"),
|
|
("TorqueMaxLatAccel", "250"),
|
|
("TrueVEgoUi", "0"),
|
|
("TurnSpeedControl", "0"),
|
|
("TurnVisionControl", "0"),
|
|
("VisionCurveLaneless", "0"),
|
|
("VwAccType", "0"),
|
|
]
|
|
if not PC:
|
|
default_params.append(("LastUpdateTime", datetime.datetime.utcnow().isoformat().encode('utf8')))
|
|
|
|
if params.get_bool("RecordFrontLock"):
|
|
params.put_bool("RecordFront", True)
|
|
|
|
# set unset params
|
|
for k, v in default_params:
|
|
if params.get(k) is None:
|
|
params.put(k, v)
|
|
|
|
# parameters set by Environment Variables
|
|
if os.getenv("HANDSMONITORING") is not None:
|
|
params.put_bool("HandsOnWheelMonitoring", bool(int(os.getenv("HANDSMONITORING", "0"))))
|
|
|
|
# is this dashcam?
|
|
if os.getenv("PASSIVE") is not None:
|
|
params.put_bool("Passive", bool(int(os.getenv("PASSIVE", "0"))))
|
|
|
|
if params.get("Passive") is None:
|
|
raise Exception("Passive must be set to continue")
|
|
|
|
# Create folders needed for msgq
|
|
try:
|
|
os.mkdir("/dev/shm")
|
|
except FileExistsError:
|
|
pass
|
|
except PermissionError:
|
|
print("WARNING: failed to make /dev/shm")
|
|
|
|
# set version params
|
|
params.put("Version", get_version())
|
|
params.put("TermsVersion", terms_version)
|
|
params.put("TrainingVersion", training_version)
|
|
params.put("GitCommit", get_commit(default=""))
|
|
params.put("GitBranch", get_short_branch(default=""))
|
|
params.put("GitRemote", get_origin(default=""))
|
|
params.put_bool("IsTestedBranch", is_tested_branch())
|
|
params.put_bool("IsReleaseBranch", is_release_branch())
|
|
|
|
# set dongle id
|
|
reg_res = register(show_spinner=True)
|
|
if reg_res:
|
|
dongle_id = reg_res
|
|
else:
|
|
serial = params.get("HardwareSerial")
|
|
raise Exception(f"Registration failed for device {serial}")
|
|
os.environ['DONGLE_ID'] = dongle_id # Needed for swaglog
|
|
|
|
if not is_dirty():
|
|
os.environ['CLEAN'] = '1'
|
|
|
|
# init logging
|
|
sentry.init(sentry.SentryProject.SELFDRIVE)
|
|
cloudlog.bind_global(dongle_id=dongle_id, version=get_version(), dirty=is_dirty(),
|
|
device=HARDWARE.get_device_type())
|
|
|
|
if os.path.isfile(f'{CRASHES_DIR}/error.txt'):
|
|
os.remove(f'{CRASHES_DIR}/error.txt')
|
|
|
|
|
|
def manager_prepare() -> None:
|
|
for p in managed_processes.values():
|
|
p.prepare()
|
|
|
|
|
|
def manager_cleanup() -> None:
|
|
# send signals to kill all procs
|
|
for p in managed_processes.values():
|
|
p.stop(block=False)
|
|
|
|
# ensure all are killed
|
|
for p in managed_processes.values():
|
|
p.stop(block=True)
|
|
|
|
cloudlog.info("everything is dead")
|
|
|
|
|
|
def manager_thread() -> None:
|
|
cloudlog.bind(daemon="manager")
|
|
cloudlog.info("manager start")
|
|
cloudlog.info({"environ": os.environ})
|
|
|
|
params = Params()
|
|
|
|
ignore: List[str] = []
|
|
if params.get("DongleId", encoding='utf8') in (None, UNREGISTERED_DONGLE_ID):
|
|
ignore += ["manage_athenad", "uploader"]
|
|
if os.getenv("NOBOARD") is not None:
|
|
ignore.append("pandad")
|
|
ignore += [x for x in os.getenv("BLOCK", "").split(",") if len(x) > 0]
|
|
|
|
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
|
|
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)
|
|
print(running)
|
|
cloudlog.debug(running)
|
|
|
|
# send managerState
|
|
msg = messaging.new_message('managerState')
|
|
msg.managerState.processes = [p.get_process_state_msg() for p in managed_processes.values()]
|
|
pm.send('managerState', msg)
|
|
|
|
# Exit main loop when uninstall/shutdown/reboot is needed
|
|
shutdown = False
|
|
for param in ("DoUninstall", "DoShutdown", "DoReboot"):
|
|
if params.get_bool(param):
|
|
shutdown = True
|
|
params.put("LastManagerExitReason", param)
|
|
cloudlog.warning(f"Shutting down manager - {param} set")
|
|
|
|
if shutdown:
|
|
break
|
|
|
|
|
|
def main() -> None:
|
|
prepare_only = os.getenv("PREPAREONLY") is not None
|
|
|
|
manager_init()
|
|
|
|
# Start UI early so prepare can happen in the background
|
|
if not prepare_only:
|
|
managed_processes['ui'].start()
|
|
|
|
manager_prepare()
|
|
|
|
if prepare_only:
|
|
return
|
|
|
|
# SystemExit on sigterm
|
|
signal.signal(signal.SIGTERM, lambda signum, frame: sys.exit(1))
|
|
|
|
try:
|
|
manager_thread()
|
|
except Exception:
|
|
traceback.print_exc()
|
|
sentry.capture_exception()
|
|
finally:
|
|
manager_cleanup()
|
|
|
|
params = Params()
|
|
if params.get_bool("DoUninstall"):
|
|
cloudlog.warning("uninstalling")
|
|
HARDWARE.uninstall()
|
|
elif params.get_bool("DoReboot"):
|
|
cloudlog.warning("reboot")
|
|
HARDWARE.reboot()
|
|
elif params.get_bool("DoShutdown"):
|
|
cloudlog.warning("shutdown")
|
|
HARDWARE.shutdown()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unblock_stdout()
|
|
|
|
try:
|
|
main()
|
|
except Exception:
|
|
add_file_handler(cloudlog)
|
|
cloudlog.exception("Manager failed to start")
|
|
|
|
try:
|
|
managed_processes['ui'].stop()
|
|
except Exception:
|
|
pass
|
|
|
|
# Show last 3 lines of traceback
|
|
error = traceback.format_exc(-3)
|
|
error = "Manager failed to start\n\n" + error
|
|
with TextWindow(error) as t:
|
|
t.wait_for_exit()
|
|
|
|
raise
|
|
|
|
# manual exit because we are forked
|
|
sys.exit(0)
|