mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-10-01 03:43:46 +08:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2a12dbd0ad |
@@ -237,8 +237,6 @@ struct StarPilotPlan @0xf98d843bfd7004a3 {
|
||||
cscLearnedLatAccel @40 :Float32; # learned comfort at the current curvature, before margin
|
||||
cscBindingDistance @41 :Float32; # distance to the horizon point setting the target, m
|
||||
approachStopLength @42 :Float32; # pre-commit distance to a detected stop, m; 0 when off
|
||||
slcPresentedSpeedLimitSource @43 :Text; # source of the shown accepted or pending posted limit
|
||||
slcIsLimitingMaxSet @44 :Bool; # SLC target is below the configured Max Set
|
||||
}
|
||||
|
||||
struct StarPilotRadarState @0xb86e6369214c01c8 {
|
||||
|
||||
Binary file not shown.
@@ -744,7 +744,6 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
||||
{"SubaruAvhStartup", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||
{"SubaruRedneckCruise", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||
{"TacoTune", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||
{"TeslaAOLDisengageOnBrake", {PERSISTENT, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||
{"TeslaCoopSteering", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||
{"TestAlert", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
||||
{"TetheringEnabled", {PERSISTENT, INT, "0", "0", 0}},
|
||||
|
||||
Binary file not shown.
+2
-2
@@ -21,11 +21,11 @@ fi
|
||||
export QCOM_PRIORITY=12
|
||||
|
||||
if [ -z "$AGNOS_VERSION" ]; then
|
||||
export AGNOS_VERSION="19.8.1"
|
||||
export AGNOS_VERSION="19.6.20"
|
||||
fi
|
||||
|
||||
if [ -z "$AGNOS_ACCEPTED_VERSIONS" ]; then
|
||||
export AGNOS_ACCEPTED_VERSIONS="19.8.1 19.8.2"
|
||||
export AGNOS_ACCEPTED_VERSIONS="$AGNOS_VERSION"
|
||||
fi
|
||||
|
||||
export STAGING_ROOT="/data/safe_staging"
|
||||
|
||||
@@ -4,7 +4,7 @@ from opendbc.can import CANPacker
|
||||
from opendbc.car import ACCELERATION_DUE_TO_GRAVITY, Bus, DT_CTRL, structs
|
||||
from opendbc.car.lateral import ISO_LATERAL_ACCEL, apply_std_steer_angle_limits
|
||||
from opendbc.car.ford import fordcan
|
||||
from opendbc.car.ford.values import CAR, CarControllerParams, FordFlags
|
||||
from opendbc.car.ford.values import CarControllerParams, FordFlags
|
||||
from opendbc.car.interfaces import CarControllerBase, V_CRUISE_MAX
|
||||
# This Ford extension boundary substantially adapts BluePilot bp-7.0 work. See the root CREDITS.md
|
||||
# (including Alan Polk's d0aac605f and db2bdff05) and THIRD_PARTY_NOTICES.md.
|
||||
@@ -64,9 +64,7 @@ def apply_ford_curvature_limits(apply_curvature, apply_curvature_last, current_c
|
||||
return apply_curvature
|
||||
|
||||
|
||||
def apply_creep_compensation(accel: float, v_ego: float, car_fingerprint: str, *, standstill: bool, stopping: bool) -> float:
|
||||
if car_fingerprint == CAR.FORD_MUSTANG_MACH_E_MK1 and not (standstill and stopping):
|
||||
return accel
|
||||
def apply_creep_compensation(accel: float, v_ego: float) -> float:
|
||||
creep_accel = np.interp(v_ego, [1., 3.], [0.6, 0.])
|
||||
creep_accel = np.interp(accel, [0., 0.2], [creep_accel, 0.])
|
||||
accel -= creep_accel
|
||||
@@ -167,7 +165,7 @@ class CarController(CarControllerBase):
|
||||
can_sends.append(starpilot_fordcan.create_lat_ctl2_msg(
|
||||
self.packer, self.CAN, 1 if lateral.active else 0,
|
||||
lateral.ramp_type, lateral.precision_type,
|
||||
-lateral.curvature, -lateral.curvature_rate, counter, -lateral.path_angle))
|
||||
-lateral.curvature, -lateral.curvature_rate, counter))
|
||||
else:
|
||||
can_sends.append(starpilot_fordcan.create_lat_ctl_msg(
|
||||
self.packer, self.CAN, lateral.active,
|
||||
@@ -183,11 +181,12 @@ class CarController(CarControllerBase):
|
||||
if self.CP.openpilotLongitudinalControl and (self.frame % CarControllerParams.ACC_CONTROL_STEP) == 0:
|
||||
accel = actuators.accel
|
||||
gas = accel
|
||||
stopping = actuators.longControlState == LongCtrlState.stopping
|
||||
|
||||
if CC.longActive:
|
||||
accel = apply_creep_compensation(accel, CS.out.vEgo, self.CP.carFingerprint,
|
||||
standstill=CS.out.standstill, stopping=stopping)
|
||||
# Compensate for engine creep at low speed.
|
||||
# Either the ABS does not account for engine creep, or the correction is very slow
|
||||
# TODO: verify this applies to EV/hybrid
|
||||
accel = apply_creep_compensation(accel, CS.out.vEgo)
|
||||
|
||||
# The stock system has been seen rate limiting the brake accel to 5 m/s^3,
|
||||
# however even 3.5 m/s^3 causes some overshoot with a step response.
|
||||
@@ -211,6 +210,7 @@ class CarController(CarControllerBase):
|
||||
elif accel_pitch_compensated < 0.0:
|
||||
self.brake_request = True
|
||||
|
||||
stopping = CC.actuators.longControlState == LongCtrlState.stopping
|
||||
# TODO: look into using the actuators packet to send the desired speed
|
||||
can_sends.append(fordcan.create_acc_msg(self.packer, self.CAN, CC.longActive, gas, accel, stopping, self.brake_request, v_ego_kph=V_CRUISE_MAX))
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ from opendbc.car.ford.carcontroller import CarController
|
||||
from opendbc.car.ford.carstate import CarState
|
||||
from opendbc.car.ford.fordcan import CanBus
|
||||
from opendbc.car.ford.radar_interface import RadarInterface
|
||||
from opendbc.car.ford.values import CAR, CarControllerParams, DBC, Ecu, FordFlags, RADAR, FordSafetyFlags
|
||||
from opendbc.car.ford.values import CarControllerParams, DBC, Ecu, FordFlags, RADAR, FordSafetyFlags
|
||||
from opendbc.car.interfaces import CarInterfaceBase
|
||||
|
||||
TransmissionType = structs.CarParams.TransmissionType
|
||||
@@ -63,8 +63,6 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
if ret.flags & FordFlags.CANFD:
|
||||
ret.safetyConfigs[-1].safetyParam |= FordSafetyFlags.CANFD.value
|
||||
if candidate == CAR.FORD_MUSTANG_MACH_E_MK1:
|
||||
ret.safetyConfigs[-1].safetyParam |= FordSafetyFlags.MACH_E_CURVATURE.value
|
||||
|
||||
# TRON (SecOC) platforms are not supported
|
||||
# LateralMotionControl2, ACCDATA are 16 bytes on these platforms
|
||||
|
||||
@@ -9,7 +9,7 @@ import pytest
|
||||
from opendbc.car import Bus, gen_empty_fingerprint
|
||||
from opendbc.can import CANPacker
|
||||
from opendbc.car.ford import fordcan
|
||||
from opendbc.car.ford.carcontroller import FordStockCruiseButton, apply_creep_compensation
|
||||
from opendbc.car.ford.carcontroller import FordStockCruiseButton
|
||||
from opendbc.car.gps import FORD_MACH_E_GPS_MESSAGES, get_car_gps_config, parse_ford_can_gps
|
||||
from opendbc.car.structs import CarParams
|
||||
from opendbc.car.fw_versions import build_fw_dict
|
||||
@@ -38,17 +38,6 @@ def test_stock_cruise_button_ignores_press_with_cruise_master_off():
|
||||
assert button.update(True, cruise_available=False, cruise_enabled=False) == (False, False)
|
||||
|
||||
|
||||
def test_mach_e_does_not_apply_engine_creep_compensation():
|
||||
for accel in (-1.0, -0.1, 0.0, 0.1):
|
||||
assert apply_creep_compensation(accel, 0.5, CAR.FORD_MUSTANG_MACH_E_MK1,
|
||||
standstill=False, stopping=False) == accel
|
||||
|
||||
assert apply_creep_compensation(0.0, 0.0, CAR.FORD_MUSTANG_MACH_E_MK1,
|
||||
standstill=True, stopping=True) == -0.6
|
||||
assert apply_creep_compensation(0.0, 0.5, CAR.FORD_F_150_MK14,
|
||||
standstill=False, stopping=False) == -0.6
|
||||
|
||||
|
||||
ECU_ADDRESSES = {
|
||||
Ecu.eps: 0x730, # Power Steering Control Module (PSCM)
|
||||
Ecu.abs: 0x760, # Anti-Lock Brake System (ABS)
|
||||
@@ -203,12 +192,10 @@ def test_mach_e_longitudinal_toggle_controls_stock_acc_selection():
|
||||
assert not stock.openpilotLongitudinalControl
|
||||
assert stock.pcmCruise
|
||||
assert not (stock.safetyConfigs[-1].safetyParam & FordSafetyFlags.LONG_CONTROL)
|
||||
assert stock.safetyConfigs[-1].safetyParam & FordSafetyFlags.MACH_E_CURVATURE
|
||||
|
||||
assert enhanced.alphaLongitudinalAvailable
|
||||
assert enhanced.openpilotLongitudinalControl
|
||||
assert enhanced.safetyConfigs[-1].safetyParam & FordSafetyFlags.LONG_CONTROL
|
||||
assert enhanced.safetyConfigs[-1].safetyParam & FordSafetyFlags.MACH_E_CURVATURE
|
||||
|
||||
|
||||
def test_mach_e_can_gps_decode():
|
||||
|
||||
@@ -50,7 +50,6 @@ class FordSafetyFlags(IntFlag):
|
||||
LONG_CONTROL = 1
|
||||
CANFD = 2
|
||||
LKA_STEERING = 4
|
||||
MACH_E_CURVATURE = 8
|
||||
|
||||
|
||||
class FordFlags(IntFlag):
|
||||
|
||||
@@ -42,11 +42,9 @@ IONIQ_6_RESPONSE_MULTIPLIER = 1.2
|
||||
IONIQ_6_CANFD_SCC_ACCEL_STEP = (6.0 / 50.0) * IONIQ_6_RESPONSE_MULTIPLIER
|
||||
IONIQ_6_CANFD_SCC_DECEL_STEP = (15.0 / 50.0) * IONIQ_6_RESPONSE_MULTIPLIER
|
||||
EV9_CANFD_SCC_DECEL_STEP = 10.0 / 50.0
|
||||
RAY_PEDAL_COMMAND_CAP = 0.55
|
||||
RAY_PEDAL_RATE_UP = 0.02
|
||||
RAY_PEDAL_COMMAND_CAP = 0.35 # Ray firmware voltage scaling is route-derived; validate before raising.
|
||||
RAY_PEDAL_RATE_UP = 0.012 # per 25 Hz command (0.30 normalized pedal per second)
|
||||
RAY_PEDAL_RATE_DOWN = 0.06
|
||||
RAY_PEDAL_OVERSPEED_CUTOFF = 0.5
|
||||
RAY_PEDAL_TAPER_BELOW_TARGET = 0.75
|
||||
GENESIS_G90_STOP_HOLD_SPEED_BP = [0.0, 0.03, 0.08, 0.16, 0.3, 0.5, 0.8, 1.2, 2.0, 3.0]
|
||||
GENESIS_G90_STOP_HOLD_ACCEL_V = [-0.10, -0.10, -0.12, -0.18, -0.30, -0.50, -0.75, -1.00, -1.40, -1.80]
|
||||
GENESIS_G90_STOP_HOLD_RELAX_SPEED_BP = [0.0, 0.08, 0.16, 0.3, 0.5, 0.8, 1.2, 2.0, 3.0]
|
||||
@@ -770,8 +768,7 @@ class CarController(CarControllerBase):
|
||||
lead_data = self._can_lead_data.update(lead_distance, lead_rel_speed, lead_visible)
|
||||
|
||||
# HUD messages
|
||||
stinger_hud_enabled = CC.enabled or (self.CP.carFingerprint == CAR.KIA_STINGER_2022 and CC.latActive)
|
||||
sys_warning, sys_state, left_lane_warning, right_lane_warning = process_hud_alert(stinger_hud_enabled, self.car_fingerprint,
|
||||
sys_warning, sys_state, left_lane_warning, right_lane_warning = process_hud_alert(CC.enabled, self.car_fingerprint,
|
||||
hud_control)
|
||||
|
||||
if blended_hda2:
|
||||
@@ -812,12 +809,12 @@ class CarController(CarControllerBase):
|
||||
|
||||
# Button messages
|
||||
if not self.long_active_ecu:
|
||||
if self._ray_pedal and CC.enabled and CS.out.cruiseState.enabled:
|
||||
if (self.frame - self.last_button_frame) * DT_CTRL > 0.04:
|
||||
if self.cancel_counter > CANCEL_BUTTON_DELAY_FRAMES:
|
||||
can_sends.append(hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.CANCEL, self.CP))
|
||||
elif self._ray_pedal and CC.enabled and CS.out.cruiseState.enabled:
|
||||
if (self.frame - self.last_button_frame) * DT_CTRL > 0.1:
|
||||
can_sends.append(hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.CANCEL, self.CP))
|
||||
self.last_button_frame = self.frame
|
||||
elif self.cancel_counter > CANCEL_BUTTON_DELAY_FRAMES:
|
||||
can_sends.append(hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.CANCEL, self.CP))
|
||||
elif CC.cruiseControl.resume and not self._ray_pedal:
|
||||
# send resume at a max freq of 10Hz
|
||||
if (self.frame - self.last_button_frame) * DT_CTRL > 0.1:
|
||||
@@ -832,29 +829,14 @@ class CarController(CarControllerBase):
|
||||
if self._ray_pedal and self.frame % 4 == 0:
|
||||
pedal_ready = CS.ray_pedal_valid and CS.ray_pedal_state == 0
|
||||
pedal_active = (CC.longActive and pedal_ready and not CC.cruiseControl.override and
|
||||
not CS.out.gasPressed and not CS.out.brakePressed)
|
||||
not CS.out.gasPressed and not CS.out.brakePressed and
|
||||
not CS.out.cruiseState.enabled)
|
||||
if pedal_active:
|
||||
set_speed = hud_control.setSpeed
|
||||
if not np.isfinite(set_speed) or set_speed < 1.0:
|
||||
self._ray_pedal_gas_last = 0.0
|
||||
else:
|
||||
speed_error = set_speed - CS.out.vEgo
|
||||
if speed_error <= -RAY_PEDAL_OVERSPEED_CUTOFF:
|
||||
self._ray_pedal_gas_last = 0.0
|
||||
else:
|
||||
pedal_offset = float(np.interp(CS.out.vEgo, [0., 2., 4., 8., 12., 20.],
|
||||
[0.08, 0.13, 0.20, 0.32, 0.42, 0.48]))
|
||||
pedal_gain = 2.0 if accel < 0.0 else 0.22
|
||||
target = float(np.clip(pedal_offset + accel * pedal_gain, 0.0, RAY_PEDAL_COMMAND_CAP))
|
||||
if speed_error < 0.0:
|
||||
target *= float(np.clip(0.65 * (1.0 + speed_error / RAY_PEDAL_OVERSPEED_CUTOFF), 0.0, 1.0))
|
||||
elif speed_error < RAY_PEDAL_TAPER_BELOW_TARGET:
|
||||
target *= 0.65 + 0.35 * speed_error / RAY_PEDAL_TAPER_BELOW_TARGET
|
||||
if target <= 0.001:
|
||||
self._ray_pedal_gas_last = 0.0
|
||||
else:
|
||||
next_gas = rate_limit(target, self._ray_pedal_gas_last, -RAY_PEDAL_RATE_DOWN, RAY_PEDAL_RATE_UP)
|
||||
self._ray_pedal_gas_last = min(next_gas, target)
|
||||
target = float(np.clip(accel / CarControllerParams.ACCEL_MAX * RAY_PEDAL_COMMAND_CAP,
|
||||
0.0, RAY_PEDAL_COMMAND_CAP))
|
||||
self._ray_pedal_gas_last = rate_limit(
|
||||
target, self._ray_pedal_gas_last, -RAY_PEDAL_RATE_DOWN, RAY_PEDAL_RATE_UP,
|
||||
)
|
||||
else:
|
||||
self._ray_pedal_gas_last = 0.0
|
||||
can_sends.append(create_gas_interceptor_command(
|
||||
|
||||
@@ -12,7 +12,7 @@ _adrv_0x51_templates: dict[CAR, bytes] = {}
|
||||
|
||||
|
||||
def cache_adrv_0x51_template(car_fingerprint: CAR, dat: bytes | None) -> None:
|
||||
if car_fingerprint not in (CAR.KIA_EV6, CAR.GENESIS_GV70_ELECTRIFIED_1ST_GEN):
|
||||
if car_fingerprint != CAR.KIA_EV6:
|
||||
return
|
||||
|
||||
if dat is None:
|
||||
@@ -26,6 +26,7 @@ def create_adrv_0x51(packer, CAN, frame: int, car_fingerprint: CAR | None = None
|
||||
if template is None:
|
||||
return packer.make_can_msg("ADRV_0x51", CAN.ACAN, {})
|
||||
|
||||
# EV6 MRR30 tracks stop when the ADAS takeover replaces this platform payload with zeros.
|
||||
dat = bytearray(template)
|
||||
dat[2] = (template[2] + frame + 1) & 0xFF
|
||||
dat[3] = (dat[3] & ~0x1) | int(drive_gear)
|
||||
|
||||
@@ -201,8 +201,6 @@ class CarInterface(CarInterfaceBase):
|
||||
if ret.flags & HyundaiFlags.CANFD_ANGLE_STEERING:
|
||||
ret.steerControlType = structs.CarParams.SteerControlType.angle
|
||||
ret.safetyConfigs[-1].safetyParam |= HyundaiSafetyFlags.CANFD_ANGLE_STEERING.value
|
||||
if candidate == CAR.KIA_SPORTAGE_HEV_2026:
|
||||
ret.safetyConfigs[-1].safetyParam |= HyundaiStarPilotSafetyFlags.CANFD_NO_STOCK_LKA.value
|
||||
if candidate == CAR.HYUNDAI_IONIQ_6:
|
||||
# Keep lateral active through stops: zeroing torque at standstill dropped the
|
||||
# stop-turn hold and forced a rate-limit re-ramp from zero on every pull-away
|
||||
@@ -333,8 +331,8 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
if candidate == CAR.HYUNDAI_ELANTRA_2021:
|
||||
ret.longitudinalActuatorDelay = 0.22
|
||||
ret.stopAccel = -1.1
|
||||
ret.stoppingDecelRate = 0.55
|
||||
ret.stopAccel = -0.85
|
||||
ret.stoppingDecelRate = 0.35
|
||||
|
||||
if candidate == CAR.HYUNDAI_ELANTRA_HEV_2024:
|
||||
ret.longitudinalActuatorDelay = 0.22
|
||||
@@ -395,7 +393,7 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
if not skip_disable_ecu:
|
||||
disable_can_recv = can_recv
|
||||
if CP.carFingerprint in (CAR.KIA_EV6, CAR.GENESIS_GV70_ELECTRIFIED_1ST_GEN) and can_recv is not None:
|
||||
if CP.carFingerprint == CAR.KIA_EV6 and can_recv is not None:
|
||||
hyundaicanfd.cache_adrv_0x51_template(CP.carFingerprint, None)
|
||||
base_can_recv = can_recv
|
||||
adrv_bus = CanBus(CP).ACAN
|
||||
|
||||
@@ -552,13 +552,6 @@ class TestHyundaiFingerprint:
|
||||
CP = CarInterface.get_params(CAR.KIA_SPORTAGE_HEV_2026, fingerprint, [], False, False, False, None)
|
||||
assert CP.flags & HyundaiFlags.SEND_LFA
|
||||
|
||||
@pytest.mark.parametrize("candidate", list(CAR))
|
||||
def test_no_stock_lka_safety_flag_is_sportage_only(self, candidate):
|
||||
CP = CarInterface.get_params(candidate, gen_empty_fingerprint(), [], False, False, False, None)
|
||||
if CP.flags & HyundaiFlags.CANFD:
|
||||
assert bool(CP.safetyConfigs[-1].safetyParam & HyundaiStarPilotSafetyFlags.CANFD_NO_STOCK_LKA) == \
|
||||
(candidate == CAR.KIA_SPORTAGE_HEV_2026)
|
||||
|
||||
def test_smart_mdps_allows_low_speed_steering(self):
|
||||
candidate = CAR.HYUNDAI_IONIQ_EV_LTD
|
||||
|
||||
@@ -1086,31 +1079,6 @@ class TestHyundaiFingerprint:
|
||||
|
||||
assert not (FPCP.flags & HyundaiStarPilotFlags.HAS_LKAS12)
|
||||
|
||||
@pytest.mark.parametrize("length, expected", ((6, True), (8, False)))
|
||||
def test_stinger_only_replaces_six_byte_lkas12(self, length, expected):
|
||||
fingerprint = gen_empty_fingerprint()
|
||||
fingerprint[2][0x53E] = length
|
||||
CP = CarInterface.get_params(CAR.KIA_STINGER_2022, fingerprint, [], True, False, False, None)
|
||||
FPCP = CarInterface.get_starpilot_params(CAR.KIA_STINGER_2022, fingerprint, [], CP, get_test_toggles())
|
||||
|
||||
assert bool(FPCP.flags & HyundaiStarPilotFlags.HAS_LKAS12) is expected
|
||||
|
||||
@pytest.mark.parametrize("alpha_long, main_aol, expected", (
|
||||
(True, True, True), (True, False, True), (False, True, False),
|
||||
))
|
||||
def test_stinger_aol_latches_lkas_after_long_engagement(self, alpha_long, main_aol, expected):
|
||||
toggles = get_test_toggles()
|
||||
toggles.always_on_lateral_main = main_aol
|
||||
fingerprint = gen_empty_fingerprint()
|
||||
CP = CarInterface.get_params(CAR.KIA_STINGER_2022, fingerprint, [], alpha_long, False, False, toggles)
|
||||
FPCP = CarInterface.get_starpilot_params(CAR.KIA_STINGER_2022, fingerprint, [], CP, toggles)
|
||||
|
||||
assert bool(FPCP.safetyConfigs[-1].safetyParam & HyundaiStarPilotSafetyFlags.AOL_LKAS_ON_ENGAGE) is expected
|
||||
|
||||
sonata_cp = CarInterface.get_params(CAR.HYUNDAI_SONATA, fingerprint, [], alpha_long, False, False, toggles)
|
||||
sonata_fpcp = CarInterface.get_starpilot_params(CAR.HYUNDAI_SONATA, fingerprint, [], sonata_cp, toggles)
|
||||
assert not (sonata_fpcp.safetyConfigs[-1].safetyParam & HyundaiStarPilotSafetyFlags.AOL_LKAS_ON_ENGAGE)
|
||||
|
||||
def test_ray_ev_does_not_treat_eight_byte_485_as_lfa(self):
|
||||
fingerprint = gen_empty_fingerprint()
|
||||
fingerprint[2][0x485] = 8
|
||||
@@ -1316,103 +1284,6 @@ class TestHyundaiFingerprint:
|
||||
assert canfd_alt_buttons_cp.flags & HyundaiFlags.CANFD_ALT_BUTTONS
|
||||
assert not canfd_alt_buttons_fpcp.redneckCruiseAvailable
|
||||
|
||||
def test_sportage_hev_hda2_redneck_uses_stock_scc(self, monkeypatch):
|
||||
class FakeParams:
|
||||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def get_bool(key):
|
||||
return key == "RedneckCruise"
|
||||
|
||||
monkeypatch.setattr("opendbc.car.interfaces.Params", FakeParams)
|
||||
toggles = get_test_toggles()
|
||||
fingerprint = gen_empty_fingerprint()
|
||||
can_bus = CanBus(None, fingerprint, True)
|
||||
fingerprint[can_bus.CAM][0x110] = 32
|
||||
fingerprint[can_bus.ECAN][0x1CF] = 8
|
||||
|
||||
CP = CarInterface.get_params(CAR.KIA_SPORTAGE_HEV_2026, fingerprint, [], False, False, False, toggles)
|
||||
FPCP = CarInterface.get_starpilot_params(CAR.KIA_SPORTAGE_HEV_2026, fingerprint, [], CP, toggles)
|
||||
|
||||
assert CP.flags & HyundaiFlags.CANFD_LKA_STEERING
|
||||
assert FPCP.redneckCruiseAvailable
|
||||
assert not FPCP.pcmCruiseSpeed
|
||||
assert CP.pcmCruise
|
||||
assert not CP.openpilotLongitudinalControl
|
||||
assert not CP.safetyConfigs[-1].safetyParam & HyundaiSafetyFlags.LONG
|
||||
controller = CarInterface(CP, FPCP).CC
|
||||
assert not controller.long_active_ecu
|
||||
|
||||
controller.frame = 30
|
||||
CS = SimpleNamespace(redneck_send_button=1, buttons_counter=5)
|
||||
msgs = controller._create_canfd_redneck_button_messages(CS)
|
||||
assert len(msgs) == 20
|
||||
assert all(msg[0] == 0x1CF and msg[2] == can_bus.ECAN for msg in msgs)
|
||||
assert all(msg[1][2] & 0x7 == Buttons.RES_ACCEL for msg in msgs)
|
||||
|
||||
controller.frame = 60
|
||||
CS.redneck_send_button = 2
|
||||
msgs = controller._create_canfd_redneck_button_messages(CS)
|
||||
assert len(msgs) == 20
|
||||
assert all(msg[1][2] & 0x7 == Buttons.SET_DECEL for msg in msgs)
|
||||
|
||||
monkeypatch.setattr(FakeParams, "get_bool", staticmethod(lambda key: False))
|
||||
CP = CarInterface.get_params(CAR.KIA_SPORTAGE_HEV_2026, fingerprint, [], False, False, False, toggles)
|
||||
FPCP = CarInterface.get_starpilot_params(CAR.KIA_SPORTAGE_HEV_2026, fingerprint, [], CP, toggles)
|
||||
assert FPCP.redneckCruiseAvailable
|
||||
assert FPCP.pcmCruiseSpeed
|
||||
assert CP.pcmCruise
|
||||
assert not CP.openpilotLongitudinalControl
|
||||
|
||||
def test_sportage_redneck_rejects_unverified_button_layouts(self, monkeypatch):
|
||||
class FakeParams:
|
||||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def get_bool(key):
|
||||
return key == "RedneckCruise"
|
||||
|
||||
monkeypatch.setattr("opendbc.car.interfaces.Params", FakeParams)
|
||||
toggles = get_test_toggles()
|
||||
for button_address, button_bus, button_length, lka_steering in (
|
||||
(0x1AA, 1, 16, True),
|
||||
(0x1CF, 0, 8, True),
|
||||
(0x1CF, 0, 8, False),
|
||||
(0x1CF, 1, 16, True),
|
||||
):
|
||||
fingerprint = gen_empty_fingerprint()
|
||||
can_bus = CanBus(None, fingerprint, lka_steering)
|
||||
if lka_steering:
|
||||
fingerprint[can_bus.CAM][0x110] = 32
|
||||
fingerprint[button_bus][button_address] = button_length
|
||||
|
||||
CP = CarInterface.get_params(CAR.KIA_SPORTAGE_HEV_2026, fingerprint, [], False, False, False, toggles)
|
||||
FPCP = CarInterface.get_starpilot_params(CAR.KIA_SPORTAGE_HEV_2026, fingerprint, [], CP, toggles)
|
||||
assert not FPCP.redneckCruiseAvailable
|
||||
assert FPCP.pcmCruiseSpeed
|
||||
assert CP.pcmCruise
|
||||
assert not CP.openpilotLongitudinalControl
|
||||
|
||||
fingerprint = gen_empty_fingerprint()
|
||||
can_bus = CanBus(None, fingerprint, True)
|
||||
fingerprint[can_bus.CAM][0x110] = 32
|
||||
fingerprint[can_bus.ECAN][0x1CF] = 8
|
||||
fingerprint[can_bus.ECAN][0x1AA] = 16
|
||||
CP = CarInterface.get_params(CAR.KIA_SPORTAGE_HEV_2026, fingerprint, [], False, False, False, toggles)
|
||||
FPCP = CarInterface.get_starpilot_params(CAR.KIA_SPORTAGE_HEV_2026, fingerprint, [], CP, toggles)
|
||||
assert not FPCP.redneckCruiseAvailable
|
||||
|
||||
fingerprint = gen_empty_fingerprint()
|
||||
can_bus = CanBus(None, fingerprint, True)
|
||||
fingerprint[can_bus.CAM][0x110] = 32
|
||||
fingerprint[can_bus.ECAN][0x1CF] = 8
|
||||
CP = CarInterface.get_params(CAR.KIA_SPORTAGE_HEV_2026, fingerprint, [], False, False, False, toggles)
|
||||
CP.openpilotLongitudinalControl = True
|
||||
FPCP = CarInterface.get_starpilot_params(CAR.KIA_SPORTAGE_HEV_2026, fingerprint, [], CP, toggles)
|
||||
assert not FPCP.redneckCruiseAvailable
|
||||
|
||||
def test_hyundai_non_scc_without_redneck_keeps_stock_longitudinal_mode(self, monkeypatch):
|
||||
class FakeParams:
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -1752,8 +1623,8 @@ class TestHyundaiFingerprint:
|
||||
CP = CarInterface.get_params(CAR.HYUNDAI_ELANTRA_2021, gen_empty_fingerprint(), [], True, False, False, toggles)
|
||||
|
||||
assert CP.longitudinalActuatorDelay == pytest.approx(0.22)
|
||||
assert CP.stopAccel == pytest.approx(-1.1)
|
||||
assert CP.stoppingDecelRate == pytest.approx(0.55)
|
||||
assert CP.stopAccel == pytest.approx(-0.85)
|
||||
assert CP.stoppingDecelRate == pytest.approx(0.35)
|
||||
|
||||
def test_elantra_hev_2024_longitudinal_delay_matches_observed_response(self):
|
||||
toggles = get_test_toggles()
|
||||
|
||||
@@ -145,7 +145,6 @@ def test_ray_controller_heartbeats_and_only_actuates_when_ready(speed):
|
||||
)
|
||||
hud = SimpleNamespace(
|
||||
visualAlert=CarControl.HUDControl.VisualAlert.none,
|
||||
setSpeed=20.0,
|
||||
leftLaneVisible=True, rightLaneVisible=True,
|
||||
leftLaneDepart=False, rightLaneDepart=False,
|
||||
)
|
||||
@@ -168,23 +167,23 @@ def test_ray_controller_heartbeats_and_only_actuates_when_ready(speed):
|
||||
controller.frame = 16
|
||||
messages = controller.create_can_msgs(True, 0, False, 0.0, 2.0, False,
|
||||
hud, actuators, CS, CC, 2, 0)
|
||||
assert next(dat for addr, dat, bus in messages if addr == 0x200 and bus == 0)[4] & 0x80
|
||||
assert any(addr == 0x4F1 and bus == 0 and dat[0] & 7 == 4 for addr, dat, bus in messages)
|
||||
assert next(dat for addr, dat, bus in messages if addr == 0x200 and bus == 0)[:4] == bytes(4)
|
||||
assert any(addr == 0x4F1 and bus == 0 for addr, _, bus in messages) # cancel stock CC
|
||||
|
||||
CS.out.cruiseState.enabled = False
|
||||
CS.out.brakePressed = True
|
||||
assert pedal_msg(2.0, 20)[:4] == bytes(4)
|
||||
CS.out.brakePressed = False
|
||||
assert pedal_msg(2.0, 24)[4] & 0x80
|
||||
assert controller._ray_pedal_gas_last == pytest.approx(0.02)
|
||||
assert controller._ray_pedal_gas_last == pytest.approx(0.012)
|
||||
assert pedal_msg(2.0, 28)[4] & 0x80
|
||||
assert controller._ray_pedal_gas_last == pytest.approx(0.04)
|
||||
assert controller._ray_pedal_gas_last == pytest.approx(0.024)
|
||||
CS.out.brakePressed = True
|
||||
assert pedal_msg(2.0, 32)[:4] == bytes(4)
|
||||
assert controller._ray_pedal_gas_last == 0.0
|
||||
CS.out.brakePressed = False
|
||||
assert pedal_msg(2.0, 36)[4] & 0x80
|
||||
assert controller._ray_pedal_gas_last == pytest.approx(0.02)
|
||||
assert controller._ray_pedal_gas_last == pytest.approx(0.012)
|
||||
|
||||
CC.longActive = False
|
||||
assert pedal_msg(2.0, 40)[:4] == bytes(4)
|
||||
@@ -199,49 +198,6 @@ def test_ray_controller_heartbeats_and_only_actuates_when_ready(speed):
|
||||
CS.ray_pedal_state = fault
|
||||
assert pedal_msg(2.0, 48 + 4 * fault)[:4] == bytes(4)
|
||||
|
||||
CS.ray_pedal_state = 0
|
||||
CS.out.vEgo = 10.0
|
||||
assert pedal_msg(0.0, 72)[4] & 0x80
|
||||
assert pedal_msg(-1.0, 76)[:4] == bytes(4)
|
||||
|
||||
CS.out.vEgo = 12.0
|
||||
for frame in range(80, 80 + 4 * 40, 4):
|
||||
pedal_msg(1.5, frame)
|
||||
assert controller._ray_pedal_gas_last == pytest.approx(0.55)
|
||||
for frame in range(240, 240 + 4 * 12, 4):
|
||||
dat = pedal_msg(-1.5, frame)
|
||||
assert dat[:4] == bytes(4)
|
||||
|
||||
for frame in range(288, 288 + 4 * 40, 4):
|
||||
pedal_msg(1.5, frame)
|
||||
assert controller._ray_pedal_gas_last == pytest.approx(0.55)
|
||||
hud.setSpeed = 12.0
|
||||
pedal_msg(1.5, 448)
|
||||
assert controller._ray_pedal_gas_last == pytest.approx(0.55 * 0.65)
|
||||
hud.setSpeed = 11.8
|
||||
dat = pedal_msg(1.5, 452)
|
||||
assert controller._ray_pedal_gas_last == pytest.approx(0.55 * 0.65 * 0.6)
|
||||
assert dat[4] & 0x80
|
||||
hud.setSpeed = 11.4
|
||||
assert pedal_msg(1.5, 456)[:4] == bytes(4)
|
||||
hud.setSpeed = float('nan')
|
||||
assert pedal_msg(1.5, 460)[:4] == bytes(4)
|
||||
hud.setSpeed = 20.0
|
||||
assert pedal_msg(-0.3, 464)[:4] == bytes(4)
|
||||
CS.out.vEgo = 15.0
|
||||
hud.setSpeed = 53.0 / 3.6
|
||||
pedal_msg(-0.16, 468)
|
||||
assert controller._ray_pedal_gas_last < 0.1
|
||||
CS.out.vEgo = 12.0
|
||||
hud.setSpeed = 8.0 / 3.6
|
||||
assert pedal_msg(-0.3, 472)[:4] == bytes(4)
|
||||
hud.setSpeed = 145.0 / 3.6
|
||||
assert pedal_msg(1.5, 476)[4] & 0x80
|
||||
assert controller._ray_pedal_gas_last == pytest.approx(0.02)
|
||||
assert pedal_msg(1.5, 480)[4] & 0x80
|
||||
assert controller._ray_pedal_gas_last == pytest.approx(0.04)
|
||||
assert pedal_msg(-0.3, 484)[:4] == bytes(4)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("candidate", [CAR.KIA_RAY_EV, CAR.HYUNDAI_KONA_EV_NON_SCC])
|
||||
def test_ray_stock_cruise_cancellation_survives_accelerator_override(candidate):
|
||||
@@ -260,7 +216,6 @@ def test_ray_stock_cruise_cancellation_survives_accelerator_override(candidate):
|
||||
)
|
||||
hud = SimpleNamespace(
|
||||
visualAlert=CarControl.HUDControl.VisualAlert.none,
|
||||
setSpeed=20.0,
|
||||
leftLaneVisible=True, rightLaneVisible=True, leftLaneDepart=False, rightLaneDepart=False,
|
||||
)
|
||||
actuators = SimpleNamespace(longControlState=CarControl.Actuators.LongControlState.off)
|
||||
@@ -281,7 +236,6 @@ def test_ray_stock_cruise_cancellation_survives_accelerator_override(candidate):
|
||||
assert pedal[:4] == bytes(4)
|
||||
assert not (pedal[4] & 0x80)
|
||||
assert not cancel_frames(messages(24)) # retain the existing cancellation rate limit
|
||||
assert cancel_frames(messages(25))
|
||||
assert cancel_frames(messages(32))
|
||||
|
||||
CS.out.cruiseState.enabled = False
|
||||
|
||||
@@ -117,7 +117,6 @@ class HyundaiSafetyFlags(IntFlag):
|
||||
|
||||
|
||||
class HyundaiStarPilotSafetyFlags(IntFlag):
|
||||
CANFD_NO_STOCK_LKA = 4096 # CAN-FD only; classic CAN uses this bit for NON_SCC.
|
||||
AOL_MAIN_LKAS_ON_ENGAGE = 128
|
||||
AOL_MAIN_LKAS_SYNC = 32
|
||||
HAS_LDA_BUTTON = 1024
|
||||
|
||||
@@ -244,28 +244,15 @@ class CarInterfaceBase(ABC):
|
||||
if 0x1FA in fingerprint[CAN.ECAN]:
|
||||
fp_ret.flags |= HyundaiStarPilotFlags.SPEED_LIMIT_AVAILABLE.value
|
||||
|
||||
if candidate != HYUNDAI.KIA_RAY_EV and not (CP.flags & HyundaiFlags.CANFD) and 0x53E in fingerprint[2] and \
|
||||
(candidate != HYUNDAI.KIA_STINGER_2022 or fingerprint[2][0x53E] == 6):
|
||||
if candidate != HYUNDAI.KIA_RAY_EV and not (CP.flags & HyundaiFlags.CANFD) and 0x53E in fingerprint[2]:
|
||||
fp_ret.flags |= HyundaiStarPilotFlags.HAS_LKAS12.value
|
||||
|
||||
sportage_stock_scc_buttons = (
|
||||
candidate == HYUNDAI.KIA_SPORTAGE_HEV_2026 and
|
||||
not CP.openpilotLongitudinalControl and
|
||||
bool(CP.flags & HyundaiFlags.CANFD_LKA_STEERING) and
|
||||
not bool(CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS) and
|
||||
fingerprint[CAN.ECAN].get(0x1CF) == 8 and
|
||||
0x1AA not in fingerprint[CAN.ECAN]
|
||||
)
|
||||
fp_ret.redneckCruiseAvailable = (
|
||||
(bool(CP.flags & HyundaiFlags.NON_SCC) and
|
||||
not bool(CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS) and
|
||||
not (candidate == HYUNDAI.KIA_RAY_EV and CP.enableGasInterceptorDEPRECATED)) or
|
||||
sportage_stock_scc_buttons
|
||||
)
|
||||
fp_ret.redneckCruiseAvailable = (bool(CP.flags & HyundaiFlags.NON_SCC) and
|
||||
not bool(CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS) and
|
||||
not (candidate == HYUNDAI.KIA_RAY_EV and CP.enableGasInterceptorDEPRECATED))
|
||||
if fp_ret.redneckCruiseAvailable and params.get_bool("RedneckCruise"):
|
||||
fp_ret.pcmCruiseSpeed = False
|
||||
if CP.flags & HyundaiFlags.NON_SCC:
|
||||
CP.openpilotLongitudinalControl = True
|
||||
CP.openpilotLongitudinalControl = True
|
||||
|
||||
if candidate == HYUNDAI.HYUNDAI_ELANTRA_HEV_2024 and CP.openpilotLongitudinalControl:
|
||||
fp_ret.flags |= HyundaiStarPilotFlags.MAIN_CRUISE_STATE_TRACKING.value
|
||||
@@ -288,9 +275,6 @@ class CarInterfaceBase(ABC):
|
||||
if candidate == HYUNDAI.HYUNDAI_SONATA_HYBRID:
|
||||
fp_ret.safetyConfigs[-1].safetyParam |= HyundaiStarPilotSafetyFlags.AOL_LKAS_ON_ENGAGE.value
|
||||
|
||||
if candidate == HYUNDAI.KIA_STINGER_2022 and CP.openpilotLongitudinalControl:
|
||||
fp_ret.safetyConfigs[-1].safetyParam |= HyundaiStarPilotSafetyFlags.AOL_LKAS_ON_ENGAGE.value
|
||||
|
||||
# The refresh Elantra's safety mapping comes from the resolved Galaxy
|
||||
# toggle above, not from this legacy persisted-parameter fallback.
|
||||
if candidate != HYUNDAI.HYUNDAI_ELANTRA_HEV_2024 and \
|
||||
|
||||
@@ -46,7 +46,6 @@ class CarController(CarControllerBase):
|
||||
self.angle_override_confirm_frames = 0
|
||||
self.angle_lkas_active = False
|
||||
self.angle_handoff_active = False
|
||||
self.ascent_angle_initialized = False
|
||||
self.ascent_aol_arm_frames = 0
|
||||
|
||||
self.cruise_button_prev = 0
|
||||
@@ -205,10 +204,6 @@ class CarController(CarControllerBase):
|
||||
return subarucan.create_steering_control_angle(self.packer, apply_steer, lkas_active, self.angle_bus)
|
||||
|
||||
if self.CP.carFingerprint in (CAR.SUBARU_ASCENT_2023, CAR.SUBARU_OUTBACK_2023):
|
||||
if self.CP.carFingerprint == CAR.SUBARU_ASCENT_2023 and not self.ascent_angle_initialized:
|
||||
self.apply_steer_last = CS.out.steeringAngleDeg
|
||||
self.ascent_angle_initialized = True
|
||||
|
||||
mads_only = CC.latActive and not CC.enabled
|
||||
mads_only_ok = CS.out.vEgoRaw > _ANGLE_MADS_MIN_SPEED and \
|
||||
abs(CS.out.steeringAngleDeg) < _ANGLE_MADS_MAX_STEER_ANGLE
|
||||
@@ -228,7 +223,7 @@ class CarController(CarControllerBase):
|
||||
manual_handoff = self._angle_manual_handoff(CS, lkas_available)
|
||||
lkas_active = lkas_available and not manual_handoff
|
||||
|
||||
if lkas_active and not self.angle_lkas_active and self.CP.carFingerprint != CAR.SUBARU_ASCENT_2023:
|
||||
if lkas_active and not self.angle_lkas_active:
|
||||
self.apply_steer_last = CS.out.steeringAngleDeg
|
||||
|
||||
apply_steer = apply_std_steer_angle_limits(
|
||||
|
||||
@@ -682,28 +682,6 @@ def test_ascent_angle_controller_reengages_immediately_after_manual_steering_sto
|
||||
assert CS.out.steeringAngleDeg < parser.vl["ES_LKAS_ANGLE"]["LKAS_Output"] < CC.actuators.steeringAngleDeg
|
||||
|
||||
|
||||
def test_ascent_reentry_rate_uses_last_transmitted_angle():
|
||||
CP = CarInterface.get_non_essential_params(CAR.SUBARU_ASCENT_2023)
|
||||
controller = CarController({}, CP)
|
||||
controller.angle_handoff_active = True
|
||||
CC = SimpleNamespace(enabled=True, latActive=True, actuators=SimpleNamespace(steeringAngleDeg=-1.45))
|
||||
CS = SimpleNamespace(out=SimpleNamespace(
|
||||
vEgoRaw=30.3, steeringAngleDeg=0.78, steeringRateDeg=-1.5, steeringTorque=56.0,
|
||||
gearShifter=structs.CarState.GearShifter.drive, standstill=False,
|
||||
))
|
||||
parser = CANParser(DBC[CP.carFingerprint][Bus.pt], [("ES_LKAS_ANGLE", 0)], CanBus.main)
|
||||
|
||||
parser.update([(1, [controller.lateral_angle(CC, CS)])])
|
||||
assert parser.vl["ES_LKAS_ANGLE"]["LKAS_Request"] == 0
|
||||
assert parser.vl["ES_LKAS_ANGLE"]["LKAS_Output"] == pytest.approx(0.78)
|
||||
|
||||
CS.out.steeringAngleDeg = 0.74
|
||||
CS.out.steeringRateDeg = -1.99
|
||||
parser.update([(2, [controller.lateral_angle(CC, CS)])])
|
||||
assert parser.vl["ES_LKAS_ANGLE"]["LKAS_Request"] == 1
|
||||
assert parser.vl["ES_LKAS_ANGLE"]["LKAS_Output"] == pytest.approx(0.53, abs=0.01)
|
||||
|
||||
|
||||
def test_ascent_angle_controller_waits_for_parking_lot_safety_envelope():
|
||||
CP = CarInterface.get_non_essential_params(CAR.SUBARU_ASCENT_2023)
|
||||
controller = CarController({}, CP)
|
||||
|
||||
@@ -11,7 +11,7 @@ from opendbc.car.interfaces import CarControllerBase
|
||||
from opendbc.car.toyota import toyotacan
|
||||
from opendbc.car.toyota.values import CAR, MIN_ACC_SPEED, NO_STOP_TIMER_CAR, PEDAL_TRANSITION, TSS2_CAR, \
|
||||
CarControllerParams, ToyotaFlags, \
|
||||
UNSUPPORTED_DSU_CAR, LEGACY_PRIUS_CAR, TOYOTA_AUTO_HOLD_CARS, TOYOTA_AUTO_HOLD_AEB_CARS
|
||||
UNSUPPORTED_DSU_CAR, LEGACY_PRIUS_CAR, TOYOTA_AUTO_HOLD_CARS
|
||||
from opendbc.can import CANPacker
|
||||
|
||||
Ecu = structs.CarParams.Ecu
|
||||
@@ -336,22 +336,6 @@ class CarController(CarControllerBase):
|
||||
|
||||
return self.brake_hold_active
|
||||
|
||||
def create_auto_brake_hold_messages(self, CS: structs.CarState, brake_hold_allowed_timer: int = 100):
|
||||
brake_hold_allowed = (CS.out.standstill and CS.out.cruiseState.available and
|
||||
not CS.out.gasPressed and not CS.out.cruiseState.enabled and
|
||||
CS.out.gearShifter not in (PARK, REVERSE))
|
||||
|
||||
if brake_hold_allowed and not self.brake_hold_active and CS.out.brakePressed:
|
||||
self._brake_hold_counter += 1
|
||||
self.brake_hold_active = self._brake_hold_counter > brake_hold_allowed_timer
|
||||
elif not brake_hold_allowed:
|
||||
self._brake_hold_counter = 0
|
||||
self.brake_hold_active = False
|
||||
|
||||
if self.frame % 2 == 0:
|
||||
return [toyotacan.create_brake_hold_command(self.packer, self.frame, CS.pre_collision_2, self.brake_hold_active)]
|
||||
return []
|
||||
|
||||
def reset_auto_hold_state(self):
|
||||
self._brake_hold_counter = 0
|
||||
self.brake_hold_active = False
|
||||
@@ -452,10 +436,7 @@ class CarController(CarControllerBase):
|
||||
|
||||
self._update_standstill_request(CC, CS, actuators, starpilot_toggles)
|
||||
if supports_toyota_auto_hold(self.CP, getattr(starpilot_toggles, "toyota_auto_hold", False)):
|
||||
if self.CP.carFingerprint in TOYOTA_AUTO_HOLD_AEB_CARS:
|
||||
can_sends.extend(self.create_auto_brake_hold_messages(CS))
|
||||
else:
|
||||
self.update_auto_hold_state(CS, pcm_cancel_cmd)
|
||||
self.update_auto_hold_state(CS, pcm_cancel_cmd)
|
||||
else:
|
||||
self.reset_auto_hold_state()
|
||||
|
||||
@@ -565,7 +546,7 @@ class CarController(CarControllerBase):
|
||||
|
||||
pcm_accel_cmd = float(np.clip(pcm_accel_cmd, self.params.ACCEL_MIN, self.params.ACCEL_MAX))
|
||||
|
||||
if self.brake_hold_active and self.CP.carFingerprint not in TOYOTA_AUTO_HOLD_AEB_CARS:
|
||||
if self.brake_hold_active:
|
||||
pcm_accel_cmd = TOYOTA_AUTO_HOLD_ACCEL
|
||||
self.permit_braking = True
|
||||
self.standstill_req = True
|
||||
|
||||
@@ -9,7 +9,6 @@ from opendbc.car.interfaces import CarStateBase
|
||||
from opendbc.car.toyota.values import ToyotaFlags, ToyotaStarPilotFlags, CAR, DBC, STEER_THRESHOLD, NO_STOP_TIMER_CAR, \
|
||||
TSS2_CAR, RADAR_ACC_CAR, EPS_SCALE, UNSUPPORTED_DSU_CAR, \
|
||||
SECOC_CAR, LEGACY_PRIUS_CAR
|
||||
from opendbc.safety import ALTERNATIVE_EXPERIENCE
|
||||
|
||||
ButtonType = structs.CarState.ButtonEvent.Type
|
||||
SteerControlType = structs.CarParams.SteerControlType
|
||||
@@ -91,11 +90,6 @@ class CarState(CarStateBase):
|
||||
self.has_can_filter = self.FPCP.flags & ToyotaStarPilotFlags.RADAR_CAN_FILTER.value
|
||||
self.has_SDSU = self.FPCP.flags & ToyotaStarPilotFlags.SMART_DSU.value
|
||||
self.has_ZSS = self.FPCP.flags & ToyotaStarPilotFlags.ZSS.value
|
||||
self.auto_brake_hold = bool(
|
||||
self.CP.flags & ToyotaFlags.AUTO_BRAKE_HOLD.value and
|
||||
getattr(self.CP, "alternativeExperience", 0) & ALTERNATIVE_EXPERIENCE.ALLOW_AEB
|
||||
)
|
||||
self.pre_collision_2 = {}
|
||||
|
||||
def update(self, can_parsers, starpilot_toggles) -> structs.CarState:
|
||||
cp = can_parsers[Bus.pt]
|
||||
@@ -231,9 +225,6 @@ class CarState(CarStateBase):
|
||||
if self.CP.carFingerprint != CAR.TOYOTA_PRIUS_V:
|
||||
self.lkas_hud = copy.copy(cp_cam.vl["LKAS_HUD"])
|
||||
|
||||
if self.auto_brake_hold:
|
||||
self.pre_collision_2 = copy.copy(cp_cam.vl["PRE_COLLISION_2"])
|
||||
|
||||
if self.CP.carFingerprint not in UNSUPPORTED_DSU_CAR:
|
||||
self.pcm_follow_distance = cp.vl["PCM_CRUISE_2"]["PCM_FOLLOW_DISTANCE"]
|
||||
|
||||
@@ -318,10 +309,6 @@ class CarState(CarStateBase):
|
||||
if CP.carFingerprint in DISTANCE_BUTTON_CAR:
|
||||
pt_messages.append(("PCM_CRUISE_4", 1))
|
||||
|
||||
if (CP.flags & ToyotaFlags.AUTO_BRAKE_HOLD.value and
|
||||
getattr(CP, "alternativeExperience", 0) & ALTERNATIVE_EXPERIENCE.ALLOW_AEB):
|
||||
cam_messages.append(("PRE_COLLISION_2", 50))
|
||||
|
||||
return {
|
||||
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], pt_messages, 0),
|
||||
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], cam_messages, 2),
|
||||
|
||||
@@ -4,8 +4,7 @@ from opendbc.car.toyota.carcontroller import CarController
|
||||
from opendbc.car.toyota.radar_interface import RadarInterface
|
||||
from opendbc.car.toyota.values import Ecu, CAR, DBC, ToyotaFlags, CarControllerParams, TSS2_CAR, RADAR_ACC_CAR, NO_DSU_CAR, \
|
||||
MIN_ACC_SPEED, EPS_SCALE, NO_STOP_TIMER_CAR, ANGLE_CONTROL_CAR, \
|
||||
ToyotaSafetyFlags, LEGACY_PRIUS_CAR, TOYOTA_AUTO_HOLD_CARS, \
|
||||
TOYOTA_AUTO_HOLD_AEB_CARS
|
||||
ToyotaSafetyFlags, LEGACY_PRIUS_CAR, TOYOTA_AUTO_HOLD_CARS
|
||||
from opendbc.car.disable_ecu import disable_ecu
|
||||
from opendbc.car.interfaces import CarInterfaceBase
|
||||
from opendbc.safety import ALTERNATIVE_EXPERIENCE
|
||||
@@ -166,9 +165,7 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
toyota_auto_hold = Params(return_defaults=True).get_bool("ToyotaAutoHold")
|
||||
if toyota_auto_hold and ret.openpilotLongitudinalControl and candidate in TOYOTA_AUTO_HOLD_CARS:
|
||||
ret.alternativeExperience |= (ALTERNATIVE_EXPERIENCE.ALLOW_AEB
|
||||
if candidate in TOYOTA_AUTO_HOLD_AEB_CARS
|
||||
else ALTERNATIVE_EXPERIENCE.TOYOTA_AUTO_HOLD)
|
||||
ret.alternativeExperience |= ALTERNATIVE_EXPERIENCE.TOYOTA_AUTO_HOLD
|
||||
ret.flags |= ToyotaFlags.AUTO_BRAKE_HOLD.value
|
||||
|
||||
if not ret.openpilotLongitudinalControl:
|
||||
|
||||
@@ -25,7 +25,6 @@ from opendbc.car.toyota.radar_interface import RadarInterface, TSSP_RADAR_EGO_SP
|
||||
from opendbc.car.toyota.values import CAR, DBC, MIN_ACC_SPEED, TSS2_CAR, ANGLE_CONTROL_CAR, RADAR_ACC_CAR, SECOC_CAR, \
|
||||
FW_QUERY_CONFIG, PLATFORM_CODE_ECUS, FUZZY_EXCLUDED_PLATFORMS, \
|
||||
ToyotaFlags, ToyotaSafetyFlags, ToyotaStarPilotFlags, TOYOTA_AUTO_HOLD_CARS, \
|
||||
TOYOTA_AUTO_HOLD_AEB_CARS, \
|
||||
get_platform_codes
|
||||
from opendbc.safety import ALTERNATIVE_EXPERIENCE
|
||||
from openpilot.common.params import Params
|
||||
@@ -212,17 +211,13 @@ class TestToyotaInterfaces:
|
||||
params.remove("ToyotaAutoHold")
|
||||
|
||||
assert car_params.flags & ToyotaFlags.AUTO_BRAKE_HOLD.value
|
||||
if candidate in TOYOTA_AUTO_HOLD_AEB_CARS:
|
||||
assert car_params.alternativeExperience & ALTERNATIVE_EXPERIENCE.ALLOW_AEB
|
||||
assert not car_params.alternativeExperience & ALTERNATIVE_EXPERIENCE.TOYOTA_AUTO_HOLD
|
||||
else:
|
||||
assert car_params.alternativeExperience & ALTERNATIVE_EXPERIENCE.TOYOTA_AUTO_HOLD
|
||||
assert not car_params.alternativeExperience & ALTERNATIVE_EXPERIENCE.ALLOW_AEB
|
||||
assert car_params.alternativeExperience & ALTERNATIVE_EXPERIENCE.TOYOTA_AUTO_HOLD
|
||||
assert not car_params.alternativeExperience & ALTERNATIVE_EXPERIENCE.ALLOW_AEB
|
||||
|
||||
can_parsers = CarState.get_can_parsers(car_params)
|
||||
car_state = CarState(car_params, SimpleNamespace(flags=0))
|
||||
car_state.update(can_parsers, SimpleNamespace(cluster_offset=1.0))
|
||||
assert (0x344 in can_parsers[Bus.cam].vl) == (candidate in TOYOTA_AUTO_HOLD_AEB_CARS)
|
||||
assert "PRE_COLLISION_2" not in can_parsers[Bus.cam].vl
|
||||
|
||||
@pytest.mark.parametrize("candidate", [CAR.TOYOTA_CAMRY_TSS2, CAR.TOYOTA_RAV4, CAR.TOYOTA_RAV4H])
|
||||
def test_auto_hold_is_disabled_by_default(self, candidate):
|
||||
@@ -894,31 +889,6 @@ class TestToyotaCarController:
|
||||
controller.update_auto_hold_state(cs, activation_frames=0)
|
||||
assert not controller.brake_hold_active
|
||||
|
||||
def test_camry_auto_hold_uses_legacy_aeb_brake_path(self):
|
||||
controller = self._make_controller()
|
||||
controller.CP.carFingerprint = CAR.TOYOTA_CAMRY_TSS2
|
||||
controller.packer = CANPacker(DBC[CAR.TOYOTA_CAMRY_TSS2][Bus.pt])
|
||||
controller.frame = 0
|
||||
|
||||
cs = SimpleNamespace(
|
||||
out=SimpleNamespace(
|
||||
standstill=True,
|
||||
cruiseState=SimpleNamespace(available=True, enabled=False),
|
||||
gasPressed=False,
|
||||
brakePressed=True,
|
||||
gearShifter=structs.CarState.GearShifter.drive,
|
||||
),
|
||||
pre_collision_2={},
|
||||
)
|
||||
|
||||
can_sends = controller.create_auto_brake_hold_messages(cs, brake_hold_allowed_timer=0)
|
||||
parser = CANParser(DBC[CAR.TOYOTA_CAMRY_TSS2][Bus.pt], [("PRE_COLLISION_2", 0)], 0)
|
||||
parser.update([(1, can_sends)])
|
||||
|
||||
assert controller.brake_hold_active
|
||||
assert parser.vl["PRE_COLLISION_2"]["DSS1GDRV"] == -1.0
|
||||
assert parser.vl["PRE_COLLISION_2"]["PBRTRGR"] == 1
|
||||
|
||||
def test_prius_resume_request_releases_standstill_latch(self):
|
||||
controller = self._make_controller(standstill_req=True, last_standstill=True)
|
||||
|
||||
|
||||
@@ -89,38 +89,6 @@ def create_pcs_commands(packer, accel, active, mass):
|
||||
return [msg1, msg2]
|
||||
|
||||
|
||||
def create_brake_hold_command(packer, frame, pre_collision_2, brake_hold_active):
|
||||
values = {s: pre_collision_2[s] for s in [
|
||||
"DSS1GDRV",
|
||||
"DS1STAT2",
|
||||
"DS1STBK2",
|
||||
"PCSWAR",
|
||||
"PCSALM",
|
||||
"PCSOPR",
|
||||
"PCSABK",
|
||||
"PBATRGR",
|
||||
"PPTRGR",
|
||||
"IBTRGR",
|
||||
"CLEXTRGR",
|
||||
"IRLT_REQ",
|
||||
"BRKHLD",
|
||||
"AVSTRGR",
|
||||
"VGRSTRGR",
|
||||
"PREFILL",
|
||||
"PBRTRGR",
|
||||
"PCSDIS",
|
||||
"PBPREPMP",
|
||||
] if s in pre_collision_2}
|
||||
|
||||
if brake_hold_active:
|
||||
values = {
|
||||
"DSS1GDRV": 0x3FF,
|
||||
"PBRTRGR": frame % 730 < 727,
|
||||
}
|
||||
|
||||
return packer.make_can_msg("PRE_COLLISION_2", 0, values)
|
||||
|
||||
|
||||
def create_acc_cancel_command(packer):
|
||||
values = {
|
||||
"GAS_RELEASED": 0,
|
||||
|
||||
@@ -629,10 +629,6 @@ TOYOTA_AUTO_HOLD_CARS = (TSS2_CAR - RADAR_ACC_CAR - SECOC_CAR) | {
|
||||
CAR.TOYOTA_RAV4H,
|
||||
}
|
||||
|
||||
# The Camry uses the legacy camera AEB replacement for Auto Hold. Other
|
||||
# supported Toyota models use the ACC_CONTROL hold request.
|
||||
TOYOTA_AUTO_HOLD_AEB_CARS = {CAR.TOYOTA_CAMRY_TSS2}
|
||||
|
||||
# no resume button press required
|
||||
NO_STOP_TIMER_CAR = CAR.with_flags(ToyotaFlags.NO_STOP_TIMER)
|
||||
|
||||
|
||||
@@ -96,8 +96,6 @@ static bool ford_lka_steering = false;
|
||||
static bool ford_extended_lateral = false;
|
||||
static bool ford_longitudinal = false;
|
||||
static bool ford_cancel_resume_button = false;
|
||||
static bool ford_mach_e_curvature = false;
|
||||
static int ford_path_angle_last = 0;
|
||||
|
||||
// Curvature rate limits
|
||||
#define FORD_LIMITS(limit_lateral_acceleration) { \
|
||||
@@ -123,10 +121,10 @@ static int ford_path_angle_last = 0;
|
||||
|
||||
static const AngleSteeringLimits FORD_STEERING_LIMITS = FORD_LIMITS(false);
|
||||
|
||||
#define FORD_EXTENDED_LIMITS(limit_lateral_acceleration, max_curvature_error) { \
|
||||
#define FORD_EXTENDED_LIMITS(limit_lateral_acceleration) { \
|
||||
.max_angle = 1000, \
|
||||
.angle_deg_to_can = 50000, \
|
||||
.max_angle_error = (max_curvature_error), \
|
||||
.max_angle_error = 100, \
|
||||
.angle_rate_up_lookup = { \
|
||||
{5., 16., 25.}, \
|
||||
{0.0025, 0.0014, 0.00018} \
|
||||
@@ -142,7 +140,7 @@ static const AngleSteeringLimits FORD_STEERING_LIMITS = FORD_LIMITS(false);
|
||||
.inactive_angle_is_zero = true, \
|
||||
}
|
||||
|
||||
static const AngleSteeringLimits FORD_EXTENDED_STEERING_LIMITS = FORD_EXTENDED_LIMITS(false, 100);
|
||||
static const AngleSteeringLimits FORD_EXTENDED_STEERING_LIMITS = FORD_EXTENDED_LIMITS(false);
|
||||
|
||||
static void ford_rx_hook(const CANPacket_t *msg) {
|
||||
if (msg->bus == FORD_MAIN_BUS) {
|
||||
@@ -320,8 +318,7 @@ static bool ford_tx_hook(const CANPacket_t *msg) {
|
||||
// Safety check for LateralMotionControl2 action
|
||||
if (msg->addr == FORD_LateralMotionControl2) {
|
||||
static const AngleSteeringLimits FORD_CANFD_STEERING_LIMITS = FORD_LIMITS(true);
|
||||
static const AngleSteeringLimits FORD_CANFD_EXTENDED_STEERING_LIMITS = FORD_EXTENDED_LIMITS(true, 100);
|
||||
static const AngleSteeringLimits FORD_MACH_E_CURVATURE_LIMITS = FORD_EXTENDED_LIMITS(true, 300);
|
||||
static const AngleSteeringLimits FORD_CANFD_EXTENDED_STEERING_LIMITS = FORD_EXTENDED_LIMITS(true);
|
||||
|
||||
// Signal: LatCtl_D2_Rq
|
||||
bool steer_control_enabled = ((msg->data[0] >> 4) & 0x7U) != 0U;
|
||||
@@ -339,19 +336,9 @@ static bool ford_tx_hook(const CANPacket_t *msg) {
|
||||
if (ford_extended_lateral) {
|
||||
violation |= desired_path_offset != 0;
|
||||
violation |= (desired_curvature_rate < -1024) || (desired_curvature_rate > 1023);
|
||||
if (desired_path_angle != 0) {
|
||||
const float speed = vehicle_speed.max / VEHICLE_SPEED_FACTOR;
|
||||
const float curvature = (float)SAFETY_ABS(desired_curvature) / 50000.0f;
|
||||
const float path_angle = (float)SAFETY_ABS(desired_path_angle) / 2000.0f;
|
||||
const float combined_acceleration = (curvature + path_angle / SAFETY_MAX(speed, 1.0f)) * speed * speed;
|
||||
violation |= !ford_mach_e_curvature || !steer_control_enabled || !controls_allowed;
|
||||
violation |= (speed < 3.0f) || (speed >= 8.8f);
|
||||
violation |= (SAFETY_ABS(desired_curvature) < 975) || (SAFETY_ABS(desired_path_angle) > 320);
|
||||
violation |= (desired_curvature * desired_path_angle <= 0) || (combined_acceleration > 2.5f);
|
||||
violation |= SAFETY_ABS(desired_path_angle - ford_path_angle_last) > 110;
|
||||
}
|
||||
violation |= desired_path_angle != 0;
|
||||
violation |= steer_angle_cmd_checks(desired_curvature, steer_control_enabled,
|
||||
ford_mach_e_curvature ? FORD_MACH_E_CURVATURE_LIMITS : FORD_CANFD_EXTENDED_STEERING_LIMITS);
|
||||
FORD_CANFD_EXTENDED_STEERING_LIMITS);
|
||||
if (!steer_control_enabled) {
|
||||
violation |= (desired_curvature != 0) || (desired_curvature_rate != 0);
|
||||
}
|
||||
@@ -365,8 +352,6 @@ static bool ford_tx_hook(const CANPacket_t *msg) {
|
||||
|
||||
if (violation) {
|
||||
tx = false;
|
||||
} else {
|
||||
ford_path_angle_last = desired_path_angle;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,11 +406,8 @@ static safety_config ford_init(uint16_t param) {
|
||||
|
||||
const uint16_t FORD_PARAM_CANFD = 2;
|
||||
const uint16_t FORD_PARAM_LKA_STEERING = 4;
|
||||
const uint16_t FORD_PARAM_MACH_E_CURVATURE = 8;
|
||||
const bool ford_canfd = GET_FLAG(param, FORD_PARAM_CANFD);
|
||||
ford_lka_steering = GET_FLAG(param, FORD_PARAM_LKA_STEERING);
|
||||
ford_mach_e_curvature = ford_canfd && GET_FLAG(param, FORD_PARAM_MACH_E_CURVATURE);
|
||||
ford_path_angle_last = 0;
|
||||
ford_extended_lateral = false;
|
||||
ford_cancel_resume_button = false;
|
||||
|
||||
|
||||
@@ -330,7 +330,7 @@ static bool hyundai_tx_hook(const CANPacket_t *msg) {
|
||||
const int expected_track2 = 497 + (2 * ((int)track1 - 264));
|
||||
if ((msg->data[4] & 0x70U) != 0U ||
|
||||
(msg->data[5] != hyundai_ray_pedal_checksum(msg)) ||
|
||||
(enabled && (track1 < 264U || track1 > 473U || track2 < 497U || track2 > 919U ||
|
||||
(enabled && (track1 < 264U || track1 > 397U || track2 < 497U || track2 > 766U ||
|
||||
SAFETY_ABS((int)track2 - expected_track2) > 40)) ||
|
||||
(!enabled && ((track1 != 0U) || (track2 != 0U))) ||
|
||||
longitudinal_interceptor_checks(msg) ||
|
||||
|
||||
@@ -65,7 +65,6 @@
|
||||
static bool hyundai_canfd_alt_buttons = false;
|
||||
static bool hyundai_canfd_lka_steering_alt = false;
|
||||
static bool hyundai_canfd_angle_steering = false;
|
||||
static bool hyundai_canfd_no_stock_lka = false;
|
||||
static bool hyundai_ccnc = false;
|
||||
static bool hyundai_canfd_ccnc_angle_long = false;
|
||||
static bool hyundai_canfd_lka_alt_drive_gear = false;
|
||||
@@ -101,8 +100,7 @@ static bool hyundai_canfd_lka_alt_openpilot_allowed(void) {
|
||||
}
|
||||
|
||||
static bool hyundai_canfd_lka_alt_stock_forwarding(void) {
|
||||
return hyundai_canfd_lka_steering_alt && hyundai_canfd_angle_steering &&
|
||||
!hyundai_canfd_no_stock_lka && !hyundai_canfd_lka_alt_openpilot_allowed();
|
||||
return hyundai_canfd_lka_steering_alt && hyundai_canfd_angle_steering && !hyundai_canfd_lka_alt_openpilot_allowed();
|
||||
}
|
||||
|
||||
static void hyundai_canfd_rx_all_hook(const CANPacket_t *msg) {
|
||||
@@ -272,10 +270,6 @@ static bool hyundai_canfd_tx_hook(const CANPacket_t *msg) {
|
||||
const int lkas_angle_active = (msg->data[9] >> 4U) & 0x3U;
|
||||
const bool steer_angle_req = lkas_angle_active != 1;
|
||||
|
||||
if (hyundai_canfd_no_stock_lka && steer_angle_req && !hyundai_canfd_lka_alt_openpilot_allowed()) {
|
||||
tx = false;
|
||||
}
|
||||
|
||||
int desired_angle = (msg->data[11] << 6U) | (msg->data[10] >> 2U);
|
||||
desired_angle = to_signed(desired_angle, 14);
|
||||
|
||||
@@ -370,7 +364,6 @@ static safety_config hyundai_canfd_init(uint16_t param) {
|
||||
const uint16_t HYUNDAI_PARAM_CANFD_LKA_STEERING_ALT = 128;
|
||||
const uint16_t HYUNDAI_PARAM_CANFD_ALT_BUTTONS = 32;
|
||||
const uint16_t HYUNDAI_PARAM_CANFD_ANGLE_STEERING = 1024;
|
||||
const uint16_t HYUNDAI_PARAM_CANFD_NO_STOCK_LKA = 4096U;
|
||||
const uint16_t HYUNDAI_PARAM_CCNC = 32768U;
|
||||
|
||||
static const CanMsg HYUNDAI_CANFD_LKA_STEERING_TX_MSGS[] = {
|
||||
@@ -486,15 +479,12 @@ static safety_config hyundai_canfd_init(uint16_t param) {
|
||||
{0x7C4, 2, 8, .check_relay = true}, /* camera support frame */ \
|
||||
{0xEA, 2, 24, .check_relay = true}, /* MDPS support frame */ \
|
||||
|
||||
// This CAN-FD-only bit is independent of classic CAN's NON_SCC mode.
|
||||
hyundai_common_init(param & ~HYUNDAI_PARAM_CANFD_NO_STOCK_LKA);
|
||||
hyundai_common_init(param);
|
||||
|
||||
gen_crc_lookup_table_16(0x1021, hyundai_canfd_crc_lut);
|
||||
hyundai_canfd_alt_buttons = GET_FLAG(param, HYUNDAI_PARAM_CANFD_ALT_BUTTONS);
|
||||
hyundai_canfd_lka_steering_alt = GET_FLAG(param, HYUNDAI_PARAM_CANFD_LKA_STEERING_ALT);
|
||||
hyundai_canfd_angle_steering = GET_FLAG(param, HYUNDAI_PARAM_CANFD_ANGLE_STEERING);
|
||||
hyundai_canfd_no_stock_lka = hyundai_canfd_angle_steering && hyundai_canfd_lka_steering &&
|
||||
hyundai_canfd_lka_steering_alt && GET_FLAG(param, HYUNDAI_PARAM_CANFD_NO_STOCK_LKA);
|
||||
hyundai_ccnc = GET_FLAG(param, HYUNDAI_PARAM_CCNC);
|
||||
hyundai_canfd_ccnc_angle_long = hyundai_longitudinal && hyundai_canfd_lka_steering &&
|
||||
hyundai_canfd_lka_steering_alt && hyundai_canfd_angle_steering && hyundai_ccnc;
|
||||
|
||||
@@ -404,12 +404,7 @@ static bool toyota_tx_hook(const CANPacket_t *msg) {
|
||||
tx = false;
|
||||
}
|
||||
|
||||
// Camry Auto Hold replaces the camera AEB message only while stopped.
|
||||
if ((msg->addr == 0x344U) && ((alternative_experience & ALT_EXP_ALLOW_AEB) != 0)) {
|
||||
if (vehicle_moving || gas_pressed || !acc_main_on) {
|
||||
tx = false;
|
||||
}
|
||||
} else if ((msg->addr == 0x344U) && toyota_stock_longitudinal) {
|
||||
if ((msg->addr == 0x344U) && toyota_stock_longitudinal) {
|
||||
tx = false;
|
||||
}
|
||||
}
|
||||
@@ -576,21 +571,11 @@ static safety_config toyota_init(uint16_t param) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool toyota_fwd_hook(int bus_num, int addr) {
|
||||
bool block_msg = false;
|
||||
if (bus_num == 2) {
|
||||
block_msg = (addr == 0x344) && ((alternative_experience & ALT_EXP_ALLOW_AEB) != 0) &&
|
||||
!vehicle_moving && !gas_pressed && acc_main_on;
|
||||
}
|
||||
return block_msg;
|
||||
}
|
||||
|
||||
const safety_hooks toyota_hooks = {
|
||||
.init = toyota_init,
|
||||
.rx = toyota_rx_hook,
|
||||
.rx_all = toyota_rx_all_hook,
|
||||
.tx = toyota_tx_hook,
|
||||
.fwd = toyota_fwd_hook,
|
||||
.get_checksum = toyota_get_checksum,
|
||||
.compute_checksum = toyota_compute_checksum,
|
||||
.get_quality_flag_valid = toyota_get_quality_flag_valid,
|
||||
|
||||
@@ -467,53 +467,6 @@ class TestFordCANFDStockSafety(TestFordSafetyBase):
|
||||
self.safety.set_safety_hooks(CarParams.SafetyModel.ford, FordSafetyFlags.CANFD)
|
||||
self.safety.init_tests()
|
||||
|
||||
|
||||
class TestFordMachEExtendedCurvatureSafety(TestFordCANFDStockSafety):
|
||||
def setUp(self):
|
||||
self.packer = CANPackerSafety("ford_lincoln_base_pt")
|
||||
self.safety = libsafety_py.libsafety
|
||||
self.safety.set_safety_hooks(CarParams.SafetyModel.ford,
|
||||
FordSafetyFlags.CANFD | FordSafetyFlags.MACH_E_CURVATURE)
|
||||
self.safety.init_tests()
|
||||
|
||||
def test_mach_e_extended_curvature_error(self):
|
||||
self.safety.set_controls_allowed(True)
|
||||
self._reset_curvature_measurement(0.0, 12.0)
|
||||
self.assertTrue(self._tx(self._extended_lka_msg()))
|
||||
|
||||
for curvature, allowed in ((0.0058, True), (0.0062, False), (-0.0058, True), (-0.0062, False)):
|
||||
self._set_prev_desired_angle(curvature)
|
||||
self.assertEqual(allowed, self._tx(self._lat_ctl_msg(True, 0.0, 0.0, curvature, 0.0)))
|
||||
|
||||
self.assertFalse(self._tx(self._lat_ctl_msg(True, 0.0, 0.02, 0.005, 0.0)))
|
||||
|
||||
def test_mach_e_bounded_path_angle_assist(self):
|
||||
self.safety.set_controls_allowed(True)
|
||||
self._reset_curvature_measurement(0.02, 7.5)
|
||||
self._set_prev_desired_angle(0.02)
|
||||
self.assertTrue(self._tx(self._extended_lka_msg()))
|
||||
for path_angle in (0.055, 0.11, 0.15):
|
||||
self.assertTrue(self._tx(self._lat_ctl_msg(True, 0.0, path_angle, 0.02, 0.0)))
|
||||
self.assertFalse(self._tx(self._lat_ctl_msg(True, 0.0, 0.161, 0.02, 0.0)))
|
||||
self.assertTrue(self._tx(self._lat_ctl_msg(True, 0.0, 0.0, 0.02, 0.0)))
|
||||
self.assertFalse(self._tx(self._lat_ctl_msg(True, 0.0, -0.055, 0.02, 0.0)))
|
||||
self.assertFalse(self._tx(self._lat_ctl_msg(True, 0.0, 0.055, 0.018, 0.0)))
|
||||
self.assertFalse(self._tx(self._lat_ctl_msg(True, 0.0, 0.12, 0.02, 0.0)))
|
||||
self._reset_curvature_measurement(0.02, 9.0)
|
||||
self.assertFalse(self._tx(self._lat_ctl_msg(True, 0.0, 0.055, 0.02, 0.0)))
|
||||
|
||||
def test_other_canfd_fords_keep_original_error(self):
|
||||
self.safety.set_safety_hooks(CarParams.SafetyModel.ford, FordSafetyFlags.CANFD)
|
||||
self.safety.init_tests()
|
||||
self.safety.set_controls_allowed(True)
|
||||
self._reset_curvature_measurement(0.0, 12.0)
|
||||
self.assertTrue(self._tx(self._extended_lka_msg()))
|
||||
self._set_prev_desired_angle(0.0058)
|
||||
self.assertFalse(self._tx(self._lat_ctl_msg(True, 0.0, 0.0, 0.0058, 0.0)))
|
||||
self._reset_curvature_measurement(0.02, 7.5)
|
||||
self._set_prev_desired_angle(0.02)
|
||||
self.assertFalse(self._tx(self._lat_ctl_msg(True, 0.0, 0.055, 0.02, 0.0)))
|
||||
|
||||
class TestFordStockSafety(TestFordSafetyBase):
|
||||
STEER_MESSAGE = MSG_LateralMotionControl
|
||||
STOCK_LONGITUDINAL = True
|
||||
|
||||
@@ -635,23 +635,6 @@ class TestHyundaiLongitudinalAolLkasOnEngageSafety(HyundaiAolLkasOnEngageBase, T
|
||||
HyundaiSafetyFlags.LONG | HyundaiStarPilotSafetyFlags.AOL_LKAS_ON_ENGAGE)
|
||||
self.safety.init_tests()
|
||||
|
||||
def test_main_off_after_brake_keeps_lateral_permission(self):
|
||||
self.safety.set_alternative_experience(ALTERNATIVE_EXPERIENCE.ALWAYS_ON_LATERAL)
|
||||
|
||||
self._rx(self._button_msg(Buttons.NONE, main_button=1))
|
||||
self._rx(self._button_msg(Buttons.NONE, main_button=0))
|
||||
self._rx(self._button_msg(Buttons.SET))
|
||||
self._rx(self._button_msg(Buttons.NONE))
|
||||
self._rx(self._user_brake_msg(True))
|
||||
self._rx(self._button_msg(Buttons.NONE, main_button=1))
|
||||
self._rx(self._button_msg(Buttons.NONE, main_button=0))
|
||||
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
self.assertFalse(self.safety.get_acc_main_on())
|
||||
self.assertTrue(self.safety.get_lkas_on())
|
||||
self._set_prev_torque(0)
|
||||
self.assertTrue(self._tx(self._torque_cmd_msg(self.MAX_RATE_UP)))
|
||||
|
||||
|
||||
class TestHyundaiLongitudinalAolMainLkasOnEngageSafety(TestHyundaiLongitudinalSafety):
|
||||
def setUp(self):
|
||||
|
||||
@@ -959,85 +959,5 @@ class TestHyundaiCanfdLKASteeringAolLkasOnEngageEV(HyundaiAolLkasOnEngageStockBa
|
||||
self.safety.init_tests()
|
||||
|
||||
|
||||
class TestSportageNoStockLka(unittest.TestCase):
|
||||
TX_MSGS = None # Supplemental transition tests, not a separate safety mode.
|
||||
PARAM = (HyundaiSafetyFlags.CANFD_LKA_STEERING | HyundaiSafetyFlags.CANFD_LKA_STEERING_ALT |
|
||||
HyundaiSafetyFlags.CANFD_ANGLE_STEERING | HyundaiSafetyFlags.HYBRID_GAS)
|
||||
|
||||
def setUp(self):
|
||||
self.safety = libsafety_py.libsafety
|
||||
self.packer = CANPackerSafety("hyundai_canfd_generated")
|
||||
self._init(True)
|
||||
|
||||
def _init(self, suppress):
|
||||
param = self.PARAM | (HyundaiStarPilotSafetyFlags.CANFD_NO_STOCK_LKA if suppress else 0)
|
||||
self.safety.set_safety_hooks(CarParams.SafetyModel.hyundaiCanfd, param)
|
||||
self.safety.init_tests()
|
||||
self.safety.set_alternative_experience(ALTERNATIVE_EXPERIENCE.ALWAYS_ON_LATERAL)
|
||||
|
||||
def _speed(self, speed):
|
||||
for _ in range(common.MAX_SAMPLE_VALS):
|
||||
self.safety.safety_rx_hook(self.packer.make_can_msg_safety(
|
||||
"WHEEL_SPEEDS", 1, {f"WHL_Spd{pos}Val": speed for pos in ("FL", "FR", "RL", "RR")}))
|
||||
|
||||
def _toggle(self):
|
||||
for pressed in (1, 0):
|
||||
self.safety.safety_rx_hook(self.packer.make_can_msg_safety("CRUISE_BUTTONS", 1, {"LDA_BTN": pressed}))
|
||||
|
||||
def _steer(self, active, gain=None):
|
||||
return self.packer.make_can_msg_safety("LKAS_ALT", 0, {
|
||||
"LKAS_ANGLE_ACTIVE": 2 if active else 1,
|
||||
"ADAS_StrAnglReqVal": 0,
|
||||
"ADAS_ACIAnglTqRedcGainVal": (0.4 if active else 0.0) if gain is None else gain,
|
||||
"Damping_Gain": 100,
|
||||
})
|
||||
|
||||
def test_stock_scc_buttons_require_engagement(self):
|
||||
resume = self.packer.make_can_msg_safety("CRUISE_BUTTONS", 1, {"CRUISE_BUTTONS": Buttons.RESUME})
|
||||
set_button = self.packer.make_can_msg_safety("CRUISE_BUTTONS", 1, {"CRUISE_BUTTONS": Buttons.SET})
|
||||
self.assertFalse(self.safety.safety_tx_hook(resume))
|
||||
self.assertFalse(self.safety.safety_tx_hook(set_button))
|
||||
|
||||
self.safety.safety_rx_hook(set_button)
|
||||
self.safety.safety_rx_hook(self.packer.make_can_msg_safety("SCC_CONTROL", 1, {"ACCMode": 1}))
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
self.assertTrue(self.safety.safety_tx_hook(resume))
|
||||
self.assertTrue(self.safety.safety_tx_hook(set_button))
|
||||
|
||||
self.safety.safety_rx_hook(self.packer.make_can_msg_safety("SCC_CONTROL", 1, {"ACCMode": 0}))
|
||||
self.assertFalse(self.safety.safety_tx_hook(resume))
|
||||
self.assertFalse(self.safety.safety_tx_hook(set_button))
|
||||
|
||||
def test_aol_toggle_keeps_stock_blocked_and_inactive_status_allowed(self):
|
||||
self._speed(30)
|
||||
for expected_aol in (False, True, False, True, False):
|
||||
if expected_aol != self.safety.get_aol_allowed():
|
||||
self._toggle()
|
||||
self.assertEqual(expected_aol, self.safety.get_aol_allowed())
|
||||
for addr in (0x110, 0x362):
|
||||
self.assertEqual(-1, self.safety.safety_fwd_hook(2, addr))
|
||||
self.assertTrue(self.safety.safety_tx_hook(self._steer(False)))
|
||||
self.assertTrue(self.safety.safety_tx_hook(common.make_msg(0, 0x362, 32)))
|
||||
self.assertEqual(expected_aol, self.safety.safety_tx_hook(self._steer(True)))
|
||||
self.assertFalse(self.safety.safety_tx_hook(self._steer(False, gain=0.4)))
|
||||
|
||||
def test_standstill_does_not_allow_active_steering(self):
|
||||
self._speed(0)
|
||||
self._toggle()
|
||||
self.assertTrue(self.safety.get_aol_allowed())
|
||||
self.assertFalse(self.safety.safety_tx_hook(self._steer(True)))
|
||||
self.assertTrue(self.safety.safety_tx_hook(self._steer(False)))
|
||||
self.assertEqual(-1, self.safety.safety_fwd_hook(2, 0x110))
|
||||
|
||||
def test_unflagged_handoff_and_reinitialization_unchanged(self):
|
||||
self._init(False)
|
||||
self._speed(30)
|
||||
self.assertEqual(0, self.safety.safety_fwd_hook(2, 0x110))
|
||||
self.assertFalse(self.safety.safety_tx_hook(self._steer(False)))
|
||||
self._toggle()
|
||||
self.assertEqual(-1, self.safety.safety_fwd_hook(2, 0x110))
|
||||
self.assertTrue(self.safety.safety_tx_hook(self._steer(True)))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -21,9 +21,8 @@ def test_ray_pedal_tx_isolation_and_limits(param):
|
||||
|
||||
has_ray_signature = param in (0x9405, 0x9C05)
|
||||
assert tx(0) is has_ray_signature
|
||||
assert tx(0.55) is has_ray_signature
|
||||
assert not tx(0.56)
|
||||
assert not tx(0.70)
|
||||
assert tx(0.35) is has_ray_signature
|
||||
assert not tx(0.36) # above the Ray-only initial command cap
|
||||
assert not tx(1.0)
|
||||
|
||||
if has_ray_signature:
|
||||
|
||||
@@ -147,34 +147,6 @@ class TestToyotaSafetyBase(common.CarSafetyTest, common.LongitudinalAccelSafetyT
|
||||
self.safety.set_alternative_experience(0)
|
||||
self.assertFalse(self._tx(hold_msg))
|
||||
|
||||
def test_auto_brake_hold_aeb_replacement_only_at_standstill(self):
|
||||
if (not self.LONGITUDINAL or
|
||||
self.safety.get_current_safety_param() & (ToyotaSafetyFlags.STOCK_LONGITUDINAL.value | ToyotaSafetyFlags.SECOC.value)):
|
||||
raise unittest.SkipTest("Toyota AEB Auto Hold requires non-SecOC openpilot longitudinal control")
|
||||
|
||||
self.safety.set_alternative_experience(ALTERNATIVE_EXPERIENCE.ALLOW_AEB)
|
||||
hold_msg = libsafety_py.make_CANPacket(0x344, 0, b"\xfd\x80\x00\x00\x00\x00\x00\xcc")
|
||||
|
||||
self._rx(self._speed_msg(0))
|
||||
self._rx(self._toggle_aol(True))
|
||||
self._rx(self._user_gas_msg(False))
|
||||
self.assertTrue(self._tx(hold_msg))
|
||||
self.assertEqual(-1, self.safety.safety_fwd_hook(2, 0x344))
|
||||
|
||||
self._rx(self._speed_msg(1.0))
|
||||
self.assertFalse(self._tx(hold_msg))
|
||||
self.assertEqual(0, self.safety.safety_fwd_hook(2, 0x344))
|
||||
|
||||
self._rx(self._speed_msg(0))
|
||||
self._rx(self._user_gas_msg(True))
|
||||
self.assertFalse(self._tx(hold_msg))
|
||||
self.assertEqual(0, self.safety.safety_fwd_hook(2, 0x344))
|
||||
|
||||
self._rx(self._user_gas_msg(False))
|
||||
self._rx(self._toggle_aol(False))
|
||||
self.assertFalse(self._tx(hold_msg))
|
||||
self.assertEqual(0, self.safety.safety_fwd_hook(2, 0x344))
|
||||
|
||||
# Only allow LTA msgs with no actuation
|
||||
def test_lta_steer_cmd(self):
|
||||
for engaged, req, req2, torque_wind_down, angle in itertools.product([True, False],
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,2 +1,2 @@
|
||||
extern const uint8_t gitversion[19];
|
||||
const uint8_t gitversion[19] = "DEV-96ef704d-DEBUG";
|
||||
const uint8_t gitversion[19] = "DEV-5925aecd-DEBUG";
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user