[TIZI/TICI] ui: Visuals panel (#1496)
* commaai/openpilot:d05cb31e2e916fba41ba8167030945f427fd811b * bump opendbc * bump opendbc * bump opendbc * bump opendbc * bump opendbc * sunnypilot: remove Qt * cabana: revert to stock Qt * commaai/openpilot:5198b1b079c37742c1050f02ce0aa6dd42b038b9 * commaai/openpilot:954b567b9ba0f3d1ae57d6aa7797fa86dd92ec6e * commaai/openpilot:7534b2a160faa683412c04c1254440e338931c5e * sum more * bump opendbc * not yet * should've been symlink'ed * raylib says wut * quiet mode back * more fixes * no more * too extra red diff on the side * need to bring this back * too extra * let's update docs here * Revert "let's update docs here" This reverts commit 51fe03cd5121e6fdf14657b2c33852c34922b851. * param to control stock vs sp ui * init styles * SP Toggles * Lint * optimizations * multi-button * Lint * param to control stock vs sp ui * init styles * SP Toggles * Lint * optimizations * Panels. With Icons. And Scroller. * patience, grasshopper * more patience, grasshopper * sp raylib preview * fix callback * fix ui preview * add ui previews * introducing ui_state_sp for py * param to control stock vs sp ui * better * add ui_update callback * better padding * init * revert padding to 20 * new line, who dis * this * support for next line multi-button * use inline=false * uhh * disabled colors * hide em all * lambdas * NOT inline * final touches * hide HIDE * ruff.. RUFF.. WHY RUFF * listitem -> listitemsp * Revert "add ui_update callback" This reverts commit 4da32cc0097434aab0aa6a3c35465eabb23c8958. * add show_description method * remove padding from line separator. like, WHY? 😩😩 * scroller -> scroller_tici * scroller -> scroller_tici * remove line separator padding * ui: `GuiApplicationExt` * add to readme * use gui_app.sunnypilot_ui() * use gui_app.sunnypilot_ui() * use gui_app.sunnypilot_ui() * uhhh. nope * optimizations * I THINK this is not needed, i don't see it used on the visuals panel... * unhide for now... Why hidden tho? * refresh controls * missing * blindspot * standstill timer * road name toggle * more descriptions * more descriptions * update desc * param turn signals * sort * fix * always show desc if not available * should be bool * rocket fuel * steering arc * lint --------- Co-authored-by: Jason Wen <haibin.wen3@gmail.com> Co-authored-by: DevTekVE <devtekve@gmail.com>
This commit is contained in:
@@ -249,7 +249,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
||||
{"OsmStateTitle", {PERSISTENT, STRING}},
|
||||
{"OsmWayTest", {PERSISTENT, STRING}},
|
||||
{"RoadName", {CLEAR_ON_ONROAD_TRANSITION, STRING}},
|
||||
{"RoadNameToggle", {PERSISTENT, STRING}},
|
||||
{"RoadNameToggle", {PERSISTENT | BACKUP, BOOL, "0"}},
|
||||
|
||||
// Speed Limit
|
||||
{"SpeedLimitMode", {PERSISTENT | BACKUP, INT, "1"}},
|
||||
|
||||
@@ -5,9 +5,18 @@ This file is part of sunnypilot and is licensed under the MIT License.
|
||||
See the LICENSE.md file in the root directory for more details.
|
||||
"""
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.selfdrive.ui.ui_state import ui_state
|
||||
from openpilot.system.ui.lib.multilang import tr, tr_noop
|
||||
from openpilot.system.ui.sunnypilot.widgets.list_view import toggle_item_sp, multiple_button_item_sp
|
||||
from openpilot.system.ui.widgets.scroller_tici import Scroller
|
||||
from openpilot.system.ui.widgets import Widget
|
||||
|
||||
CHEVRON_INFO_DESCRIPTION = {
|
||||
"enabled": tr_noop("Display useful metrics below the chevron that tracks the lead car " +
|
||||
"only applicable to cars with sunnypilot longitudinal control."),
|
||||
"disabled": tr_noop("This feature requires sunnypilot longitudinal control to be available.")
|
||||
}
|
||||
|
||||
|
||||
class VisualsLayout(Widget):
|
||||
def __init__(self):
|
||||
@@ -18,13 +27,128 @@ class VisualsLayout(Widget):
|
||||
self._scroller = Scroller(items, line_separator=True, spacing=0)
|
||||
|
||||
def _initialize_items(self):
|
||||
items = [
|
||||
self._toggle_defs = {
|
||||
"BlindSpot": (
|
||||
lambda: tr("Show Blind Spot Warnings"),
|
||||
tr("Enabling this will display warnings when a vehicle is detected in your " +
|
||||
"blind spot as long as your car has BSM supported."),
|
||||
None,
|
||||
),
|
||||
"TorqueBar": (
|
||||
lambda: tr("Steering Arc"),
|
||||
tr("Display steering arc on the driving screen when lateral control is enabled."),
|
||||
None,
|
||||
),
|
||||
"RainbowMode": (
|
||||
lambda: tr("Enable Tesla Rainbow Mode"),
|
||||
tr("A beautiful rainbow effect on the path the model wants to take. " +
|
||||
"It does not affect driving in any way."),
|
||||
None,
|
||||
),
|
||||
"StandstillTimer": (
|
||||
lambda: tr("Enable Standstill Timer"),
|
||||
tr("Show a timer on the HUD when the car is at a standstill."),
|
||||
None,
|
||||
),
|
||||
"RoadNameToggle": (
|
||||
lambda: tr("Display Road Name"),
|
||||
tr("Displays the name of the road the car is traveling on." +
|
||||
"<br>The OpenStreetMap database of the location must be downloaded from " +
|
||||
"the OSM panel to fetch the road name."),
|
||||
None,
|
||||
),
|
||||
"GreenLightAlert": (
|
||||
lambda: tr("Green Traffic Light Alert (Beta)"),
|
||||
tr("A chime and on-screen alert will play when the traffic light you are waiting for " +
|
||||
"turns green and you have no vehicle in front of you." +
|
||||
"<br>Note: This chime is only designed as a notification. " +
|
||||
"It is the driver's responsibility to observe their environment and make decisions accordingly."),
|
||||
None,
|
||||
),
|
||||
"LeadDepartAlert": (
|
||||
lambda: tr("Lead Departure Alert (Beta)"),
|
||||
tr("A chime and on-screen alert will play when you are stopped, and the vehicle in front of you start moving." +
|
||||
"<br>Note: This chime is only designed as a notification. " +
|
||||
"It is the driver's responsibility to observe their environment and make decisions accordingly."),
|
||||
None,
|
||||
),
|
||||
"TrueVEgoUI": (
|
||||
lambda: tr("Speedometer: Always Display True Speed"),
|
||||
tr("For applicable vehicles, always display the true vehicle current speed from wheel speed sensors."),
|
||||
None,
|
||||
),
|
||||
"HideVEgoUI": (
|
||||
lambda: tr("Speedometer: Hide from Onroad Screen"),
|
||||
tr("When enabled, the speedometer on the onroad screen is not displayed."),
|
||||
None,
|
||||
),
|
||||
"ShowTurnSignals": (
|
||||
lambda: tr("Display Turn Signals"),
|
||||
tr("When enabled, visual turn indicators are drawn on the HUD."),
|
||||
None,
|
||||
),
|
||||
"RocketFuel": (
|
||||
lambda: tr("Real-time Acceleration Bar"),
|
||||
tr("Show an indicator on the left side of the screen to display real-time vehicle acceleration and deceleration. " +
|
||||
"This displays what the car is currently doing, not what the planner is requesting."),
|
||||
None,
|
||||
),
|
||||
}
|
||||
self._toggles = {}
|
||||
for param, (title, desc, callback) in self._toggle_defs.items():
|
||||
toggle = toggle_item_sp(
|
||||
title=title,
|
||||
description=desc,
|
||||
param=param,
|
||||
initial_state=ui_state.params.get_bool(param),
|
||||
callback=callback,
|
||||
)
|
||||
self._toggles[param] = toggle
|
||||
|
||||
self._chevron_info = multiple_button_item_sp(
|
||||
title=lambda: tr("Display Metrics Below Chevron"),
|
||||
description="",
|
||||
buttons=[lambda: tr("Off"), lambda: tr("Distance"), lambda: tr("Speed"), lambda: tr("Time"), lambda: tr("All")],
|
||||
param="ChevronInfo",
|
||||
inline=False
|
||||
)
|
||||
self._dev_ui_info = multiple_button_item_sp(
|
||||
title=lambda: tr("Developer UI"),
|
||||
description=lambda: tr("Display real-time parameters and metrics from various sources."),
|
||||
buttons=[lambda: tr("Off"), lambda: tr("Bottom"), lambda: tr("Right"), lambda: tr("Right & Bottom")],
|
||||
param="DevUIInfo",
|
||||
button_width=350,
|
||||
inline=False
|
||||
)
|
||||
|
||||
items = list(self._toggles.values()) + [
|
||||
self._chevron_info,
|
||||
self._dev_ui_info,
|
||||
]
|
||||
return items
|
||||
|
||||
def _update_state(self):
|
||||
super()._update_state()
|
||||
|
||||
for param in self._toggle_defs:
|
||||
self._toggles[param].action_item.set_state(self._params.get_bool(param))
|
||||
|
||||
self._dev_ui_info.action_item.set_selected_button(ui_state.params.get("DevUIInfo", return_default=True))
|
||||
|
||||
if ui_state.has_longitudinal_control:
|
||||
self._chevron_info.set_description(tr(CHEVRON_INFO_DESCRIPTION["enabled"]))
|
||||
self._chevron_info.action_item.set_selected_button(ui_state.params.get("ChevronInfo", return_default=True))
|
||||
self._chevron_info.action_item.set_enabled(True)
|
||||
else:
|
||||
self._chevron_info.set_description(tr(CHEVRON_INFO_DESCRIPTION["disabled"]))
|
||||
self._chevron_info.action_item.set_enabled(False)
|
||||
ui_state.params.put("ChevronInfo", 0)
|
||||
|
||||
def _render(self, rect):
|
||||
self._scroller.render(rect)
|
||||
|
||||
def show_event(self):
|
||||
self._scroller.show_event()
|
||||
if not ui_state.has_longitudinal_control:
|
||||
self._chevron_info.set_description(tr(CHEVRON_INFO_DESCRIPTION["disabled"]))
|
||||
self._chevron_info.show_description(True)
|
||||
|
||||
@@ -31,6 +31,9 @@ class BlindSpotIndicators:
|
||||
return self._blind_spot_left_alpha_filter.x > 0.01 or self._blind_spot_right_alpha_filter.x > 0.01
|
||||
|
||||
def render(self, rect: rl.Rectangle) -> None:
|
||||
if not ui_state.blindspot:
|
||||
return
|
||||
|
||||
BLIND_SPOT_MARGIN_X = 20 # Distance from edge of screen
|
||||
BLIND_SPOT_Y_OFFSET = 100 # Distance from top of screen
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ class CircularAlertsRenderer:
|
||||
self._e2e_alert_frame = 0
|
||||
self._green_light_alert = False
|
||||
self._lead_depart_alert = False
|
||||
self._standstill_timer = False
|
||||
self._standstill_elapsed_time = 0.0
|
||||
self._is_standstill = False
|
||||
self._alert_text = ""
|
||||
@@ -36,7 +35,6 @@ class CircularAlertsRenderer:
|
||||
car_state = sm['carState']
|
||||
self._green_light_alert = lp_sp.e2eAlerts.greenLightAlert
|
||||
self._lead_depart_alert = lp_sp.e2eAlerts.leadDepartAlert
|
||||
self._standstill_timer = ui_state.standstill_timer
|
||||
self._is_standstill = car_state.standstill
|
||||
|
||||
if not ui_state.started:
|
||||
@@ -61,7 +59,7 @@ class CircularAlertsRenderer:
|
||||
self._alert_text = "LEAD VEHICLE\nDEPARTING"
|
||||
self._alert_img = self._lead_depart_alert_img
|
||||
|
||||
elif self._standstill_timer and self._is_standstill:
|
||||
elif ui_state.standstill_timer and self._is_standstill:
|
||||
self._alert_img = None
|
||||
self._standstill_elapsed_time += 1.0 / gui_app.target_fps
|
||||
minute = int(self._standstill_elapsed_time / 60)
|
||||
@@ -75,7 +73,7 @@ class CircularAlertsRenderer:
|
||||
self._standstill_elapsed_time = 0.0
|
||||
|
||||
def render(self, rect: rl.Rectangle) -> None:
|
||||
if not self._allow_e2e_alerts or (self._e2e_alert_display_timer <= 0 and not (self._standstill_timer and self._is_standstill)):
|
||||
if not self._allow_e2e_alerts or (self._e2e_alert_display_timer <= 0 and not (ui_state.standstill_timer and self._is_standstill)):
|
||||
return
|
||||
|
||||
e2e_alert_size = 250
|
||||
@@ -91,7 +89,7 @@ class CircularAlertsRenderer:
|
||||
is_pulsing = (self._e2e_alert_frame % gui_app.target_fps) < (gui_app.target_fps / 2.5)
|
||||
|
||||
# Standstill Timer (STOPPED) should be static white
|
||||
if self._e2e_alert_display_timer == 0 and self._standstill_timer and self._is_standstill:
|
||||
if self._e2e_alert_display_timer == 0 and ui_state.standstill_timer and self._is_standstill:
|
||||
frame_color = rl.Color(255, 255, 255, 75)
|
||||
else:
|
||||
frame_color = rl.Color(255, 255, 255, 75) if is_pulsing else rl.Color(0, 255, 0, 75)
|
||||
@@ -121,7 +119,7 @@ class CircularAlertsRenderer:
|
||||
# Draw lines upwards from bottom
|
||||
current_y = bottom_y - (len(lines) * text_size * FONT_SCALE)
|
||||
|
||||
if self._e2e_alert_display_timer == 0 and self._standstill_timer and self._is_standstill:
|
||||
if self._e2e_alert_display_timer == 0 and ui_state.standstill_timer and self._is_standstill:
|
||||
# Standstill Timer Text
|
||||
alert_alt_text = "STOPPED"
|
||||
top_text_size = 80
|
||||
|
||||
@@ -59,6 +59,4 @@ class HudRendererSP(HudRenderer):
|
||||
self.smart_cruise_control_renderer.render(rect)
|
||||
self.turn_signal_controller.render(rect)
|
||||
self.circular_alerts_renderer.render(rect)
|
||||
|
||||
if ui_state.rocket_fuel:
|
||||
self.rocket_fuel.render(rect, ui_state.sm)
|
||||
self.rocket_fuel.render(rect, ui_state.sm)
|
||||
|
||||
@@ -31,7 +31,7 @@ class RoadNameRenderer(Widget):
|
||||
self.road_name = lmd.roadName
|
||||
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
if not self.road_name:
|
||||
if not self.road_name or not ui_state.road_name_toggle:
|
||||
return
|
||||
|
||||
text = self.road_name
|
||||
|
||||
@@ -6,12 +6,17 @@ See the LICENSE.md file in the root directory for more details.
|
||||
"""
|
||||
import pyray as rl
|
||||
|
||||
from openpilot.selfdrive.ui.ui_state import ui_state
|
||||
|
||||
|
||||
class RocketFuel:
|
||||
def __init__(self):
|
||||
self.vc_accel = 0.0
|
||||
|
||||
def render(self, rect: rl.Rectangle, sm) -> None:
|
||||
if not ui_state.rocket_fuel:
|
||||
return
|
||||
|
||||
vc_accel0 = sm['carState'].aEgo
|
||||
|
||||
# Smooth the acceleration
|
||||
|
||||
@@ -137,6 +137,9 @@ class TurnSignalController:
|
||||
self._right_signal.deactivate()
|
||||
|
||||
def render(self, rect: rl.Rectangle):
|
||||
if not ui_state.turn_signals:
|
||||
return
|
||||
|
||||
x = rect.x + rect.width / 2
|
||||
|
||||
left_x = x - self._config.left_x - self._config.size
|
||||
|
||||
@@ -120,22 +120,23 @@ class UIStateSP:
|
||||
CP_SP_bytes = self.params.get("CarParamsSPPersistent")
|
||||
if CP_SP_bytes is not None:
|
||||
self.CP_SP = messaging.log_from_bytes(CP_SP_bytes, custom.CarParamsSP)
|
||||
self.sunnylink_enabled = self.params.get_bool("SunnylinkEnabled")
|
||||
self.developer_ui = self.params.get("DevUIInfo")
|
||||
self.rocket_fuel = self.params.get_bool("RocketFuel")
|
||||
self.rainbow_path = self.params.get_bool("RainbowMode")
|
||||
self.chevron_metrics = self.params.get("ChevronInfo")
|
||||
self.torque_bar = self.params.get_bool("TorqueBar")
|
||||
self.active_bundle = self.params.get("ModelManager_ActiveBundle")
|
||||
self.blindspot = self.params.get_bool("BlindSpot")
|
||||
self.chevron_metrics = self.params.get("ChevronInfo")
|
||||
self.custom_interactive_timeout = self.params.get("InteractivityTimeout", return_default=True)
|
||||
self.speed_limit_mode = self.params.get("SpeedLimitMode", return_default=True)
|
||||
self.standstill_timer = self.params.get_bool("StandstillTimer")
|
||||
self.true_v_ego_ui = self.params.get_bool("TrueVEgoUI")
|
||||
self.developer_ui = self.params.get("DevUIInfo")
|
||||
self.hide_v_ego_ui = self.params.get_bool("HideVEgoUI")
|
||||
|
||||
# Onroad Screen Brightness
|
||||
self.onroad_brightness = int(float(self.params.get("OnroadScreenOffBrightness", return_default=True)))
|
||||
self.onroad_brightness_timer_param = self.params.get("OnroadScreenOffTimer", return_default=True)
|
||||
self.rainbow_path = self.params.get_bool("RainbowMode")
|
||||
self.road_name_toggle = self.params.get_bool("RoadNameToggle")
|
||||
self.rocket_fuel = self.params.get_bool("RocketFuel")
|
||||
self.speed_limit_mode = self.params.get("SpeedLimitMode", return_default=True)
|
||||
self.standstill_timer = self.params.get_bool("StandstillTimer")
|
||||
self.sunnylink_enabled = self.params.get_bool("SunnylinkEnabled")
|
||||
self.torque_bar = self.params.get_bool("TorqueBar")
|
||||
self.true_v_ego_ui = self.params.get_bool("TrueVEgoUI")
|
||||
self.turn_signals = self.params.get_bool("ShowTurnSignals")
|
||||
|
||||
|
||||
class DeviceSP:
|
||||
|
||||
@@ -90,8 +90,8 @@
|
||||
"description": ""
|
||||
},
|
||||
"BlindSpot": {
|
||||
"title": "Blind Spot Detection",
|
||||
"description": ""
|
||||
"title": "[TIZI/TICI only] Blind Spot Detection",
|
||||
"description": "Enabling this will display warnings when a vehicle is detected in your blind spot as long as your car has BSM supported."
|
||||
},
|
||||
"BlinkerMinLateralControlSpeed": {
|
||||
"title": "Blinker Min Lateral Control Speed",
|
||||
@@ -339,8 +339,8 @@
|
||||
"description": ""
|
||||
},
|
||||
"GreenLightAlert": {
|
||||
"title": "Green Light Alert",
|
||||
"description": ""
|
||||
"title": "Green Traffic Light Alert (Beta)",
|
||||
"description": "A chime and on-screen alert (TIZI/TICI only) will play when the traffic light you are waiting for turns green and you have no vehicle in front of you. <br>Note: This chime is only designed as a notification. It is the driver's responsibility to observe their environment and make decisions accordingly."
|
||||
},
|
||||
"GsmApn": {
|
||||
"title": "GSM APN",
|
||||
@@ -367,8 +367,8 @@
|
||||
"description": ""
|
||||
},
|
||||
"HideVEgoUI": {
|
||||
"title": "Hide vEgo UI",
|
||||
"description": ""
|
||||
"title": "[TIZI/TICI only] Speedometer: Hide from Onroad Screen",
|
||||
"description": "When enabled, the speedometer on the onroad screen is not displayed."
|
||||
},
|
||||
"HyundaiLongitudinalTuning": {
|
||||
"title": "Hyundai Longitudinal Tuning",
|
||||
@@ -585,8 +585,8 @@
|
||||
"description": ""
|
||||
},
|
||||
"LeadDepartAlert": {
|
||||
"title": "Lead Depart Alert",
|
||||
"description": ""
|
||||
"title": "Lead Departure Alert (Beta)",
|
||||
"description": "A chime and on-screen alert (TIZI/TICI only) will play when you are stopped, and the vehicle in front of you start moving. <br>Note: This chime is only designed as a notification. It is the driver's responsibility to observe their environment and make decisions accordingly."
|
||||
},
|
||||
"LiveDelay": {
|
||||
"title": "Live Delay",
|
||||
@@ -1079,12 +1079,12 @@
|
||||
"description": ""
|
||||
},
|
||||
"RoadNameToggle": {
|
||||
"title": "Display Road Name",
|
||||
"description": ""
|
||||
"title": "[TIZI/TICI only] Display Road Name",
|
||||
"description": "Displays the name of the road the car is traveling on. <br>The OpenStreetMap database of the location must be downloaded to fetch the road name."
|
||||
},
|
||||
"RocketFuel": {
|
||||
"title": "Display Rocket Fuel Bar",
|
||||
"description": "Show an indicator on the left side of the screen to display real-time vehicle acceleration and deceleration."
|
||||
"title": "[TIZI/TICI only] Real-time Acceleration Bar",
|
||||
"description": "Show an indicator on the left side of the screen to display real-time vehicle acceleration and deceleration. This displays what the car is currently doing, not what the planner is requesting."
|
||||
},
|
||||
"RouteCount": {
|
||||
"title": "Route Count",
|
||||
@@ -1103,8 +1103,8 @@
|
||||
"description": ""
|
||||
},
|
||||
"ShowTurnSignals": {
|
||||
"title": "Show Turn Signals",
|
||||
"description": ""
|
||||
"title": "[TIZI/TICI only] Display Turn Signals",
|
||||
"description": "When enabled, visual turn indicators are drawn on the HUD."
|
||||
},
|
||||
"SmartCruiseControlMap": {
|
||||
"title": "Smart Cruise Control - Map",
|
||||
@@ -1196,8 +1196,8 @@
|
||||
"description": ""
|
||||
},
|
||||
"StandstillTimer": {
|
||||
"title": "Standstill Timer",
|
||||
"description": ""
|
||||
"title": "[TIZI/TICI only] Standstill Timer",
|
||||
"description": "Show a timer on the HUD when the car is at a standstill."
|
||||
},
|
||||
"SubaruStopAndGo": {
|
||||
"title": "Subaru Stop and Go",
|
||||
@@ -1240,8 +1240,8 @@
|
||||
"description": ""
|
||||
},
|
||||
"TorqueBar": {
|
||||
"title": "Steering Arc",
|
||||
"description": "[TIZI/TICI only] Display steering arc on the driving screen when lateral control is enabled."
|
||||
"title": "[TIZI/TICI only] Steering Arc",
|
||||
"description": "Display steering arc on the driving screen when lateral control is enabled."
|
||||
},
|
||||
"TorqueParamsOverrideEnabled": {
|
||||
"title": "Manual Real-Time Tuning",
|
||||
@@ -1271,8 +1271,8 @@
|
||||
"description": ""
|
||||
},
|
||||
"TrueVEgoUI": {
|
||||
"title": "True vEgo UI",
|
||||
"description": ""
|
||||
"title": "[TIZI/TICI only] Speedometer: Always Display True Speed",
|
||||
"description": "For applicable vehicles, always display the true vehicle current speed from wheel speed sensors."
|
||||
},
|
||||
"UbloxAvailable": {
|
||||
"title": "Ublox Available",
|
||||
|
||||
Reference in New Issue
Block a user