Files
sunnypilot/selfdrive/manager/manager.py
T
Jason Wen 7021d2ce20 move-fast: sunnypilot specials (#32)
* 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
2023-02-18 23:22:07 -05:00

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)