enforce message checks in can parser (#20742)

* enforce message checks in can parser

* nissan

* vw

* hkg

* subaru

* toyota

* honda bosch

* gm

* honda nidec

* bump opendbc

* not all tss2 have bsm

* toyota fixes

* honda fixes

* vw fix

* fix subaru

* fix long tests

* update refs

* crv bsm
albatross
Adeeb Shihadeh 2021-04-25 12:52:16 -07:00 committed by GitHub
parent c9a29d6deb
commit 6c7ed8f2e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 250 additions and 151 deletions

2
cereal

@ -1 +1 @@
Subproject commit 8e5eb3ba4db9975e3370f3e4f5e60c0e7b73d078 Subproject commit 9532238f186a5022235decc22f3eaf91b636cedc

@ -1 +1 @@
Subproject commit 774b4c98f6b2ae22f23703521e368918014d74b7 Subproject commit df29a0726ba95b185241c1e0b8b1c1e37fc96e76

View File

@ -53,4 +53,4 @@ class CarState(CarStateBase):
("Brake_Lights", "BCM_to_HS_Body", 0.), ("Brake_Lights", "BCM_to_HS_Body", 0.),
] ]
checks = [] checks = []
return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0) return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0, enforce_checks=False)

View File

@ -104,9 +104,29 @@ class CarState(CarStateBase):
("CruiseMainOn", "ECMEngineStatus", 0), ("CruiseMainOn", "ECMEngineStatus", 0),
] ]
checks = [
("BCMTurnSignals", 1),
("ECMPRDNL", 10),
("PSCMStatus", 10),
("ESPStatus", 10),
("BCMDoorBeltStatus", 10),
("EPBStatus", 20),
("EBCMWheelSpdFront", 20),
("EBCMWheelSpdRear", 20),
("AcceleratorPedal", 33),
("AcceleratorPedal2", 33),
("ASCMSteeringButton", 33),
("ECMEngineStatus", 100),
("PSCMSteeringAngle", 100),
("EBCMBrakePedalPosition", 100),
]
if CP.carFingerprint == CAR.VOLT: if CP.carFingerprint == CAR.VOLT:
signals += [ signals += [
("RegenPaddle", "EBCMRegenPaddle", 0), ("RegenPaddle", "EBCMRegenPaddle", 0),
] ]
checks += [
("EBCMRegenPaddle", 50),
]
return CANParser(DBC[CP.carFingerprint]['pt'], signals, [], CanBus.POWERTRAIN) return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, CanBus.POWERTRAIN)

View File

@ -34,7 +34,7 @@ def create_radar_can_parser(car_fingerprint):
[0.0] * NUM_SLOTS + [0.0] * NUM_SLOTS + [0.0] * NUM_SLOTS + [0.0] * NUM_SLOTS +
[0.0] * NUM_SLOTS + [0] * NUM_SLOTS)) [0.0] * NUM_SLOTS + [0] * NUM_SLOTS))
checks = [] checks = list({(s[1], 14) for s in signals})
return CANParser(DBC[car_fingerprint]['radar'], signals, checks, CanBus.OBSTACLE) return CANParser(DBC[car_fingerprint]['radar'], signals, checks, CanBus.OBSTACLE)

View File

