|
|
|
@ -4,20 +4,30 @@ from common.conversions import Conversions as CV |
|
|
|
|
from selfdrive.car.interfaces import CarStateBase |
|
|
|
|
from opendbc.can.parser import CANParser |
|
|
|
|
from opendbc.can.can_define import CANDefine |
|
|
|
|
from selfdrive.car.volkswagen.values import DBC_FILES, CANBUS, NetworkLocation, TransmissionType, GearShifter, BUTTON_STATES, CarControllerParams |
|
|
|
|
from selfdrive.car.volkswagen.values import PQ_CARS, DBC_FILES, CANBUS, NetworkLocation, TransmissionType, GearShifter, BUTTON_STATES, CarControllerParams |
|
|
|
|
|
|
|
|
|
class CarState(CarStateBase): |
|
|
|
|
def __init__(self, CP): |
|
|
|
|
super().__init__(CP) |
|
|
|
|
can_define = CANDefine(DBC_FILES.mqb) |
|
|
|
|
if CP.transmissionType == TransmissionType.automatic: |
|
|
|
|
self.shifter_values = can_define.dv["Getriebe_11"]["GE_Fahrstufe"] |
|
|
|
|
elif CP.transmissionType == TransmissionType.direct: |
|
|
|
|
self.shifter_values = can_define.dv["EV_Gearshift"]["GearPosition"] |
|
|
|
|
self.hca_status_values = can_define.dv["LH_EPS_03"]["EPS_HCA_Status"] |
|
|
|
|
self.buttonStates = BUTTON_STATES.copy() |
|
|
|
|
|
|
|
|
|
if CP.carFingerprint in PQ_CARS: |
|
|
|
|
can_define = CANDefine(DBC_FILES.pq) |
|
|
|
|
self.hca_status_values = can_define.dv["Lenkhilfe_2"]["LH2_Sta_HCA"] |
|
|
|
|
if CP.transmissionType == TransmissionType.automatic: |
|
|
|
|
self.shifter_values = can_define.dv["Getriebe_1"]["Waehlhebelposition__Getriebe_1_"] |
|
|
|
|
else: |
|
|
|
|
can_define = CANDefine(DBC_FILES.mqb) |
|
|
|
|
self.hca_status_values = can_define.dv["LH_EPS_03"]["EPS_HCA_Status"] |
|
|
|
|
if CP.transmissionType == TransmissionType.automatic: |
|
|
|
|
self.shifter_values = can_define.dv["Getriebe_11"]["GE_Fahrstufe"] |
|
|
|
|
elif CP.transmissionType == TransmissionType.direct: |
|
|
|
|
self.shifter_values = can_define.dv["EV_Gearshift"]["GearPosition"] |
|
|
|
|
|
|
|
|
|
def update(self, pt_cp, cam_cp, ext_cp, trans_type): |
|
|
|
|
if self.CP.carFingerprint in PQ_CARS: |
|
|
|
|
return self.update_pq(pt_cp, cam_cp, ext_cp, trans_type) |
|
|
|
|
|
|
|
|
|
ret = car.CarState.new_message() |
|
|
|
|
# Update vehicle speed and acceleration from ABS wheel speeds. |
|
|
|
|
ret.wheelSpeeds = self.get_wheel_speeds( |
|
|
|
@ -140,8 +150,138 @@ class CarState(CarStateBase): |
|
|
|
|
|
|
|
|
|
return ret |
|
|
|
|
|
|
|
|
|
def update_pq(self, pt_cp, cam_cp, ext_cp, trans_type): |
|
|
|
|
ret = car.CarState.new_message() |
|
|
|
|
# Update vehicle speed and acceleration from ABS wheel speeds. |
|
|
|
|
ret.wheelSpeeds = self.get_wheel_speeds( |
|
|
|
|
pt_cp.vl["Bremse_3"]["Radgeschw__VL_4_1"], |
|
|
|
|
pt_cp.vl["Bremse_3"]["Radgeschw__VR_4_1"], |
|
|
|
|
pt_cp.vl["Bremse_3"]["Radgeschw__HL_4_1"], |
|
|
|
|
pt_cp.vl["Bremse_3"]["Radgeschw__HR_4_1"], |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
# FIXME: Match current Panda/support NSF by getting vEgoRaw from ego speed signal |
|
|
|
|
ret.vEgoRaw = float(np.mean([ret.wheelSpeeds.fl, ret.wheelSpeeds.fr, ret.wheelSpeeds.rl, ret.wheelSpeeds.rr])) |
|
|
|
|
ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw) |
|
|
|
|
ret.standstill = ret.vEgo < 0.1 |
|
|
|
|
|
|
|
|
|
# Update steering angle, rate, yaw rate, and driver input torque. VW send |
|
|
|
|
# the sign/direction in a separate signal so they must be recombined. |
|
|
|
|
ret.steeringAngleDeg = pt_cp.vl["Lenkhilfe_3"]["LH3_BLW"] * (1, -1)[int(pt_cp.vl["Lenkhilfe_3"]["LH3_BLWSign"])] |
|
|
|
|
ret.steeringRateDeg = pt_cp.vl["Lenkwinkel_1"]["Lenkradwinkel_Geschwindigkeit"] * (1, -1)[int(pt_cp.vl["Lenkwinkel_1"]["Lenkradwinkel_Geschwindigkeit_S"])] |
|
|
|
|
ret.steeringTorque = pt_cp.vl["Lenkhilfe_3"]["LH3_LM"] * (1, -1)[int(pt_cp.vl["Lenkhilfe_3"]["LH3_LMSign"])] |
|
|
|
|
ret.steeringPressed = abs(ret.steeringTorque) > CarControllerParams.STEER_DRIVER_ALLOWANCE |
|
|
|
|
ret.yawRate = pt_cp.vl["Bremse_5"]["Giergeschwindigkeit"] * (1, -1)[int(pt_cp.vl["Bremse_5"]["Vorzeichen_der_Giergeschwindigk"])] * CV.DEG_TO_RAD |
|
|
|
|
|
|
|
|
|
# Verify EPS readiness to accept steering commands |
|
|
|
|
hca_status = self.hca_status_values.get(pt_cp.vl["Lenkhilfe_2"]["LH2_Sta_HCA"]) |
|
|
|
|
ret.steerFaultPermanent = hca_status in ["DISABLED", "FAULT"] |
|
|
|
|
ret.steerFaultTemporary = hca_status in ["INITIALIZING", "REJECTED"] |
|
|
|
|
|
|
|
|
|
# Update gas, brakes, and gearshift. |
|
|
|
|
ret.gas = pt_cp.vl["Motor_3"]["Fahrpedal_Rohsignal"] / 100.0 |
|
|
|
|
ret.gasPressed = ret.gas > 0 |
|
|
|
|
ret.brake = pt_cp.vl["Bremse_5"]["Bremsdruck"] / 250.0 # FIXME: this is pressure in Bar, not sure what OP expects |
|
|
|
|
ret.brakePressed = bool(pt_cp.vl["Motor_2"]["Bremstestschalter"]) |
|
|
|
|
self.parkingBrakeSet = bool(pt_cp.vl["Kombi_1"]["Bremsinfo"]) |
|
|
|
|
|
|
|
|
|
# Update gear and/or clutch position data. |
|
|
|
|
if trans_type == TransmissionType.automatic: |
|
|
|
|
ret.gearShifter = self.parse_gear_shifter( |
|
|
|
|
self.shifter_values.get(pt_cp.vl["Getriebe_1"]["Waehlhebelposition__Getriebe_1_"], None)) |
|
|
|
|
elif trans_type == TransmissionType.manual: |
|
|
|
|
ret.clutchPressed = not pt_cp.vl["Motor_1"]["Kupplungsschalter"] |
|
|
|
|
reverse_light = bool(pt_cp.vl["Gate_Komf_1"]["GK1_Rueckfahr"]) |
|
|
|
|
if reverse_light: |
|
|
|
|
ret.gearShifter = GearShifter.reverse |
|
|
|
|
else: |
|
|
|
|
ret.gearShifter = GearShifter.drive |
|
|
|
|
|
|
|
|
|
# Update door and trunk/hatch lid open status. |
|
|
|
|
# FIXME: need to locate signals for other three doors and trunk if possible |
|
|
|
|
ret.doorOpen = bool(pt_cp.vl["Gate_Komf_1"]["GK1_Fa_Tuerkont"]) |
|
|
|
|
|
|
|
|
|
# Update seatbelt fastened status. |
|
|
|
|
ret.seatbeltUnlatched = not bool(pt_cp.vl["Airbag_1"]["Gurtschalter_Fahrer"]) |
|
|
|
|
|
|
|
|
|
# Consume blind-spot monitoring info/warning LED states, if available. |
|
|
|
|
# Infostufe: BSM LED on, Warnung: BSM LED flashing |
|
|
|
|
if self.CP.enableBsm: |
|
|
|
|
ret.leftBlindspot = bool(ext_cp.vl["SWA_1"]["SWA_Infostufe_SWA_li"]) or bool(ext_cp.vl["SWA_1"]["SWA_Warnung_SWA_li"]) |
|
|
|
|
ret.rightBlindspot = bool(ext_cp.vl["SWA_1"]["SWA_Infostufe_SWA_re"]) or bool(ext_cp.vl["SWA_1"]["SWA_Warnung_SWA_re"]) |
|
|
|
|
|
|
|
|
|
# Consume factory LDW data relevant for factory SWA (Lane Change Assist) |
|
|
|
|
# and capture it for forwarding to the blind spot radar controller |
|
|
|
|
# TODO: populate this |
|
|
|
|
self.ldw_stock_values = None |
|
|
|
|
|
|
|
|
|
# Stock FCW is considered active if the release bit for brake-jerk warning |
|
|
|
|
# is set. Stock AEB considered active if the partial braking or target |
|
|
|
|
# braking release bits are set. |
|
|
|
|
# Refer to VW Self Study Program 890253: Volkswagen Driver Assistance |
|
|
|
|
# Systems, chapter on Front Assist with Braking: Golf Family for all MQB |
|
|
|
|
# TODO: fix document ref and populate this |
|
|
|
|
ret.stockFcw = False |
|
|
|
|
ret.stockAeb = False |
|
|
|
|
|
|
|
|
|
# Update ACC radar status. |
|
|
|
|
accStatus = ext_cp.vl["ACC_GRA_Anziege"]["ACA_StaACC"] |
|
|
|
|
if accStatus == 2: |
|
|
|
|
# ACC okay and enabled, but not currently engaged |
|
|
|
|
ret.cruiseState.available = True |
|
|
|
|
ret.cruiseState.enabled = False |
|
|
|
|
elif accStatus in [3, 4, 5]: |
|
|
|
|
# ACC okay and enabled, currently engaged and regulating speed (3) or engaged with driver accelerating (4) or overrun (5) |
|
|
|
|
# Verify against Motor_2 to keep in lockstep with Panda safety |
|
|
|
|
ret.cruiseState.available = True |
|
|
|
|
if pt_cp.vl["Motor_2"]["GRA_Status"] in [1, 2]: |
|
|
|
|
ret.cruiseState.enabled = True |
|
|
|
|
else: |
|
|
|
|
ret.cruiseState.enabled = False |
|
|
|
|
else: |
|
|
|
|
# ACC okay but disabled (1), or a radar visibility or other fault/disruption (6 or 7) |
|
|
|
|
ret.cruiseState.available = False |
|
|
|
|
ret.cruiseState.enabled = False |
|
|
|
|
|
|
|
|
|
# Update ACC setpoint. When the setpoint reads as 255, the driver has not |
|
|
|
|
# yet established an ACC setpoint, so treat it as zero. |
|
|
|
|
ret.cruiseState.speed = ext_cp.vl["ACC_GRA_Anziege"]["ACA_V_Wunsch"] * CV.KPH_TO_MS |
|
|
|
|
if ret.cruiseState.speed > 70: # 255 kph in m/s == no current setpoint |
|
|
|
|
ret.cruiseState.speed = 0 |
|
|
|
|
|
|
|
|
|
# Update control button states for turn signals and ACC controls. |
|
|
|
|
self.buttonStates["accelCruise"] = bool(pt_cp.vl["GRA_Neu"]["GRA_Up_kurz"]) or bool(pt_cp.vl["GRA_Neu"]["GRA_Up_lang"]) |
|
|
|
|
self.buttonStates["decelCruise"] = bool(pt_cp.vl["GRA_Neu"]["GRA_Down_kurz"]) or bool(pt_cp.vl["GRA_Neu"]["GRA_Down_lang"]) |
|
|
|
|
self.buttonStates["cancel"] = bool(pt_cp.vl["GRA_Neu"]["GRA_Abbrechen"]) |
|
|
|
|
self.buttonStates["setCruise"] = bool(pt_cp.vl["GRA_Neu"]["GRA_Neu_Setzen"]) |
|
|
|
|
self.buttonStates["resumeCruise"] = bool(pt_cp.vl["GRA_Neu"]["GRA_Recall"]) |
|
|
|
|
self.buttonStates["gapAdjustCruise"] = bool(pt_cp.vl["GRA_Neu"]["GRA_Zeitluecke"]) |
|
|
|
|
ret.leftBlinker = bool(pt_cp.vl["Gate_Komf_1"]["GK1_Blinker_li"]) |
|
|
|
|
ret.rightBlinker = bool(pt_cp.vl["Gate_Komf_1"]["GK1_Blinker_re"]) |
|
|
|
|
|
|
|
|
|
# Read ACC hardware button type configuration info that has to pass thru |
|
|
|
|
# to the radar. Ends up being different for steering wheel buttons vs |
|
|
|
|
# third stalk type controls. |
|
|
|
|
self.graHauptschalter = pt_cp.vl["GRA_Neu"]["GRA_Hauptschalt"] |
|
|
|
|
self.graSenderCoding = pt_cp.vl["GRA_Neu"]["GRA_Sender"] |
|
|
|
|
self.graTypHauptschalter = False |
|
|
|
|
self.graButtonTypeInfo = False |
|
|
|
|
self.graTipStufe2 = False |
|
|
|
|
|
|
|
|
|
# Pick up the GRA_ACC_01 CAN message counter so we can sync to it for |
|
|
|
|
# later cruise-control button spamming. |
|
|
|
|
self.graMsgBusCounter = pt_cp.vl["GRA_Neu"]["GRA_Neu_Zaehler"] |
|
|
|
|
|
|
|
|
|
# Additional safety checks performed in CarInterface. |
|
|
|
|
ret.espDisabled = bool(pt_cp.vl["Bremse_1"]["ESP_Passiv_getastet"]) |
|
|
|
|
|
|
|
|
|
return ret |
|
|
|
|
|
|
|
|
|
@staticmethod |
|
|
|
|
def get_can_parser(CP): |
|
|
|
|
if CP.carFingerprint in PQ_CARS: |
|
|
|
|
return CarState.get_can_parser_pq(CP) |
|
|
|
|
|
|
|
|
|
signals = [ |
|
|
|
|
# sig_name, sig_address |
|
|
|
|
("LWI_Lenkradwinkel", "LWI_01"), # Absolute steering angle |
|
|
|
@ -226,6 +366,9 @@ class CarState(CarStateBase): |
|
|
|
|
|
|
|
|
|
@staticmethod |
|
|
|
|
def get_cam_can_parser(CP): |
|
|
|
|
if CP.carFingerprint in PQ_CARS: |
|
|
|
|
return CarState.get_cam_can_parser_pq(CP) |
|
|
|
|
|
|
|
|
|
signals = [] |
|
|
|
|
checks = [] |
|
|
|
|
|
|
|
|
@ -252,6 +395,101 @@ class CarState(CarStateBase): |
|
|
|
|
|
|
|
|
|
return CANParser(DBC_FILES.mqb, signals, checks, CANBUS.cam) |
|
|
|
|
|
|
|
|
|
@staticmethod |
|
|
|
|
def get_can_parser_pq(CP): |
|
|
|
|
signals = [ |
|
|
|
|
# sig_name, sig_address, default |
|
|
|
|
("LH3_BLW", "Lenkhilfe_3"), # Absolute steering angle |
|
|
|
|
("LH3_BLWSign", "Lenkhilfe_3"), # Steering angle sign |
|
|
|
|
("LH3_LM", "Lenkhilfe_3"), # Absolute driver torque input |
|
|
|
|
("LH3_LMSign", "Lenkhilfe_3"), # Driver torque input sign |
|
|
|
|
("LH2_Sta_HCA", "Lenkhilfe_2"), # Steering rack HCA status |
|
|
|
|
("Lenkradwinkel_Geschwindigkeit", "Lenkwinkel_1"), # Absolute steering rate |
|
|
|
|
("Lenkradwinkel_Geschwindigkeit_S", "Lenkwinkel_1"), # Steering rate sign |
|
|
|
|
("Radgeschw__VL_4_1", "Bremse_3"), # ABS wheel speed, front left |
|
|
|
|
("Radgeschw__VR_4_1", "Bremse_3"), # ABS wheel speed, front right |
|
|
|
|
("Radgeschw__HL_4_1", "Bremse_3"), # ABS wheel speed, rear left |
|
|
|
|
("Radgeschw__HR_4_1", "Bremse_3"), # ABS wheel speed, rear right |
|
|
|
|
("Giergeschwindigkeit", "Bremse_5"), # Absolute yaw rate |
|
|
|
|
("Vorzeichen_der_Giergeschwindigk", "Bremse_5"), # Yaw rate sign |
|
|
|
|
("Gurtschalter_Fahrer", "Airbag_1"), # Seatbelt status, driver |
|
|
|
|
("Gurtschalter_Beifahrer", "Airbag_1"), # Seatbelt status, passenger |
|
|
|
|
("Bremstestschalter", "Motor_2"), # Brake pedal pressed (brake light test switch) |
|
|
|
|
("Bremslichtschalter", "Motor_2"), # Brakes applied (brake light switch) |
|
|
|
|
("Bremsdruck", "Bremse_5"), # Brake pressure applied |
|
|
|
|
("Vorzeichen_Bremsdruck", "Bremse_5"), # Brake pressure applied sign (???) |
|
|
|
|
("Fahrpedal_Rohsignal", "Motor_3"), # Accelerator pedal value |
|
|
|
|
("ESP_Passiv_getastet", "Bremse_1"), # Stability control disabled |
|
|
|
|
("GRA_Status", "Motor_2"), # ACC engagement status |
|
|
|
|
("GK1_Fa_Tuerkont", "Gate_Komf_1"), # Door open, driver |
|
|
|
|
("GK1_Blinker_li", "Gate_Komf_1"), # Left turn signal on |
|
|
|
|
("GK1_Blinker_re", "Gate_Komf_1"), # Right turn signal on |
|
|
|
|
("Bremsinfo", "Kombi_1"), # Manual handbrake applied |
|
|
|
|
("GRA_Hauptschalt", "GRA_Neu"), # ACC button, on/off |
|
|
|
|
("GRA_Abbrechen", "GRA_Neu"), # ACC button, cancel |
|
|
|
|
("GRA_Neu_Setzen", "GRA_Neu"), # ACC button, set |
|
|
|
|
("GRA_Up_lang", "GRA_Neu"), # ACC button, increase or accel, long press |
|
|
|
|
("GRA_Down_lang", "GRA_Neu"), # ACC button, decrease or decel, long press |
|
|
|
|
("GRA_Up_kurz", "GRA_Neu"), # ACC button, increase or accel, short press |
|
|
|
|
("GRA_Down_kurz", "GRA_Neu"), # ACC button, decrease or decel, short press |
|
|
|
|
("GRA_Recall", "GRA_Neu"), # ACC button, resume |
|
|
|
|
("GRA_Zeitluecke", "GRA_Neu"), # ACC button, time gap adj |
|
|
|
|
("GRA_Neu_Zaehler", "GRA_Neu"), # ACC button, time gap adj |
|
|
|
|
("GRA_Sender", "GRA_Neu"), # GRA Sender Coding |
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
checks = [ |
|
|
|
|
# sig_address, frequency |
|
|
|
|
("Bremse_1", 100), # From J104 ABS/ESP controller |
|
|
|
|
("Bremse_3", 100), # From J104 ABS/ESP controller |
|
|
|
|
("Lenkhilfe_3", 100), # From J500 Steering Assist with integrated sensors |
|
|
|
|
("Lenkwinkel_1", 100), # From J500 Steering Assist with integrated sensors |
|
|
|
|
("Motor_3", 100), # From J623 Engine control module |
|
|
|
|
("Airbag_1", 50), # From J234 Airbag control module |
|
|
|
|
("Bremse_5", 50), # From J104 ABS/ESP controller |
|
|
|
|
("GRA_Neu", 50), # From J??? steering wheel control buttons |
|
|
|
|
("Kombi_1", 50), # From J285 Instrument cluster |
|
|
|
|
("Motor_2", 50), # From J623 Engine control module |
|
|
|
|
("Lenkhilfe_2", 20), # From J500 Steering Assist with integrated sensors |
|
|
|
|
("Gate_Komf_1", 10), # From J533 CAN gateway |
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
if CP.transmissionType == TransmissionType.automatic: |
|
|
|
|
signals += [("Waehlhebelposition__Getriebe_1_", "Getriebe_1", 0)] # Auto trans gear selector position |
|
|
|
|
checks += [("Getriebe_1", 100)] # From J743 Auto transmission control module |
|
|
|
|
elif CP.transmissionType == TransmissionType.manual: |
|
|
|
|
signals += [("Kupplungsschalter", "Motor_1", 0), # Clutch switch |
|
|
|
|
("GK1_Rueckfahr", "Gate_Komf_1", 0)] # Reverse light from BCM |
|
|
|
|
checks += [("Motor_1", 100)] # From J623 Engine control module |
|
|
|
|
|
|
|
|
|
if CP.networkLocation == NetworkLocation.fwdCamera: |
|
|
|
|
# Extended CAN devices other than the camera are here on CANBUS.pt |
|
|
|
|
signals += PqExtraSignals.fwd_radar_signals |
|
|
|
|
checks += PqExtraSignals.fwd_radar_checks |
|
|
|
|
if CP.enableBsm: |
|
|
|
|
signals += PqExtraSignals.bsm_radar_signals |
|
|
|
|
checks += PqExtraSignals.bsm_radar_checks |
|
|
|
|
|
|
|
|
|
return CANParser(DBC_FILES.pq, signals, checks, CANBUS.pt) |
|
|
|
|
|
|
|
|
|
@staticmethod |
|
|
|
|
def get_cam_can_parser_pq(CP): |
|
|
|
|
|
|
|
|
|
# TODO: Populate this for NetworkLocation.fwdCamera |
|
|
|
|
signals = [] |
|
|
|
|
checks = [] |
|
|
|
|
|
|
|
|
|
if CP.networkLocation == NetworkLocation.gateway: |
|
|
|
|
# Radars are here on CANBUS.cam |
|
|
|
|
signals += PqExtraSignals.fwd_radar_signals |
|
|
|
|
checks += PqExtraSignals.fwd_radar_checks |
|
|
|
|
if CP.enableBsm: |
|
|
|
|
signals += PqExtraSignals.bsm_radar_signals |
|
|
|
|
checks += PqExtraSignals.bsm_radar_checks |
|
|
|
|
|
|
|
|
|
return CANParser(DBC_FILES.pq, signals, checks, CANBUS.cam) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class MqbExtraSignals: |
|
|
|
|
# Additional signal and message lists for optional or bus-portable controllers |
|
|
|
|
fwd_radar_signals = [ |
|
|
|
@ -273,3 +511,22 @@ class MqbExtraSignals: |
|
|
|
|
bsm_radar_checks = [ |
|
|
|
|
("SWA_01", 20), # From J1086 Lane Change Assist |
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
class PqExtraSignals: |
|
|
|
|
# Additional signal and message lists for optional or bus-portable controllers |
|
|
|
|
fwd_radar_signals = [ |
|
|
|
|
("ACA_StaACC", "ACC_GRA_Anziege", 0), # ACC drivetrain coordinator status |
|
|
|
|
("ACA_V_Wunsch", "ACC_GRA_Anziege", 0), # ACC set speed |
|
|
|
|
] |
|
|
|
|
fwd_radar_checks = [ |
|
|
|
|
("ACC_GRA_Anziege", 25), # From J428 ACC radar control module |
|
|
|
|
] |
|
|
|
|
bsm_radar_signals = [ |
|
|
|
|
("SWA_Infostufe_SWA_li", "SWA_1", 0), # Blind spot object info, left |
|
|
|
|
("SWA_Warnung_SWA_li", "SWA_1", 0), # Blind spot object warning, left |
|
|
|
|
("SWA_Infostufe_SWA_re", "SWA_1", 0), # Blind spot object info, right |
|
|
|
|
("SWA_Warnung_SWA_re", "SWA_1", 0), # Blind spot object warning, right |
|
|
|
|
] |
|
|
|
|
bsm_radar_checks = [ |
|
|
|
|
("SWA_1", 20), # From J1086 Lane Change Assist |
|
|
|
|
] |
|
|
|
|