mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-02-24 05:13:57 +08:00
* Refactor and extend ModelRenderer for custom Sunnypilot logic Refactored `ModelRenderer` to `ModelRendererSP` with enhanced features such as lane line updates, path drawing, and lead management for Sunnypilot. Introduced new methods for model updates, lead drawing, and improved path rendering with experimental mode support. Ensured compatibility by integrating with Sunnypilot-specific HUD and camera components. * Update selfdrive/ui/sunnypilot/qt/onroad/model.cc * Refactor `ModelRenderer` for modularity Moved constants and `get_path_length_idx` function to the header file for reuse and clarity. Updated `drawPath` and related methods to better handle surface dimensions, improving rendering flexibility. Made key functions virtual to allow further customization in derived classes. * Cleaning logic on ModelRenderSP Given that we've refactored slightly the original ModelRender, we no longer need to duplicate the logic on our own implementation * Enable blind spot detection and visualization. Added support for blind spot warnings, including gradient-colored visualizations for left and right blind spots on the on-road UI. Introduced a new "BlindSpot" parameter with related logic for detection and rendering, as well as a settings option for user toggling. * Cleanup format Clean Cleanup and fixes * Let's backup the BlindSpot setting * add false for restart-needed * Add blind spot warning toggle to VisualsPanel Moved blind spot warning toggle from settings.cc to VisualsPanel and implemented support for dynamic parameter updates. This change introduces a dedicated layout for managing visual settings and improves modularity in the settings interface. * Update Blind Spot Warnings setting description Clarified the description to specify that warnings are displayed only if the car supports Blind Spot Monitoring (BSM). This ensures better user understanding of the feature's requirements. * Avoid diff on settings.cc * More cleanup --------- Co-authored-by: DevTekVE <devtekve@gmail.com> Co-authored-by: Jason Wen <haibin.wen3@gmail.com> Co-authored-by: Nayan <nayan8teen@gmail.com>
253 lines
7.8 KiB
Python
Executable File
253 lines
7.8 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import datetime
|
|
import os
|
|
import signal
|
|
import sys
|
|
import traceback
|
|
|
|
from cereal import log
|
|
import cereal.messaging as messaging
|
|
import openpilot.system.sentry as sentry
|
|
from openpilot.common.params import Params, ParamKeyType
|
|
from openpilot.system.hardware import HARDWARE
|
|
from openpilot.system.manager.helpers import unblock_stdout, write_onroad_params, save_bootlog
|
|
from openpilot.system.manager.process import ensure_running
|
|
from openpilot.system.manager.process_config import managed_processes
|
|
from openpilot.system.athena.registration import register, UNREGISTERED_DONGLE_ID
|
|
from openpilot.common.swaglog import cloudlog, add_file_handler
|
|
from openpilot.system.version import get_build_metadata, terms_version, training_version
|
|
from openpilot.system.hardware.hw import Paths
|
|
|
|
|
|
def manager_init() -> None:
|
|
save_bootlog()
|
|
|
|
build_metadata = get_build_metadata()
|
|
|
|
params = Params()
|
|
params.clear_all(ParamKeyType.CLEAR_ON_MANAGER_START)
|
|
params.clear_all(ParamKeyType.CLEAR_ON_ONROAD_TRANSITION)
|
|
params.clear_all(ParamKeyType.CLEAR_ON_OFFROAD_TRANSITION)
|
|
if build_metadata.release_channel:
|
|
params.clear_all(ParamKeyType.DEVELOPMENT_ONLY)
|
|
|
|
default_params: list[tuple[str, str | bytes]] = [
|
|
("CompletedTrainingVersion", "0"),
|
|
("DisengageOnAccelerator", "0"),
|
|
("GsmMetered", "1"),
|
|
("HasAcceptedTerms", "0"),
|
|
("LanguageSetting", "main_en"),
|
|
("OpenpilotEnabledToggle", "1"),
|
|
("LongitudinalPersonality", str(log.LongitudinalPersonality.standard)),
|
|
]
|
|
|
|
sunnypilot_default_params: list[tuple[str, str | bytes]] = [
|
|
("AutoLaneChangeTimer", "0"),
|
|
("AutoLaneChangeBsmDelay", "0"),
|
|
("BlindSpot", "0"),
|
|
("BlinkerMinLateralControlSpeed", "20"), # MPH or km/h
|
|
("BlinkerPauseLateralControl", "0"),
|
|
("DynamicExperimentalControl", "0"),
|
|
("HyundaiLongitudinalTuning", "0"),
|
|
("LagdToggle", "1"),
|
|
("Mads", "1"),
|
|
("MadsMainCruiseAllowed", "1"),
|
|
("MadsSteeringMode", "0"),
|
|
("MadsUnifiedEngagementMode", "1"),
|
|
("MaxTimeOffroad", "1800"),
|
|
("Brightness", "0"),
|
|
("ModelManager_LastSyncTime", "0"),
|
|
("ModelManager_ModelsCache", ""),
|
|
("NeuralNetworkLateralControl", "0"),
|
|
("QuietMode", "0"),
|
|
]
|
|
|
|
if params.get_bool("RecordFrontLock"):
|
|
params.put_bool("RecordFront", True)
|
|
|
|
# set unset params
|
|
for k, v in (default_params + sunnypilot_default_params):
|
|
if params.get(k) is None:
|
|
params.put(k, v)
|
|
|
|
# Create folders needed for msgq
|
|
try:
|
|
os.mkdir(Paths.shm_path())
|
|
except FileExistsError:
|
|
pass
|
|
except PermissionError:
|
|
print(f"WARNING: failed to make {Paths.shm_path()}")
|
|
|
|
# set params
|
|
serial = HARDWARE.get_serial()
|
|
params.put("Version", build_metadata.openpilot.version)
|
|
params.put("TermsVersion", terms_version)
|
|
params.put("TrainingVersion", training_version)
|
|
params.put("GitCommit", build_metadata.openpilot.git_commit)
|
|
params.put("GitCommitDate", build_metadata.openpilot.git_commit_date)
|
|
params.put("GitBranch", build_metadata.channel)
|
|
params.put("GitRemote", build_metadata.openpilot.git_origin)
|
|
params.put_bool("IsTestedBranch", build_metadata.tested_channel)
|
|
params.put_bool("IsReleaseBranch", build_metadata.release_channel)
|
|
params.put("HardwareSerial", serial)
|
|
|
|
# set dongle id
|
|
reg_res = register(show_spinner=True)
|
|
if reg_res:
|
|
dongle_id = reg_res
|
|
else:
|
|
raise Exception(f"Registration failed for device {serial}")
|
|
os.environ['DONGLE_ID'] = dongle_id # Needed for swaglog
|
|
os.environ['GIT_ORIGIN'] = build_metadata.openpilot.git_normalized_origin # Needed for swaglog
|
|
os.environ['GIT_BRANCH'] = build_metadata.channel # Needed for swaglog
|
|
os.environ['GIT_COMMIT'] = build_metadata.openpilot.git_commit # Needed for swaglog
|
|
|
|
if not build_metadata.openpilot.is_dirty:
|
|
os.environ['CLEAN'] = '1'
|
|
|
|
# init logging
|
|
sentry.init(sentry.SentryProject.SELFDRIVE)
|
|
cloudlog.bind_global(dongle_id=dongle_id,
|
|
version=build_metadata.openpilot.version,
|
|
origin=build_metadata.openpilot.git_normalized_origin,
|
|
branch=build_metadata.channel,
|
|
commit=build_metadata.openpilot.git_commit,
|
|
dirty=build_metadata.openpilot.is_dirty,
|
|
device=HARDWARE.get_device_type())
|
|
|
|
# preimport all processes
|
|
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'])
|
|
|
|
write_onroad_params(False, params)
|
|
ensure_running(managed_processes.values(), False, params=params, CP=sm['carParams'], not_run=ignore)
|
|
|
|
started_prev = False
|
|
|
|
while True:
|
|
sm.update(1000)
|
|
|
|
started = sm['deviceState'].started
|
|
|
|
if started and not started_prev:
|
|
params.clear_all(ParamKeyType.CLEAR_ON_ONROAD_TRANSITION)
|
|
elif not started and started_prev:
|
|
params.clear_all(ParamKeyType.CLEAR_ON_OFFROAD_TRANSITION)
|
|
|
|
# update onroad params, which drives pandad's safety setter thread
|
|
if started != started_prev:
|
|
write_onroad_params(started, params)
|
|
|
|
started_prev = started
|
|
|
|
ensure_running(managed_processes.values(), started, params=params, CP=sm['carParams'], not_run=ignore)
|
|
|
|
running = ' '.join("{}{}\u001b[0m".format("\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', valid=True)
|
|
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", f"{param} {datetime.datetime.now()}")
|
|
cloudlog.warning(f"Shutting down manager - {param} set")
|
|
|
|
if shutdown:
|
|
break
|
|
|
|
|
|
def main() -> None:
|
|
manager_init()
|
|
if os.getenv("PREPAREONLY") is not None:
|
|
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__":
|
|
from openpilot.system.ui.text import TextWindow
|
|
|
|
unblock_stdout()
|
|
|
|
try:
|
|
main()
|
|
except KeyboardInterrupt:
|
|
print("got CTRL-C, exiting")
|
|
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)
|