@ -22,41 +22,43 @@ def calc_cruise_offset(offset, speed):
def get_can_signals(CP): def get_can_signals(CP):
# this function generates lists for signal, messages and initial values # this function generates lists for signal, messages and initial values
signals = [ signals = [
("XMISSION_SPEED", "ENGINE_DATA", 0), ("XMISSION_SPEED", "ENGINE_DATA", 0),
("WHEEL_SPEED_FL", "WHEEL_SPEEDS", 0), ("WHEEL_SPEED_FL", "WHEEL_SPEEDS", 0),
("WHEEL_SPEED_FR", "WHEEL_SPEEDS", 0), ("WHEEL_SPEED_FR", "WHEEL_SPEEDS", 0),
("WHEEL_SPEED_RL", "WHEEL_SPEEDS", 0), ("WHEEL_SPEED_RL", "WHEEL_SPEEDS", 0),
("WHEEL_SPEED_RR", "WHEEL_SPEEDS", 0), ("WHEEL_SPEED_RR", "WHEEL_SPEEDS", 0),
("STEER_ANGLE", "STEERING_SENSORS", 0), ("STEER_ANGLE", "STEERING_SENSORS", 0),
("STEER_ANGLE_RATE", "STEERING_SENSORS", 0), ("STEER_ANGLE_RATE", "STEERING_SENSORS", 0),
("MOTOR_TORQUE", "STEER_MOTOR_TORQUE", 0), ("MOTOR_TORQUE", "STEER_MOTOR_TORQUE", 0),
("STEER_TORQUE_SENSOR", "STEER_STATUS", 0), ("STEER_TORQUE_SENSOR", "STEER_STATUS", 0),
("LEFT_BLINKER", "SCM_FEEDBACK", 0), ("LEFT_BLINKER", "SCM_FEEDBACK", 0),
("RIGHT_BLINKER", "SCM_FEEDBACK", 0), ("RIGHT_BLINKER", "SCM_FEEDBACK", 0),
("GEAR", "GEARBOX", 0), ("GEAR", "GEARBOX", 0),
("SEATBELT_DRIVER_LAMP", "SEATBELT_STATUS", 1), ("SEATBELT_DRIVER_LAMP", "SEATBELT_STATUS", 1),
("SEATBELT_DRIVER_LATCHED", "SEATBELT_STATUS", 0), ("SEATBELT_DRIVER_LATCHED", "SEATBELT_STATUS", 0),
("BRAKE_PRESSED", "POWERTRAIN_DATA", 0), ("BRAKE_PRESSED", "POWERTRAIN_DATA", 0),
("BRAKE_SWITCH", "POWERTRAIN_DATA", 0), ("BRAKE_SWITCH", "POWERTRAIN_DATA", 0),
("CRUISE_BUTTONS", "SCM_BUTTONS", 0), ("CRUISE_BUTTONS", "SCM_BUTTONS", 0),
("ESP_DISABLED", "VSA_STATUS", 1), ("ESP_DISABLED", "VSA_STATUS", 1),
("USER_BRAKE", "VSA_STATUS", 0), ("USER_BRAKE", "VSA_STATUS", 0),
("BRAKE_HOLD_ACTIVE", "VSA_STATUS", 0), ("BRAKE_HOLD_ACTIVE", "VSA_STATUS", 0),
("STEER_STATUS", "STEER_STATUS", 5), ("STEER_STATUS", "STEER_STATUS", 5),
("GEAR_SHIFTER", "GEARBOX", 0), ("GEAR_SHIFTER", "GEARBOX", 0),
("PEDAL_GAS", "POWERTRAIN_DATA", 0), ("PEDAL_GAS", "POWERTRAIN_DATA", 0),
("CRUISE_SETTING", "SCM_BUTTONS", 0), ("CRUISE_SETTING", "SCM_BUTTONS", 0),
("ACC_STATUS", "POWERTRAIN_DATA", 0), ("ACC_STATUS", "POWERTRAIN_DATA", 0),
] ]
checks = [ checks = [
("ENGINE_DATA", 100), ("ENGINE_DATA", 100),
("WHEEL_SPEEDS", 50), ("WHEEL_SPEEDS", 50),
("STEERING_SENSORS", 100), ("STEERING_SENSORS", 100),
("SEATBELT_STATUS", 10), ("SEATBELT_STATUS", 10),
("CRUISE", 10), ("CRUISE", 10),
("POWERTRAIN_DATA", 100), ("POWERTRAIN_DATA", 100),
("VSA_STATUS", 50), ("VSA_STATUS", 50),
("STEER_STATUS", 100),
("STEER_MOTOR_TORQUE", 0), # TODO: not on every car
] ]
if CP.carFingerprint == CAR.ODYSSEY_CHN: if CP.carFingerprint == CAR.ODYSSEY_CHN:
@ -84,12 +86,19 @@ def get_can_signals(CP):
if CP.carFingerprint not in (CAR.ACCORDH, CAR.CIVIC_BOSCH, CAR.CIVIC_BOSCH_DIESEL, CAR.CRV_HYBRID, CAR.INSIGHT): if CP.carFingerprint not in (CAR.ACCORDH, CAR.CIVIC_BOSCH, CAR.CIVIC_BOSCH_DIESEL, CAR.CRV_HYBRID, CAR.INSIGHT):
signals += [("BRAKE_PRESSED", "BRAKE_MODULE", 0)] signals += [("BRAKE_PRESSED", "BRAKE_MODULE", 0)]
checks += [("BRAKE_MODULE", 50)] checks += [("BRAKE_MODULE", 50)]
signals += [("CAR_GAS", "GAS_PEDAL_2", 0),
("MAIN_ON", "SCM_FEEDBACK", 0), signals += [
("CRUISE_CONTROL_LABEL", "ACC_HUD", 0), ("CAR_GAS", "GAS_PEDAL_2", 0),
("EPB_STATE", "EPB_STATUS", 0), ("MAIN_ON", "SCM_FEEDBACK", 0),
("CRUISE_SPEED", "ACC_HUD", 0)] ("CRUISE_CONTROL_LABEL", "ACC_HUD", 0),
checks += [("GAS_PEDAL_2", 100)] ("EPB_STATE", "EPB_STATUS", 0),
("CRUISE_SPEED", "ACC_HUD", 0)
]
checks += [
("ACC_HUD", 10),
("EPB_STATUS", 50),
("GAS_PEDAL_2", 100),
]
if CP.openpilotLongitudinalControl: if CP.openpilotLongitudinalControl:
signals += [("BRAKE_ERROR_1", "STANDSTILL", 1), signals += [("BRAKE_ERROR_1", "STANDSTILL", 1),
("BRAKE_ERROR_2", "STANDSTILL", 1)] ("BRAKE_ERROR_2", "STANDSTILL", 1)]
@ -119,27 +128,43 @@ def get_can_signals(CP):
("DOOR_OPEN_RL", "DOORS_STATUS", 1), ("DOOR_OPEN_RL", "DOORS_STATUS", 1),
("DOOR_OPEN_RR", "DOORS_STATUS", 1), ("DOOR_OPEN_RR", "DOORS_STATUS", 1),
("WHEELS_MOVING", "STANDSTILL", 1)] ("WHEELS_MOVING", "STANDSTILL", 1)]
checks += [("DOORS_STATUS", 3)] checks += [
("DOORS_STATUS", 3),
("STANDSTILL", 50),
]
if CP.carFingerprint == CAR.CIVIC: if CP.carFingerprint == CAR.CIVIC:
signals += [("CAR_GAS", "GAS_PEDAL_2", 0), signals += [("CAR_GAS", "GAS_PEDAL_2", 0),
("MAIN_ON", "SCM_FEEDBACK", 0), ("MAIN_ON", "SCM_FEEDBACK", 0),
("IMPERIAL_UNIT", "HUD_SETTING", 0), ("IMPERIAL_UNIT", "HUD_SETTING", 0),
("EPB_STATE", "EPB_STATUS", 0)] ("EPB_STATE", "EPB_STATUS", 0)]
checks += [
("HUD_SETTING", 50),
("EPB_STATUS", 50),
("GAS_PEDAL_2", 100),
]
elif CP.carFingerprint == CAR.ACURA_ILX: elif CP.carFingerprint == CAR.ACURA_ILX:
signals += [("CAR_GAS", "GAS_PEDAL_2", 0), signals += [("CAR_GAS", "GAS_PEDAL_2", 0),
("MAIN_ON", "SCM_BUTTONS", 0)] ("MAIN_ON", "SCM_BUTTONS", 0)]
checks += [
("GAS_PEDAL_2", 100),
]
elif CP.carFingerprint in (CAR.CRV, CAR.CRV_EU, CAR.ACURA_RDX, CAR.PILOT_2019, CAR.RIDGELINE): elif CP.carFingerprint in (CAR.CRV, CAR.CRV_EU, CAR.ACURA_RDX, CAR.PILOT_2019, CAR.RIDGELINE):
signals += [("MAIN_ON", "SCM_BUTTONS", 0)] signals += [("MAIN_ON", "SCM_BUTTONS", 0)]
elif CP.carFingerprint == CAR.FIT: elif CP.carFingerprint == CAR.FIT:
signals += [("CAR_GAS", "GAS_PEDAL_2", 0), signals += [("CAR_GAS", "GAS_PEDAL_2", 0),
("MAIN_ON", "SCM_BUTTONS", 0), ("MAIN_ON", "SCM_BUTTONS", 0),
("BRAKE_HOLD_ACTIVE", "VSA_STATUS", 0)] ("BRAKE_HOLD_ACTIVE", "VSA_STATUS", 0)]
checks += [
("GAS_PEDAL_2", 100),
]
elif CP.carFingerprint == CAR.HRV: elif CP.carFingerprint == CAR.HRV:
signals += [("CAR_GAS", "GAS_PEDAL", 0), signals += [("CAR_GAS", "GAS_PEDAL", 0),
("MAIN_ON", "SCM_BUTTONS", 0), ("MAIN_ON", "SCM_BUTTONS", 0),
("BRAKE_HOLD_ACTIVE", "VSA_STATUS", 0)] ("BRAKE_HOLD_ACTIVE", "VSA_STATUS", 0)]
checks += [
("GAS_PEDAL", 100),
]
elif CP.carFingerprint == CAR.ODYSSEY: elif CP.carFingerprint == CAR.ODYSSEY:
signals += [("MAIN_ON", "SCM_FEEDBACK", 0), signals += [("MAIN_ON", "SCM_FEEDBACK", 0),
("EPB_STATE", "EPB_STATUS", 0)] ("EPB_STATE", "EPB_STATUS", 0)]
@ -147,6 +172,9 @@ def get_can_signals(CP):
elif CP.carFingerprint == CAR.PILOT: elif CP.carFingerprint == CAR.PILOT:
signals += [("MAIN_ON", "SCM_BUTTONS", 0), signals += [("MAIN_ON", "SCM_BUTTONS", 0),
("CAR_GAS", "GAS_PEDAL_2", 0)] ("CAR_GAS", "GAS_PEDAL_2", 0)]
checks += [
("GAS_PEDAL_2", 0), # TODO: fix this freq, seems this signal isn't present at all on some models
]
elif CP.carFingerprint == CAR.ODYSSEY_CHN: elif CP.carFingerprint == CAR.ODYSSEY_CHN:
signals += [("MAIN_ON", "SCM_BUTTONS", 0), signals += [("MAIN_ON", "SCM_BUTTONS", 0),
("EPB_STATE", "EPB_STATUS", 0)] ("EPB_STATE", "EPB_STATUS", 0)]
@ -325,7 +353,7 @@ class CarState(CarStateBase):
self.stock_hud = cp_cam.vl["ACC_HUD"] self.stock_hud = cp_cam.vl["ACC_HUD"]
self.stock_brake = cp_cam.vl["BRAKE_COMMAND"] self.stock_brake = cp_cam.vl["BRAKE_COMMAND"]
if self.CP.carFingerprint in (CAR.CRV_5G, ): if self.CP.enableBsm and self.CP.carFingerprint in (CAR.CRV_5G, ):
# BSM messages are on B-CAN, requires a panda forwarding B-CAN messages to CAN 0 # BSM messages are on B-CAN, requires a panda forwarding B-CAN messages to CAN 0
# more info here: https://github.com/commaai/openpilot/pull/1867 # more info here: https://github.com/commaai/openpilot/pull/1867
ret.leftBlindspot = cp_body.vl["BSM_STATUS_LEFT"]['BSM_ALERT'] == 1 ret.leftBlindspot = cp_body.vl["BSM_STATUS_LEFT"]['BSM_ALERT'] == 1
@ -343,9 +371,17 @@ class CarState(CarStateBase):
def get_cam_can_parser(CP): def get_cam_can_parser(CP):
signals = [] signals = []
# all hondas except CRV, RDX and 2019 Odyssey@China use 0xe4 for steering
checks = [(0xe4, 100)]
if CP.carFingerprint in [CAR.CRV, CAR.CRV_EU, CAR.ACURA_RDX, CAR.ODYSSEY_CHN]:
checks = [(0x194, 100)]
if CP.carFingerprint in HONDA_BOSCH: if CP.carFingerprint in HONDA_BOSCH:
signals += [("ACCEL_COMMAND", "ACC_CONTROL", 0), signals += [("ACCEL_COMMAND", "ACC_CONTROL", 0),
("AEB_STATUS", "ACC_CONTROL", 0)] ("AEB_STATUS", "ACC_CONTROL", 0)]
checks += [
("ACC_CONTROL", 0), # TODO: fix freq, this seems to be on the wrong bus
]
else: else:
signals += [("COMPUTER_BRAKE", "BRAKE_COMMAND", 0), signals += [("COMPUTER_BRAKE", "BRAKE_COMMAND", 0),
("AEB_REQ_1", "BRAKE_COMMAND", 0), ("AEB_REQ_1", "BRAKE_COMMAND", 0),
@ -355,24 +391,24 @@ class CarState(CarStateBase):
("FCM_OFF_2", "ACC_HUD", 0), ("FCM_OFF_2", "ACC_HUD", 0),
("FCM_PROBLEM", "ACC_HUD", 0), ("FCM_PROBLEM", "ACC_HUD", 0),
("ICONS", "ACC_HUD", 0)] ("ICONS", "ACC_HUD", 0)]
checks += [
# all hondas except CRV, RDX and 2019 Odyssey@China use 0xe4 for steering ("ACC_HUD", 10),
checks = [(0xe4, 100)] ("BRAKE_COMMAND", 50),
if CP.carFingerprint in [CAR.CRV, CAR.CRV_EU, CAR.ACURA_RDX, CAR.ODYSSEY_CHN]: ]
checks = [(0x194, 100)]
return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2) return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2)
@staticmethod @staticmethod
def get_body_can_parser(CP): def get_body_can_parser(CP):
signals = [] if CP.enableBsm and CP.carFingerprint == CAR.CRV_5G:
checks = [] signals = [("BSM_ALERT", "BSM_STATUS_RIGHT", 0),
("BSM_ALERT", "BSM_STATUS_LEFT", 0)]
if CP.carFingerprint == CAR.CRV_5G:
signals += [("BSM_ALERT", "BSM_STATUS_RIGHT", 0),
("BSM_ALERT", "BSM_STATUS_LEFT", 0)]
# TODO: get freqs
checks = [
("BSM_STATUS_LEFT", 0),
("BSM_STATUS_RIGHT", 0),
]
bus_body = 0 # B-CAN is forwarded to ACC-CAN radar side (CAN 0 on fake ethernet port) bus_body = 0 # B-CAN is forwarded to ACC-CAN radar side (CAN 0 on fake ethernet port)
return CANParser(DBC[CP.carFingerprint]['body'], signals, checks, bus_body) return CANParser(DBC[CP.carFingerprint]['body'], signals, checks, bus_body)
return None return None

