mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-21 16:23:46 +08:00
September 27th, 2025 Update
This commit is contained in:
@@ -10,30 +10,16 @@ const SteeringLimits GM_STEERING_LIMITS = {
|
||||
};
|
||||
|
||||
const LongitudinalLimits GM_ASCM_LONG_LIMITS = {
|
||||
.max_gas = 7168,
|
||||
.min_gas = 5500,
|
||||
.inactive_gas = 5500,
|
||||
.max_brake = 400,
|
||||
};
|
||||
|
||||
const LongitudinalLimits GM_ASCM_LONG_LIMITS_SPORT = {
|
||||
.max_gas = 8191,
|
||||
.min_gas = 5500,
|
||||
.inactive_gas = 5500,
|
||||
.max_gas = 3072,
|
||||
.min_gas = 1404,
|
||||
.inactive_gas = 1404,
|
||||
.max_brake = 400,
|
||||
};
|
||||
|
||||
const LongitudinalLimits GM_CAM_LONG_LIMITS = {
|
||||
.max_gas = 7496,
|
||||
.min_gas = 5610,
|
||||
.inactive_gas = 5650,
|
||||
.max_brake = 400,
|
||||
};
|
||||
|
||||
const LongitudinalLimits GM_CAM_LONG_LIMITS_SPORT = {
|
||||
.max_gas = 8848,
|
||||
.min_gas = 5610,
|
||||
.inactive_gas = 5650,
|
||||
.max_gas = 3400,
|
||||
.min_gas = 1514,
|
||||
.inactive_gas = 1554,
|
||||
.max_brake = 400,
|
||||
};
|
||||
|
||||
@@ -157,7 +143,7 @@ static void gm_rx_hook(const CANPacket_t *to_push) {
|
||||
}
|
||||
|
||||
if ((addr == 0xC9) && ((gm_hw == GM_CAM) || (gm_hw == GM_SDGM))) {
|
||||
brake_pressed = GET_BIT(to_push, 40U) != 0U;
|
||||
brake_pressed = GET_BIT(to_push, 40U);
|
||||
}
|
||||
|
||||
if (addr == 0xC9) {
|
||||
@@ -243,7 +229,7 @@ static bool gm_tx_hook(const CANPacket_t *to_send) {
|
||||
// GAS/REGEN: safety check
|
||||
if (addr == 0x2CB) {
|
||||
bool apply = GET_BIT(to_send, 0U);
|
||||
int gas_regen = ((GET_BYTE(to_send, 1) & 0x1U) << 13) + ((GET_BYTE(to_send, 2) & 0xFFU) << 5) + ((GET_BYTE(to_send, 3) & 0xF8U) >> 3);
|
||||
int gas_regen = ((GET_BYTE(to_send, 2) & 0x7FU) << 5) + ((GET_BYTE(to_send, 3) & 0xF8U) >> 3);
|
||||
|
||||
bool violation = false;
|
||||
// Allow apply bit in pre-enabled and overriding states
|
||||
@@ -300,8 +286,6 @@ static int gm_fwd_hook(int bus_num, int addr) {
|
||||
}
|
||||
|
||||
static safety_config gm_init(uint16_t param) {
|
||||
sport_mode = alternative_experience & ALT_EXP_RAISE_LONGITUDINAL_LIMITS_TO_ISO_MAX;
|
||||
|
||||
if GET_FLAG(param, GM_PARAM_HW_CAM) {
|
||||
gm_hw = GM_CAM;
|
||||
} else if GET_FLAG(param, GM_PARAM_HW_SDGM) {
|
||||
@@ -313,17 +297,9 @@ static safety_config gm_init(uint16_t param) {
|
||||
gm_force_ascm = GET_FLAG(param, GM_PARAM_HW_ASCM_LONG);
|
||||
|
||||
if (gm_hw == GM_ASCM || gm_force_ascm) {
|
||||
if (sport_mode) {
|
||||
gm_long_limits = &GM_ASCM_LONG_LIMITS_SPORT;
|
||||
} else {
|
||||
gm_long_limits = &GM_ASCM_LONG_LIMITS;
|
||||
}
|
||||
gm_long_limits = &GM_ASCM_LONG_LIMITS;
|
||||
} else if ((gm_hw == GM_CAM) || (gm_hw == GM_SDGM)) {
|
||||
if (sport_mode) {
|
||||
gm_long_limits = &GM_CAM_LONG_LIMITS_SPORT;
|
||||
} else {
|
||||
gm_long_limits = &GM_CAM_LONG_LIMITS;
|
||||
}
|
||||
gm_long_limits = &GM_CAM_LONG_LIMITS;
|
||||
} else {
|
||||
}
|
||||
|
||||
|
||||
@@ -19,14 +19,6 @@ const LongitudinalLimits HONDA_BOSCH_LONG_LIMITS = {
|
||||
.inactive_gas = -30000,
|
||||
};
|
||||
|
||||
const LongitudinalLimits HONDA_BOSCH_LONG_LIMITS_SPORT = {
|
||||
.max_accel = 400, // accel is used for brakes
|
||||
.min_accel = -350,
|
||||
|
||||
.max_gas = 2000,
|
||||
.inactive_gas = -30000,
|
||||
};
|
||||
|
||||
const LongitudinalLimits HONDA_NIDEC_LONG_LIMITS = {
|
||||
.max_gas = 198, // 0xc6
|
||||
.max_brake = 255,
|
||||
@@ -284,8 +276,6 @@ static void honda_rx_hook(const CANPacket_t *to_push) {
|
||||
}
|
||||
|
||||
static bool honda_tx_hook(const CANPacket_t *to_send) {
|
||||
sport_mode = alternative_experience & ALT_EXP_RAISE_LONGITUDINAL_LIMITS_TO_ISO_MAX;
|
||||
|
||||
bool tx = true;
|
||||
int addr = GET_ADDR(to_send);
|
||||
int bus = GET_BUS(to_send);
|
||||
@@ -329,13 +319,8 @@ static bool honda_tx_hook(const CANPacket_t *to_send) {
|
||||
gas = to_signed(gas, 16);
|
||||
|
||||
bool violation = false;
|
||||
if (sport_mode) {
|
||||
violation |= longitudinal_accel_checks(accel, HONDA_BOSCH_LONG_LIMITS_SPORT);
|
||||
violation |= longitudinal_gas_checks(gas, HONDA_BOSCH_LONG_LIMITS_SPORT);
|
||||
} else {
|
||||
violation |= longitudinal_accel_checks(accel, HONDA_BOSCH_LONG_LIMITS);
|
||||
violation |= longitudinal_gas_checks(gas, HONDA_BOSCH_LONG_LIMITS);
|
||||
}
|
||||
violation |= longitudinal_accel_checks(accel, HONDA_BOSCH_LONG_LIMITS);
|
||||
violation |= longitudinal_gas_checks(gas, HONDA_BOSCH_LONG_LIMITS);
|
||||
if (violation) {
|
||||
tx = false;
|
||||
}
|
||||
@@ -347,11 +332,7 @@ static bool honda_tx_hook(const CANPacket_t *to_send) {
|
||||
accel = to_signed(accel, 12);
|
||||
|
||||
bool violation = false;
|
||||
if (sport_mode) {
|
||||
violation |= longitudinal_accel_checks(accel, HONDA_BOSCH_LONG_LIMITS_SPORT);
|
||||
} else {
|
||||
violation |= longitudinal_accel_checks(accel, HONDA_BOSCH_LONG_LIMITS);
|
||||
}
|
||||
violation |= longitudinal_accel_checks(accel, HONDA_BOSCH_LONG_LIMITS);
|
||||
if (violation) {
|
||||
tx = false;
|
||||
}
|
||||
|
||||
@@ -25,11 +25,6 @@ const LongitudinalLimits HYUNDAI_LONG_LIMITS = {
|
||||
.min_accel = -350, // 1/100 m/s2
|
||||
};
|
||||
|
||||
const LongitudinalLimits HYUNDAI_LONG_LIMITS_SPORT = {
|
||||
.max_accel = 400, // 1/100 m/s2
|
||||
.min_accel = -350, // 1/100 m/s2
|
||||
};
|
||||
|
||||
const CanMsg HYUNDAI_TX_MSGS[] = {
|
||||
{0x340, 0, 8}, // LKAS11 Bus 0
|
||||
{0x4F1, 0, 4}, // CLU11 Bus 0
|
||||
@@ -226,8 +221,6 @@ static void hyundai_rx_hook(const CANPacket_t *to_push) {
|
||||
}
|
||||
|
||||
static bool hyundai_tx_hook(const CANPacket_t *to_send) {
|
||||
sport_mode = alternative_experience & ALT_EXP_RAISE_LONGITUDINAL_LIMITS_TO_ISO_MAX;
|
||||
|
||||
bool tx = true;
|
||||
int addr = GET_ADDR(to_send);
|
||||
|
||||
@@ -252,13 +245,8 @@ static bool hyundai_tx_hook(const CANPacket_t *to_send) {
|
||||
|
||||
bool violation = false;
|
||||
|
||||
if (sport_mode) {
|
||||
violation |= longitudinal_accel_checks(desired_accel_raw, HYUNDAI_LONG_LIMITS_SPORT);
|
||||
violation |= longitudinal_accel_checks(desired_accel_val, HYUNDAI_LONG_LIMITS_SPORT);
|
||||
} else {
|
||||
violation |= longitudinal_accel_checks(desired_accel_raw, HYUNDAI_LONG_LIMITS);
|
||||
violation |= longitudinal_accel_checks(desired_accel_val, HYUNDAI_LONG_LIMITS);
|
||||
}
|
||||
violation |= longitudinal_accel_checks(desired_accel_raw, HYUNDAI_LONG_LIMITS);
|
||||
violation |= longitudinal_accel_checks(desired_accel_val, HYUNDAI_LONG_LIMITS);
|
||||
violation |= (aeb_decel_cmd != 0);
|
||||
violation |= aeb_req;
|
||||
|
||||
|
||||
@@ -248,11 +248,13 @@ static bool hyundai_canfd_tx_hook(const CANPacket_t *to_send) {
|
||||
bool steer_req = GET_BIT(to_send, 52U);
|
||||
|
||||
// 2m/s margin
|
||||
if (hyundai_canfd_taco_tune_hack && (hyundai_canfd_front_left_vego < (11.f + 2.f) || hyundai_canfd_rear_right_vego < (11.f + 2.f))) {
|
||||
if ((hyundai_canfd_front_left_vego < (11.f + 2.f) && hyundai_canfd_rear_right_vego < (11.f + 2.f)) && hyundai_canfd_taco_tune_hack) {
|
||||
bool aol_active = (alternative_experience & ALT_EXP_ALWAYS_ON_LATERAL) && lkas_on;
|
||||
|
||||
bool violation = false;
|
||||
uint32_t ts = microsecond_timer_get();
|
||||
|
||||
if (controls_allowed || lkas_on) {
|
||||
if (controls_allowed || aol_active) {
|
||||
// *** global torque limit check ***
|
||||
violation |= max_limit_check(desired_torque, 384, -384);
|
||||
|
||||
@@ -263,12 +265,12 @@ static bool hyundai_canfd_tx_hook(const CANPacket_t *to_send) {
|
||||
}
|
||||
|
||||
// no torque if controls is not allowed
|
||||
if (!(controls_allowed || lkas_on) && (desired_torque != 0)) {
|
||||
if (!(controls_allowed || aol_active) && (desired_torque != 0)) {
|
||||
violation = true;
|
||||
}
|
||||
|
||||
// reset to 0 if either controls is not allowed or there's a violation
|
||||
if (violation || !(controls_allowed || lkas_on)) {
|
||||
if (violation || !(controls_allowed || aol_active)) {
|
||||
valid_steer_req_count = 0;
|
||||
invalid_steer_req_count = 0;
|
||||
desired_torque_last = 0;
|
||||
|
||||
@@ -44,6 +44,10 @@ static void nissan_rx_hook(const CANPacket_t *to_push) {
|
||||
int bus = GET_BUS(to_push);
|
||||
int addr = GET_ADDR(to_push);
|
||||
|
||||
if (addr == 0x1b6) {
|
||||
acc_main_on = GET_BIT(to_push, 36U);
|
||||
}
|
||||
|
||||
if (bus == (nissan_alt_eps ? 1 : 0)) {
|
||||
if (addr == 0x2) {
|
||||
// Current steering angle
|
||||
@@ -64,10 +68,6 @@ static void nissan_rx_hook(const CANPacket_t *to_push) {
|
||||
UPDATE_VEHICLE_SPEED((right_rear + left_rear) / 2.0 * 0.005 / 3.6);
|
||||
}
|
||||
|
||||
if (addr == 0x1b6) {
|
||||
acc_main_on = GET_BIT(to_push, 36U);
|
||||
}
|
||||
|
||||
// X-Trail 0x15c, Leaf 0x239
|
||||
if ((addr == 0x15c) || (addr == 0x239)) {
|
||||
if (addr == 0x15c){
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
|
||||
const SteeringLimits SUBARU_STEERING_LIMITS = SUBARU_STEERING_LIMITS_GENERATOR(3071, 50, 70);
|
||||
const SteeringLimits SUBARU_GEN2_STEERING_LIMITS = SUBARU_STEERING_LIMITS_GENERATOR(1000, 40, 40);
|
||||
const SteeringLimits SUBARU_GEN2_STEERING_LIMITS = SUBARU_STEERING_LIMITS_GENERATOR(1600, 40, 40);
|
||||
|
||||
|
||||
const LongitudinalLimits SUBARU_LONG_LIMITS = {
|
||||
|
||||
@@ -37,11 +37,6 @@ const LongitudinalLimits TOYOTA_LONG_LIMITS = {
|
||||
.min_accel = -3500, // -3.5 m/s2
|
||||
};
|
||||
|
||||
const LongitudinalLimits TOYOTA_LONG_LIMITS_SPORT = {
|
||||
.max_accel = 4000, // 4.0 m/s2
|
||||
.min_accel = -3500, // -3.5 m/s2
|
||||
};
|
||||
|
||||
// panda interceptor threshold needs to be equivalent to openpilot threshold to avoid controls mismatches
|
||||
// If thresholds are mismatched then it is possible for panda to see the gas fall and rise while openpilot is in the pre-enabled state
|
||||
// Threshold calculated from DBC gains: round((((15 + 75.555) / 0.159375) + ((15 + 151.111) / 0.159375)) / 2) = 805
|
||||
@@ -289,8 +284,6 @@ static void toyota_rx_hook(const CANPacket_t *to_push) {
|
||||
}
|
||||
|
||||
static bool toyota_tx_hook(const CANPacket_t *to_send) {
|
||||
sport_mode = alternative_experience & ALT_EXP_RAISE_LONGITUDINAL_LIMITS_TO_ISO_MAX;
|
||||
|
||||
bool tx = true;
|
||||
int addr = GET_ADDR(to_send);
|
||||
int bus = GET_BUS(to_send);
|
||||
@@ -315,11 +308,7 @@ static bool toyota_tx_hook(const CANPacket_t *to_send) {
|
||||
// SecOC cars move accel to 0x183. Only allow inactive accel on 0x343 to match stock behavior
|
||||
violation = desired_accel != TOYOTA_LONG_LIMITS.inactive_accel;
|
||||
} else {
|
||||
if (sport_mode) {
|
||||
violation |= longitudinal_accel_checks(desired_accel, TOYOTA_LONG_LIMITS_SPORT);
|
||||
} else {
|
||||
violation |= longitudinal_accel_checks(desired_accel, TOYOTA_LONG_LIMITS);
|
||||
}
|
||||
violation |= longitudinal_accel_checks(desired_accel, TOYOTA_LONG_LIMITS);
|
||||
}
|
||||
|
||||
// only ACC messages that cancel are allowed when openpilot is not controlling longitudinal
|
||||
@@ -343,11 +332,7 @@ static bool toyota_tx_hook(const CANPacket_t *to_send) {
|
||||
desired_accel = to_signed(desired_accel, 16);
|
||||
|
||||
bool violation = false;
|
||||
if (sport_mode) {
|
||||
violation |= longitudinal_accel_checks(desired_accel, TOYOTA_LONG_LIMITS_SPORT);
|
||||
} else {
|
||||
violation |= longitudinal_accel_checks(desired_accel, TOYOTA_LONG_LIMITS);
|
||||
}
|
||||
violation |= longitudinal_accel_checks(desired_accel, TOYOTA_LONG_LIMITS);
|
||||
|
||||
if (violation) {
|
||||
tx = false;
|
||||
|
||||
@@ -20,12 +20,6 @@ const LongitudinalLimits VOLKSWAGEN_MQB_LONG_LIMITS = {
|
||||
.inactive_accel = 3010, // VW sends one increment above the max range when inactive
|
||||
};
|
||||
|
||||
const LongitudinalLimits VOLKSWAGEN_MQB_LONG_LIMITS_SPORT = {
|
||||
.max_accel = 4000,
|
||||
.min_accel = -3500,
|
||||
.inactive_accel = 3010, // VW sends one increment above the max range when inactive
|
||||
};
|
||||
|
||||
#define MSG_ESP_19 0x0B2 // RX from ABS, for wheel speeds
|
||||
#define MSG_LH_EPS_03 0x09F // RX from EPS, for driver steering torque
|
||||
#define MSG_ESP_05 0x106 // RX from ABS, for brake switch state
|
||||
@@ -203,8 +197,6 @@ static void volkswagen_mqb_rx_hook(const CANPacket_t *to_push) {
|
||||
}
|
||||
|
||||
static bool volkswagen_mqb_tx_hook(const CANPacket_t *to_send) {
|
||||
sport_mode = alternative_experience & ALT_EXP_RAISE_LONGITUDINAL_LIMITS_TO_ISO_MAX;
|
||||
|
||||
int addr = GET_ADDR(to_send);
|
||||
bool tx = true;
|
||||
|
||||
@@ -242,13 +234,7 @@ static bool volkswagen_mqb_tx_hook(const CANPacket_t *to_send) {
|
||||
desired_accel = (((GET_BYTE(to_send, 7) << 3) | ((GET_BYTE(to_send, 6) & 0xE0U) >> 5)) * 5U) - 7220U;
|
||||
}
|
||||
|
||||
if (sport_mode) {
|
||||
if (desired_accel != 0) {
|
||||
violation |= longitudinal_accel_checks(desired_accel, VOLKSWAGEN_MQB_LONG_LIMITS_SPORT);
|
||||
}
|
||||
} else {
|
||||
violation |= longitudinal_accel_checks(desired_accel, VOLKSWAGEN_MQB_LONG_LIMITS);
|
||||
}
|
||||
violation |= longitudinal_accel_checks(desired_accel, VOLKSWAGEN_MQB_LONG_LIMITS);
|
||||
|
||||
if (violation) {
|
||||
tx = false;
|
||||
|
||||
@@ -20,12 +20,6 @@ const LongitudinalLimits VOLKSWAGEN_PQ_LONG_LIMITS = {
|
||||
.inactive_accel = 3010, // VW sends one increment above the max range when inactive
|
||||
};
|
||||
|
||||
const LongitudinalLimits VOLKSWAGEN_PQ_LONG_LIMITS_SPORT = {
|
||||
.max_accel = 4000,
|
||||
.min_accel = -3500,
|
||||
.inactive_accel = 3010, // VW sends one increment above the max range when inactive
|
||||
};
|
||||
|
||||
#define MSG_LENKHILFE_3 0x0D0 // RX from EPS, for steering angle and driver steering torque
|
||||
#define MSG_HCA_1 0x0D2 // TX by OP, Heading Control Assist steering torque
|
||||
#define MSG_BREMSE_1 0x1A0 // RX from ABS, for ego speed
|
||||
@@ -124,11 +118,13 @@ static void volkswagen_pq_rx_hook(const CANPacket_t *to_push) {
|
||||
update_sample(&torque_driver, torque_driver_new);
|
||||
}
|
||||
|
||||
if (addr == MSG_MOTOR_5) {
|
||||
acc_main_on = GET_BIT(to_push, 50U);
|
||||
}
|
||||
|
||||
if (volkswagen_longitudinal) {
|
||||
if (addr == MSG_MOTOR_5) {
|
||||
// ACC main switch on is a prerequisite to enter controls, exit controls immediately on main switch off
|
||||
// Signal: Motor_5.GRA_Hauptschalter
|
||||
acc_main_on = GET_BIT(to_push, 50U);
|
||||
if (!acc_main_on) {
|
||||
controls_allowed = false;
|
||||
}
|
||||
@@ -176,8 +172,6 @@ static void volkswagen_pq_rx_hook(const CANPacket_t *to_push) {
|
||||
}
|
||||
|
||||
static bool volkswagen_pq_tx_hook(const CANPacket_t *to_send) {
|
||||
sport_mode = alternative_experience & ALT_EXP_RAISE_LONGITUDINAL_LIMITS_TO_ISO_MAX;
|
||||
|
||||
int addr = GET_ADDR(to_send);
|
||||
bool tx = true;
|
||||
|
||||
@@ -206,14 +200,8 @@ static bool volkswagen_pq_tx_hook(const CANPacket_t *to_send) {
|
||||
// Signal: ACC_System.ACS_Sollbeschl (acceleration in m/s2, scale 0.005, offset -7.22)
|
||||
int desired_accel = ((((GET_BYTE(to_send, 4) & 0x7U) << 8) | GET_BYTE(to_send, 3)) * 5U) - 7220U;
|
||||
|
||||
if (sport_mode) {
|
||||
if (longitudinal_accel_checks(desired_accel, VOLKSWAGEN_PQ_LONG_LIMITS_SPORT)) {
|
||||
tx = false;
|
||||
}
|
||||
} else {
|
||||
if (longitudinal_accel_checks(desired_accel, VOLKSWAGEN_PQ_LONG_LIMITS)) {
|
||||
tx = false;
|
||||
}
|
||||
if (longitudinal_accel_checks(desired_accel, VOLKSWAGEN_PQ_LONG_LIMITS)) {
|
||||
tx = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -220,7 +220,6 @@ bool brake_pressed_prev = false;
|
||||
bool regen_braking = false;
|
||||
bool regen_braking_prev = false;
|
||||
bool cruise_engaged_prev = false;
|
||||
bool sport_mode = false;
|
||||
struct sample_t vehicle_speed;
|
||||
bool vehicle_moving = false;
|
||||
bool acc_main_on = false; // referred to as "ACC off" in ISO 15622:2018
|
||||
|
||||
@@ -339,6 +339,42 @@ class TorqueSteeringSafetyTestBase(PandaSafetyTestBase, abc.ABC):
|
||||
for _ in range(10):
|
||||
self.assertFalse(self._tx(self._torque_cmd_msg(self.MAX_TORQUE, 1)))
|
||||
|
||||
# FrogPilot tests
|
||||
def _toggle_aol(self, toggle_on):
|
||||
"""Toggles "Always On Lateral" On/Off"""
|
||||
pass
|
||||
|
||||
def test_always_on_lateral(self):
|
||||
if self._toggle_aol(True) is None:
|
||||
raise unittest.SkipTest("AOL message not implemented for this safety mode")
|
||||
|
||||
self.safety.set_controls_allowed(False)
|
||||
|
||||
torque_cmd = self.MAX_RATE_UP # Use the max rate
|
||||
|
||||
# Without alt exp, make sure steering is blocked
|
||||
self.safety.set_alternative_experience(0)
|
||||
self._set_prev_torque(0)
|
||||
self.assertFalse(self._tx(self._torque_cmd_msg(torque_cmd)))
|
||||
|
||||
# With alt exp, but without main on, steering should be blocked
|
||||
self.safety.set_alternative_experience(ALTERNATIVE_EXPERIENCE.ALWAYS_ON_LATERAL)
|
||||
self._rx(self._toggle_aol(False))
|
||||
self._set_prev_torque(0)
|
||||
self.assertFalse(self._tx(self._torque_cmd_msg(torque_cmd)))
|
||||
self.assertFalse(self.safety.get_longitudinal_allowed())
|
||||
|
||||
# With alt exp and main on, steering should be allowed
|
||||
self._rx(self._toggle_aol(True))
|
||||
self._set_prev_torque(0)
|
||||
self.assertTrue(self._tx(self._torque_cmd_msg(torque_cmd)))
|
||||
self.assertFalse(self.safety.get_longitudinal_allowed())
|
||||
|
||||
# Turn off main, steering should be blocked again
|
||||
self._rx(self._toggle_aol(False))
|
||||
self.safety.set_desired_torque_last(torque_cmd)
|
||||
self.assertFalse(self._tx(self._torque_cmd_msg(torque_cmd)))
|
||||
|
||||
|
||||
class SteerRequestCutSafetyTest(TorqueSteeringSafetyTestBase, abc.ABC):
|
||||
|
||||
@@ -769,6 +805,44 @@ class AngleSteeringSafetyTest(PandaSafetyTestBase):
|
||||
should_tx = controls_allowed if steer_control_enabled else angle_cmd == angle_meas
|
||||
self.assertEqual(should_tx, self._tx(self._angle_cmd_msg(angle_cmd, steer_control_enabled)))
|
||||
|
||||
# FrogPilot tests
|
||||
def _toggle_aol(self, toggle_on):
|
||||
"""Toggles "Always On Lateral" on/off"""
|
||||
pass
|
||||
|
||||
def test_always_on_lateral(self):
|
||||
if self._toggle_aol(True) is None:
|
||||
raise unittest.SkipTest("AOL message not implemented for this safety mode")
|
||||
|
||||
self.safety.set_controls_allowed(False)
|
||||
|
||||
self._reset_angle_measurement(0)
|
||||
self._reset_speed_measurement(1)
|
||||
angle_cmd = self.ANGLE_RATE_UP[0] / 2.0 # Use half of the max angle rate
|
||||
|
||||
# Without alt exp, make sure steering is blocked
|
||||
self.safety.set_alternative_experience(0)
|
||||
self._set_prev_desired_angle(0)
|
||||
self.assertFalse(self._tx(self._angle_cmd_msg(angle=angle_cmd, enabled=True)))
|
||||
|
||||
# With alt exp, but without main on, steering should be blocked
|
||||
self.safety.set_alternative_experience(ALTERNATIVE_EXPERIENCE.ALWAYS_ON_LATERAL)
|
||||
self._rx(self._toggle_aol(False))
|
||||
self._set_prev_desired_angle(0)
|
||||
self.assertFalse(self._tx(self._angle_cmd_msg(angle=angle_cmd, enabled=True)))
|
||||
self.assertFalse(self.safety.get_longitudinal_allowed())
|
||||
|
||||
# With alt exp and main on, steering should be allowed
|
||||
self._rx(self._toggle_aol(True))
|
||||
self._set_prev_desired_angle(0)
|
||||
self.assertTrue(self._tx(self._angle_cmd_msg(angle=angle_cmd, enabled=True)))
|
||||
self.assertFalse(self.safety.get_longitudinal_allowed())
|
||||
|
||||
# Turn off main, steering should be blocked again
|
||||
self._rx(self._toggle_aol(False))
|
||||
self._set_prev_desired_angle(angle_cmd)
|
||||
self.assertFalse(self._tx(self._angle_cmd_msg(angle=angle_cmd, enabled=True)))
|
||||
|
||||
|
||||
class PandaSafetyTest(PandaSafetyTestBase):
|
||||
TX_MSGS: list[list[int]] | None = None
|
||||
|
||||
@@ -72,9 +72,31 @@ class HyundaiButtonBase:
|
||||
self.assertEqual(controls_allowed, self.safety.get_controls_allowed())
|
||||
self._rx(self._button_msg(Buttons.NONE))
|
||||
|
||||
# FrogPilot tests
|
||||
def _toggle_aol(self, toggle_on):
|
||||
"""
|
||||
Simulates toggling the main cruise button. The safety model requires a
|
||||
press and release to change the main cruise state. This function
|
||||
resets the safety model to a known state before each call.
|
||||
"""
|
||||
if not hasattr(self, "_aol_state"):
|
||||
self._aol_state = False
|
||||
|
||||
# Already in the requested state
|
||||
if toggle_on == self._aol_state:
|
||||
return None
|
||||
|
||||
# Toggle: press + release sequence
|
||||
self._rx(self._button_msg(Buttons.NONE, main_button=1))
|
||||
self._rx(self._button_msg(Buttons.NONE, main_button=0))
|
||||
|
||||
self._aol_state = toggle_on
|
||||
return None # avoid duplicate message in harness
|
||||
|
||||
|
||||
class HyundaiLongitudinalBase(common.LongitudinalAccelSafetyTest):
|
||||
# pylint: disable=no-member,abstract-method
|
||||
__test__ = False
|
||||
|
||||
DISABLED_ECU_UDS_MSG: tuple[int, int]
|
||||
DISABLED_ECU_ACTUATION_MSG: tuple[int, int]
|
||||
@@ -154,4 +176,3 @@ class HyundaiLongitudinalBase(common.LongitudinalAccelSafetyTest):
|
||||
self.assertFalse(self.safety.get_relay_malfunction())
|
||||
self._rx(make_msg(bus, addr, 8))
|
||||
self.assertTrue(self.safety.get_relay_malfunction())
|
||||
|
||||
|
||||
@@ -72,6 +72,12 @@ class TestChryslerSafety(common.PandaCarSafetyTest, common.MotorTorqueSteeringSa
|
||||
self.assertFalse(self._tx(self._button_msg(cancel=True, resume=True)))
|
||||
self.assertFalse(self._tx(self._button_msg(cancel=False, resume=False)))
|
||||
|
||||
# FrogPilot tests
|
||||
def _toggle_aol(self, toggle_on):
|
||||
# DAS_3, bit 20 is ACC_AVAILABLE
|
||||
values = {"ACC_AVAILABLE": 1 if toggle_on else 0}
|
||||
return self.packer.make_can_msg_panda("DAS_3", self.DAS_BUS, values)
|
||||
|
||||
|
||||
class TestChryslerRamDTSafety(TestChryslerSafety):
|
||||
TX_MSGS = [[0xB1, 2], [0xA6, 0], [0xFA, 0]]
|
||||
|
||||
@@ -8,6 +8,8 @@ from panda.tests.libpanda import libpanda_py
|
||||
|
||||
|
||||
class TestDefaultRxHookBase(common.PandaSafetyTest):
|
||||
__test__ = False
|
||||
|
||||
def test_rx_hook(self):
|
||||
# default rx hook allows all msgs
|
||||
for bus in range(4):
|
||||
|
||||
@@ -354,6 +354,17 @@ class TestFordSafetyBase(common.PandaCarSafetyTest):
|
||||
for bus in (0, 2):
|
||||
self.assertEqual(enabled, self._tx(self._acc_button_msg(Buttons.CANCEL, bus)))
|
||||
|
||||
# FrogPilot tests
|
||||
def _toggle_aol(self, toggle_on):
|
||||
# EngBrakeData, CcStat_D_Actl is the cruise state
|
||||
# 3 is standby (main on), 5 is active (engaged)
|
||||
brake = self.safety.get_brake_pressed_prev()
|
||||
values = {
|
||||
"BpedDrvAppl_D_Actl": 2 if brake else 1,
|
||||
"CcStat_D_Actl": 3 if toggle_on else 0,
|
||||
}
|
||||
return self.packer.make_can_msg_panda("EngBrakeData", 0, values)
|
||||
|
||||
|
||||
class TestFordStockSafety(TestFordSafetyBase):
|
||||
STEER_MESSAGE = MSG_LateralMotionControl
|
||||
|
||||
@@ -140,6 +140,12 @@ class TestGmSafetyBase(common.PandaCarSafetyTest, common.DriverTorqueSteeringSaf
|
||||
values = {"ACCButtons": buttons}
|
||||
return self.packer.make_can_msg_panda("ASCMSteeringButton", self.BUTTONS_BUS, values)
|
||||
|
||||
# FrogPilot tests
|
||||
def _toggle_aol(self, toggle_on):
|
||||
# ECMEngineStatus, bit 29 is CruiseMainOn
|
||||
values = {"CruiseMainOn": 1 if toggle_on else 0}
|
||||
return self.packer.make_can_msg_panda("ECMEngineStatus", 0, values)
|
||||
|
||||
|
||||
class TestGmAscmSafety(GmLongitudinalBase, TestGmSafetyBase):
|
||||
TX_MSGS = [[0x180, 0], [0x409, 0], [0x40A, 0], [0x2CB, 0], [0x370, 0], # pt bus
|
||||
|
||||
@@ -250,6 +250,13 @@ class HondaBase(common.PandaCarSafetyTest):
|
||||
self.assertTrue(self._tx(self._send_steer_msg(0x0000)))
|
||||
self.assertFalse(self._tx(self._send_steer_msg(0x1000)))
|
||||
|
||||
# FrogPilot tests
|
||||
def _toggle_aol(self, toggle_on):
|
||||
# SCM_FEEDBACK, bit 28 is MAIN_ON
|
||||
values = {"MAIN_ON": 1 if toggle_on else 0, "COUNTER": self.cnt_acc_state % 4}
|
||||
self.__class__.cnt_acc_state += 1
|
||||
return self.packer.make_can_msg_panda("SCM_FEEDBACK", self.PT_BUS, values)
|
||||
|
||||
|
||||
# ********************* Honda Nidec **********************
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ class TestHyundaiCanfdBase(HyundaiButtonBase, common.PandaCarSafetyTest, common.
|
||||
|
||||
MAX_RATE_UP = 2
|
||||
MAX_RATE_DOWN = 3
|
||||
MAX_TORQUE = 270
|
||||
MAX_TORQUE = 330
|
||||
|
||||
MAX_RT_DELTA = 112
|
||||
RT_INTERVAL = 250000
|
||||
@@ -78,6 +78,28 @@ class TestHyundaiCanfdBase(HyundaiButtonBase, common.PandaCarSafetyTest, common.
|
||||
}
|
||||
return self.packer.make_can_msg_panda("CRUISE_BUTTONS", bus, values)
|
||||
|
||||
# FrogPilot tests
|
||||
def _toggle_aol(self, toggle_on):
|
||||
if not hasattr(self, "_aol_state"):
|
||||
self._aol_state = False
|
||||
|
||||
# Already in the requested state
|
||||
if toggle_on == self._aol_state:
|
||||
return None
|
||||
|
||||
# Simulate button press + release
|
||||
values = {
|
||||
"CRUISE_BUTTONS": 0,
|
||||
"ADAPTIVE_CRUISE_MAIN_BTN": 0,
|
||||
"LFA_BTN": 1,
|
||||
"COUNTER": 0,
|
||||
}
|
||||
self._rx(self.packer.make_can_msg_panda("CRUISE_BUTTONS", self.PT_BUS, values))
|
||||
self._rx(self.packer.make_can_msg_panda("CRUISE_BUTTONS", self.PT_BUS, {**values, "LFA_BTN": 0}))
|
||||
|
||||
self._aol_state = toggle_on
|
||||
return None # avoid duplicate message in harness
|
||||
|
||||
|
||||
class TestHyundaiCanfdHDA1Base(TestHyundaiCanfdBase):
|
||||
|
||||
@@ -155,6 +177,28 @@ class TestHyundaiCanfdHDA1AltButtons(TestHyundaiCanfdHDA1Base):
|
||||
self.safety.set_controls_allowed(enabled)
|
||||
self.assertFalse(self._tx(self._button_msg(btn)))
|
||||
|
||||
# FrogPilot tests
|
||||
def _toggle_aol(self, toggle_on):
|
||||
if not hasattr(self, "_aol_state"):
|
||||
self._aol_state = False
|
||||
|
||||
# Already in the requested state
|
||||
if toggle_on == self._aol_state:
|
||||
return None
|
||||
|
||||
# Simulate button press + release
|
||||
values = {
|
||||
"CRUISE_BUTTONS_ALT": 0,
|
||||
"ADAPTIVE_CRUISE_MAIN_BTN": 0,
|
||||
"LFA_BTN": 1,
|
||||
"COUNTER": 0,
|
||||
}
|
||||
self._rx(self.packer.make_can_msg_panda("CRUISE_BUTTONS_ALT", self.PT_BUS, values))
|
||||
self._rx(self.packer.make_can_msg_panda("CRUISE_BUTTONS_ALT", self.PT_BUS, {**values, "LFA_BTN": 0}))
|
||||
|
||||
self._aol_state = toggle_on
|
||||
return None # avoid duplicate message in harness
|
||||
|
||||
|
||||
class TestHyundaiCanfdHDA2EV(TestHyundaiCanfdBase):
|
||||
|
||||
@@ -268,5 +312,91 @@ class TestHyundaiCanfdHDA1Long(HyundaiLongitudinalBase, TestHyundaiCanfdHDA1Base
|
||||
pass
|
||||
|
||||
|
||||
# FrogPilot tests
|
||||
class TestTacoTuneHack(TestHyundaiCanfdHDA2EV):
|
||||
|
||||
# Vego = raw_speed * 0.00868. Low speed is < 13 m/s.
|
||||
# 13 / 0.00868 = 1497.7. So raw speed 1497 is low, 1498 is high.
|
||||
SPEED_LOW = 1497
|
||||
SPEED_HIGH = 1498
|
||||
|
||||
def setUp(self):
|
||||
self.packer = CANPackerPanda("hyundai_canfd")
|
||||
self.safety = libpanda_py.libpanda
|
||||
# HDA2 EV with Taco Tune Hack flag
|
||||
param = Panda.FLAG_HYUNDAI_CANFD_HDA2 | Panda.FLAG_HYUNDAI_EV_GAS | Panda.FLAG_HYUNDAI_TACO_TUNE_HACK
|
||||
self.safety.set_safety_hooks(Panda.SAFETY_HYUNDAI_CANFD, param)
|
||||
self.safety.init_tests()
|
||||
|
||||
self.MAX_TORQUE = super().MAX_TORQUE
|
||||
|
||||
def test_taco_tune_hack(self):
|
||||
# Override MAX_TORQUE to the hacked value
|
||||
self.MAX_TORQUE = 384
|
||||
|
||||
# Test at low speed with controls allowed
|
||||
self.safety.init_tests()
|
||||
self.safety.set_controls_allowed(True)
|
||||
self._rx(self._speed_msg(self.SPEED_LOW))
|
||||
|
||||
# Rate limits should be bypassed, and torque limit raised to MAX_TORQUE
|
||||
self._set_prev_torque(0)
|
||||
self.assertTrue(self._tx(self._torque_cmd_msg(self.MAX_TORQUE)))
|
||||
self.assertFalse(self._tx(self._torque_cmd_msg(self.MAX_TORQUE + 1)))
|
||||
|
||||
# Test at low speed with controls not allowed
|
||||
self.safety.set_controls_allowed(False)
|
||||
self.assertTrue(self._tx(self._torque_cmd_msg(0)))
|
||||
self.assertFalse(self._tx(self._torque_cmd_msg(1)))
|
||||
|
||||
# Test at high speed with controls allowed
|
||||
self.safety.init_tests()
|
||||
self.safety.set_controls_allowed(True)
|
||||
self._rx(self._speed_msg(self.SPEED_HIGH))
|
||||
|
||||
# Normal rate limits should apply
|
||||
self._set_prev_torque(0)
|
||||
self.assertTrue(self._tx(self._torque_cmd_msg(self.MAX_RATE_UP)))
|
||||
self._set_prev_torque(0) # Reset prev_torque to test the limit from 0
|
||||
self.assertFalse(self._tx(self._torque_cmd_msg(self.MAX_RATE_UP + 1)))
|
||||
|
||||
# Normal max torque should apply
|
||||
self._set_prev_torque(super().MAX_TORQUE - 1)
|
||||
self.assertTrue(self._tx(self._torque_cmd_msg(super().MAX_TORQUE)))
|
||||
self.assertFalse(self._tx(self._torque_cmd_msg(super().MAX_TORQUE + 1)))
|
||||
|
||||
def test_against_torque_driver(self):
|
||||
self._rx(self._speed_msg(self.SPEED_HIGH))
|
||||
super().test_against_torque_driver()
|
||||
|
||||
def test_steer_req_bit_realtime(self):
|
||||
self._rx(self._speed_msg(self.SPEED_HIGH))
|
||||
super().test_steer_req_bit_realtime()
|
||||
|
||||
def test_steer_req_bit_frames(self):
|
||||
self._rx(self._speed_msg(self.SPEED_HIGH))
|
||||
super().test_steer_req_bit_frames()
|
||||
|
||||
def test_steer_req_bit_multi_invalid(self):
|
||||
self._rx(self._speed_msg(self.SPEED_HIGH))
|
||||
super().test_steer_req_bit_multi_invalid()
|
||||
|
||||
def test_steer_safety_check(self):
|
||||
self._rx(self._speed_msg(self.SPEED_HIGH))
|
||||
super().test_steer_safety_check()
|
||||
|
||||
def test_steer_req_bit(self):
|
||||
self._rx(self._speed_msg(self.SPEED_HIGH))
|
||||
super().test_steer_req_bit()
|
||||
|
||||
def test_non_realtime_limit_up(self):
|
||||
self._rx(self._speed_msg(self.SPEED_HIGH))
|
||||
super().test_non_realtime_limit_up()
|
||||
|
||||
def test_realtime_limits(self):
|
||||
self._rx(self._speed_msg(self.SPEED_HIGH))
|
||||
super().test_realtime_limits()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -81,6 +81,12 @@ class TestMazdaSafety(common.PandaCarSafetyTest, common.DriverTorqueSteeringSafe
|
||||
self.assertTrue(self._tx(self._button_msg(cancel=True)))
|
||||
self.assertTrue(self._tx(self._button_msg(resume=True)))
|
||||
|
||||
# FrogPilot tests
|
||||
def _toggle_aol(self, toggle_on):
|
||||
# CRZ_CTRL, CRZ_AVAILABLE is the main on button
|
||||
values = {"CRZ_AVAILABLE": 1 if toggle_on else 0}
|
||||
return self.packer.make_can_msg_panda("CRZ_CTRL", 0, values)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -78,6 +78,12 @@ class TestNissanSafety(common.PandaCarSafetyTest, common.AngleSteeringSafetyTest
|
||||
tx = self._tx(self._acc_button_cmd(**args))
|
||||
self.assertEqual(tx, should_tx)
|
||||
|
||||
# FrogPilot tests
|
||||
def _toggle_aol(self, toggle_on):
|
||||
# PRO_PILOT, CRUISE_ON is the main on button for X-Trail/Rogue/Altima
|
||||
values = {"CRUISE_ON": 1 if toggle_on else 0}
|
||||
return self.packer.make_can_msg_panda("PRO_PILOT", 2, values)
|
||||
|
||||
|
||||
class TestNissanSafetyAltEpsBus(TestNissanSafety):
|
||||
"""Altima uses different buses"""
|
||||
@@ -112,6 +118,12 @@ class TestNissanLeafSafety(TestNissanSafety):
|
||||
def test_acc_buttons(self):
|
||||
pass
|
||||
|
||||
# FrogPilot tests
|
||||
def _toggle_aol(self, toggle_on):
|
||||
# CRUISE_THROTTLE, CRUISE_AVAILABLE is the main on button for Leaf
|
||||
values = {"CRUISE_AVAILABLE": 1 if toggle_on else 0}
|
||||
return self.packer.make_can_msg_panda("CRUISE_THROTTLE", 0, values)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -106,6 +106,12 @@ class TestSubaruSafetyBase(common.PandaCarSafetyTest):
|
||||
values = {"Cruise_Activated": enable}
|
||||
return self.packer.make_can_msg_panda("CruiseControl", self.ALT_MAIN_BUS, values)
|
||||
|
||||
# FrogPilot tests
|
||||
def _toggle_aol(self, toggle_on):
|
||||
# CruiseControl, Cruise_On is the main on button
|
||||
values = {"Cruise_On": 1 if toggle_on else 0}
|
||||
return self.packer.make_can_msg_panda("CruiseControl", self.ALT_MAIN_BUS, values)
|
||||
|
||||
|
||||
class TestSubaruStockLongitudinalSafetyBase(TestSubaruSafetyBase):
|
||||
def _cancel_msg(self, cancel, cruise_throttle=0):
|
||||
@@ -155,7 +161,7 @@ class TestSubaruLongitudinalSafetyBase(TestSubaruSafetyBase, common.Longitudinal
|
||||
class TestSubaruTorqueSafetyBase(TestSubaruSafetyBase, common.DriverTorqueSteeringSafetyTest, common.SteerRequestCutSafetyTest):
|
||||
MAX_RATE_UP = 50
|
||||
MAX_RATE_DOWN = 70
|
||||
MAX_TORQUE = 2047
|
||||
MAX_TORQUE = 3071
|
||||
|
||||
# Safety around steering req bit
|
||||
MIN_VALID_STEERING_FRAMES = 7
|
||||
@@ -178,7 +184,7 @@ class TestSubaruGen2TorqueSafetyBase(TestSubaruTorqueSafetyBase):
|
||||
|
||||
MAX_RATE_UP = 40
|
||||
MAX_RATE_DOWN = 40
|
||||
MAX_TORQUE = 1000
|
||||
MAX_TORQUE = 1600
|
||||
|
||||
|
||||
class TestSubaruGen2TorqueStockLongitudinalSafety(TestSubaruStockLongitudinalSafetyBase, TestSubaruGen2TorqueSafetyBase):
|
||||
|
||||
@@ -60,6 +60,12 @@ class TestSubaruPreglobalSafety(common.PandaCarSafetyTest, common.DriverTorqueSt
|
||||
values = {"Cruise_Activated": enable}
|
||||
return self.packer.make_can_msg_panda("CruiseControl", 0, values)
|
||||
|
||||
# FrogPilot tests
|
||||
def _toggle_aol(self, toggle_on):
|
||||
# CruiseControl, Cruise_On is the main on button
|
||||
values = {"Cruise_On": 1 if toggle_on else 0}
|
||||
return self.packer.make_can_msg_panda("CruiseControl", 0, values)
|
||||
|
||||
|
||||
class TestSubaruPreglobalReversedDriverTorqueSafety(TestSubaruPreglobalSafety):
|
||||
FLAGS = Panda.FLAG_SUBARU_PREGLOBAL_REVERSED_DRIVER_TORQUE
|
||||
|
||||
@@ -107,6 +107,12 @@ class TestTeslaSteeringSafety(TestTeslaSafety, common.AngleSteeringSafetyTest):
|
||||
tx = self._tx(self._control_lever_cmd(btn))
|
||||
self.assertEqual(tx, should_tx)
|
||||
|
||||
# FrogPilot tests
|
||||
def _toggle_aol(self, toggle_on):
|
||||
# DI_state, DI_cruiseState is the cruise state, 1 is standby
|
||||
values = {"DI_cruiseState": 1 if toggle_on else 0}
|
||||
return self.packer.make_can_msg_panda("DI_state", 0, values)
|
||||
|
||||
|
||||
class TestTeslaRavenSteeringSafety(TestTeslaSteeringSafety):
|
||||
def setUp(self):
|
||||
|
||||
@@ -9,7 +9,8 @@ from panda.tests.libpanda import libpanda_py
|
||||
import panda.tests.safety.common as common
|
||||
from panda.tests.safety.common import CANPackerPanda
|
||||
|
||||
TOYOTA_COMMON_TX_MSGS = [[0x2E4, 0], [0x191, 0], [0x412, 0], [0x343, 0], [0x1D2, 0]] # LKAS + LTA + ACC & PCM cancel cmds
|
||||
TOYOTA_COMMON_TX_MSGS = [[0x2E4, 0], [0x191, 0], [0x412, 0], [0x343, 0], [0x1D2, 0], [0x1D3, 0]] # LKAS + LTA + ACC & PCM cancel cmds
|
||||
TOYOTA_SECOC_TX_MSGS = [[0x131, 0]] + TOYOTA_COMMON_TX_MSGS
|
||||
TOYOTA_COMMON_LONG_TX_MSGS = [[0x283, 0], [0x2E6, 0], [0x2E7, 0], [0x33E, 0], [0x344, 0], [0x365, 0], [0x366, 0], [0x4CB, 0], # DSU bus 0
|
||||
[0x128, 1], [0x141, 1], [0x160, 1], [0x161, 1], [0x470, 1], # DSU bus 1
|
||||
[0x411, 0], # PCS_HUD
|
||||
@@ -86,7 +87,7 @@ class TestToyotaSafetyBase(common.PandaCarSafetyTest, common.LongitudinalAccelSa
|
||||
(False, b"\x0F\x03\xAA\xAA\x00\x00\x00\x00"), # non-tester present
|
||||
(True, b"\x0F\x02\x3E\x00\x00\x00\x00\x00")):
|
||||
tester_present = libpanda_py.make_CANPacket(0x750, 0, msg)
|
||||
self.assertEqual(should_tx and not stock_longitudinal, self._tx(tester_present))
|
||||
self.assertEqual(should_tx, self._tx(tester_present))
|
||||
|
||||
def test_block_aeb(self, stock_longitudinal: bool = False):
|
||||
for controls_allowed in (True, False):
|
||||
@@ -108,7 +109,8 @@ class TestToyotaSafetyBase(common.PandaCarSafetyTest, common.LongitudinalAccelSa
|
||||
self.safety.set_controls_allowed(engaged)
|
||||
|
||||
should_tx = not req and not req2 and angle == 0 and torque_wind_down == 0
|
||||
self.assertEqual(should_tx, self._tx(self._lta_msg(req, req2, angle, torque_wind_down)))
|
||||
self.assertEqual(should_tx, self._tx(self._lta_msg(req, req2, angle, torque_wind_down)),
|
||||
f"{req=} {req2=} {angle=} {torque_wind_down=}")
|
||||
|
||||
def test_rx_hook(self):
|
||||
# checksum checks
|
||||
@@ -126,6 +128,12 @@ class TestToyotaSafetyBase(common.PandaCarSafetyTest, common.LongitudinalAccelSa
|
||||
self.assertFalse(self._rx(to_push))
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
|
||||
# FrogPilot tests
|
||||
def _toggle_aol(self, toggle_on):
|
||||
# pcm_cruise_2, bit 15 is toggle_on
|
||||
values = {"MAIN_ON": 1 if toggle_on else 0}
|
||||
return self.packer.make_can_msg_panda("PCM_CRUISE_2", 0, values)
|
||||
|
||||
|
||||
class TestToyotaSafetyGasInterceptorBase(common.GasInterceptorSafetyTest, TestToyotaSafetyBase):
|
||||
|
||||
@@ -363,5 +371,38 @@ class TestToyotaStockLongitudinalAngle(TestToyotaStockLongitudinalBase, TestToyo
|
||||
self.safety.init_tests()
|
||||
|
||||
|
||||
class TestToyotaSecOcSafety(TestToyotaStockLongitudinalBase):
|
||||
|
||||
TX_MSGS = TOYOTA_SECOC_TX_MSGS
|
||||
RELAY_MALFUNCTION_ADDRS = {0: (0x2E4,)}
|
||||
FWD_BLACKLISTED_ADDRS = {2: [0x2E4, 0x412, 0x191, 0x131]}
|
||||
|
||||
def setUp(self):
|
||||
self.packer = CANPackerPanda("toyota_rav4_prime_generated")
|
||||
self.safety = libpanda_py.libpanda
|
||||
self.safety.set_safety_hooks(Panda.SAFETY_TOYOTA, self.EPS_SCALE | Panda.FLAG_TOYOTA_STOCK_LONGITUDINAL | Panda.FLAG_TOYOTA_SECOC)
|
||||
self.safety.init_tests()
|
||||
|
||||
# This platform also has alternate brake and PCM messages, but same naming in the DBC, so same packers work
|
||||
|
||||
def _user_gas_msg(self, gas):
|
||||
values = {"GAS_PEDAL_USER": gas}
|
||||
return self.packer.make_can_msg_panda("GAS_PEDAL", 0, values)
|
||||
|
||||
# This platform sends both STEERING_LTA (same as other Toyota) and STEERING_LTA_2 (SecOC signed)
|
||||
# STEERING_LTA is checked for no-actuation by the base class, STEERING_LTA_2 is checked for no-actuation below
|
||||
|
||||
def _lta_2_msg(self, req, req2, angle_cmd, torque_wind_down=100):
|
||||
values = {"STEER_REQUEST": req, "STEER_REQUEST_2": req2, "STEER_ANGLE_CMD": angle_cmd}
|
||||
return self.packer.make_can_msg_panda("STEERING_LTA_2", 0, values)
|
||||
|
||||
def test_lta_2_steer_cmd(self):
|
||||
for engaged, req, req2, angle in itertools.product([True, False], [0, 1], [0, 1], np.linspace(-20, 20, 5)):
|
||||
self.safety.set_controls_allowed(engaged)
|
||||
|
||||
should_tx = not req and not req2 and angle == 0
|
||||
self.assertEqual(should_tx, self._tx(self._lta_2_msg(req, req2, angle)), f"{req=} {req2=} {angle=}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -134,6 +134,11 @@ class TestVolkswagenMqbSafety(common.PandaCarSafetyTest, common.DriverTorqueStee
|
||||
self.assertEqual(0, self.safety.get_torque_driver_max())
|
||||
self.assertEqual(0, self.safety.get_torque_driver_min())
|
||||
|
||||
# FrogPilot tests
|
||||
def _toggle_aol(self, toggle_on):
|
||||
# TSK_06, TSK_Status is the cruise state, 2 is standby
|
||||
return self._tsk_status_msg(False, main_switch=toggle_on)
|
||||
|
||||
|
||||
class TestVolkswagenMqbStockSafety(TestVolkswagenMqbSafety):
|
||||
TX_MSGS = [[MSG_HCA_01, 0], [MSG_LDW_02, 0], [MSG_LH_EPS_03, 2], [MSG_GRA_ACC_01, 0], [MSG_GRA_ACC_01, 2]]
|
||||
|
||||
@@ -115,6 +115,11 @@ class TestVolkswagenPqSafety(common.PandaCarSafetyTest, common.DriverTorqueSteer
|
||||
self.assertEqual(0, self.safety.get_torque_driver_max())
|
||||
self.assertEqual(0, self.safety.get_torque_driver_min())
|
||||
|
||||
# FrogPilot tests
|
||||
def _toggle_aol(self, toggle_on):
|
||||
# Motor_5, GRA_Hauptschalter is the main cruise switch
|
||||
return self._motor_5_msg(main_switch=toggle_on)
|
||||
|
||||
|
||||
class TestVolkswagenPqStockSafety(TestVolkswagenPqSafety):
|
||||
# Transmit of GRA_Neu is allowed on bus 0 and 2 to keep compatibility with gateway and camera integration
|
||||
|
||||
Reference in New Issue
Block a user