mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-05 03:54:04 +08:00
Separate Volt CC steering minimum from cruise engagement
This commit is contained in:
@@ -19,6 +19,8 @@ class CarEvents:
|
||||
self.CP = CP
|
||||
self.event_rules = event_rules(CP)
|
||||
|
||||
from opendbc.car.gm.values import is_volt_cc_profile
|
||||
self.volt_cc_profile = CP.brand == "gm" and is_volt_cc_profile(CP)
|
||||
self.steering_unpressed = 0
|
||||
self.low_speed_alert = False
|
||||
self.no_steer_warning = False
|
||||
@@ -74,6 +76,12 @@ class CarEvents:
|
||||
events.add(EventName.manualRestart)
|
||||
|
||||
elif self.CP.brand == 'gm':
|
||||
if self.volt_cc_profile:
|
||||
# Conventional LONG requires the car's cruise acknowledgment. MAIN alone
|
||||
# still arms independent steering and cannot create a LONG engagement.
|
||||
if (CS.canValid and not CS.canTimeout and CS.cruiseState.available and CS.cruiseState.enabled and
|
||||
(CS.buttonEnable or not CS_prev.cruiseState.enabled)):
|
||||
events.add(EventName.buttonEnable)
|
||||
# Enabling at a standstill with brake is allowed
|
||||
# TODO: verify 17 Volt can enable for the first time at a stop and allow for all GMs
|
||||
if CS.vEgo < self.CP.minEnableSpeed and not (CS.standstill and CS.brakePressed and
|
||||
@@ -152,7 +160,7 @@ class CarEvents:
|
||||
events.add(EventName.invalidLkasSetting)
|
||||
if CS.lowSpeedAlert:
|
||||
events.add(EventName.belowSteerSpeed)
|
||||
if CS.buttonEnable:
|
||||
if CS.buttonEnable and not self.volt_cc_profile:
|
||||
events.add(EventName.buttonEnable)
|
||||
|
||||
# Handle cancel button presses
|
||||
|
||||
@@ -26,8 +26,8 @@ def test_cold_park_main_waits_without_losing_intent(index, main_action):
|
||||
_exercise_parked_main(index, main_action)
|
||||
|
||||
|
||||
def _exercise_parked_main(index, main_action, *, below_engage=False):
|
||||
cp = list(cases())[index]
|
||||
def _exercise_parked_main(index, main_action, *, below_engage=False, cp=None):
|
||||
cp = list(cases())[index] if cp is None else cp
|
||||
case = fixture.IoniqAvailabilityTests(methodName='runTest')
|
||||
with OpenpilotPrefix(), ExitStack() as cleanup:
|
||||
cleanup.callback(case.doCleanups)
|
||||
@@ -44,6 +44,9 @@ def _exercise_parked_main(index, main_action, *, below_engage=False):
|
||||
cleanup.callback(card.vehicle_startup.close)
|
||||
card.ci_initialized = True
|
||||
card.car_params_published = True
|
||||
if getattr(card, 'volt_cc_selected', False):
|
||||
card.volt_cc_boot_offset_ns = 0
|
||||
card.volt_cc_source_floor_ns = 9_000_000_000
|
||||
card.sm.frame = 1
|
||||
assert card.CP.to_dict() == sd.CP.to_dict() == controls.CP.to_dict()
|
||||
original_pm = card.pm
|
||||
@@ -159,6 +162,11 @@ def _exercise_parked_main(index, main_action, *, below_engage=False):
|
||||
def receive_card(now):
|
||||
nonlocal last_control_stamp
|
||||
rows = list(wire_batch(now))
|
||||
if getattr(card, 'volt_cc_selected', False):
|
||||
device = messaging.new_message('deviceState', valid=True, logMonoTime=now)
|
||||
device.deviceState.started = True
|
||||
device.deviceState.startedMonoTime = 9_000_000_000
|
||||
rows.append(device.as_reader())
|
||||
rows += [sd.pm.messages[k] for k in ('aolAxisState', 'selfdriveState', 'onroadEvents') if k in sd.pm.messages]
|
||||
published = controls.pm.messages['carControl']
|
||||
if published.logMonoTime != last_control_stamp:
|
||||
@@ -178,10 +186,19 @@ def _exercise_parked_main(index, main_action, *, below_engage=False):
|
||||
def physical(tick, stamp, driving):
|
||||
speed = max(4.0, cp.minSteerSpeed + 2.0)
|
||||
if below_engage:
|
||||
speed = cp.minSteerSpeed + 0.05
|
||||
assert speed < cp.minEnableSpeed
|
||||
else:
|
||||
speed = max(speed, cp.minEnableSpeed + 2.0)
|
||||
packets = parsed_packets(cp, packer, stamp, tick, speed if driving else 0.0, True)
|
||||
from opendbc.car.gm.values import CAR, is_volt_cc_f1_profile
|
||||
if is_volt_cc_f1_profile(cp):
|
||||
packets = [f for f in packets if f[0] != 0xBE]
|
||||
packets.append(packer.make_can_msg('EBCMBrakePedalPosition', 0, {}))
|
||||
if cp.carFingerprint == CAR.CHEVROLET_VOLT_CC and tick in (320, 321):
|
||||
button = packer.make_can_msg('ASCMSteeringButton', 0,
|
||||
{'ACCButtons': 3 if tick == 320 else 1, 'RollingCounter': tick % 4})
|
||||
packets = [f for f in packets if f[0] != button[0]] + [button]
|
||||
packets = [f for f in packets if f[0] not in (0x1F5, 0x12A, 0x184, 0x17D)]
|
||||
if cp.pcmCruise and cp.networkLocation == structs.CarParams.NetworkLocation.fwdCamera:
|
||||
address = packer.make_can_msg('ASCMActiveCruiseControlStatus', 2, {})[0]
|
||||
@@ -210,7 +227,7 @@ def _exercise_parked_main(index, main_action, *, below_engage=False):
|
||||
assert safety.safety_config_valid() and safety.aol_get_permission_mask() == 0
|
||||
tx = 0
|
||||
active = 0
|
||||
for tick in range(1, 381):
|
||||
for tick in range(1, 581 if below_engage and cp.carFingerprint == "CHEVROLET_VOLT_CC" else 381):
|
||||
now = 10_020_000_000 + (tick - 1) * 10_000_000
|
||||
driving = tick > 300
|
||||
safety.set_timer(now // 1000)
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
from dataclasses import replace
|
||||
|
||||
import pytest
|
||||
from opendbc.car import structs
|
||||
from opendbc.car.common.conversions import Conversions as CV
|
||||
from opendbc.car.gm.tests.test_volt_cc_f1 import params as f1_params
|
||||
from opendbc.car.gm.tests.test_volt_cc_gas import fixture as be_fixture
|
||||
from openpilot.cereal import log
|
||||
from openpilot.selfdrive.car.car_events import CarEvents
|
||||
from openpilot.starpilot.aol.tests.test_gm_cc_lateral_minimum import setup
|
||||
from openpilot.starpilot.aol.tests.test_gm_parked_startup import _exercise_parked_main
|
||||
from openpilot.starpilot.car.gm.aol import cc_independent_lateral_below_engage
|
||||
|
||||
|
||||
def params(f1):
|
||||
cp = f1_params() if f1 else be_fixture()[0]
|
||||
cp.alternativeExperience = 32
|
||||
return cp
|
||||
|
||||
|
||||
@pytest.mark.parametrize('f1', [False, True])
|
||||
def test_volt_cc_steering_minimum_keeps_cruise_minimum(f1):
|
||||
cp = params(f1)
|
||||
_, intent = setup()
|
||||
assert cp.minSteerSpeed == pytest.approx(7 * CV.MPH_TO_MS)
|
||||
assert cp.minEnableSpeed == pytest.approx(24 * CV.MPH_TO_MS)
|
||||
assert cc_independent_lateral_below_engage(cp, intent, enabled=False, active=False)
|
||||
assert not cc_independent_lateral_below_engage(cp, replace(intent, allowedLatch=False), enabled=False, active=False)
|
||||
assert not cc_independent_lateral_below_engage(cp, intent, enabled=True, active=True)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('f1', [False, True])
|
||||
@pytest.mark.parametrize('active,previous,button,valid,expected', [
|
||||
(False, False, True, True, False), (True, False, False, True, True),
|
||||
(True, True, True, True, True), (True, True, False, True, False),
|
||||
(True, False, False, False, False)])
|
||||
def test_volt_cc_long_waits_for_real_cruise_ack(f1, active, previous, button, valid, expected):
|
||||
cp = params(f1)
|
||||
cs = structs.CarState(canValid=valid, buttonEnable=button, vEgo=12, gearShifter='drive')
|
||||
cs.cruiseState.available = True
|
||||
cs.cruiseState.enabled = active
|
||||
prior = structs.CarState()
|
||||
prior.cruiseState.enabled = previous
|
||||
events = CarEvents(cp).update(cs, prior, structs.CarControl())
|
||||
assert (log.OnroadEvent.EventName.buttonEnable in events.names) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize('f1', [False, True])
|
||||
def test_volt_cc_main_already_on_arms_steering_at_seven_mph(f1):
|
||||
_exercise_parked_main(0, 0, below_engage=True, cp=params(f1))
|
||||
@@ -29,10 +29,10 @@ def native_accepts_cp(cp, model: int, param: int) -> bool:
|
||||
|
||||
|
||||
def cc_independent_lateral_below_engage(cp, intent, *, enabled, active):
|
||||
"""An armed independent Bolt LAT request uses its steering speed gate."""
|
||||
from opendbc.car.gm.values import is_bolt_cc_profile
|
||||
"""An armed conventional-cruise LAT request uses its steering speed gate."""
|
||||
from opendbc.car.gm.values import is_bolt_cc_profile, is_volt_cc_profile
|
||||
return bool(not enabled and not active and qualified_gm(cp) and aol_enabled(cp) and
|
||||
is_bolt_cc_profile(cp) and intent is not None and intent.settingsQualified and
|
||||
(is_bolt_cc_profile(cp) or is_volt_cc_profile(cp)) and intent is not None and intent.settingsQualified and
|
||||
intent.allowedLatch and intent.lateralArmed and not intent.pauseLateral)
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"protected_inventory_sha256": "df360061636f084000aa4afe04c561fc519e8cebcb1c84a483a8eb716452db98", "schema_version": 1}
|
||||
{"protected_inventory_sha256": "505172af4fab7bd15c27b90d3c52205e2a64db67875aa1447008cc0ed932c5dc", "schema_version": 1}
|
||||
|
||||
Reference in New Issue
Block a user