View File

@ -135,6 +135,9 @@ class CarInterface(CarInterfaceBase):
ret.enableGasInterceptor = 0x201 in fingerprint[0] ret.enableGasInterceptor = 0x201 in fingerprint[0]
ret.openpilotLongitudinalControl = ret.enableCamera ret.openpilotLongitudinalControl = ret.enableCamera
if candidate == CAR.CRV_5G:
ret.enableBsm = 0x12f8bfa7 in fingerprint[0]
cloudlog.warning("ECU Camera Simulated: %r", ret.enableCamera) cloudlog.warning("ECU Camera Simulated: %r", ret.enableCamera)
cloudlog.warning("ECU Gas Interceptor: %r", ret.enableGasInterceptor) cloudlog.warning("ECU Gas Interceptor: %r", ret.enableGasInterceptor)

View File

@ -11,7 +11,7 @@ def _create_nidec_can_parser(car_fingerprint):
['REL_SPEED'] * 16, ['REL_SPEED'] * 16,
[0x400] + radar_messages[1:] * 4, [0x400] + radar_messages[1:] * 4,
[0] + [255] * 16 + [1] * 16 + [0] * 16 + [0] * 16)) [0] + [255] * 16 + [1] * 16 + [0] * 16 + [0] * 16))
checks = list(zip([0x445], [20])) checks = [(s[1], 20) for s in signals]
return CANParser(DBC[car_fingerprint]['radar'], signals, checks, 1) return CANParser(DBC[car_fingerprint]['radar'], signals, checks, 1)

