byd: fix SEAL bus topology from live dump — ADAS on bus 0, PCM_BUTTONS confirmed
Live bus dump from the Seal showed a different topology than the Han: - ACC_HUD_ADAS (813) + ACC_CMD (814) are broadcast on the vehicle CAN (bus 0), not the camera CAN. Panda rx check expected 813 on bus 2 and never saw it -> safety config invalid -> controls blocked forever. - PCM_BUTTONS (944) confirmed on bus 0 at 20Hz (MADS button placement OK) - 482 MPC_LKAS_CMD_ANGLE present on bus 2 (angle LKAS cmd; for future use) Changes: - carstate: ADAS messages (ACC_HUD_ADAS/ACC_CMD) read from bus 0 on SEAL, bus 2 on HAN (cp_adas accessor); parsers built per platform/bus - panda byd.h: 813 cruise check is bus-independent; rx checks accept 813 on bus 0 or 2, 944 on bus 0 or 2 (first-seen-wins) - interface: disable openpilot longitudinal for SEAL — stock ACC_CMD originates on bus 0 where the panda cannot intercept it. Stock ACC + MADS lateral it is (which is the point of MADS anyway). - panda firmware rebuilt Verified: SEAL (cruise+lkas button via bus 0, alphaLong=False) and HAN (bus 2 topology, alphaLong=True) both canValid; 120 safety tests + MISRA clean.
This commit is contained in:
1 parent
5684dd9d0e
commit
1abd13736b
21 files changed
+46
-30
No files matched your search
@@ -22,6 +22,10 @@ class CarState(CarStateBase, MadsCarState):
|
||||
else:
|
||||
self.steer_msg = "STEERING_TORQUE"
|
||||
|
||||
# ADAS cruise state (ACC_HUD_ADAS) and stock ACC echo (ACC_CMD) are on
|
||||
# the vehicle CAN (bus 0) on the SEAL, camera CAN (bus 2) on the HAN
|
||||
self.adas_on_pt_bus = CP.carFingerprint == CAR.BYD_SEAL_PERFORMANCE_25
|
||||
|
||||
self.mpc_lkas_cmd_msg = None
|
||||
self.eps_steering_torque_msg = None
|
||||
self.eps_prepared = False
|
||||
@@ -35,6 +39,7 @@ class CarState(CarStateBase, MadsCarState):
|
||||
def update(self, can_parsers) -> tuple[structs.CarState, structs.CarStateSP]:
|
||||
cp = can_parsers[Bus.pt]
|
||||
cp_cam = can_parsers[Bus.cam]
|
||||
cp_adas = cp if self.adas_on_pt_bus else cp_cam
|
||||
ret = structs.CarState()
|
||||
ret_sp = structs.CarStateSP()
|
||||
|
||||
@@ -59,13 +64,13 @@ class CarState(CarStateBase, MadsCarState):
|
||||
ret.steerFaultPermanent = cp.vl[self.steer_msg]["TORQUE_FAILED"] != 0
|
||||
ret.steerFaultTemporary = cp.vl[self.steer_msg]["TORQUE_FAILED"] != 0
|
||||
|
||||
ret.stockAeb = cp_cam.vl["ACC_HUD_ADAS"]["AEB"] == 1
|
||||
ret.stockFcw = cp_cam.vl["ACC_HUD_ADAS"]["FCW"] == 1 # Forward Collision Warning
|
||||
ret.stockAeb = cp_adas.vl["ACC_HUD_ADAS"]["AEB"] == 1
|
||||
ret.stockFcw = cp_adas.vl["ACC_HUD_ADAS"]["FCW"] == 1 # Forward Collision Warning
|
||||
|
||||
# Cruise state
|
||||
ret.cruiseState.enabled = cp_cam.vl["ACC_HUD_ADAS"]["CRUISE_STATE"] in (3, 5) # (Active, Override)
|
||||
ret.cruiseState.speed = cp_cam.vl["ACC_HUD_ADAS"]["SET_SPEED"] * 10 * CV.KPH_TO_MS
|
||||
ret.cruiseState.available = cp_cam.vl["ACC_HUD_ADAS"]["CRUISE_STATE"] not in (8, 9) # (Failure, PermanentFailure)
|
||||
ret.cruiseState.enabled = cp_adas.vl["ACC_HUD_ADAS"]["CRUISE_STATE"] in (3, 5) # (Active, Override)
|
||||
ret.cruiseState.speed = cp_adas.vl["ACC_HUD_ADAS"]["SET_SPEED"] * 10 * CV.KPH_TO_MS
|
||||
ret.cruiseState.available = cp_adas.vl["ACC_HUD_ADAS"]["CRUISE_STATE"] not in (8, 9) # (Failure, PermanentFailure)
|
||||
ret.cruiseState.standstill = False # This needs to be false, since we can resume from stop without sending anything special
|
||||
|
||||
# Gear
|
||||
@@ -102,7 +107,7 @@ class CarState(CarStateBase, MadsCarState):
|
||||
self.mpc_lkas_active = cp_cam.vl["MPC_LKAS_CMD"]["LKAS_ACTIVE"] != 0
|
||||
self.mpc_lkas_request_prepare = cp_cam.vl["MPC_LKAS_CMD"]["LKASPrepare"] != 0
|
||||
# for generate ACC_CMD
|
||||
self.acc_cmd_msg = copy.copy(cp_cam.vl["ACC_CMD"])
|
||||
self.acc_cmd_msg = copy.copy(cp_adas.vl["ACC_CMD"])
|
||||
return ret, ret_sp
|
||||
|
||||
@staticmethod
|
||||
@@ -123,6 +128,23 @@ class CarState(CarStateBase, MadsCarState):
|
||||
("PCM_BUTTONS", float('nan')),
|
||||
]
|
||||
|
||||
cam_messages = [
|
||||
# stock camera command echoes, only present when stock ADAS is active
|
||||
("MPC_LKAS_CMD", float('nan')),
|
||||
# SEAL camera also broadcasts an angle-based LKAS command (parsed for future use)
|
||||
("MPC_LKAS_CMD_ANGLE", float('nan')),
|
||||
# PCM_BUTTONS may be forwarded on the camera bus on some harnesses
|
||||
("PCM_BUTTONS", float('nan')),
|
||||
]
|
||||
|
||||
# ADAS cruise state and stock ACC echo: vehicle CAN (bus 0) on the SEAL,
|
||||
# camera CAN (bus 2) on the HAN. Alive-check ACC_HUD_ADAS only on the bus it lives on.
|
||||
adas_messages = [("ACC_HUD_ADAS", 10), ("ACC_CMD", float('nan'))]
|
||||
if CP.carFingerprint == CAR.BYD_SEAL_PERFORMANCE_25:
|
||||
pt_messages.extend(adas_messages)
|
||||
else:
|
||||
cam_messages.extend(adas_messages)
|
||||
|
||||
# EPS steering feedback message differs by platform; alive-check only
|
||||
# the one this car has, parse the other opportunistically
|
||||
if CP.carFingerprint == CAR.BYD_SEAL_PERFORMANCE_25:
|
||||
@@ -132,15 +154,6 @@ class CarState(CarStateBase, MadsCarState):
|
||||
pt_messages.append(("STEERING_TORQUE", 10))
|
||||
pt_messages.append(("STEERING_TORQUE_ANGLE", float('nan')))
|
||||
|
||||
cam_messages = [
|
||||
("ACC_HUD_ADAS", 10),
|
||||
# stock camera command echoes, only present when stock ADAS is active
|
||||
("MPC_LKAS_CMD", float('nan')),
|
||||
("ACC_CMD", float('nan')),
|
||||
# PCM_BUTTONS may be forwarded on the camera bus on some harnesses
|
||||
("PCM_BUTTONS", float('nan')),
|
||||
]
|
||||
|
||||
return {
|
||||
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], pt_messages, CANBUS.main_bus),
|
||||
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], cam_messages, CANBUS.cam_bus),
|
||||
|
||||
@@ -32,8 +32,11 @@ class CarInterface(CarInterfaceBase):
|
||||
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
|
||||
|
||||
# longitudinal control parameters
|
||||
ret.alphaLongitudinalAvailable = True
|
||||
if alpha_long:
|
||||
# HAN: openpilot long available (ACC_CMD replaced on the tapped camera bus).
|
||||
# SEAL: stock ACC_CMD is broadcast directly on the vehicle CAN (bus 0),
|
||||
# so it cannot be intercepted/replaced by the panda — stock ACC only (MADS).
|
||||
ret.alphaLongitudinalAvailable = candidate != CAR.BYD_SEAL_PERFORMANCE_25
|
||||
if alpha_long and ret.alphaLongitudinalAvailable:
|
||||
ret.openpilotLongitudinalControl = True
|
||||
ret.startingState = True
|
||||
ret.startAccel = 0.1
|
||||
|
||||
@@ -65,6 +65,13 @@ static bool byd_tx_hook(const CANPacket_t *msg) {
|
||||
}
|
||||
|
||||
static void byd_rx_hook(const CANPacket_t *msg) {
|
||||
// ACC_HUD_ADAS: cruise state. Vehicle CAN (bus 0) on SEAL, camera CAN (bus 2) on HAN
|
||||
if (msg->addr == 813U) {
|
||||
// CRUISE_STATE in (3, 5) == (Active, Override)
|
||||
uint8_t cruise_state = (msg->data[5] >> 4U) & 0x0FU;
|
||||
pcm_cruise_check((cruise_state == 3U) || (cruise_state == 5U));
|
||||
}
|
||||
|
||||
// Main Bus
|
||||
if (msg->bus == 0U) {
|
||||
// PEDAL
|
||||
@@ -101,15 +108,6 @@ static void byd_rx_hook(const CANPacket_t *msg) {
|
||||
if (msg->addr == 944U) {
|
||||
mads_button_press = GET_BIT(msg, BYD_LKAS_ON_BTN_BIT) ? MADS_BUTTON_PRESSED : MADS_BUTTON_NOT_PRESSED;
|
||||
}
|
||||
}
|
||||
// Cam Bus
|
||||
else if (msg->bus == 2U) {
|
||||
// ACC_HUD_ADAS
|
||||
if (msg->addr == 813U) {
|
||||
// CRUISE_STATE in (3, 5) == (Active, Override)
|
||||
uint8_t cruise_state = (msg->data[5] >> 4U) & 0x0FU;
|
||||
pcm_cruise_check((cruise_state == 3U) || (cruise_state == 5U));
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
@@ -134,8 +132,10 @@ static safety_config byd_init(uint16_t param) {
|
||||
{.msg = {{287, 0, 5, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, // STEER_MODULE
|
||||
{.msg = {{792, 0, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, // STEERING_TORQUE (HAN)
|
||||
{508, 0, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }}}, // STEERING_TORQUE_ANGLE (SEAL)
|
||||
{.msg = {{944, 0, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, // PCM_BUTTONS
|
||||
{.msg = {{813, 2, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, // ACC_HUD_ADAS
|
||||
{.msg = {{944, 0, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, // PCM_BUTTONS (vehicle CAN)
|
||||
{944, 2, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }}}, // PCM_BUTTONS (camera CAN)
|
||||
{.msg = {{813, 0, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, // ACC_HUD_ADAS (SEAL: vehicle CAN)
|
||||
{813, 2, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }}}, // ACC_HUD_ADAS (HAN: camera CAN)
|
||||
{.msg = {{307, 0, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, // STALKS
|
||||
{.msg = {{660, 0, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, // METER_CLUSTER
|
||||
{.msg = {{790, 2, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, // MPC_LKAS_CMD
|
||||
|
||||
Reference in new issue
Block a user