@@ -18,6 +18,7 @@ def __init__(self, CP):
1818 self .esp_hold_confirmation = False
1919 self .upscale_lead_car_signal = False
2020 self .eps_stock_values = False
21+ self .acc_type = 0
2122
2223 def update_button_enable (self , buttonEvents : list [structs .CarState .ButtonEvent ]):
2324 if not self .CP .pcmCruise :
@@ -48,6 +49,8 @@ def update(self, can_parsers) -> structs.CarState:
4849
4950 if self .CP .flags & VolkswagenFlags .PQ :
5051 return self .update_pq (pt_cp , cam_cp , ext_cp )
52+ elif self .CP .flags & VolkswagenFlags .MLB :
53+ return self .update_mlb (pt_cp , cam_cp , ext_cp )
5154
5255 ret = structs .CarState ()
5356
@@ -73,11 +76,9 @@ def update(self, can_parsers) -> structs.CarState:
7376 pt_cp .vl ["ESP_19" ]["ESP_HR_Radgeschw_02" ],
7477 )
7578
76- hca_status = self .CCP .hca_status_values .get (pt_cp .vl ["LH_EPS_03" ]["EPS_HCA_Status" ])
7779 if self .CP .flags & VolkswagenFlags .STOCK_HCA_PRESENT :
7880 ret .carFaultedNonCritical = bool (cam_cp .vl ["HCA_01" ]["EA_Ruckfreigabe" ]) or cam_cp .vl ["HCA_01" ]["EA_ACC_Sollstatus" ] > 0 # EA
7981
80- drive_mode = True
8182 ret .brake = pt_cp .vl ["ESP_05" ]["ESP_Bremsdruck" ] / 250.0 # FIXME: this is pressure in Bar, not sure what OP expects
8283 brake_pedal_pressed = bool (pt_cp .vl ["Motor_14" ]["MO_Fahrer_bremst" ])
8384 brake_pressure_detected = bool (pt_cp .vl ["ESP_05" ]["ESP_Fahrer_bremst" ])
@@ -114,11 +115,7 @@ def update(self, can_parsers) -> structs.CarState:
114115 # Shared logic
115116 ret .vEgoCluster = pt_cp .vl ["Kombi_01" ]["KBI_angez_Geschw" ] * CV .KPH_TO_MS
116117
117- ret .steeringAngleDeg = pt_cp .vl ["LWI_01" ]["LWI_Lenkradwinkel" ] * (1 , - 1 )[int (pt_cp .vl ["LWI_01" ]["LWI_VZ_Lenkradwinkel" ])]
118- ret .steeringRateDeg = pt_cp .vl ["LWI_01" ]["LWI_Lenkradw_Geschw" ] * (1 , - 1 )[int (pt_cp .vl ["LWI_01" ]["LWI_VZ_Lenkradw_Geschw" ])]
119- ret .steeringTorque = pt_cp .vl ["LH_EPS_03" ]["EPS_Lenkmoment" ] * (1 , - 1 )[int (pt_cp .vl ["LH_EPS_03" ]["EPS_VZ_Lenkmoment" ])]
120- ret .steeringPressed = abs (ret .steeringTorque ) > self .CCP .STEER_DRIVER_ALLOWANCE
121- ret .steerFaultTemporary , ret .steerFaultPermanent = self .update_hca_state (hca_status , drive_mode )
118+ self .parse_mlb_mqb_steering_state (ret , pt_cp )
122119
123120 ret .gasPressed = pt_cp .vl ["Motor_20" ]["MO_Fahrpedalrohwert_01" ] > 0
124121 ret .espActive = bool (pt_cp .vl ["ESP_21" ]["ESP_Eingriff" ])
@@ -233,6 +230,61 @@ def update_pq(self, pt_cp, cam_cp, ext_cp) -> structs.CarState:
233230 self .frame += 1
234231 return ret
235232
233+ def update_mlb (self , pt_cp , cam_cp , ext_cp ) -> structs .CarState :
234+ ret = structs .CarState ()
235+
236+ self .parse_wheel_speeds (ret ,
237+ pt_cp .vl ["ESP_03" ]["ESP_VL_Radgeschw" ],
238+ pt_cp .vl ["ESP_03" ]["ESP_VR_Radgeschw" ],
239+ pt_cp .vl ["ESP_03" ]["ESP_HL_Radgeschw" ],
240+ pt_cp .vl ["ESP_03" ]["ESP_HR_Radgeschw" ],
241+ )
242+
243+ ret .gasPressed = pt_cp .vl ["Motor_03" ]["MO_Fahrpedalrohwert_01" ] > 0
244+ ret .gearShifter = self .parse_gear_shifter (self .CCP .shifter_values .get (pt_cp .vl ["Getriebe_03" ]["GE_Waehlhebel" ], None ))
245+
246+ # ACC okay but disabled (1), ACC ready (2), a radar visibility or other fault/disruption (6 or 7)
247+ # currently regulating speed (3), driver accel override (4), brake only (5)
248+ # TODO: get this from the drivetrain side instead, for openpilot long support later
249+ ret .cruiseState .available = ext_cp .vl ["ACC_05" ]["ACC_Status_ACC" ] in (2 , 3 , 4 , 5 )
250+ ret .cruiseState .enabled = ext_cp .vl ["ACC_05" ]["ACC_Status_ACC" ] in (3 , 4 , 5 )
251+ ret .accFaulted = ext_cp .vl ["ACC_05" ]["ACC_Status_ACC" ] in (6 , 7 )
252+
253+ self .parse_mlb_mqb_steering_state (ret , pt_cp )
254+
255+ ret .brake = pt_cp .vl ["ESP_05" ]["ESP_Bremsdruck" ] / 250.0
256+ brake_pedal_pressed = bool (pt_cp .vl ["Motor_03" ]["MO_Fahrer_bremst" ])
257+ brake_pressure_detected = bool (pt_cp .vl ["ESP_05" ]["ESP_Fahrer_bremst" ])
258+ ret .brakePressed = brake_pedal_pressed or brake_pressure_detected
259+ ret .parkingBrake = bool (pt_cp .vl ["Kombi_01" ]["KBI_Handbremse" ])
260+ ret .espDisabled = pt_cp .vl ["ESP_01" ]["ESP_Tastung_passiv" ] != 0
261+
262+ ret .leftBlinker , ret .rightBlinker = self .update_blinker_from_stalk (300 , pt_cp .vl ["Gateway_11" ]["BH_Blinker_li" ],
263+ pt_cp .vl ["Gateway_11" ]["BH_Blinker_re" ])
264+
265+ ret .seatbeltUnlatched = pt_cp .vl ["Gateway_06" ]["AB_Gurtschloss_FA" ] != 3
266+ ret .doorOpen = any ([pt_cp .vl ["Gateway_05" ]["FT_Tuer_geoeffnet" ],
267+ pt_cp .vl ["Gateway_05" ]["BT_Tuer_geoeffnet" ],
268+ pt_cp .vl ["Gateway_05" ]["HL_Tuer_geoeffnet" ],
269+ pt_cp .vl ["Gateway_05" ]["HR_Tuer_geoeffnet" ]])
270+
271+ # Consume blind-spot monitoring info/warning LED states, if available.
272+ # Infostufe: BSM LED on, Warnung: BSM LED flashing
273+ if self .CP .enableBsm :
274+ ret .leftBlindspot = bool (ext_cp .vl ["SWA_01" ]["SWA_Infostufe_SWA_li" ]) or bool (ext_cp .vl ["SWA_01" ]["SWA_Warnung_SWA_li" ])
275+ ret .rightBlindspot = bool (ext_cp .vl ["SWA_01" ]["SWA_Infostufe_SWA_re" ]) or bool (ext_cp .vl ["SWA_01" ]["SWA_Warnung_SWA_re" ])
276+
277+ self .ldw_stock_values = cam_cp .vl ["LDW_02" ] if self .CP .networkLocation == NetworkLocation .fwdCamera else {}
278+ self .gra_stock_values = pt_cp .vl ["LS_01" ]
279+
280+ ret .buttonEvents = self .create_button_events (pt_cp , self .CCP .BUTTONS )
281+
282+ ret .cruiseState .standstill = self .CP .pcmCruise and self .esp_hold_confirmation
283+ ret .standstill = ret .vEgoRaw == 0
284+
285+ self .frame += 1
286+ return ret
287+
236288 def update_low_speed_alert (self , v_ego : float ) -> bool :
237289 # Low speed steer alert hysteresis logic
238290 if (self .CP .minSteerSpeed - 1e-3 ) > CarControllerParams .DEFAULT_MIN_STEER_SPEED and v_ego < (self .CP .minSteerSpeed + 1. ):
@@ -241,6 +293,16 @@ def update_low_speed_alert(self, v_ego: float) -> bool:
241293 self .low_speed_alert = False
242294 return self .low_speed_alert
243295
296+ def parse_mlb_mqb_steering_state (self , ret , pt_cp , drive_mode = True ):
297+ ret .steeringAngleDeg = pt_cp .vl ["LWI_01" ]["LWI_Lenkradwinkel" ] * (1 , - 1 )[int (pt_cp .vl ["LWI_01" ]["LWI_VZ_Lenkradwinkel" ])]
298+ ret .steeringRateDeg = pt_cp .vl ["LWI_01" ]["LWI_Lenkradw_Geschw" ] * (1 , - 1 )[int (pt_cp .vl ["LWI_01" ]["LWI_VZ_Lenkradw_Geschw" ])]
299+ ret .steeringTorque = pt_cp .vl ["LH_EPS_03" ]["EPS_Lenkmoment" ] * (1 , - 1 )[int (pt_cp .vl ["LH_EPS_03" ]["EPS_VZ_Lenkmoment" ])]
300+ ret .steeringPressed = abs (ret .steeringTorque ) > self .CCP .STEER_DRIVER_ALLOWANCE
301+
302+ hca_status = self .CCP .hca_status_values .get (pt_cp .vl ["LH_EPS_03" ]["EPS_HCA_Status" ])
303+ ret .steerFaultTemporary , ret .steerFaultPermanent = self .update_hca_state (hca_status , drive_mode )
304+ return
305+
244306 def update_hca_state (self , hca_status , drive_mode = True ):
245307 # Treat FAULT as temporary for worst likely EPS recovery time, for cars without factory Lane Assist
246308 # DISABLED means the EPS hasn't been configured to support Lane Assist
@@ -254,18 +316,20 @@ def get_can_parsers(CP):
254316 if CP .flags & VolkswagenFlags .PQ :
255317 return CarState .get_can_parsers_pq (CP )
256318
257- # another case of the 1-50Hz
258- cam_messages = []
319+ # manually configure some optional and variable-rate/edge-triggered messages
320+ pt_messages , cam_messages = [], []
321+
322+ if not CP .flags & VolkswagenFlags .MLB :
323+ pt_messages += [
324+ ("Blinkmodi_02" , 1 ) # From J519 BCM (sent at 1Hz when no lights active, 50Hz when active)
325+ ]
259326 if CP .flags & VolkswagenFlags .STOCK_HCA_PRESENT :
260327 cam_messages += [
261328 ("HCA_01" , 1 ), # From R242 Driver assistance camera, 50Hz if steering/1Hz if not
262329 ]
263330
264331 return {
265- Bus .pt : CANParser (DBC [CP .carFingerprint ][Bus .pt ], [
266- # the 50->1Hz is currently too much for the CANParser to figure out
267- ("Blinkmodi_02" , 1 ), # From J519 BCM (sent at 1Hz when no lights active, 50Hz when active)
268- ], CanBus (CP ).pt ),
332+ Bus .pt : CANParser (DBC [CP .carFingerprint ][Bus .pt ], pt_messages , CanBus (CP ).pt ),
269333 Bus .cam : CANParser (DBC [CP .carFingerprint ][Bus .pt ], cam_messages , CanBus (CP ).cam ),
270334 }
271335
0 commit comments