View File

@ -189,8 +189,6 @@ class CarState(CarStateBase):
("ESC_Off_Step", "TCS15", 0), ("ESC_Off_Step", "TCS15", 0),
("AVH_LAMP", "TCS15", 0), ("AVH_LAMP", "TCS15", 0),
("CF_Lvr_GearInf", "LVR11", 0), # Transmission Gear (0 = N or P, 1-8 = Fwd, 14 = Rev)
("CR_Mdps_StrColTq", "MDPS12", 0), ("CR_Mdps_StrColTq", "MDPS12", 0),
("CF_Mdps_ToiActive", "MDPS12", 0), ("CF_Mdps_ToiActive", "MDPS12", 0),
("CF_Mdps_ToiUnavail", "MDPS12", 0), ("CF_Mdps_ToiUnavail", "MDPS12", 0),
@ -215,6 +213,7 @@ class CarState(CarStateBase):
("CLU11", 50), ("CLU11", 50),
("ESP12", 100), ("ESP12", 100),
("CGW1", 10), ("CGW1", 10),
("CGW2", 5),
("CGW4", 5), ("CGW4", 5),
("WHL_SPD11", 50), ("WHL_SPD11", 50),
("SAS11", 100), ("SAS11", 100),

View File

@ -146,10 +146,13 @@ class CarState(CarStateBase):
checks = [ checks = [
# sig_address, frequency # sig_address, frequency
("STEER_ANGLE_SENSOR", 100),
("WHEEL_SPEEDS_REAR", 50), ("WHEEL_SPEEDS_REAR", 50),
("WHEEL_SPEEDS_FRONT", 50), ("WHEEL_SPEEDS_FRONT", 50),
("STEER_ANGLE_SENSOR", 100), ("ESP", 25),
("GEARBOX", 25),
("DOORS_LIGHTS", 10), ("DOORS_LIGHTS", 10),
("LIGHTS", 10),
] ]
if CP.carFingerprint in [CAR.ROGUE, CAR.XTRAIL, CAR.ALTIMA]: if CP.carFingerprint in [CAR.ROGUE, CAR.XTRAIL, CAR.ALTIMA]:
@ -201,6 +204,9 @@ class CarState(CarStateBase):
checks += [ checks += [
("BRAKE_PEDAL", 100), ("BRAKE_PEDAL", 100),
("CRUISE_THROTTLE", 50), ("CRUISE_THROTTLE", 50),
("CANCEL_MSG", 50),
("HUD_SETTINGS", 25),
("SEATBELT", 10),
] ]
if CP.carFingerprint == CAR.ALTIMA: if CP.carFingerprint == CAR.ALTIMA:
@ -241,6 +247,7 @@ class CarState(CarStateBase):
("CRUISE_ON", "PRO_PILOT", 0), ("CRUISE_ON", "PRO_PILOT", 0),
] ]
checks = [ checks = [
("LKAS", 100),
("PRO_PILOT", 100), ("PRO_PILOT", 100),
] ]
else: else:
@ -327,7 +334,11 @@ class CarState(CarStateBase):
] ]
checks = [ checks = [
("PROPILOT_HUD_INFO_MSG", 2),
("LKAS_SETTINGS", 10),
("CRUISE_STATE", 50), ("CRUISE_STATE", 50),
("PROPILOT_HUD", 50),
("LKAS", 100),
] ]
return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2) return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2)
@ -341,7 +352,9 @@ class CarState(CarStateBase):
signals += [ signals += [
("CRUISE_ON", "PRO_PILOT", 0), ("CRUISE_ON", "PRO_PILOT", 0),
] ]
checks += [
("PRO_PILOT", 100),
]
elif CP.carFingerprint == CAR.ALTIMA: elif CP.carFingerprint == CAR.ALTIMA:
signals += [ signals += [
("STEER_TORQUE_DRIVER", "STEER_TORQUE_SENSOR", 0), ("STEER_TORQUE_DRIVER", "STEER_TORQUE_SENSOR", 0),

View File

@ -37,8 +37,9 @@ class CarState(CarStateBase):
ret.leftBlinker, ret.rightBlinker = self.update_blinker(50, cp.vl["Dashlights"]['LEFT_BLINKER'], ret.leftBlinker, ret.rightBlinker = self.update_blinker(50, cp.vl["Dashlights"]['LEFT_BLINKER'],
cp.vl["Dashlights"]['RIGHT_BLINKER']) cp.vl["Dashlights"]['RIGHT_BLINKER'])
ret.leftBlindspot = (cp.vl["BSD_RCTA"]['L_ADJACENT'] == 1) or (cp.vl["BSD_RCTA"]['L_APPROACHING'] == 1) if self.CP.enableBsm:
ret.rightBlindspot = (cp.vl["BSD_RCTA"]['R_ADJACENT'] == 1) or (cp.vl["BSD_RCTA"]['R_APPROACHING'] == 1) ret.leftBlindspot = (cp.vl["BSD_RCTA"]['L_ADJACENT'] == 1) or (cp.vl["BSD_RCTA"]['L_APPROACHING'] == 1)
ret.rightBlindspot = (cp.vl["BSD_RCTA"]['R_ADJACENT'] == 1) or (cp.vl["BSD_RCTA"]['R_APPROACHING'] == 1)
can_gear = int(cp.vl["Transmission"]['Gear']) can_gear = int(cp.vl["Transmission"]['Gear'])
ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(can_gear, None)) ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(can_gear, None))
@ -102,10 +103,6 @@ class CarState(CarStateBase):
("DOOR_OPEN_RL", "BodyInfo", 1), ("DOOR_OPEN_RL", "BodyInfo", 1),
("Units", "Dash_State", 1), ("Units", "Dash_State", 1),
("Gear", "Transmission", 0), ("Gear", "Transmission", 0),
("L_ADJACENT", "BSD_RCTA", 0),
("R_ADJACENT", "BSD_RCTA", 0),
("L_APPROACHING", "BSD_RCTA", 0),
("R_APPROACHING", "BSD_RCTA", 0),
] ]
checks = [ checks = [
@ -116,8 +113,21 @@ class CarState(CarStateBase):
("Wheel_Speeds", 50), ("Wheel_Speeds", 50),
("Transmission", 100), ("Transmission", 100),
("Steering_Torque", 50), ("Steering_Torque", 50),
("Dash_State", 1),
("BodyInfo", 1),
] ]
if CP.enableBsm:
signals += [
("L_ADJACENT", "BSD_RCTA", 0),
("R_ADJACENT", "BSD_RCTA", 0),
("L_APPROACHING", "BSD_RCTA", 0),
("R_APPROACHING", "BSD_RCTA", 0),
]
checks += [
("BSD_RCTA", 17),
]
if CP.carFingerprint in PREGLOBAL_CARS: if CP.carFingerprint in PREGLOBAL_CARS:
signals += [ signals += [
("LKA_Lockout", "Steering_Torque", 0), ("LKA_Lockout", "Steering_Torque", 0),

View File

@ -27,6 +27,7 @@ class CarInterface(CarInterfaceBase):
ret.dashcamOnly = candidate in PREGLOBAL_CARS ret.dashcamOnly = candidate in PREGLOBAL_CARS
ret.enableCamera = True ret.enableCamera = True
ret.enableBsm = 0x228 in fingerprint[0]
ret.steerRateCost = 0.7 ret.steerRateCost = 0.7
ret.steerLimitTimer = 0.4 ret.steerLimitTimer = 0.4

View File

@ -1,70 +1,69 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import unittest import unittest
import importlib import importlib
from parameterized import parameterized
from cereal import car
from selfdrive.car.fingerprints import all_known_cars from selfdrive.car.fingerprints import all_known_cars
from selfdrive.car.car_helpers import interfaces from selfdrive.car.car_helpers import interfaces
from selfdrive.car.fingerprints import _FINGERPRINTS as FINGERPRINTS from selfdrive.car.fingerprints import _FINGERPRINTS as FINGERPRINTS
from cereal import car
class TestCarInterfaces(unittest.TestCase): class TestCarInterfaces(unittest.TestCase):
def test_car_interfaces(self):
all_cars = all_known_cars()
for car_name in all_cars: @parameterized.expand([(car,) for car in all_known_cars()])
print(car_name) def test_car_interfaces(self, car_name):
fingerprint = FINGERPRINTS[car_name][0] print(car_name)
fingerprint = FINGERPRINTS[car_name][0]
CarInterface, CarController, CarState = interfaces[car_name] CarInterface, CarController, CarState = interfaces[car_name]
fingerprints = { fingerprints = {
0: fingerprint, 0: fingerprint,
1: fingerprint, 1: fingerprint,
2: fingerprint, 2: fingerprint,
} }
car_fw = [] car_fw = []
car_params = CarInterface.get_params(car_name, fingerprints, car_fw) car_params = CarInterface.get_params(car_name, fingerprints, car_fw)
car_interface = CarInterface(car_params, CarController, CarState) car_interface = CarInterface(car_params, CarController, CarState)
assert car_params assert car_params
assert car_interface assert car_interface
self.assertGreater(car_params.mass, 1) self.assertGreater(car_params.mass, 1)
self.assertGreater(car_params.steerRateCost, 1e-3) self.assertGreater(car_params.steerRateCost, 1e-3)
if car_params.steerControlType != car.CarParams.SteerControlType.angle: if car_params.steerControlType != car.CarParams.SteerControlType.angle:
tuning = car_params.lateralTuning.which() tuning = car_params.lateralTuning.which()
if tuning == 'pid': if tuning == 'pid':
self.assertTrue(len(car_params.lateralTuning.pid.kpV)) self.assertTrue(len(car_params.lateralTuning.pid.kpV))
elif tuning == 'lqr': elif tuning == 'lqr':
self.assertTrue(len(car_params.lateralTuning.lqr.a)) self.assertTrue(len(car_params.lateralTuning.lqr.a))
elif tuning == 'indi': elif tuning == 'indi':
self.assertTrue(len(car_params.lateralTuning.indi.outerLoopGainV)) self.assertTrue(len(car_params.lateralTuning.indi.outerLoopGainV))
# Run car interface # Run car interface
CC = car.CarControl.new_message() CC = car.CarControl.new_message()
for _ in range(10): for _ in range(10):
car_interface.update(CC, []) car_interface.update(CC, [])
car_interface.apply(CC) car_interface.apply(CC)
car_interface.apply(CC) car_interface.apply(CC)
CC = car.CarControl.new_message() CC = car.CarControl.new_message()
CC.enabled = True CC.enabled = True
for _ in range(10): for _ in range(10):
car_interface.update(CC, []) car_interface.update(CC, [])
car_interface.apply(CC) car_interface.apply(CC)
car_interface.apply(CC) car_interface.apply(CC)
# Test radar interface # Test radar interface
RadarInterface = importlib.import_module('selfdrive.car.%s.radar_interface' % car_params.carName).RadarInterface RadarInterface = importlib.import_module('selfdrive.car.%s.radar_interface' % car_params.carName).RadarInterface
radar_interface = RadarInterface(car_params) radar_interface = RadarInterface(car_params)
assert radar_interface assert radar_interface
# Run radar interface once # Run radar interface once
radar_interface.update([]) radar_interface.update([])
if not car_params.radarOffCan and hasattr(radar_interface, '_update') and hasattr(radar_interface, 'trigger_msg'): if not car_params.radarOffCan and hasattr(radar_interface, '_update') and hasattr(radar_interface, 'trigger_msg'):
radar_interface._update([radar_interface.trigger_msg]) radar_interface._update([radar_interface.trigger_msg])
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()

View File

@ -4,7 +4,7 @@ from opendbc.can.can_define import CANDefine
from selfdrive.car.interfaces import CarStateBase from selfdrive.car.interfaces import CarStateBase
from opendbc.can.parser import CANParser from opendbc.can.parser import CANParser
from selfdrive.config import Conversions as CV from selfdrive.config import Conversions as CV
from selfdrive.car.toyota.values import CAR, DBC, STEER_THRESHOLD, TSS2_CAR, NO_STOP_TIMER_CAR from selfdrive.car.toyota.values import CAR, DBC, STEER_THRESHOLD, NO_STOP_TIMER_CAR
class CarState(CarStateBase): class CarState(CarStateBase):
@ -90,17 +90,14 @@ class CarState(CarStateBase):
ret.cruiseState.enabled = bool(cp.vl["PCM_CRUISE"]['CRUISE_ACTIVE']) ret.cruiseState.enabled = bool(cp.vl["PCM_CRUISE"]['CRUISE_ACTIVE'])
ret.cruiseState.nonAdaptive = cp.vl["PCM_CRUISE"]['CRUISE_STATE'] in [1, 2, 3, 4, 5, 6] ret.cruiseState.nonAdaptive = cp.vl["PCM_CRUISE"]['CRUISE_STATE'] in [1, 2, 3, 4, 5, 6]
if self.CP.carFingerprint == CAR.PRIUS: ret.genericToggle = bool(cp.vl["LIGHT_STALK"]['AUTO_HIGH_BEAM'])
ret.genericToggle = cp.vl["AUTOPARK_STATUS"]['STATE'] != 0
else:
ret.genericToggle = bool(cp.vl["LIGHT_STALK"]['AUTO_HIGH_BEAM'])
ret.stockAeb = bool(cp_cam.vl["PRE_COLLISION"]["PRECOLLISION_ACTIVE"] and cp_cam.vl["PRE_COLLISION"]["FORCE"] < -1e-5) ret.stockAeb = bool(cp_cam.vl["PRE_COLLISION"]["PRECOLLISION_ACTIVE"] and cp_cam.vl["PRE_COLLISION"]["FORCE"] < -1e-5)
ret.espDisabled = cp.vl["ESP_CONTROL"]['TC_DISABLED'] != 0 ret.espDisabled = cp.vl["ESP_CONTROL"]['TC_DISABLED'] != 0
# 2 is standby, 10 is active. TODO: check that everything else is really a faulty state # 2 is standby, 10 is active. TODO: check that everything else is really a faulty state
self.steer_state = cp.vl["EPS_STATUS"]['LKA_STATE'] self.steer_state = cp.vl["EPS_STATUS"]['LKA_STATE']
if self.CP.carFingerprint in TSS2_CAR: if self.CP.enableBsm:
ret.leftBlindspot = (cp.vl["BSM"]['L_ADJACENT'] == 1) or (cp.vl["BSM"]['L_APPROACHING'] == 1) ret.leftBlindspot = (cp.vl["BSM"]['L_ADJACENT'] == 1) or (cp.vl["BSM"]['L_APPROACHING'] == 1)
ret.rightBlindspot = (cp.vl["BSM"]['R_ADJACENT'] == 1) or (cp.vl["BSM"]['R_APPROACHING'] == 1) ret.rightBlindspot = (cp.vl["BSM"]['R_ADJACENT'] == 1) or (cp.vl["BSM"]['R_APPROACHING'] == 1)
@ -140,13 +137,18 @@ class CarState(CarStateBase):
] ]
checks = [ checks = [
("GEAR_PACKET", 1),
("LIGHT_STALK", 1),
("STEERING_LEVERS", 0.15),
("SEATS_DOORS", 3),
("ESP_CONTROL", 3),
("EPS_STATUS", 25),
("BRAKE_MODULE", 40), ("BRAKE_MODULE", 40),
("GAS_PEDAL", 33), ("GAS_PEDAL", 33),
("WHEEL_SPEEDS", 80), ("WHEEL_SPEEDS", 80),
("STEER_ANGLE_SENSOR", 80), ("STEER_ANGLE_SENSOR", 80),
("PCM_CRUISE", 33), ("PCM_CRUISE", 33),
("STEER_TORQUE_SENSOR", 50), ("STEER_TORQUE_SENSOR", 50),
("EPS_STATUS", 25),
] ]
if CP.carFingerprint == CAR.LEXUS_IS: if CP.carFingerprint == CAR.LEXUS_IS:
@ -159,20 +161,22 @@ class CarState(CarStateBase):
signals.append(("LOW_SPEED_LOCKOUT", "PCM_CRUISE_2", 0)) signals.append(("LOW_SPEED_LOCKOUT", "PCM_CRUISE_2", 0))
checks.append(("PCM_CRUISE_2", 33)) checks.append(("PCM_CRUISE_2", 33))
if CP.carFingerprint == CAR.PRIUS:
signals += [("STATE", "AUTOPARK_STATUS", 0)]
# add gas interceptor reading if we are using it # add gas interceptor reading if we are using it
if CP.enableGasInterceptor: if CP.enableGasInterceptor:
signals.append(("INTERCEPTOR_GAS", "GAS_SENSOR", 0)) signals.append(("INTERCEPTOR_GAS", "GAS_SENSOR", 0))
signals.append(("INTERCEPTOR_GAS2", "GAS_SENSOR", 0)) signals.append(("INTERCEPTOR_GAS2", "GAS_SENSOR", 0))
checks.append(("GAS_SENSOR", 50)) checks.append(("GAS_SENSOR", 50))
if CP.carFingerprint in TSS2_CAR: if CP.enableBsm:
signals += [("L_ADJACENT", "BSM", 0)] signals += [
signals += [("L_APPROACHING", "BSM", 0)] ("L_ADJACENT", "BSM", 0),
signals += [("R_ADJACENT", "BSM", 0)] ("L_APPROACHING", "BSM", 0),
signals += [("R_APPROACHING", "BSM", 0)] ("R_ADJACENT", "BSM", 0),
("R_APPROACHING", "BSM", 0),
]
checks += [
("BSM", 1)
]
return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0) return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0)
@ -186,7 +190,8 @@ class CarState(CarStateBase):
# use steering message to check if panda is connected to frc # use steering message to check if panda is connected to frc
checks = [ checks = [
("STEERING_LKA", 42) ("STEERING_LKA", 42),
("PRE_COLLISION", 0), # TODO: figure out why freq is inconsistent
] ]
return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2) return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2)

