diff --git a/opendbc_repo/opendbc/car/toyota/interface.py b/opendbc_repo/opendbc/car/toyota/interface.py index 0441db279..f7c08534d 100644 --- a/opendbc_repo/opendbc/car/toyota/interface.py +++ b/opendbc_repo/opendbc/car/toyota/interface.py @@ -28,6 +28,9 @@ class CarInterface(CarInterfaceBase): ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.toyota)] ret.safetyConfigs[0].safetyParam = EPS_SCALE[candidate] + if candidate == CAR.LEXUS_IS: + ret.safetyConfigs[0].safetyParam |= ToyotaSafetyFlags.ALT_CRUISE.value + # BRAKE_MODULE is on a different address for these cars if DBC[candidate][Bus.pt] == "toyota_new_mc_pt_generated": ret.safetyConfigs[0].safetyParam |= ToyotaSafetyFlags.ALT_BRAKE.value diff --git a/opendbc_repo/opendbc/car/toyota/tests/test_toyota.py b/opendbc_repo/opendbc/car/toyota/tests/test_toyota.py index ecae7d9d8..62fbf2dcc 100644 --- a/opendbc_repo/opendbc/car/toyota/tests/test_toyota.py +++ b/opendbc_repo/opendbc/car/toyota/tests/test_toyota.py @@ -132,6 +132,7 @@ class TestToyotaInterfaces: assert not car_params.flags & ToyotaFlags.DSU_BYPASS.value assert not car_params.openpilotLongitudinalControl assert car_params.safetyConfigs[0].safetyParam & ToyotaSafetyFlags.STOCK_LONGITUDINAL.value + assert car_params.safetyConfigs[0].safetyParam & ToyotaSafetyFlags.ALT_CRUISE.value @pytest.mark.parametrize(("native_bus", "message"), [(1, 0x343), (0, 0x4CB)]) def test_prius_dsu_bypass_allows_native_bus_message(self, native_bus, message): @@ -152,6 +153,7 @@ class TestToyotaInterfaces: assert car_params.flags & ToyotaFlags.DSU_BYPASS.value assert car_params.openpilotLongitudinalControl assert not car_params.safetyConfigs[0].safetyParam & ToyotaSafetyFlags.STOCK_LONGITUDINAL.value + assert not car_params.safetyConfigs[0].safetyParam & ToyotaSafetyFlags.ALT_CRUISE.value def test_dsu_bypass_does_not_change_tss2_or_smart_dsu(self): fingerprint = {bus: {} for bus in range(8)} diff --git a/opendbc_repo/opendbc/car/toyota/values.py b/opendbc_repo/opendbc/car/toyota/values.py index 1517ca4db..edbd83780 100644 --- a/opendbc_repo/opendbc/car/toyota/values.py +++ b/opendbc_repo/opendbc/car/toyota/values.py @@ -58,6 +58,7 @@ class ToyotaSafetyFlags(IntFlag): SECOC = (8 << 8) LONG_FILTER = (16 << 8) GAS_INTERCEPTOR = (32 << 8) + ALT_CRUISE = (64 << 8) class ToyotaFlags(IntFlag): diff --git a/opendbc_repo/opendbc/safety/modes/toyota.h b/opendbc_repo/opendbc/safety/modes/toyota.h index 9ab746923..2c3b6d820 100644 --- a/opendbc_repo/opendbc/safety/modes/toyota.h +++ b/opendbc_repo/opendbc/safety/modes/toyota.h @@ -50,23 +50,36 @@ #define TOYOTA_COMMON_RX_CHECKS(lta) \ {.msg = {{ 0xaa, 0, 8, 83U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ {.msg = {{0x260, 0, 8, 50U, .ignore_counter = true, .ignore_quality_flag=!(lta)}, { 0 }, { 0 }}}, \ - /* StarPilot Variables */ \ + +#define TOYOTA_CRUISE_RX_CHECK \ + {.msg = {{0x1D3, 0, 8, 33U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ + +#define TOYOTA_ALT_CRUISE_RX_CHECK \ {.msg = {{0x1D3, 0, 8, 33U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, \ {0x1D3, 0, 5, 33U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, \ {0x365, 0, 7, 10U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}}}, \ #define TOYOTA_RX_CHECKS(lta) \ TOYOTA_COMMON_RX_CHECKS(lta) \ + TOYOTA_CRUISE_RX_CHECK \ + {.msg = {{0x1D2, 0, 8, 33U, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ + {.msg = {{0x226, 0, 8, 40U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ + +#define TOYOTA_ALT_CRUISE_RX_CHECKS(lta) \ + TOYOTA_COMMON_RX_CHECKS(lta) \ + TOYOTA_ALT_CRUISE_RX_CHECK \ {.msg = {{0x1D2, 0, 8, 33U, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ {.msg = {{0x226, 0, 8, 40U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ #define TOYOTA_ALT_BRAKE_RX_CHECKS(lta) \ TOYOTA_COMMON_RX_CHECKS(lta) \ + TOYOTA_CRUISE_RX_CHECK \ {.msg = {{0x1D2, 0, 8, 33U, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ {.msg = {{0x224, 0, 8, 40U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ #define TOYOTA_SECOC_RX_CHECKS \ TOYOTA_COMMON_RX_CHECKS(false) \ + TOYOTA_CRUISE_RX_CHECK \ {.msg = {{0x176, 0, 8, 32U, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ {.msg = {{0x116, 0, 8, 42U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ {.msg = {{0x101, 0, 8, 50U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ @@ -80,6 +93,7 @@ static bool toyota_stock_longitudinal = false; static bool toyota_lta = false; static int toyota_dbc_eps_torque_factor = 100; // conversion factor for STEER_TORQUE_EPS in %: see dbc file static bool toyota_long_filter = false; +static bool toyota_alt_cruise = false; static uint32_t toyota_compute_checksum(const CANPacket_t *msg) { int len = GET_LEN(msg); @@ -111,7 +125,7 @@ static bool toyota_get_quality_flag_valid(const CANPacket_t *msg) { } static void toyota_rx_all_hook(const CANPacket_t *msg) { - if ((msg->bus == 0U) && (msg->addr == 0x365U) && (GET_LEN(msg) == 7U)) { + if (toyota_alt_cruise && (msg->bus == 0U) && (msg->addr == 0x365U) && (GET_LEN(msg) == 7U)) { acc_main_on = GET_BIT(msg, 0U); // DSU_CRUISE.MAIN_ON } } @@ -441,6 +455,7 @@ static safety_config toyota_init(uint16_t param) { const uint32_t TOYOTA_PARAM_LTA = 4UL << TOYOTA_PARAM_OFFSET; const uint32_t TOYOTA_PARAM_LONG_FILTER = 16UL << TOYOTA_PARAM_OFFSET; const uint32_t TOYOTA_PARAM_GAS_INTERCEPTOR = 32UL << TOYOTA_PARAM_OFFSET; + const uint32_t TOYOTA_PARAM_ALT_CRUISE = 64UL << TOYOTA_PARAM_OFFSET; #ifdef ALLOW_DEBUG const uint32_t TOYOTA_PARAM_SECOC = 8UL << TOYOTA_PARAM_OFFSET; @@ -452,6 +467,7 @@ static safety_config toyota_init(uint16_t param) { toyota_lta = GET_FLAG(param, TOYOTA_PARAM_LTA); toyota_long_filter = GET_FLAG(param, TOYOTA_PARAM_LONG_FILTER); enable_gas_interceptor = GET_FLAG(param, TOYOTA_PARAM_GAS_INTERCEPTOR); + toyota_alt_cruise = GET_FLAG(param, TOYOTA_PARAM_ALT_CRUISE); toyota_dbc_eps_torque_factor = param & TOYOTA_EPS_FACTOR; if (toyota_stock_longitudinal || toyota_secoc) { @@ -519,8 +535,19 @@ static safety_config toyota_init(uint16_t param) { TOYOTA_ALT_BRAKE_RX_CHECKS(false) TOYOTA_GAS_INTERCEPTOR_ADDR_CHECK }; + static RxCheck toyota_lka_alt_cruise_rx_checks[] = { + TOYOTA_ALT_CRUISE_RX_CHECKS(false) + }; + static RxCheck toyota_lka_alt_cruise_interceptor_rx_checks[] = { + TOYOTA_ALT_CRUISE_RX_CHECKS(false) + TOYOTA_GAS_INTERCEPTOR_ADDR_CHECK + }; - if (enable_gas_interceptor && !toyota_alt_brake) { + if (toyota_alt_cruise && enable_gas_interceptor) { + SET_RX_CHECKS(toyota_lka_alt_cruise_interceptor_rx_checks, ret); + } else if (toyota_alt_cruise) { + SET_RX_CHECKS(toyota_lka_alt_cruise_rx_checks, ret); + } else if (enable_gas_interceptor && !toyota_alt_brake) { SET_RX_CHECKS(toyota_lka_interceptor_rx_checks, ret); } else if (enable_gas_interceptor) { SET_RX_CHECKS(toyota_lka_alt_brake_interceptor_rx_checks, ret); diff --git a/opendbc_repo/opendbc/safety/tests/test_toyota.py b/opendbc_repo/opendbc/safety/tests/test_toyota.py index 8e0e81c3a..2077e4acb 100644 --- a/opendbc_repo/opendbc/safety/tests/test_toyota.py +++ b/opendbc_repo/opendbc/safety/tests/test_toyota.py @@ -160,7 +160,8 @@ def test_toyota_aol_rx_check_variants(): safety = libsafety_py.libsafety for addr, length in ((0x1D3, 8), (0x1D3, 5), (0x365, 7)): - safety.set_safety_hooks(CarParams.SafetyModel.toyota, TestToyotaSafetyBase.EPS_SCALE) + safety.set_safety_hooks(CarParams.SafetyModel.toyota, + TestToyotaSafetyBase.EPS_SCALE | ToyotaSafetyFlags.ALT_CRUISE) safety.init_tests() messages = ( @@ -177,7 +178,8 @@ def test_toyota_aol_rx_check_variants(): def test_toyota_dsu_cruise_main_bit(): safety = libsafety_py.libsafety - safety.set_safety_hooks(CarParams.SafetyModel.toyota, TestToyotaSafetyBase.EPS_SCALE) + safety.set_safety_hooks(CarParams.SafetyModel.toyota, + TestToyotaSafetyBase.EPS_SCALE | ToyotaSafetyFlags.ALT_CRUISE) safety.init_tests() safety.safety_rx_hook(libsafety_py.make_CANPacket(0x1D3, 0, bytes(5))) @@ -193,6 +195,19 @@ def test_toyota_dsu_cruise_main_bit(): assert not safety.get_acc_main_on() +def test_toyota_standard_cruise_ignores_dsu_main(): + packer = CANPackerSafety("toyota_nodsu_pt_generated") + safety = libsafety_py.libsafety + safety.set_safety_hooks(CarParams.SafetyModel.toyota, TestToyotaSafetyBase.EPS_SCALE) + safety.init_tests() + + assert safety.safety_rx_hook(packer.make_can_msg_safety("PCM_CRUISE_2", 0, {"MAIN_ON": 1})) + assert safety.get_acc_main_on() + + safety.safety_rx_hook(libsafety_py.make_CANPacket(0x365, 0, bytes(7))) + assert safety.get_acc_main_on() + + class TestToyotaSafetyTorque(TestToyotaSafetyBase, common.MotorTorqueSteeringSafetyTest, common.SteerRequestCutSafetyTest): MAX_RATE_UP = 15