mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-09-03 06:33:50 +08:00
Compare commits
1 Commits
Dom
...
traffic-border-c4
| Author | SHA1 | Date | |
|---|---|---|---|
| 371f063362 |
@@ -21,6 +21,7 @@ from openpilot.selfdrive.ui.mici.onroad.starpilot_status import (
|
|||||||
)
|
)
|
||||||
from openpilot.selfdrive.ui.mici.onroad.cameraview import CameraView
|
from openpilot.selfdrive.ui.mici.onroad.cameraview import CameraView
|
||||||
from openpilot.selfdrive.ui.onroad.starpilot.pip_sidecam import PipSideCamera
|
from openpilot.selfdrive.ui.onroad.starpilot.pip_sidecam import PipSideCamera
|
||||||
|
from openpilot.selfdrive.ui.onroad.starpilot.starpilot_border import get_traffic_border_colors
|
||||||
from openpilot.selfdrive.ui.lib.starpilot_visuals import get_border_width
|
from openpilot.selfdrive.ui.lib.starpilot_visuals import get_border_width
|
||||||
from openpilot.starpilot.common.favorite_slots import is_favorite_action_key, load_favorite_slots, toggle_favorite_slot
|
from openpilot.starpilot.common.favorite_slots import is_favorite_action_key, load_favorite_slots, toggle_favorite_slot
|
||||||
from openpilot.system.ui.lib.application import FontWeight, gui_app, MousePos, MouseEvent
|
from openpilot.system.ui.lib.application import FontWeight, gui_app, MousePos, MouseEvent
|
||||||
@@ -825,6 +826,17 @@ class AugmentedRoadView(CameraView):
|
|||||||
int(self._content_rect.height),
|
int(self._content_rect.height),
|
||||||
)
|
)
|
||||||
rl.draw_rectangle_rounded_lines_ex(border_rect, 0.12, 16, border_size, get_border_color(ui_state))
|
rl.draw_rectangle_rounded_lines_ex(border_rect, 0.12, 16, border_size, get_border_color(ui_state))
|
||||||
|
|
||||||
|
if (colors := get_traffic_border_colors()) is not None:
|
||||||
|
for x, w, color in (
|
||||||
|
(border_rect.x, border_rect.width / 2, colors[0]),
|
||||||
|
(border_rect.x + border_rect.width / 2, border_rect.width - border_rect.width / 2, colors[1]),
|
||||||
|
):
|
||||||
|
if color.a > 0:
|
||||||
|
rl.begin_scissor_mode(int(x), int(border_rect.y), int(w), int(border_rect.height))
|
||||||
|
rl.draw_rectangle_rounded_lines_ex(border_rect, 0.12, 16, border_size, color)
|
||||||
|
rl.end_scissor_mode()
|
||||||
|
|
||||||
rl.end_scissor_mode()
|
rl.end_scissor_mode()
|
||||||
|
|
||||||
def _get_border_width(self) -> int:
|
def _get_border_width(self) -> int:
|
||||||
|
|||||||
@@ -170,55 +170,65 @@ def _render_csc_glow(border_rect: rl.Rectangle, border_width: float = UI_BORDER_
|
|||||||
_smoothed_steer = 0.0
|
_smoothed_steer = 0.0
|
||||||
|
|
||||||
|
|
||||||
|
def get_traffic_border_colors() -> tuple[rl.Color, rl.Color] | None:
|
||||||
|
sm = ui_state.sm
|
||||||
|
car_state = sm["carState"] if sm.valid.get("carState", False) else None
|
||||||
|
if car_state is None:
|
||||||
|
return None
|
||||||
|
params = ui_state.ui_params
|
||||||
|
show_signal = params.get_bool("SignalMetrics")
|
||||||
|
show_blindspot = params.get_bool("BlindSpotMetrics")
|
||||||
|
if not (show_signal or show_blindspot):
|
||||||
|
return None
|
||||||
|
|
||||||
|
left_blindspot = car_state.leftBlindspot
|
||||||
|
right_blindspot = car_state.rightBlindspot
|
||||||
|
if ui_state.starpilot_toggles.get("v_asm_enabled", False):
|
||||||
|
vasm_left, vasm_right = get_fresh_vasm_state(ui_state.params_memory)
|
||||||
|
left_blindspot = left_blindspot or vasm_left
|
||||||
|
right_blindspot = right_blindspot or vasm_right
|
||||||
|
left_blinker = car_state.leftBlinker
|
||||||
|
right_blinker = car_state.rightBlinker
|
||||||
|
|
||||||
|
if not ((show_signal and (left_blinker or right_blinker)) or (show_blindspot and (left_blindspot or right_blindspot))):
|
||||||
|
return None
|
||||||
|
|
||||||
|
interval = 250 if show_blindspot and (left_blindspot or right_blindspot) else 500
|
||||||
|
flicker_active = (int(rl.get_time() * 1000) % (interval * 2)) < interval
|
||||||
|
|
||||||
|
def get_half_border_color(blindspot, turn_signal):
|
||||||
|
if turn_signal and show_signal:
|
||||||
|
if blindspot:
|
||||||
|
return TRAFFIC_COLOR if flicker_active else CEM_OVERRIDE_COLOR
|
||||||
|
else:
|
||||||
|
return CEM_OVERRIDE_COLOR if flicker_active else rl.Color(0, 0, 0, 0)
|
||||||
|
elif blindspot and show_blindspot:
|
||||||
|
return TRAFFIC_COLOR
|
||||||
|
else:
|
||||||
|
return rl.Color(0, 0, 0, 0)
|
||||||
|
|
||||||
|
left_color = get_half_border_color(left_blindspot, left_blinker)
|
||||||
|
right_color = get_half_border_color(right_blindspot, right_blinker)
|
||||||
|
|
||||||
|
return left_color, right_color
|
||||||
|
|
||||||
|
|
||||||
def render_background_effects(rect: rl.Rectangle, border_width: float):
|
def render_background_effects(rect: rl.Rectangle, border_width: float):
|
||||||
global _smoothed_steer
|
global _smoothed_steer
|
||||||
sm = ui_state.sm
|
sm = ui_state.sm
|
||||||
|
|
||||||
# 1. Turn Signal and Blind Spot indicators
|
# 1. Turn Signal and Blind Spot indicators
|
||||||
car_state = sm["carState"] if sm.valid.get("carState", False) else None
|
colors = get_traffic_border_colors()
|
||||||
if car_state:
|
if colors is not None:
|
||||||
params = ui_state.ui_params
|
left_color, right_color = colors
|
||||||
show_signal = params.get_bool("SignalMetrics")
|
if left_color.a > 0:
|
||||||
show_blindspot = params.get_bool("BlindSpotMetrics")
|
rl.begin_scissor_mode(int(rect.x), int(rect.y), int(rect.width // 2), int(rect.height))
|
||||||
if show_signal or show_blindspot:
|
rl.draw_rectangle_rounded(rect, 0.12, 10, left_color)
|
||||||
left_blindspot = car_state.leftBlindspot
|
rl.end_scissor_mode()
|
||||||
right_blindspot = car_state.rightBlindspot
|
if right_color.a > 0:
|
||||||
if ui_state.starpilot_toggles.get("v_asm_enabled", False):
|
rl.begin_scissor_mode(int(rect.x + rect.width // 2), int(rect.y), int(rect.width // 2), int(rect.height))
|
||||||
vasm_left, vasm_right = get_fresh_vasm_state(ui_state.params_memory)
|
rl.draw_rectangle_rounded(rect, 0.12, 10, right_color)
|
||||||
left_blindspot = left_blindspot or vasm_left
|
rl.end_scissor_mode()
|
||||||
right_blindspot = right_blindspot or vasm_right
|
|
||||||
left_blinker = car_state.leftBlinker
|
|
||||||
right_blinker = car_state.rightBlinker
|
|
||||||
|
|
||||||
if (show_signal and (left_blinker or right_blinker)) or (show_blindspot and (left_blindspot or right_blindspot)):
|
|
||||||
interval = 250 if show_blindspot and (left_blindspot or right_blindspot) else 500
|
|
||||||
flicker_active = (int(rl.get_time() * 1000) % (interval * 2)) < interval
|
|
||||||
|
|
||||||
def get_half_border_color(blindspot, turn_signal):
|
|
||||||
if turn_signal and show_signal:
|
|
||||||
if blindspot:
|
|
||||||
return TRAFFIC_COLOR if flicker_active else CEM_OVERRIDE_COLOR
|
|
||||||
else:
|
|
||||||
return CEM_OVERRIDE_COLOR if flicker_active else rl.Color(0, 0, 0, 0)
|
|
||||||
elif blindspot and show_blindspot:
|
|
||||||
return TRAFFIC_COLOR
|
|
||||||
else:
|
|
||||||
return rl.Color(0, 0, 0, 0)
|
|
||||||
|
|
||||||
left_color = get_half_border_color(left_blindspot, left_blinker)
|
|
||||||
right_color = get_half_border_color(right_blindspot, right_blinker)
|
|
||||||
|
|
||||||
# Draw left side borders
|
|
||||||
if left_color.a > 0:
|
|
||||||
rl.begin_scissor_mode(int(rect.x), int(rect.y), int(rect.width // 2), int(rect.height))
|
|
||||||
rl.draw_rectangle_rounded(rect, 0.12, 10, left_color)
|
|
||||||
rl.end_scissor_mode()
|
|
||||||
|
|
||||||
# Draw right side borders
|
|
||||||
if right_color.a > 0:
|
|
||||||
rl.begin_scissor_mode(int(rect.x + rect.width // 2), int(rect.y), int(rect.width // 2), int(rect.height))
|
|
||||||
rl.draw_rectangle_rounded(rect, 0.12, 10, right_color)
|
|
||||||
rl.end_scissor_mode()
|
|
||||||
|
|
||||||
# 2. Steering Torque Border
|
# 2. Steering Torque Border
|
||||||
car_control = sm["carControl"] if sm.valid.get("carControl", False) else None
|
car_control = sm["carControl"] if sm.valid.get("carControl", False) else None
|
||||||
|
|||||||
@@ -0,0 +1,149 @@
|
|||||||
|
from types import SimpleNamespace
|
||||||
|
|
||||||
|
from openpilot.selfdrive.ui.lib.starpilot_status import TRAFFIC_COLOR, CEM_OVERRIDE_COLOR
|
||||||
|
from openpilot.selfdrive.ui.onroad.starpilot import starpilot_border
|
||||||
|
from openpilot.selfdrive.ui.ui_state import ui_state
|
||||||
|
|
||||||
|
TRANSPARENT = (0, 0, 0, 0)
|
||||||
|
|
||||||
|
|
||||||
|
def _rgba(color):
|
||||||
|
return color.r, color.g, color.b, color.a
|
||||||
|
|
||||||
|
|
||||||
|
def _car_state(left_blindspot=False, right_blindspot=False, left_blinker=False, right_blinker=False):
|
||||||
|
return SimpleNamespace(
|
||||||
|
leftBlindspot=left_blindspot,
|
||||||
|
rightBlindspot=right_blindspot,
|
||||||
|
leftBlinker=left_blinker,
|
||||||
|
rightBlinker=right_blinker,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _setup(monkeypatch, *, car_state, signal=True, blindspot=True, v_asm_enabled=False, v_asm=(False, False), time=0.0):
|
||||||
|
class FakeSM(dict):
|
||||||
|
valid = {"carState": True}
|
||||||
|
|
||||||
|
monkeypatch.setattr(ui_state, "sm", FakeSM(carState=car_state))
|
||||||
|
monkeypatch.setattr(
|
||||||
|
ui_state,
|
||||||
|
"ui_params",
|
||||||
|
SimpleNamespace(get_bool=lambda key: {"SignalMetrics": signal, "BlindSpotMetrics": blindspot}[key]),
|
||||||
|
)
|
||||||
|
monkeypatch.setattr(ui_state, "starpilot_toggles", {"v_asm_enabled": v_asm_enabled})
|
||||||
|
monkeypatch.setattr(ui_state, "params_memory", object())
|
||||||
|
monkeypatch.setattr(starpilot_border, "get_fresh_vasm_state", lambda _memory: v_asm)
|
||||||
|
monkeypatch.setattr(starpilot_border.rl, "get_time", lambda: time)
|
||||||
|
|
||||||
|
|
||||||
|
def test_traffic_border_inactive_when_metrics_disabled(monkeypatch):
|
||||||
|
_setup(monkeypatch, car_state=_car_state(left_blinker=True), signal=False, blindspot=False)
|
||||||
|
|
||||||
|
assert starpilot_border.get_traffic_border_colors() is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_traffic_border_inactive_when_nothing_active(monkeypatch):
|
||||||
|
_setup(monkeypatch, car_state=_car_state())
|
||||||
|
|
||||||
|
assert starpilot_border.get_traffic_border_colors() is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_traffic_border_left_blindspot_is_red(monkeypatch):
|
||||||
|
_setup(monkeypatch, car_state=_car_state(left_blindspot=True))
|
||||||
|
|
||||||
|
left, right = starpilot_border.get_traffic_border_colors()
|
||||||
|
|
||||||
|
assert _rgba(left) == _rgba(TRAFFIC_COLOR)
|
||||||
|
assert _rgba(right) == TRANSPARENT
|
||||||
|
|
||||||
|
|
||||||
|
def test_traffic_border_right_blindspot_is_red(monkeypatch):
|
||||||
|
_setup(monkeypatch, car_state=_car_state(right_blindspot=True))
|
||||||
|
|
||||||
|
left, right = starpilot_border.get_traffic_border_colors()
|
||||||
|
|
||||||
|
assert _rgba(left) == TRANSPARENT
|
||||||
|
assert _rgba(right) == _rgba(TRAFFIC_COLOR)
|
||||||
|
|
||||||
|
|
||||||
|
def test_traffic_border_blinker_alone_flickers_amber(monkeypatch):
|
||||||
|
_setup(monkeypatch, car_state=_car_state(left_blinker=True), blindspot=False, time=0.1)
|
||||||
|
|
||||||
|
left, right = starpilot_border.get_traffic_border_colors()
|
||||||
|
assert _rgba(left) == _rgba(CEM_OVERRIDE_COLOR)
|
||||||
|
assert _rgba(right) == TRANSPARENT
|
||||||
|
|
||||||
|
_setup(monkeypatch, car_state=_car_state(left_blinker=True), blindspot=False, time=0.6)
|
||||||
|
left, right = starpilot_border.get_traffic_border_colors()
|
||||||
|
assert _rgba(left) == TRANSPARENT
|
||||||
|
assert _rgba(right) == TRANSPARENT
|
||||||
|
|
||||||
|
|
||||||
|
def test_traffic_border_blinker_with_blindspot_flickers_red_and_amber(monkeypatch):
|
||||||
|
_setup(monkeypatch, car_state=_car_state(left_blinker=True, left_blindspot=True), time=0.1)
|
||||||
|
|
||||||
|
left, _ = starpilot_border.get_traffic_border_colors()
|
||||||
|
assert _rgba(left) == _rgba(TRAFFIC_COLOR)
|
||||||
|
|
||||||
|
_setup(monkeypatch, car_state=_car_state(left_blinker=True, left_blindspot=True), time=0.3)
|
||||||
|
left, _ = starpilot_border.get_traffic_border_colors()
|
||||||
|
assert _rgba(left) == _rgba(CEM_OVERRIDE_COLOR)
|
||||||
|
|
||||||
|
|
||||||
|
def test_traffic_border_v_asm_blindspot_is_red(monkeypatch):
|
||||||
|
_setup(monkeypatch, car_state=_car_state(), v_asm_enabled=True, v_asm=(True, False))
|
||||||
|
|
||||||
|
left, right = starpilot_border.get_traffic_border_colors()
|
||||||
|
assert _rgba(left) == _rgba(TRAFFIC_COLOR)
|
||||||
|
assert _rgba(right) == TRANSPARENT
|
||||||
|
|
||||||
|
|
||||||
|
def test_c4_draw_border_paints_traffic_color_on_active_half(monkeypatch):
|
||||||
|
import pyray as rl
|
||||||
|
from openpilot.selfdrive.ui.mici.onroad import augmented_road_view as mici_view
|
||||||
|
|
||||||
|
view = object.__new__(mici_view.AugmentedRoadView)
|
||||||
|
view._content_rect = rl.Rectangle(10, 20, 200, 100)
|
||||||
|
view._get_border_width = lambda: 8
|
||||||
|
view._closed = True
|
||||||
|
|
||||||
|
base_color = rl.Color(0, 0, 0, 255)
|
||||||
|
calls = []
|
||||||
|
monkeypatch.setattr(mici_view, "get_border_color", lambda _state: base_color)
|
||||||
|
monkeypatch.setattr(mici_view, "get_traffic_border_colors", lambda: (TRAFFIC_COLOR, rl.Color(0, 0, 0, 0)))
|
||||||
|
monkeypatch.setattr(mici_view.rl, "begin_scissor_mode", lambda *args: calls.append(("begin_scissor", args)))
|
||||||
|
monkeypatch.setattr(mici_view.rl, "end_scissor_mode", lambda: calls.append(("end_scissor",)))
|
||||||
|
monkeypatch.setattr(mici_view.rl, "draw_rectangle_rounded_lines_ex", lambda *args: calls.append(("line", args)))
|
||||||
|
|
||||||
|
view._draw_border()
|
||||||
|
|
||||||
|
lines = [c for c in calls if c[0] == "line"]
|
||||||
|
assert len(lines) == 2
|
||||||
|
assert _rgba(lines[0][1][4]) == _rgba(base_color)
|
||||||
|
assert _rgba(lines[1][1][4]) == _rgba(TRAFFIC_COLOR)
|
||||||
|
|
||||||
|
scissor = [c for c in calls if c[0] == "begin_scissor"]
|
||||||
|
assert scissor[0][1] == (10, 20, 200, 100)
|
||||||
|
assert scissor[1][1] == (14, 24, 96, 92)
|
||||||
|
|
||||||
|
|
||||||
|
def test_c4_draw_border_skips_traffic_colors_when_inactive(monkeypatch):
|
||||||
|
import pyray as rl
|
||||||
|
from openpilot.selfdrive.ui.mici.onroad import augmented_road_view as mici_view
|
||||||
|
|
||||||
|
view = object.__new__(mici_view.AugmentedRoadView)
|
||||||
|
view._content_rect = rl.Rectangle(10, 20, 200, 100)
|
||||||
|
view._get_border_width = lambda: 8
|
||||||
|
view._closed = True
|
||||||
|
|
||||||
|
calls = []
|
||||||
|
monkeypatch.setattr(mici_view, "get_border_color", lambda _state: rl.Color(0, 0, 0, 255))
|
||||||
|
monkeypatch.setattr(mici_view, "get_traffic_border_colors", lambda: None)
|
||||||
|
monkeypatch.setattr(mici_view.rl, "begin_scissor_mode", lambda *args: calls.append(("begin_scissor", args)))
|
||||||
|
monkeypatch.setattr(mici_view.rl, "end_scissor_mode", lambda: calls.append(("end_scissor",)))
|
||||||
|
monkeypatch.setattr(mici_view.rl, "draw_rectangle_rounded_lines_ex", lambda *args: calls.append(("line", args)))
|
||||||
|
|
||||||
|
view._draw_border()
|
||||||
|
|
||||||
|
assert len([c for c in calls if c[0] == "line"]) == 1
|
||||||
|
assert len([c for c in calls if c[0] == "begin_scissor"]) == 1
|
||||||
Reference in New Issue
Block a user