View File

@ -321,6 +321,7 @@ class CarInterface(CarInterfaceBase):
tire_stiffness_factor=tire_stiffness_factor) tire_stiffness_factor=tire_stiffness_factor)
ret.enableCamera = True ret.enableCamera = True
ret.enableBsm = 0x3F6 in fingerprint[0] and candidate in TSS2_CAR
# Detect smartDSU, which intercepts ACC_CMD from the DSU allowing openpilot to send it # Detect smartDSU, which intercepts ACC_CMD from the DSU allowing openpilot to send it
smartDsu = 0x2FF in fingerprint[0] smartDsu = 0x2FF in fingerprint[0]
# In TSS2 cars the camera does long control # In TSS2 cars the camera does long control

View File

@ -80,8 +80,9 @@ class CarState(CarStateBase):
# detection box is dynamic based on speed and road curvature. # detection box is dynamic based on speed and road curvature.
# Refer to VW Self Study Program 890253: Volkswagen Driver Assist Systems, # Refer to VW Self Study Program 890253: Volkswagen Driver Assist Systems,
# pages 32-35. # pages 32-35.
ret.leftBlindspot = bool(pt_cp.vl["SWA_01"]["SWA_Infostufe_SWA_li"]) or bool(pt_cp.vl["SWA_01"]["SWA_Warnung_SWA_li"]) if self.CP.enableBsm:
ret.rightBlindspot = bool(pt_cp.vl["SWA_01"]["SWA_Infostufe_SWA_re"]) or bool(pt_cp.vl["SWA_01"]["SWA_Warnung_SWA_re"]) ret.leftBlindspot = bool(pt_cp.vl["SWA_01"]["SWA_Infostufe_SWA_li"]) or bool(pt_cp.vl["SWA_01"]["SWA_Warnung_SWA_li"])
ret.rightBlindspot = bool(pt_cp.vl["SWA_01"]["SWA_Infostufe_SWA_re"]) or bool(pt_cp.vl["SWA_01"]["SWA_Warnung_SWA_re"])
# Consume factory LDW data relevant for factory SWA (Lane Change Assist) # Consume factory LDW data relevant for factory SWA (Lane Change Assist)
# and capture it for forwarding to the blind spot radar controller # and capture it for forwarding to the blind spot radar controller
@ -203,10 +204,6 @@ class CarState(CarStateBase):
("GRA_Tip_Stufe_2", "GRA_ACC_01", 0), # unknown related to stalk type ("GRA_Tip_Stufe_2", "GRA_ACC_01", 0), # unknown related to stalk type
("GRA_ButtonTypeInfo", "GRA_ACC_01", 0), # unknown related to stalk type ("GRA_ButtonTypeInfo", "GRA_ACC_01", 0), # unknown related to stalk type
("COUNTER", "GRA_ACC_01", 0), # GRA_ACC_01 CAN message counter ("COUNTER", "GRA_ACC_01", 0), # GRA_ACC_01 CAN message counter
("SWA_Infostufe_SWA_li", "SWA_01", 0), # Blind spot object info, left
("SWA_Warnung_SWA_li", "SWA_01", 0), # Blind spot object warning, left
("SWA_Infostufe_SWA_re", "SWA_01", 0), # Blind spot object info, right
("SWA_Warnung_SWA_re", "SWA_01", 0), # Blind spot object warning, right
] ]
checks = [ checks = [
@ -219,6 +216,7 @@ class CarState(CarStateBase):
("ACC_10", 50), # From J428 ACC radar control module ("ACC_10", 50), # From J428 ACC radar control module
("Motor_20", 50), # From J623 Engine control module ("Motor_20", 50), # From J623 Engine control module
("TSK_06", 50), # From J623 Engine control module ("TSK_06", 50), # From J623 Engine control module
("ESP_02", 50),
("GRA_ACC_01", 33), # From J??? steering wheel control buttons ("GRA_ACC_01", 33), # From J??? steering wheel control buttons
("ACC_02", 17), # From J428 ACC radar control module ("ACC_02", 17), # From J428 ACC radar control module
("Gateway_72", 10), # From J533 CAN gateway (aggregated data) ("Gateway_72", 10), # From J533 CAN gateway (aggregated data)
@ -229,6 +227,17 @@ class CarState(CarStateBase):
("Einheiten_01", 1), # From J??? not known if gateway, cluster, or BCM ("Einheiten_01", 1), # From J??? not known if gateway, cluster, or BCM
] ]
if CP.enableBsm:
signals += [
("SWA_Infostufe_SWA_li", "SWA_01", 0), # Blind spot object info, left
("SWA_Warnung_SWA_li", "SWA_01", 0), # Blind spot object warning, left
("SWA_Infostufe_SWA_re", "SWA_01", 0), # Blind spot object info, right
("SWA_Warnung_SWA_re", "SWA_01", 0), # Blind spot object warning, right
]
checks += [
("SWA_01", 20),
]
if CP.transmissionType == TransmissionType.automatic: if CP.transmissionType == TransmissionType.automatic:
signals += [("GE_Fahrstufe", "Getriebe_11", 0)] # Auto trans gear selector position signals += [("GE_Fahrstufe", "Getriebe_11", 0)] # Auto trans gear selector position
checks += [("Getriebe_11", 20)] # From J743 Auto transmission control module checks += [("Getriebe_11", 20)] # From J743 Auto transmission control module

