ui: Customizable Onroad Brightness (#1641)
* ui: Customizable Onroad Brightness
* fixes
* lint
* reset on show/hide
* reset on show/hide for mici
* only set if true
* wrong var
* try this out
* use clear
* starts cleanup
* wake for all visual alerts and handle timeouts
* fixup: wake for all visual alerts and handle timeouts
* handle always wake if there's an event properly
* some
* slightly more
* need this back
* Reapply "ui: Global Brightness Override (#1579)"
This reverts commit a0c10be1ff.
* do not touch light sensor logic
* override properly and clip to 30% minimum
* wrap
* lint
* update immediately
* read
* max global brightness
* rename
* gotta do it for mici too lol
* revert
* Revert "revert"
This reverts commit 121a082de11960ffa40b9f1414fe46fa54023507.
* no more
* ui
* more
* intenum
* simplify ONROAD_BRIGHTNESS_TIMER_VALUES
* no more toggle
* 15 seconds countdown for auto dark regardless
* auto dark refinement
* only consume if expired
* immediately set
* rename
* update sl metadata
* no more
---------
Co-authored-by: nayan <nayan8teen@gmail.com>
Co-authored-by: DevTekVE <devtekve@gmail.com>
This commit is contained in:
@@ -168,7 +168,6 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
||||
{"OffroadMode", {CLEAR_ON_MANAGER_START, BOOL}},
|
||||
{"Offroad_TiciSupport", {CLEAR_ON_MANAGER_START, JSON}},
|
||||
{"OnroadScreenOffBrightness", {PERSISTENT | BACKUP, INT, "0"}},
|
||||
{"OnroadScreenOffControl", {PERSISTENT | BACKUP, BOOL}},
|
||||
{"OnroadScreenOffTimer", {PERSISTENT | BACKUP, INT, "15"}},
|
||||
{"OnroadUploads", {PERSISTENT | BACKUP, BOOL, "1"}},
|
||||
{"QuickBootToggle", {PERSISTENT | BACKUP, BOOL, "0"}},
|
||||
|
||||
@@ -222,6 +222,9 @@ class AlertRenderer(Widget):
|
||||
self._alert_y_filter.update(self._rect.y - 50 if alert is None else self._rect.y)
|
||||
self._alpha_filter.update(0 if alert is None else 1)
|
||||
|
||||
if gui_app.sunnypilot_ui():
|
||||
ui_state.onroad_brightness_handle_alerts(ui_state.started, alert)
|
||||
|
||||
if alert is None:
|
||||
# If still animating out, keep the previous alert
|
||||
if self._alpha_filter.x > 0.01 and self._prev_alert is not None:
|
||||
|
||||
@@ -19,6 +19,9 @@ from openpilot.common.transformations.camera import DEVICE_CAMERAS, DeviceCamera
|
||||
from openpilot.common.transformations.orientation import rot_from_euler
|
||||
from enum import IntEnum
|
||||
|
||||
if gui_app.sunnypilot_ui():
|
||||
from openpilot.selfdrive.ui.sunnypilot.ui_state import OnroadTimerStatus
|
||||
|
||||
OpState = log.SelfdriveState.OpenpilotState
|
||||
CALIBRATED = log.LiveCalibrationData.Status.calibrated
|
||||
ROAD_CAM = VisionStreamType.VISION_STREAM_ROAD
|
||||
@@ -351,6 +354,14 @@ class AugmentedRoadView(CameraView):
|
||||
|
||||
return self._cached_matrix
|
||||
|
||||
def show_event(self):
|
||||
if gui_app.sunnypilot_ui():
|
||||
ui_state.reset_onroad_sleep_timer(OnroadTimerStatus.RESUME)
|
||||
|
||||
def hide_event(self):
|
||||
if gui_app.sunnypilot_ui():
|
||||
ui_state.reset_onroad_sleep_timer(OnroadTimerStatus.PAUSE)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
gui_app.init_window("OnRoad Camera View")
|
||||
|
||||
@@ -116,6 +116,10 @@ class AlertRenderer(Widget):
|
||||
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
alert = self.get_alert(ui_state.sm)
|
||||
|
||||
if gui_app.sunnypilot_ui():
|
||||
ui_state.onroad_brightness_handle_alerts(ui_state.started, alert)
|
||||
|
||||
if not alert:
|
||||
return
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@ from openpilot.common.transformations.camera import DEVICE_CAMERAS, DeviceCamera
|
||||
from openpilot.common.transformations.orientation import rot_from_euler
|
||||
|
||||
if gui_app.sunnypilot_ui():
|
||||
from openpilot.selfdrive.ui.sunnypilot.onroad.hud_renderer import HudRendererSP as HudRenderer
|
||||
from openpilot.selfdrive.ui.sunnypilot.onroad.augmented_road_view import BORDER_COLORS_SP
|
||||
from openpilot.selfdrive.ui.sunnypilot.onroad.driver_state import DriverStateRendererSP as DriverStateRenderer
|
||||
|
||||
from openpilot.selfdrive.ui.sunnypilot.onroad.augmented_road_view import BORDER_COLORS_SP
|
||||
from openpilot.selfdrive.ui.sunnypilot.onroad.hud_renderer import HudRendererSP as HudRenderer
|
||||
from openpilot.selfdrive.ui.sunnypilot.ui_state import OnroadTimerStatus
|
||||
|
||||
OpState = log.SelfdriveState.OpenpilotState
|
||||
CALIBRATED = log.LiveCalibrationData.Status.calibrated
|
||||
@@ -224,6 +224,14 @@ class AugmentedRoadView(CameraView):
|
||||
|
||||
return self._cached_matrix
|
||||
|
||||
def show_event(self):
|
||||
if gui_app.sunnypilot_ui():
|
||||
ui_state.reset_onroad_sleep_timer(OnroadTimerStatus.RESUME)
|
||||
|
||||
def hide_event(self):
|
||||
if gui_app.sunnypilot_ui():
|
||||
ui_state.reset_onroad_sleep_timer(OnroadTimerStatus.PAUSE)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
gui_app.init_window("OnRoad Camera View")
|
||||
|
||||
@@ -4,9 +4,21 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors.
|
||||
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 enum import IntEnum
|
||||
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.system.ui.widgets.scroller_tici import Scroller
|
||||
from openpilot.system.ui.sunnypilot.widgets.option_control import OptionControlSP
|
||||
from openpilot.system.ui.widgets import Widget
|
||||
from openpilot.system.ui.lib.multilang import tr
|
||||
from openpilot.system.ui.widgets.scroller_tici import Scroller
|
||||
from openpilot.system.ui.sunnypilot.widgets.list_view import option_item_sp, ToggleActionSP
|
||||
|
||||
ONROAD_BRIGHTNESS_TIMER_VALUES = {0: 15, 1: 30, **{i: (i - 1) * 60 for i in range(2, 12)}}
|
||||
|
||||
|
||||
class OnroadBrightness(IntEnum):
|
||||
AUTO = 0
|
||||
AUTO_DARK = 1
|
||||
|
||||
|
||||
class DisplayLayout(Widget):
|
||||
@@ -18,11 +30,55 @@ class DisplayLayout(Widget):
|
||||
self._scroller = Scroller(items, line_separator=True, spacing=0)
|
||||
|
||||
def _initialize_items(self):
|
||||
self._onroad_brightness = option_item_sp(
|
||||
param="OnroadScreenOffBrightness",
|
||||
title=lambda: tr("Onroad Brightness"),
|
||||
description="",
|
||||
min_value=0,
|
||||
max_value=21,
|
||||
value_change_step=1,
|
||||
label_callback=lambda value: self.update_onroad_brightness(value),
|
||||
inline=True
|
||||
)
|
||||
self._onroad_brightness_timer = option_item_sp(
|
||||
param="OnroadScreenOffTimer",
|
||||
title=lambda: tr("Onroad Brightness Delay"),
|
||||
description="",
|
||||
min_value=0,
|
||||
max_value=11,
|
||||
value_change_step=1,
|
||||
value_map=ONROAD_BRIGHTNESS_TIMER_VALUES,
|
||||
label_callback=lambda value: f"{value} s" if value < 60 else f"{int(value/60)} m",
|
||||
inline=True
|
||||
)
|
||||
items = [
|
||||
|
||||
self._onroad_brightness,
|
||||
self._onroad_brightness_timer,
|
||||
]
|
||||
return items
|
||||
|
||||
@staticmethod
|
||||
def update_onroad_brightness(val):
|
||||
if val == OnroadBrightness.AUTO:
|
||||
return tr("Auto (Default)")
|
||||
|
||||
if val == OnroadBrightness.AUTO_DARK:
|
||||
return tr("Auto (Dark)")
|
||||
|
||||
return f"{(val - 1) * 5} %"
|
||||
|
||||
def _update_state(self):
|
||||
super()._update_state()
|
||||
|
||||
for _item in self._scroller._items:
|
||||
if isinstance(_item.action_item, ToggleActionSP) and _item.action_item.toggle.param_key is not None:
|
||||
_item.action_item.set_state(self._params.get_bool(_item.action_item.toggle.param_key))
|
||||
elif isinstance(_item.action_item, OptionControlSP) and _item.action_item.param_key is not None:
|
||||
_item.action_item.set_value(self._params.get(_item.action_item.param_key, return_default=True))
|
||||
|
||||
brightness_val = self._params.get("OnroadScreenOffBrightness", return_default=True)
|
||||
self._onroad_brightness_timer.action_item.set_enabled(brightness_val not in (OnroadBrightness.AUTO, OnroadBrightness.AUTO_DARK))
|
||||
|
||||
def _render(self, rect):
|
||||
self._scroller.render(rect)
|
||||
|
||||
|
||||
@@ -4,13 +4,25 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors.
|
||||
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 enum import Enum
|
||||
|
||||
from cereal import messaging, log, custom
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.selfdrive.ui.sunnypilot.layouts.settings.display import OnroadBrightness
|
||||
from openpilot.sunnypilot.sunnylink.sunnylink_state import SunnylinkState
|
||||
from openpilot.system.ui.lib.application import gui_app
|
||||
|
||||
OpenpilotState = log.SelfdriveState.OpenpilotState
|
||||
MADSState = custom.ModularAssistiveDrivingSystem.ModularAssistiveDrivingSystemState
|
||||
|
||||
ONROAD_BRIGHTNESS_TIMER_PAUSED = -1
|
||||
|
||||
|
||||
class OnroadTimerStatus(Enum):
|
||||
NONE = 0
|
||||
PAUSE = 1
|
||||
RESUME = 2
|
||||
|
||||
|
||||
class UIStateSP:
|
||||
def __init__(self):
|
||||
@@ -21,8 +33,11 @@ class UIStateSP:
|
||||
]
|
||||
|
||||
self.sunnylink_state = SunnylinkState()
|
||||
self.update_params()
|
||||
|
||||
self.onroad_brightness_timer: int = 0
|
||||
self.custom_interactive_timeout: int = self.params.get("InteractivityTimeout", return_default=True)
|
||||
self.reset_onroad_sleep_timer()
|
||||
|
||||
def update(self) -> None:
|
||||
if self.sunnylink_enabled:
|
||||
@@ -30,6 +45,40 @@ class UIStateSP:
|
||||
else:
|
||||
self.sunnylink_state.stop()
|
||||
|
||||
def onroad_brightness_handle_alerts(self, started: bool, alert):
|
||||
has_alert = started and self.onroad_brightness != OnroadBrightness.AUTO and alert is not None
|
||||
|
||||
self.update_onroad_brightness(has_alert)
|
||||
if has_alert:
|
||||
self.reset_onroad_sleep_timer()
|
||||
|
||||
def update_onroad_brightness(self, has_alert: bool) -> None:
|
||||
if has_alert:
|
||||
return
|
||||
|
||||
if self.onroad_brightness_timer > 0:
|
||||
self.onroad_brightness_timer -= 1
|
||||
|
||||
def reset_onroad_sleep_timer(self, timer_status: OnroadTimerStatus = OnroadTimerStatus.NONE) -> None:
|
||||
# Toggling from active state to inactive
|
||||
if timer_status == OnroadTimerStatus.PAUSE and self.onroad_brightness_timer != ONROAD_BRIGHTNESS_TIMER_PAUSED:
|
||||
self.onroad_brightness_timer = ONROAD_BRIGHTNESS_TIMER_PAUSED
|
||||
# Toggling from a previously inactive state or resetting an active timer
|
||||
elif (self.onroad_brightness_timer_param >= 0 and self.onroad_brightness != OnroadBrightness.AUTO and
|
||||
self.onroad_brightness_timer != ONROAD_BRIGHTNESS_TIMER_PAUSED) or timer_status == OnroadTimerStatus.RESUME:
|
||||
if self.onroad_brightness == OnroadBrightness.AUTO_DARK:
|
||||
self.onroad_brightness_timer = 15 * gui_app.target_fps
|
||||
else:
|
||||
self.onroad_brightness_timer = self.onroad_brightness_timer_param * gui_app.target_fps
|
||||
|
||||
@property
|
||||
def onroad_brightness_timer_expired(self) -> bool:
|
||||
return self.onroad_brightness != OnroadBrightness.AUTO and self.onroad_brightness_timer == 0
|
||||
|
||||
@property
|
||||
def auto_onroad_brightness(self) -> bool:
|
||||
return self.onroad_brightness in (OnroadBrightness.AUTO, OnroadBrightness.AUTO_DARK)
|
||||
|
||||
@staticmethod
|
||||
def update_status(ss, ss_sp, onroad_evt) -> str:
|
||||
state = ss.state
|
||||
@@ -78,6 +127,10 @@ class UIStateSP:
|
||||
self.active_bundle = self.params.get("ModelManager_ActiveBundle")
|
||||
self.custom_interactive_timeout = self.params.get("InteractivityTimeout", return_default=True)
|
||||
|
||||
# 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)
|
||||
|
||||
|
||||
class DeviceSP:
|
||||
def __init__(self):
|
||||
@@ -86,3 +139,38 @@ class DeviceSP:
|
||||
def _set_awake(self, on: bool):
|
||||
if on and self._params.get("DeviceBootMode", return_default=True) == 1:
|
||||
self._params.put_bool("OffroadMode", True)
|
||||
|
||||
@staticmethod
|
||||
def set_onroad_brightness(_ui_state, awake: bool, cur_brightness: float) -> float:
|
||||
if not awake or not _ui_state.started:
|
||||
return cur_brightness
|
||||
|
||||
if _ui_state.onroad_brightness_timer != 0:
|
||||
if _ui_state.onroad_brightness == OnroadBrightness.AUTO_DARK:
|
||||
return max(30.0, cur_brightness)
|
||||
# For AUTO (Default) and Manual modes (while timer running), use standard brightness
|
||||
return cur_brightness
|
||||
|
||||
# 0: Auto (Default), 1: Auto (Dark)
|
||||
if _ui_state.onroad_brightness == OnroadBrightness.AUTO:
|
||||
return cur_brightness
|
||||
elif _ui_state.onroad_brightness == OnroadBrightness.AUTO_DARK:
|
||||
return cur_brightness
|
||||
|
||||
# 2-21: 5% - 100%
|
||||
return float((_ui_state.onroad_brightness - 1) * 5)
|
||||
|
||||
@staticmethod
|
||||
def set_min_onroad_brightness(_ui_state, min_brightness: int) -> int:
|
||||
if _ui_state.onroad_brightness == OnroadBrightness.AUTO_DARK:
|
||||
min_brightness = 10
|
||||
|
||||
return min_brightness
|
||||
|
||||
@staticmethod
|
||||
def wake_from_dimmed_onroad_brightness(_ui_state, evs) -> None:
|
||||
if _ui_state.started and (_ui_state.onroad_brightness_timer_expired or _ui_state.onroad_brightness == OnroadBrightness.AUTO_DARK):
|
||||
if any(ev.left_down for ev in evs):
|
||||
if _ui_state.onroad_brightness_timer_expired:
|
||||
gui_app.mouse_events.clear()
|
||||
_ui_state.reset_onroad_sleep_timer()
|
||||
|
||||
@@ -258,9 +258,17 @@ class Device(DeviceSP):
|
||||
else:
|
||||
clipped_brightness = ((clipped_brightness + 16.0) / 116.0) ** 3.0
|
||||
|
||||
clipped_brightness = float(np.interp(clipped_brightness, [0, 1], [30, 100]))
|
||||
min_brightness = 30
|
||||
if gui_app.sunnypilot_ui():
|
||||
min_brightness = DeviceSP.set_min_onroad_brightness(ui_state, min_brightness)
|
||||
|
||||
clipped_brightness = float(np.interp(clipped_brightness, [0, 1], [min_brightness, 100]))
|
||||
|
||||
brightness = round(self._brightness_filter.update(clipped_brightness))
|
||||
|
||||
if gui_app.sunnypilot_ui():
|
||||
brightness = DeviceSP.set_onroad_brightness(ui_state, self._awake, brightness)
|
||||
|
||||
if not self._awake:
|
||||
brightness = 0
|
||||
|
||||
@@ -276,6 +284,9 @@ class Device(DeviceSP):
|
||||
self._ignition = ui_state.ignition
|
||||
|
||||
if ignition_just_turned_off or any(ev.left_down for ev in gui_app.mouse_events):
|
||||
if gui_app.sunnypilot_ui():
|
||||
DeviceSP.wake_from_dimmed_onroad_brightness(ui_state, gui_app.mouse_events)
|
||||
|
||||
self._reset_interactive_timeout()
|
||||
|
||||
interaction_timeout = time.monotonic() > self._interaction_time
|
||||
|
||||
@@ -777,13 +777,100 @@
|
||||
"OnroadScreenOffBrightness": {
|
||||
"title": "Onroad Brightness",
|
||||
"description": "",
|
||||
"min": 0,
|
||||
"max": 100,
|
||||
"step": 5
|
||||
"options": [
|
||||
{
|
||||
"value": 0,
|
||||
"label": "Auto (Default)"
|
||||
},
|
||||
{
|
||||
"value": 1,
|
||||
"label": "Auto (Dark)"
|
||||
},
|
||||
{
|
||||
"value": 2,
|
||||
"label": "5 %"
|
||||
},
|
||||
{
|
||||
"value": 3,
|
||||
"label": "10 %"
|
||||
},
|
||||
{
|
||||
"value": 4,
|
||||
"label": "15 %"
|
||||
},
|
||||
{
|
||||
"value": 5,
|
||||
"label": "20 %"
|
||||
},
|
||||
{
|
||||
"value": 6,
|
||||
"label": "25 %"
|
||||
},
|
||||
{
|
||||
"value": 7,
|
||||
"label": "30 %"
|
||||
},
|
||||
{
|
||||
"value": 8,
|
||||
"label": "35 %"
|
||||
},
|
||||
{
|
||||
"value": 9,
|
||||
"label": "40 %"
|
||||
},
|
||||
{
|
||||
"value": 10,
|
||||
"label": "45 %"
|
||||
},
|
||||
{
|
||||
"value": 11,
|
||||
"label": "50 %"
|
||||
},
|
||||
{
|
||||
"value": 12,
|
||||
"label": "55 %"
|
||||
},
|
||||
{
|
||||
"value": 13,
|
||||
"label": "60 %"
|
||||
},
|
||||
{
|
||||
"value": 14,
|
||||
"label": "65 %"
|
||||
},
|
||||
{
|
||||
"value": 15,
|
||||
"label": "70 %"
|
||||
},
|
||||
{
|
||||
"value": 16,
|
||||
"label": "75 %"
|
||||
},
|
||||
{
|
||||
"value": 17,
|
||||
"label": "80 %"
|
||||
},
|
||||
{
|
||||
"value": 18,
|
||||
"label": "85 %"
|
||||
},
|
||||
{
|
||||
"value": 19,
|
||||
"label": "90 %"
|
||||
},
|
||||
{
|
||||
"value": 20,
|
||||
"label": "95 %"
|
||||
},
|
||||
{
|
||||
"value": 21,
|
||||
"label": "100 %"
|
||||
}
|
||||
]
|
||||
},
|
||||
"OnroadScreenOffControl": {
|
||||
"title": "Onroad Screen: Reduced Brightness",
|
||||
"description": "Turn off device screen or reduce brightness after driving starts"
|
||||
"title": "Onroad Brightness",
|
||||
"description": "Adjusts the screen brightness while it's in onroad state."
|
||||
},
|
||||
"OnroadScreenOffTimer": {
|
||||
"title": "Onroad Brightness Delay",
|
||||
|
||||
Reference in New Issue
Block a user