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>
90 lines
4.7 KiB
Python
90 lines
4.7 KiB
Python
"""Saved assist reaches the model/torque path only with existing rolling authority."""
|
|
|
|
import json
|
|
import os
|
|
import unittest
|
|
from unittest.mock import patch
|
|
|
|
from openpilot.common.params import Params
|
|
from openpilot.common.prefix import OpenpilotPrefix
|
|
from openpilot.selfdrive.controls.controlsd import Controls
|
|
from openpilot.starpilot.lateral.tests.test_lane_runtime import feed, ioniq_candidate
|
|
from openpilot.starpilot.lateral.controller_selection import ControllerMode, DOCUMENT_KEY, replace_mode
|
|
|
|
|
|
def rolling_feed(controls, timestamp, tick, *, speed=.5, standstill=False, fault=False, active=True, gear='drive'):
|
|
captured = []
|
|
with patch.object(controls.sm, 'update_msgs', side_effect=lambda _time, events: captured.extend(events)):
|
|
feed(controls, timestamp, tick, fault=fault, active=active, enabled=active, signal=True)
|
|
events = [event.as_builder() for event in captured]
|
|
cs = next(event.carState for event in events if event.which() == 'carState')
|
|
cs.vEgo = cs.vEgoRaw = speed
|
|
cs.standstill = standstill
|
|
cs.gearShifter = gear
|
|
cs.aEgo = -.1
|
|
cs.leftBlinker = False
|
|
cs.rightBlinker = True
|
|
if tick % 5 == 0:
|
|
md = next(event.modelV2 for event in events if event.which() == 'modelV2')
|
|
md.position.x = [float(x) for x in range(51)]
|
|
md.position.y = [.1 * x * x for x in range(51)]
|
|
md.action.desiredCurvature = .0001
|
|
controls.sm.update_msgs(timestamp / 1e9, [event.as_reader() for event in events])
|
|
|
|
|
|
class TestTurnModelRuntime(unittest.TestCase):
|
|
def construct(self, enabled, mode=ControllerMode.STARPILOT):
|
|
cp, _ = ioniq_candidate()
|
|
params = Params()
|
|
params.put('CarParams', cp.to_bytes(), block=True)
|
|
params.put_bool('TurnAssist', enabled, block=True)
|
|
params.put_bool('OpenpilotEnabledToggle', True, block=True)
|
|
params.put(DOCUMENT_KEY, json.loads(replace_mode(None, cp, mode)), block=True)
|
|
return Controls()
|
|
|
|
def test_explicit_off_preserves_each_controller_commands(self):
|
|
for mode in (ControllerMode.STARPILOT, ControllerMode.STANDARD):
|
|
with self.subTest(mode=mode), OpenpilotPrefix(), patch.dict(os.environ, {'SIMULATION': '1', 'REPLAY': '1', 'AOL_REPLAY_RUNTIME': '0'}):
|
|
selected = self.construct(False, mode)
|
|
reference = self.construct(False, mode)
|
|
for tick in range(20):
|
|
now = 1_000_000_000 + tick * 10_000_000
|
|
rolling_feed(selected, now, tick)
|
|
rolling_feed(reference, now, tick)
|
|
actual, _ = selected.state_control()
|
|
expected, _ = reference.state_control()
|
|
self.assertEqual(actual.to_bytes(), expected.to_bytes())
|
|
self.assertEqual(selected.model_turn_assist.turn_hold_curvature, 0.)
|
|
|
|
def test_model_bias_reaches_actual_curvature_and_torque_limits(self):
|
|
for mode in (ControllerMode.STANDARD, ControllerMode.STARPILOT):
|
|
with OpenpilotPrefix(), patch.dict(os.environ, {'SIMULATION': '1', 'REPLAY': '1', 'AOL_REPLAY_RUNTIME': '0'}):
|
|
controls = self.construct(True, mode)
|
|
reference = self.construct(False, mode)
|
|
before = controls.LaC.torque_params.to_dict()
|
|
maximum_hold = maximum_difference = 0.
|
|
with patch.object(controls.model_turn_assist, 'update', wraps=controls.model_turn_assist.update) as update:
|
|
for tick in range(120):
|
|
rolling_feed(controls, 1_000_000_000 + tick * 10_000_000, tick)
|
|
rolling_feed(reference, 1_000_000_000 + tick * 10_000_000, tick)
|
|
command, _ = controls.state_control()
|
|
reference.state_control()
|
|
maximum_hold = max(maximum_hold, abs(controls.model_turn_assist.turn_hold_curvature))
|
|
maximum_difference = max(maximum_difference, abs(controls.desired_curvature - reference.desired_curvature))
|
|
self.assertLessEqual(abs(command.actuators.torque), 1.)
|
|
self.assertEqual(update.call_count, 120)
|
|
self.assertGreater(maximum_hold, 0.)
|
|
self.assertGreater(maximum_difference, 0.)
|
|
self.assertEqual(controls.LaC.torque_params.to_dict(), before)
|
|
|
|
def test_standstill_speed_fault_reverse_and_inactive_deny_assist(self):
|
|
for gate in ({'speed': 0.}, {'speed': .044}, {'standstill': True}, {'fault': True}, {'gear': 'reverse'}, {'active': False}):
|
|
with self.subTest(gate=gate), OpenpilotPrefix(), patch.dict(os.environ, {'SIMULATION': '1', 'REPLAY': '1', 'AOL_REPLAY_RUNTIME': '0'}):
|
|
controls = self.construct(True)
|
|
with patch.object(controls.model_turn_assist, 'update', wraps=controls.model_turn_assist.update) as update:
|
|
for tick in range(10):
|
|
rolling_feed(controls, 1_000_000_000 + tick * 10_000_000, tick, **gate)
|
|
controls.state_control()
|
|
update.assert_not_called()
|
|
self.assertEqual(controls.model_turn_assist.turn_hold_curvature, 0.)
|