View File

@ -104,7 +104,8 @@ class CarInterface(CarInterfaceBase):
ret.centerToFront = ret.wheelbase * 0.45 ret.centerToFront = ret.wheelbase * 0.45
ret.enableCamera = True # Stock camera detection doesn't apply to VW ret.enableCamera = True
ret.enableBsm = 0x30F in fingerprint[0]
# TODO: get actual value, for now starting with reasonable value for # TODO: get actual value, for now starting with reasonable value for
# civic and scaling by mass and wheelbase # civic and scaling by mass and wheelbase

View File

@ -176,12 +176,9 @@ class Plant():
return float(self.rk.frame) / self.rate return float(self.rk.frame) / self.rate
def step(self, v_lead=0.0, cruise_buttons=None, grade=0.0, publish_model=True): def step(self, v_lead=0.0, cruise_buttons=None, grade=0.0, publish_model=True):
gen_signals, gen_checks = get_can_signals(CP) gen_signals, _ = get_can_signals(CP)
sgs = [s[0] for s in gen_signals] sgs = [s[0] for s in gen_signals]
msgs = [s[1] for s in gen_signals] msgs = [s[1] for s in gen_signals]
cks_msgs = set(check[0] for check in gen_checks)
cks_msgs.add(0x18F)
cks_msgs.add(0x30C)
# ******** get messages sent to the car ******** # ******** get messages sent to the car ********
can_strings = messaging.drain_sock_raw(Plant.sendcan, wait_for_one=self.response_seen) can_strings = messaging.drain_sock_raw(Plant.sendcan, wait_for_one=self.response_seen)
@ -353,12 +350,17 @@ class Plant():
can_msgs.append([0x400, 0, radar_state_msg, 1]) can_msgs.append([0x400, 0, radar_state_msg, 1])
can_msgs.append([0x445, 0, radar_msg, 1]) can_msgs.append([0x445, 0, radar_msg, 1])
# add camera msg so controlsd thinks it's alive radar_messages = list(range(0x430, 0x43A)) + list(range(0x440, 0x445))
for m in radar_messages:
can_msgs.append([m, 0, b'\x00'*8, 1])
msg_struct["COUNTER"] = self.frame % 4 msg_struct["COUNTER"] = self.frame % 4
msg = honda.lookup_msg_id(0xe4) camera_messages = [0x1FA, 0x30C, 0xE4]
msg_data = honda.encode(msg, msg_struct) for m in camera_messages:
msg_data = fix(msg_data, 0xe4) msg = honda.lookup_msg_id(m)
can_msgs.append([0xe4, 0, msg_data, 2]) msg_data = honda.encode(msg, msg_struct)
msg_data = fix(msg_data, m)
can_msgs.append([m, 0, msg_data, 2])
# Fake sockets that controlsd subscribes to # Fake sockets that controlsd subscribes to
live_parameters = messaging.new_message('liveParameters') live_parameters = messaging.new_message('liveParameters')

View File

@ -1 +1 @@
381c4976c45f232f413b37945fbcd43391174089 8539d7c0d5186cd2d13e7f031ecb93e64b5ed8ae