mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-08 05:23:41 +08:00
80fbb4f6db
Register vehicle controls, planner modes, UI actions and Galaxy services after their providers exist. Wire the shared runtime entrypoints and cover their combined behavior. Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> Co-authored-by: Daniel Koepping <elkoled@gmail.com> Co-authored-by: Danny <dannyirwin31@yahoo.com> Co-authored-by: DimitriChrysafis <Dimitri.chrysafis@gmail.com> Co-authored-by: Dom <168790843+firestar5683@users.noreply.github.com> Co-authored-by: Harald Schäfer <harald.the.engineer@gmail.com> Co-authored-by: Kacper Rączy <gfw.kra@gmail.com> Co-authored-by: Prabhaav Pillai <prabhaav@msu.edu> Co-authored-by: dirwin31 <83434411+dirwin31@users.noreply.github.com> Co-authored-by: firestarsdog <229254897+firestarsdog@users.noreply.github.com> Co-authored-by: stef <19478336+stefpi@users.noreply.github.com> Co-authored-by: whoisdomi <dcantu83@gmail.com> Co-authored-by: Intelli <contact@intelli.software> Co-authored-by: haraschax <6804392+haraschax@users.noreply.github.com> Co-authored-by: prabhaavp <prabhaav@msu.edu>
150 lines
8.5 KiB
Python
150 lines
8.5 KiB
Python
import unittest
|
|
from dataclasses import replace
|
|
from types import SimpleNamespace as NS
|
|
from typing import cast
|
|
from unittest.mock import Mock, patch
|
|
|
|
import pyray as rl
|
|
|
|
from openpilot.starpilot.ui.live_developer_sidebar import DeveloperMetrics, render_sidebar
|
|
from openpilot.starpilot.ui.layout_preview_sidebar import metric_rects
|
|
|
|
|
|
class TestLiveDeveloperSidebar(unittest.TestCase):
|
|
def observe(self, owner, **changes):
|
|
values = {'drive': 10, 'car': NS(aEgo=-1.), 'delay': NS(lateralDelay=.15),
|
|
'torque': NS(useParams=True, frictionCoefficientFiltered=.12, latAccelFactorFiltered=2.5),
|
|
'parameters': NS(steerRatio=16.8, stiffnessFactor=.9), 'metric': True}
|
|
return owner.observe(**(values | changes))
|
|
|
|
def test_original_default_order_real_values_and_drive_reset(self):
|
|
owner = DeveloperMetrics()
|
|
rows = self.observe(owner)
|
|
self.assertEqual([r.label for r in rows], ['ACCEL', 'MAX ACCEL', 'LEARNED DELAY', 'LEARNED FRICTION', 'LEARNED LAT ACCEL', 'STEER RATIO', 'STEER STIFF'])
|
|
self.assertEqual(rows[0].value, '-1.00 m/s²')
|
|
self.observe(owner, car=NS(aEgo=5., gasPressed=True))
|
|
self.assertEqual(self.observe(owner)[1].value, '0.00 m/s²')
|
|
self.observe(owner, car=NS(aEgo=2.))
|
|
self.assertEqual(self.observe(owner)[1].value, '2.00 m/s²')
|
|
self.assertEqual(self.observe(owner, drive=11)[1].value, '0.00 m/s²')
|
|
self.assertEqual(self.observe(owner, metric=False)[0].value, '-3.28 ft/s²')
|
|
|
|
def test_missing_nonfinite_sources_and_explicit_cp_fallback(self):
|
|
rows = self.observe(DeveloperMetrics(), car=None, delay=None, torque=None, parameters=None)
|
|
self.assertTrue(all(row.value == '—' for row in rows))
|
|
rows = self.observe(DeveloperMetrics(), car=NS(aEgo=float('nan')), delay=NS(lateralDelay=float('inf')))
|
|
self.assertEqual(rows[0].value, '—')
|
|
self.assertEqual(rows[2].value, '—')
|
|
cp = NS(steerActuatorDelay=.2, lateralTuning=NS(which=lambda: 'torque', torque=NS(friction=.13, latAccelFactor=2.)))
|
|
rows = self.observe(DeveloperMetrics(), delay=None, torque=None, cp=cp)
|
|
self.assertEqual(rows[2].label, 'BASE DELAY')
|
|
self.assertEqual(rows[2].value, '0.20000')
|
|
self.assertEqual(rows[3].value, '0.13000')
|
|
|
|
def test_live_render_uses_given_metrics_inside_shifted_rail(self):
|
|
fonts = Mock()
|
|
fonts.measure.return_value = NS(width=100, height=30)
|
|
frame = rl.Rectangle(1560, 0, 300, 1080)
|
|
rows = self.observe(DeveloperMetrics())
|
|
with patch('openpilot.starpilot.ui.live_developer_sidebar.rl.draw_rectangle_rec'), \
|
|
patch('openpilot.starpilot.ui.live_developer_sidebar.rl.draw_rectangle_rounded_lines_ex'):
|
|
render_sidebar(fonts, frame, rows)
|
|
self.assertEqual(fonts.draw.call_count, 14)
|
|
self.assertNotIn('SAMPLE DATA', [call.args[0] for call in fonts.draw.call_args_list])
|
|
self.assertTrue(all(frame.x <= r.x and r.x + r.width <= frame.x + frame.width for r in metric_rects(frame, 7)))
|
|
|
|
def test_snapshot_current_stale_and_previous_drive_observations(self):
|
|
from openpilot.starpilot.ui.tests.test_runtime_snapshot import NOW, RuntimeSnapshotAdapter, ui_fake
|
|
from openpilot.starpilot.ui.shell import ShellMode
|
|
|
|
ui = ui_fake()
|
|
ui.sm['carState'].aEgo = 1.5
|
|
ui.sm['carState'].canValid = True
|
|
ui.sm['carState'].canTimeout = False
|
|
ui.sm.put('lateralDelay', NS(lateralDelay=.12))
|
|
ui.sm.put('lateralTorqueParameters', NS(useParams=True, frictionCoefficientFiltered=.15, latAccelFactorFiltered=2.4))
|
|
ui.sm.put('vehicleParameters', NS(steerRatio=17., stiffnessFactor=1.1))
|
|
adapter = RuntimeSnapshotAdapter(ui)
|
|
rows = adapter.build(ShellMode.ONROAD, now_ns=NOW).onroad.developer_metrics
|
|
self.assertEqual(rows[0].value, '4.92 ft/s²')
|
|
self.assertEqual(rows[3].value, '0.15000')
|
|
for service in ('lateralDelay', 'lateralTorqueParameters'):
|
|
ui.sm.logMonoTime[service] = NOW - 300_000_000
|
|
rows = adapter.build(ShellMode.ONROAD, now_ns=NOW).onroad.developer_metrics
|
|
self.assertEqual(rows[2].value, '0.12000')
|
|
self.assertEqual(rows[3].value, '0.15000')
|
|
for service in ('carState', 'lateralDelay', 'lateralTorqueParameters', 'vehicleParameters'):
|
|
ui.sm.logMonoTime[service] = NOW - 600_000_000
|
|
rows = adapter.build(ShellMode.ONROAD, now_ns=NOW).onroad.developer_metrics
|
|
self.assertTrue(all(row.value == '—' for row in rows))
|
|
for service in ('carState', 'lateralDelay', 'lateralTorqueParameters', 'vehicleParameters'):
|
|
ui.sm.logMonoTime[service] = NOW
|
|
ui.sm.recv_frame[service] = ui.started_frame
|
|
rows = adapter.build(ShellMode.ONROAD, now_ns=NOW).onroad.developer_metrics
|
|
self.assertTrue(all(row.value == '—' for row in rows))
|
|
|
|
def test_onroad_view_physical_rail_and_projection_omission(self):
|
|
from contextlib import ExitStack
|
|
from pathlib import Path
|
|
from openpilot.starpilot.ui.onroad import OnroadView
|
|
from openpilot.starpilot.ui.appearance_preferences import OnroadAppearance
|
|
from openpilot.starpilot.ui.onroad_state import OnroadState, SpeedLimitObservation
|
|
from openpilot.starpilot.ui.presentation import Profile
|
|
|
|
fonts = Mock(profile=Profile.LARGE)
|
|
fonts.measure.return_value = NS(width=100, height=30)
|
|
state = OnroadState(False, False, None, None, SpeedLimitObservation(), viewport_width=1560,
|
|
appearance=OnroadAppearance(show_developer_sidebar=True),
|
|
developer_metrics=self.observe(DeveloperMetrics()))
|
|
with ExitStack() as stack:
|
|
for name in ('draw_rectangle_rec', 'draw_rectangle_gradient_v', 'draw_rectangle_lines_ex',
|
|
'draw_rectangle_rounded', 'draw_rectangle_rounded_lines_ex', 'draw_line_ex', 'draw_circle', 'draw_texture_pro',
|
|
'rl_push_matrix', 'rl_translatef', 'rl_pop_matrix'):
|
|
stack.enter_context(patch('openpilot.starpilot.ui.onroad.rl.' + name))
|
|
stack.enter_context(patch('openpilot.starpilot.ui.onroad.clip.begin_scissor_mode'))
|
|
stack.enter_context(patch('openpilot.starpilot.ui.onroad.clip.end_scissor_mode'))
|
|
stack.enter_context(patch('openpilot.starpilot.ui.onroad.render_corner_hint'))
|
|
stack.enter_context(patch('openpilot.starpilot.ui.onroad.gui_app.add_render_prepare'))
|
|
rail = stack.enter_context(patch('openpilot.starpilot.ui.onroad.render_live_sidebar'))
|
|
view = OnroadView(fonts, Path('/unused'))
|
|
view.unified_speed = view.current_speed = view.steering_wheel = Mock()
|
|
view.navigation = view.alert = Mock()
|
|
view._large(state)
|
|
self.assertEqual(rail.call_args.args[1].x, 1560)
|
|
self.assertEqual(rail.call_args.args[1].width, 300)
|
|
for width in (1860, 2160):
|
|
rail.reset_mock()
|
|
expanded = replace(state, viewport_width=width, appearance=replace(state.appearance, show_developer_sidebar=False))
|
|
view._large(expanded)
|
|
rail.assert_not_called()
|
|
self.assertEqual(view.current_speed.render.call_args.args[0].width, width - 60)
|
|
self.assertEqual(view.alert.render.call_args.args[0].width, width - 60)
|
|
rail.reset_mock()
|
|
view.projection_viewport = (1280, 720)
|
|
view._large(state)
|
|
rail.assert_not_called()
|
|
|
|
def test_runtime_viewport_follows_sidebar_choice_and_left_menu_without_lag(self):
|
|
from openpilot.starpilot.ui.tests.test_runtime_layouts import runtime_app
|
|
from openpilot.starpilot.ui.onroad_state import OnroadState, SpeedLimitObservation
|
|
from openpilot.starpilot.ui.presentation import Profile
|
|
from openpilot.starpilot.ui.settings_state import Destination, SettingsState
|
|
from openpilot.starpilot.ui.shell import ShellMode, ShellSnapshot
|
|
|
|
session = runtime_app.StarShellSession.__new__(runtime_app.StarShellSession)
|
|
session.profile = Profile.LARGE
|
|
session.selected = Destination.STAR
|
|
session.compact_y = session.compact_scroll_x = 0
|
|
session.sidebar_expanded = True
|
|
state = OnroadState(False, False, None, None, SpeedLimitObservation())
|
|
session.adapter = cast(runtime_app.RuntimeSnapshotAdapter, NS(ui_state=NS(sm=NS(frame=1)), build=Mock()))
|
|
for page_width, shown, expected in ((2160, True, 1860), (2160, False, 2160),
|
|
(1860, False, 1860), (1860, True, 1560), (2160, True, 1860)):
|
|
session._onroad_page_width = page_width
|
|
session._snapshot_cache = None
|
|
session.adapter.build.return_value = ShellSnapshot(ShellMode.ONROAD, Mock(), SettingsState(),
|
|
replace(state, appearance=replace(state.appearance, show_developer_sidebar=shown)))
|
|
snapshot = session.snapshot(ShellMode.ONROAD)
|
|
self.assertEqual(snapshot.onroad.viewport_width, expected)
|
|
self.assertIs(session.snapshot(ShellMode.ONROAD), snapshot)
|