mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-06-28 01:52:06 +08:00
Tyger Tyger Burning Bright
This commit is contained in:
@@ -40,6 +40,9 @@ AUTO_HOLD_MAX_BRAKE = 240
|
||||
AUTO_HOLD_MIN_DRIVE_TIME_S = 3.0
|
||||
AUTO_HOLD_STOPPED_SPEED = 0.02
|
||||
AUTO_HOLD_2019_MIN_BRAKE = 100
|
||||
BOLT_ACC_PEDAL_FRICTION_RELEASE_FRAMES = 5
|
||||
BOLT_PEDAL_LONG_ACCEL_LIMIT_BP = [0.0, 1.5, 4.0, 8.0, 15.0, 30.0]
|
||||
BOLT_PEDAL_LONG_ACCEL_LIMIT_V = [-0.93, -1.28, -1.98, -2.58, -2.86, -2.95]
|
||||
VOLT_ONE_PEDAL_DECEL_BP = [0.5 * CV.MPH_TO_MS, 6.0 * CV.MPH_TO_MS]
|
||||
VOLT_ONE_PEDAL_DECEL_V = [-1.0, -1.1]
|
||||
VOLT_ONE_PEDAL_REGEN_PADDLE_DECEL_V = [-1.5, -1.6]
|
||||
@@ -285,6 +288,51 @@ def get_friction_brake_bus(CP):
|
||||
return CanBus.CHASSIS
|
||||
|
||||
|
||||
def supports_bolt_acc_pedal_friction_experiment(CP) -> bool:
|
||||
return (
|
||||
CP.carFingerprint == CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL and
|
||||
CP.openpilotLongitudinalControl and
|
||||
CP.enableGasInterceptorDEPRECATED and
|
||||
bool(CP.flags & GMFlags.PEDAL_LONG.value)
|
||||
)
|
||||
|
||||
|
||||
def get_bolt_acc_pedal_friction_brake(apply_brake, full_brake_accel, v_ego, params) -> int:
|
||||
if apply_brake <= 0:
|
||||
return 0
|
||||
|
||||
full_brake_accel = min(full_brake_accel, -0.1)
|
||||
legacy_full_scale = max(-params.ACCEL_MIN, 0.1)
|
||||
corrected_scale = legacy_full_scale / max(-full_brake_accel, 0.1)
|
||||
speed_gain = float(np.interp(v_ego, [0.0, 10.0, 25.0], [1.0, 1.15, 1.3]))
|
||||
|
||||
return int(round(np.clip(apply_brake * corrected_scale * speed_gain, 0, params.MAX_BRAKE)))
|
||||
|
||||
|
||||
def get_bolt_pedal_long_accel_limit(v_ego: float) -> float:
|
||||
return float(np.interp(v_ego, BOLT_PEDAL_LONG_ACCEL_LIMIT_BP, BOLT_PEDAL_LONG_ACCEL_LIMIT_V))
|
||||
|
||||
|
||||
def get_bolt_acc_pedal_planner_brake_switch(v_ego: float, params, tire_radius: float, mass: float,
|
||||
coeff_drag: float, frontal_area: float, air_density: float) -> int:
|
||||
planner_accel_limit = get_bolt_pedal_long_accel_limit(v_ego)
|
||||
aero_drag_force = 0.5 * coeff_drag * frontal_area * air_density * v_ego ** 2
|
||||
planner_torque = tire_radius * ((mass * planner_accel_limit) + aero_drag_force)
|
||||
return int(round(planner_torque + params.ZERO_GAS))
|
||||
|
||||
|
||||
def get_bolt_acc_pedal_friction_command_state(apply_brake: int, cruise_main_on: bool, release_frames: int):
|
||||
command_brake = apply_brake if cruise_main_on else 0
|
||||
|
||||
if command_brake > 0:
|
||||
release_frames = BOLT_ACC_PEDAL_FRICTION_RELEASE_FRAMES
|
||||
elif release_frames > 0:
|
||||
release_frames -= 1
|
||||
|
||||
should_send = cruise_main_on or release_frames > 0
|
||||
return command_brake, release_frames, should_send
|
||||
|
||||
|
||||
class CarController(CarControllerBase):
|
||||
def __init__(self, dbc_names, CP):
|
||||
super().__init__(dbc_names, CP)
|
||||
@@ -351,6 +399,7 @@ class CarController(CarControllerBase):
|
||||
self.gm_auto_hold_enabled = self.params_.get_bool("GMAutoHold")
|
||||
except UnknownKeyName:
|
||||
self.gm_auto_hold_enabled = False
|
||||
self.bolt_acc_pedal_friction_release_frames = 0
|
||||
|
||||
def _reset_volt_one_pedal(self):
|
||||
self.volt_one_pedal_pid.reset()
|
||||
@@ -678,6 +727,8 @@ class CarController(CarControllerBase):
|
||||
CS.out.vEgo,
|
||||
get_auto_hold_stop_threshold(self.CP, CS.auto_hold_engaged),
|
||||
)
|
||||
bolt_acc_pedal_friction_experiment = supports_bolt_acc_pedal_friction_experiment(self.CP)
|
||||
bolt_acc_pedal_friction_main_on = bolt_acc_pedal_friction_experiment and CS.out.cruiseState.available
|
||||
volt_one_pedal_braking = volt_one_pedal_active and self.volt_one_pedal_brake > 0
|
||||
volt_one_pedal_hold_active = (
|
||||
volt_one_pedal_braking and
|
||||
@@ -806,9 +857,23 @@ class CarController(CarControllerBase):
|
||||
if testing_ground.use_1:
|
||||
brake_switch_bias = get_testing_ground_1_brake_switch_bias(CS.out.vEgo)
|
||||
brake_switch = min(self.params.ZERO_GAS, brake_switch + brake_switch_bias)
|
||||
if bolt_acc_pedal_friction_main_on:
|
||||
planner_brake_switch = get_bolt_acc_pedal_planner_brake_switch(
|
||||
CS.out.vEgo, self.params, self.tireRadius, self.mass, self.coeffDrag, self.frontalArea, self.airDensity,
|
||||
)
|
||||
brake_switch = min(brake_switch, planner_brake_switch)
|
||||
brake_accel = min((scaled_torque - brake_switch) / (self.tireRadius * self.mass), 0)
|
||||
self.apply_gas = int(round(apply_gas_torque))
|
||||
self.apply_brake = int(round(np.interp(brake_accel, self.params.BRAKE_LOOKUP_BP, self.params.BRAKE_LOOKUP_V)))
|
||||
if bolt_acc_pedal_friction_main_on and self.apply_brake > 0:
|
||||
full_brake_accel = min(
|
||||
self.params.ACCEL_MIN + (0.5 * self.coeffDrag * self.frontalArea * self.airDensity * CS.out.vEgo ** 2) / self.mass +
|
||||
(self.params.ZERO_GAS - brake_switch) / (self.tireRadius * self.mass),
|
||||
-0.1,
|
||||
)
|
||||
self.apply_brake = get_bolt_acc_pedal_friction_brake(
|
||||
self.apply_brake, full_brake_accel, CS.out.vEgo, self.params,
|
||||
)
|
||||
if self.apply_brake > 0:
|
||||
self.apply_gas = self.params.INACTIVE_REGEN
|
||||
|
||||
@@ -865,6 +930,26 @@ class CarController(CarControllerBase):
|
||||
can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.POWERTRAIN, (CS.buttons_counter + 1) % 4, CruiseButtons.DECEL_SET))
|
||||
if self.CP.enableGasInterceptorDEPRECATED:
|
||||
can_sends.append(create_gas_interceptor_command(self.packer_pt, interceptor_gas_cmd, idx))
|
||||
if bolt_acc_pedal_friction_experiment:
|
||||
friction_brake_bus = get_friction_brake_bus(self.CP)
|
||||
if self.CP.networkLocation == NetworkLocation.fwdCamera:
|
||||
at_full_stop = at_full_stop and stopping
|
||||
|
||||
experiment_brake, self.bolt_acc_pedal_friction_release_frames, should_send_bolt_acc_pedal_friction = \
|
||||
get_bolt_acc_pedal_friction_command_state(
|
||||
self.apply_brake,
|
||||
bolt_acc_pedal_friction_main_on,
|
||||
self.bolt_acc_pedal_friction_release_frames,
|
||||
)
|
||||
|
||||
# This fingerprint is routed through the CC-only pedal path, so it
|
||||
# does not fall through to the normal friction-brake sender below.
|
||||
# Never apply stock friction with cruise main off, but do send a short
|
||||
# explicit zero-brake unwind so the last nonzero stock-EBCM command
|
||||
# cannot linger after a disengage or main-off event.
|
||||
if should_send_bolt_acc_pedal_friction:
|
||||
can_sends.append(gmcan.create_friction_brake_command(
|
||||
self.packer_ch, friction_brake_bus, experiment_brake, idx, False, near_stop, at_full_stop, self.CP))
|
||||
if self.CP.carFingerprint not in CC_ONLY_CAR:
|
||||
friction_brake_bus = get_friction_brake_bus(self.CP)
|
||||
# GM Camera exceptions
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import sys
|
||||
import types
|
||||
from types import SimpleNamespace
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from opendbc.car import structs
|
||||
|
||||
@@ -40,6 +42,10 @@ from opendbc.car.gm.carcontroller import (
|
||||
estimate_auto_hold_brake,
|
||||
get_adas_keepalive_step,
|
||||
get_auto_hold_stop_threshold,
|
||||
get_bolt_acc_pedal_friction_brake,
|
||||
get_bolt_acc_pedal_friction_command_state,
|
||||
get_bolt_acc_pedal_planner_brake_switch,
|
||||
get_bolt_pedal_long_accel_limit,
|
||||
get_lka_steering_cmd_counter,
|
||||
get_volt_one_pedal_target_decel,
|
||||
get_testing_ground_1_brake_switch_bias,
|
||||
@@ -51,6 +57,7 @@ from opendbc.car.gm.carcontroller import (
|
||||
should_send_stock_long_cancel,
|
||||
should_spoof_dash_speed,
|
||||
should_spoof_ecm_cruise_status,
|
||||
supports_bolt_acc_pedal_friction_experiment,
|
||||
supports_volt_auto_hold,
|
||||
supports_volt_one_pedal,
|
||||
use_interceptor_sng_launch,
|
||||
@@ -107,6 +114,90 @@ def test_gen2_bolt_acc_pedal_cancel_uses_enabled_only():
|
||||
assert not get_stock_cc_active_for_cancel(CP, _cs(False, AccState.ACTIVE))
|
||||
|
||||
|
||||
def test_bolt_acc_pedal_friction_experiment_is_single_fingerprint_only():
|
||||
assert supports_bolt_acc_pedal_friction_experiment(SimpleNamespace(
|
||||
carFingerprint=CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL,
|
||||
openpilotLongitudinalControl=True,
|
||||
enableGasInterceptorDEPRECATED=True,
|
||||
flags=GMFlags.PEDAL_LONG.value,
|
||||
))
|
||||
assert not supports_bolt_acc_pedal_friction_experiment(SimpleNamespace(
|
||||
carFingerprint=CAR.CHEVROLET_MALIBU_HYBRID_CC,
|
||||
openpilotLongitudinalControl=True,
|
||||
enableGasInterceptorDEPRECATED=True,
|
||||
flags=GMFlags.PEDAL_LONG.value,
|
||||
))
|
||||
assert not supports_bolt_acc_pedal_friction_experiment(SimpleNamespace(
|
||||
carFingerprint=CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL,
|
||||
openpilotLongitudinalControl=False,
|
||||
enableGasInterceptorDEPRECATED=True,
|
||||
flags=GMFlags.PEDAL_LONG.value,
|
||||
))
|
||||
|
||||
|
||||
def test_bolt_acc_pedal_friction_blend_preserves_zero_before_crossover():
|
||||
params = SimpleNamespace(ACCEL_MIN=-4.0, MAX_BRAKE=400)
|
||||
|
||||
assert get_bolt_acc_pedal_friction_brake(0, -2.8, 20.0, params) == 0
|
||||
|
||||
|
||||
def test_bolt_acc_pedal_friction_blend_uses_full_brake_range_after_regen():
|
||||
params = SimpleNamespace(ACCEL_MIN=-4.0, MAX_BRAKE=400)
|
||||
|
||||
# Legacy mapping tops out early once regen has already consumed part of the
|
||||
# decel request. The experiment remaps that reduced span back to full scale.
|
||||
assert get_bolt_acc_pedal_friction_brake(286, -2.86, 20.0, params) == 400
|
||||
|
||||
|
||||
def test_bolt_acc_pedal_friction_blend_biases_small_commands_upward_at_speed():
|
||||
params = SimpleNamespace(ACCEL_MIN=-4.0, MAX_BRAKE=400)
|
||||
|
||||
low_speed = get_bolt_acc_pedal_friction_brake(31, -2.86, 0.0, params)
|
||||
high_speed = get_bolt_acc_pedal_friction_brake(31, -2.86, 20.0, params)
|
||||
|
||||
assert low_speed > 31
|
||||
assert high_speed > low_speed
|
||||
|
||||
|
||||
def test_bolt_pedal_long_accel_limit_matches_planner_regen_envelope():
|
||||
assert get_bolt_pedal_long_accel_limit(6.66) == pytest.approx(-2.379, abs=1e-3)
|
||||
assert get_bolt_pedal_long_accel_limit(3.0) == pytest.approx(-1.70, abs=1e-3)
|
||||
|
||||
|
||||
def test_bolt_acc_pedal_planner_brake_switch_delays_friction_vs_stock_switch():
|
||||
params = SimpleNamespace(ZERO_GAS=6150, BRAKE_SWITCH_LOOKUP_BP=[0.5, 10.0], BRAKE_SWITCH_LOOKUP_V=[6150, 5500])
|
||||
v_ego = 6.66
|
||||
|
||||
stock_switch = int(round(np.interp(v_ego, params.BRAKE_SWITCH_LOOKUP_BP, params.BRAKE_SWITCH_LOOKUP_V)))
|
||||
planner_switch = get_bolt_acc_pedal_planner_brake_switch(
|
||||
v_ego, params, tire_radius=0.336, mass=1832.0, coeff_drag=0.30, frontal_area=2.35, air_density=1.225,
|
||||
)
|
||||
|
||||
assert planner_switch < stock_switch
|
||||
|
||||
|
||||
def test_bolt_acc_pedal_friction_command_state_requires_cruise_main_for_positive_brake():
|
||||
command_brake, release_frames, should_send = get_bolt_acc_pedal_friction_command_state(120, False, 0)
|
||||
|
||||
assert command_brake == 0
|
||||
assert release_frames == 0
|
||||
assert not should_send
|
||||
|
||||
|
||||
def test_bolt_acc_pedal_friction_command_state_sends_zero_unwind_after_main_off():
|
||||
command_brake, release_frames, should_send = get_bolt_acc_pedal_friction_command_state(120, True, 0)
|
||||
|
||||
assert command_brake == 120
|
||||
assert release_frames > 0
|
||||
assert should_send
|
||||
|
||||
command_brake, release_frames, should_send = get_bolt_acc_pedal_friction_command_state(0, False, release_frames)
|
||||
|
||||
assert command_brake == 0
|
||||
assert release_frames >= 0
|
||||
assert should_send
|
||||
|
||||
|
||||
def test_stock_cancel_is_suppressed_when_acc_is_faulted():
|
||||
CP = SimpleNamespace(carFingerprint=CAR.CHEVROLET_VOLT_CAMERA)
|
||||
cs = _cs(True, AccState.FAULTED)
|
||||
|
||||
@@ -261,6 +261,7 @@ class TestGMInterface:
|
||||
|
||||
assert car_params.alternativeExperience & ALTERNATIVE_EXPERIENCE.GM_REMAP_CANCEL_TO_DISTANCE
|
||||
assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_BOLT_2022_PEDAL.value
|
||||
assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_PANDA_PADDLE_SCHED.value
|
||||
|
||||
def test_cadillac_xt5_sdgm_sascm_gates_alpha_long(self):
|
||||
CarInterface = interfaces[CAR.CADILLAC_XT5]
|
||||
|
||||
@@ -614,6 +614,11 @@ static safety_config gm_init(uint16_t param) {
|
||||
{0x200, 0, 6, .check_relay = false},
|
||||
{0x1E1, 0, 7, .check_relay = false},
|
||||
{0xBD, 0, 7, .check_relay = false}, {0x1F5, 0, 8, .check_relay = false}}; // pt bus
|
||||
static const CanMsg GM_CAM_BOLT_2022_PEDAL_FRICTION_TX_MSGS[] = {{0x180, 0, 4, .check_relay = true}, {0x370, 0, 6, .check_relay = false}, {0x3D1, 0, 8, .check_relay = false}, {0x315, 0, 5, .check_relay = true}, // pt bus
|
||||
{0x1E1, 2, 7, .check_relay = false}, {0x184, 2, 8, .check_relay = true}, // camera bus
|
||||
{0x200, 0, 6, .check_relay = false},
|
||||
{0x1E1, 0, 7, .check_relay = false},
|
||||
{0xBD, 0, 7, .check_relay = false}, {0x1F5, 0, 8, .check_relay = false}}; // pt bus
|
||||
static const CanMsg GM_CAM_VOLT_AUTO_HOLD_TX_MSGS[] = {{0x180, 0, 4, .check_relay = true}, {0x370, 0, 6, .check_relay = false}, {0x3D1, 0, 8, .check_relay = false}, {0x315, 0, 5, .check_relay = true}, // pt bus
|
||||
{0x1E1, 2, 7, .check_relay = false}, {0x184, 2, 8, .check_relay = true}, // camera bus
|
||||
{0x200, 0, 6, .check_relay = false},
|
||||
@@ -637,6 +642,12 @@ static safety_config gm_init(uint16_t param) {
|
||||
{0x200, 0, 6, .check_relay = false},
|
||||
{0x1E1, 0, 7, .check_relay = false},
|
||||
{0xBD, 0, 7, .check_relay = false}, {0x1F5, 0, 8, .check_relay = false}}; // pt bus
|
||||
static const CanMsg GM_CAM_NO_CAMERA_BOLT_2022_PEDAL_FRICTION_TX_MSGS[] = {{0x180, 0, 4, .check_relay = false}, {0x370, 0, 6, .check_relay = false}, {0x3D1, 0, 8, .check_relay = false}, {0x315, 0, 5, .check_relay = false}, // pt bus
|
||||
{0x409, 0, 7, .check_relay = false}, {0x40A, 0, 7, .check_relay = false},
|
||||
{0x1E1, 2, 7, .check_relay = false}, {0x184, 2, 8, .check_relay = false}, // camera bus
|
||||
{0x200, 0, 6, .check_relay = false},
|
||||
{0x1E1, 0, 7, .check_relay = false},
|
||||
{0xBD, 0, 7, .check_relay = false}, {0x1F5, 0, 8, .check_relay = false}}; // pt bus
|
||||
static const CanMsg GM_CAM_NO_CAMERA_VOLT_AUTO_HOLD_TX_MSGS[] = {{0x180, 0, 4, .check_relay = false}, {0x370, 0, 6, .check_relay = false}, {0x3D1, 0, 8, .check_relay = false}, {0x315, 0, 5, .check_relay = false}, // pt bus
|
||||
{0x409, 0, 7, .check_relay = false}, {0x40A, 0, 7, .check_relay = false},
|
||||
{0x1E1, 2, 7, .check_relay = false}, {0x184, 2, 8, .check_relay = false}, // camera bus
|
||||
@@ -736,6 +747,11 @@ static safety_config gm_init(uint16_t param) {
|
||||
gm_pcm_cruise = (gm_hw == GM_CAM || gm_sdgm) && !gm_cam_long && !gm_force_ascm && !gm_pedal_long;
|
||||
const bool gm_ascm_int_stock_cam = gm_ascm_int && (gm_hw == GM_CAM) && gm_pcm_cruise && !gm_cam_long && !gm_pedal_long && !gm_cc_long;
|
||||
const bool gm_ascm_int_no_accel_pos = gm_ascm_int && (gm_hw == GM_CAM) && gm_force_brake_c9;
|
||||
// FLAG_GM_BOLT_2022_PEDAL is shared with Malibu Hybrid pedal-long. Requiring
|
||||
// the paddle scheduler bit narrows this whitelist to the Gen2 Bolt pedal-long
|
||||
// experiment, which is the only path that should probe chassis friction brake
|
||||
// while stock ACC remains canceled.
|
||||
const bool gm_bolt_2022_pedal_friction = gm_bolt_2022_pedal && gm_panda_paddle_sched && !gm_has_acc;
|
||||
gm_steer_limits = GET_FLAG(param, GM_PARAM_BOLT_2017) ? &GM_BOLT_2017_STEERING_LIMITS : &GM_STEERING_LIMITS;
|
||||
|
||||
if ((gm_hw == GM_ASCM && !gm_sdgm) || gm_ascm_int || gm_force_ascm) {
|
||||
@@ -774,13 +790,19 @@ static safety_config gm_init(uint16_t param) {
|
||||
if (gm_volt_stock_brake && gm_sdgm) {
|
||||
ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_SDGM_VOLT_AUTO_HOLD_TX_MSGS);
|
||||
} else if (gm_no_camera) {
|
||||
if (gm_volt_stock_brake) {
|
||||
if (gm_bolt_2022_pedal_friction) {
|
||||
ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_CAM_NO_CAMERA_BOLT_2022_PEDAL_FRICTION_TX_MSGS);
|
||||
} else if (gm_volt_stock_brake) {
|
||||
ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_CAM_NO_CAMERA_VOLT_AUTO_HOLD_TX_MSGS);
|
||||
} else {
|
||||
ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_CAM_NO_CAMERA_TX_MSGS);
|
||||
}
|
||||
} else {
|
||||
if (gm_volt_stock_brake) {
|
||||
if (gm_bolt_2022_pedal_friction) {
|
||||
// Experimental Gen2 Bolt pedal-long path: keep stock ACC canceled but
|
||||
// allow OP to probe chassis friction-brake acceptance through panda.
|
||||
ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_CAM_BOLT_2022_PEDAL_FRICTION_TX_MSGS);
|
||||
} else if (gm_volt_stock_brake) {
|
||||
ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_CAM_VOLT_AUTO_HOLD_TX_MSGS);
|
||||
} else {
|
||||
ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_CAM_TX_MSGS);
|
||||
|
||||
@@ -973,8 +973,8 @@ class SafetyTest(SafetyTestBase):
|
||||
continue
|
||||
if {attr, current_test}.issubset({'TestGmCameraSafety', 'TestGmCameraLongitudinalSafety', 'TestGmAscmSafety',
|
||||
'TestGmCameraEVSafety', 'TestGmCameraLongitudinalEVSafety', 'TestGmAscmEVSafety',
|
||||
'TestGmInterceptorSafety', 'TestGmCcLongitudinalSafety',
|
||||
'TestGmCcLongitudinalPandaSchedSafety'}):
|
||||
'TestGmInterceptorSafety', 'TestGmBolt2022PedalFrictionSafety',
|
||||
'TestGmCcLongitudinalSafety', 'TestGmCcLongitudinalPandaSchedSafety'}):
|
||||
continue
|
||||
if attr.startswith('TestFord') and current_test.startswith('TestFord'):
|
||||
continue
|
||||
|
||||
@@ -469,6 +469,71 @@ class TestGmInterceptorSafety(common.GasInterceptorSafetyTest, TestGmCameraSafet
|
||||
return to_send
|
||||
|
||||
|
||||
class TestGmBolt2022PedalFrictionSafety(TestGmInterceptorSafety):
|
||||
TX_MSGS = TestGmInterceptorSafety.TX_MSGS + [[0x315, 0]]
|
||||
FWD_BLACKLISTED_ADDRS = {2: [0x180, 0x370, 0x315], 0: [0x184, 0x3D1]}
|
||||
RELAY_MALFUNCTION_ADDRS = {0: (0x180, 0x315), 2: (0x184,)}
|
||||
EXTRA_SAFETY_PARAM = GMSafetyFlags.FLAG_GM_BOLT_2022_PEDAL
|
||||
|
||||
def setUp(self):
|
||||
self.packer = CANPackerPanda("gm_global_a_powertrain_generated")
|
||||
self.packer_chassis = CANPackerPanda("gm_global_a_chassis")
|
||||
self.safety = libsafety_py.libsafety
|
||||
self.safety.set_safety_hooks(
|
||||
CarParams.SafetyModel.gm,
|
||||
GMSafetyFlags.HW_CAM |
|
||||
GMSafetyFlags.FLAG_GM_NO_ACC |
|
||||
GMSafetyFlags.FLAG_GM_PEDAL_LONG |
|
||||
GMSafetyFlags.FLAG_GM_GAS_INTERCEPTOR |
|
||||
GMSafetyFlags.FLAG_GM_PANDA_PADDLE_SCHED |
|
||||
self.EXTRA_SAFETY_PARAM)
|
||||
self.safety.init_tests()
|
||||
|
||||
def _send_brake_msg(self, brake):
|
||||
values = {"FrictionBrakeCmd": -brake}
|
||||
return self.packer_chassis.make_can_msg_safety("EBCMFrictionBrakeCmd", 0, values)
|
||||
|
||||
def _engage_longitudinal(self):
|
||||
self._rx(self.packer.make_can_msg_panda("ASCMSteeringButton", 0, {"ACCButtons": Buttons.DECEL_SET}))
|
||||
self._rx(self.packer.make_can_msg_panda("ASCMSteeringButton", 0, {"ACCButtons": Buttons.UNPRESS}))
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
self.assertTrue(self.safety.get_longitudinal_allowed())
|
||||
|
||||
def test_tx_hook_on_wrong_safety_mode(self):
|
||||
self.skipTest("Gen2 Bolt pedal friction experiment intentionally shares the interceptor TX set plus 0x315")
|
||||
|
||||
def test_buttons(self):
|
||||
for controls_allowed in (False, True):
|
||||
self.safety.set_controls_allowed(controls_allowed)
|
||||
for btn in range(8):
|
||||
self.assertEqual(btn == Buttons.CANCEL, self._tx(self._button_msg(btn)))
|
||||
|
||||
def test_brake_allowed_when_controls_allowed(self):
|
||||
self._engage_longitudinal()
|
||||
self.assertTrue(self._tx(self._send_brake_msg(100)))
|
||||
|
||||
def test_brake_blocked_without_controls(self):
|
||||
self.safety.set_controls_allowed(False)
|
||||
self.assertFalse(self._tx(self._send_brake_msg(100)))
|
||||
|
||||
def test_brake_limit_enforced(self):
|
||||
self._engage_longitudinal()
|
||||
self.assertTrue(self._tx(self._send_brake_msg(400)))
|
||||
self.assertFalse(self._tx(self._send_brake_msg(401)))
|
||||
|
||||
def test_brake_whitelist_requires_paddle_scheduler_selector(self):
|
||||
self.safety.set_safety_hooks(
|
||||
CarParams.SafetyModel.gm,
|
||||
GMSafetyFlags.HW_CAM |
|
||||
GMSafetyFlags.FLAG_GM_NO_ACC |
|
||||
GMSafetyFlags.FLAG_GM_PEDAL_LONG |
|
||||
GMSafetyFlags.FLAG_GM_GAS_INTERCEPTOR |
|
||||
self.EXTRA_SAFETY_PARAM)
|
||||
self.safety.init_tests()
|
||||
self._engage_longitudinal()
|
||||
self.assertFalse(self._tx(self._send_brake_msg(100)))
|
||||
|
||||
|
||||
class TestGmCcLongitudinalSafety(TestGmCameraSafety):
|
||||
TX_MSGS = [[0x180, 0], [0x370, 0], [0x1E1, 0], [0x3D1, 0], [0xBD, 0], [0x1F5, 0], [0x184, 2], [0x1E1, 2]]
|
||||
FWD_BLACKLISTED_ADDRS = {2: [0x180], 0: [0x184, 0x3D1]} # block LKAS, PSCMStatus, and stock cruise status
|
||||
|
||||
Reference in New Issue
Block a user