openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

229 lines
12 KiB

import numpy as np
from cereal import car
from common.kalman.simple_kalman import KF1D
from selfdrive.config import Conversions as CV
from selfdrive.can.parser import CANParser
from selfdrive.can.can_define import CANDefine
from selfdrive.car.volkswagen.values import DBC, BUTTON_STATES
from selfdrive.car.volkswagen.carcontroller import CarControllerParams
GEAR = car.CarState.GearShifter
def get_mqb_gateway_can_parser(CP, canbus):
# this function generates lists for signal, messages and initial values
signals = [
# sig_name, sig_address, default
("LWI_Lenkradwinkel", "LWI_01", 0), # Absolute steering angle
("LWI_VZ_Lenkradwinkel", "LWI_01", 0), # Steering angle sign
("LWI_Lenkradw_Geschw", "LWI_01", 0), # Absolute steering rate
("LWI_VZ_Lenkradw_Geschw", "LWI_01", 0), # Steering rate sign
("ESP_VL_Radgeschw_02", "ESP_19", 0), # ABS wheel speed, front left
("ESP_VR_Radgeschw_02", "ESP_19", 0), # ABS wheel speed, front right
("ESP_HL_Radgeschw_02", "ESP_19", 0), # ABS wheel speed, rear left
("ESP_HR_Radgeschw_02", "ESP_19", 0), # ABS wheel speed, rear right
("ESP_Gierrate", "ESP_02", 0), # Absolute yaw rate
("ESP_VZ_Gierrate", "ESP_02", 0), # Yaw rate sign
("ZV_FT_offen", "Gateway_72", 0), # Door open, driver
("ZV_BT_offen", "Gateway_72", 0), # Door open, passenger
("ZV_HFS_offen", "Gateway_72", 0), # Door open, rear left
("ZV_HBFS_offen", "Gateway_72", 0), # Door open, rear right
("ZV_HD_offen", "Gateway_72", 0), # Trunk or hatch open
("BH_Blinker_li", "Gateway_72", 0), # Left turn signal on
("BH_Blinker_re", "Gateway_72", 0), # Right turn signal on
("GE_Fahrstufe", "Getriebe_11", 0), # Auto trans gear selector position
("AB_Gurtschloss_FA", "Airbag_02", 0), # Seatbelt status, driver
("AB_Gurtschloss_BF", "Airbag_02", 0), # Seatbelt status, passenger
("ESP_Fahrer_bremst", "ESP_05", 0), # Brake pedal pressed
("ESP_Status_Bremsdruck", "ESP_05", 0), # Brakes applied
("ESP_Bremsdruck", "ESP_05", 0), # Brake pressure applied
("MO_Fahrpedalrohwert_01", "Motor_20", 0), # Accelerator pedal value
("MO_Kuppl_schalter", "Motor_14", 0), # Clutch switch
("Driver_Strain", "EPS_01", 0), # Absolute driver torque input
("Driver_Strain_VZ", "EPS_01", 0), # Driver torque input sign
("HCA_Ready", "EPS_01", 0), # Steering rack HCA support configured
("ESP_Tastung_passiv", "ESP_21", 0), # Stability control disabled
("KBI_MFA_v_Einheit_02", "Einheiten_01", 0), # MPH vs KMH speed display
("KBI_Handbremse", "Kombi_01", 0), # Manual handbrake applied
("TSK_Fahrzeugmasse_02", "Motor_16", 0), # Estimated vehicle mass from drivetrain coordinator
("GRA_Hauptschalter", "GRA_ACC_01", 0), # ACC button, on/off
("GRA_Abbrechen", "GRA_ACC_01", 0), # ACC button, cancel
("GRA_Tip_Setzen", "GRA_ACC_01", 0), # ACC button, set
("GRA_Tip_Hoch", "GRA_ACC_01", 0), # ACC button, increase or accel
("GRA_Tip_Runter", "GRA_ACC_01", 0), # ACC button, decrease or decel
("GRA_Tip_Wiederaufnahme", "GRA_ACC_01", 0), # ACC button, resume
("GRA_Verstellung_Zeitluecke", "GRA_ACC_01", 0), # ACC button, time gap adj
("GRA_Typ_Hauptschalter", "GRA_ACC_01", 0), # ACC main button 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
("COUNTER", "GRA_ACC_01", 0), # GRA_ACC_01 CAN message counter
]
checks = [
# sig_address, frequency
("LWI_01", 100), # From J500 Steering Assist with integrated sensors
("EPS_01", 100), # From J500 Steering Assist with integrated sensors
("ESP_19", 100), # From J104 ABS/ESP controller
("ESP_05", 50), # From J104 ABS/ESP controller
("ESP_21", 50), # From J104 ABS/ESP controller
("Motor_20", 50), # From J623 Engine control module
("GRA_ACC_01", 33), # From J??? steering wheel control buttons
("Getriebe_11", 20), # From J743 Auto transmission control module
("Gateway_72", 10), # From J533 CAN gateway (aggregated data)
("Motor_14", 10), # From J623 Engine control module
("Airbag_02", 5), # From J234 Airbag control module
("Kombi_01", 2), # From J285 Instrument cluster
("Motor_16", 2), # From J623 Engine control module
("Einheiten_01", 1), # From J??? not known if gateway, cluster, or BCM
]
return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, canbus.gateway)
def get_mqb_extended_can_parser(CP, canbus):
signals = [
# sig_name, sig_address, default
("ACC_Status_ACC", "ACC_06", 0), # ACC engagement status
("ACC_Typ", "ACC_06", 0), # ACC type (follow to stop, stop&go)
("SetSpeed", "ACC_02", 0), # ACC set speed
]
checks = [
# sig_address, frequency
("ACC_06", 50), # From J428 ACC radar control module
("ACC_02", 17), # From J428 ACC radar control module
]
return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, canbus.extended)
def parse_gear_shifter(gear, vals):
# Return mapping of gearshift position to selected gear.
val_to_capnp = {'P': GEAR.park, 'R': GEAR.reverse, 'N': GEAR.neutral,
'D': GEAR.drive, 'E': GEAR.eco, 'S': GEAR.sport, 'T': GEAR.manumatic}
try:
return val_to_capnp[vals[gear]]
except KeyError:
return "unknown"
class CarState():
def __init__(self, CP, canbus):
# initialize can parser
self.CP = CP
self.car_fingerprint = CP.carFingerprint
self.can_define = CANDefine(DBC[CP.carFingerprint]['pt'])
self.shifter_values = self.can_define.dv["Getriebe_11"]['GE_Fahrstufe']
self.buttonStates = BUTTON_STATES.copy()
# vEgo Kalman filter
dt = 0.01
self.v_ego_kf = KF1D(x0=[[0.], [0.]],
A=[[1., dt], [0., 1.]],
C=[1., 0.],
K=[[0.12287673], [0.29666309]])
def update(self, gw_cp, ex_cp):
# Update vehicle speed and acceleration from ABS wheel speeds.
self.wheelSpeedFL = gw_cp.vl["ESP_19"]['ESP_VL_Radgeschw_02'] * CV.KPH_TO_MS
self.wheelSpeedFR = gw_cp.vl["ESP_19"]['ESP_VR_Radgeschw_02'] * CV.KPH_TO_MS
self.wheelSpeedRL = gw_cp.vl["ESP_19"]['ESP_HL_Radgeschw_02'] * CV.KPH_TO_MS
self.wheelSpeedRR = gw_cp.vl["ESP_19"]['ESP_HR_Radgeschw_02'] * CV.KPH_TO_MS
self.vEgoRaw = float(np.mean([self.wheelSpeedFL, self.wheelSpeedFR, self.wheelSpeedRL, self.wheelSpeedRR]))
v_ego_x = self.v_ego_kf.update(self.vEgoRaw)
self.vEgo = float(v_ego_x[0])
self.aEgo = float(v_ego_x[1])
self.standstill = self.vEgoRaw < 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.
self.steeringAngle = gw_cp.vl["LWI_01"]['LWI_Lenkradwinkel'] * (1,-1)[int(gw_cp.vl["LWI_01"]['LWI_VZ_Lenkradwinkel'])]
self.steeringRate = gw_cp.vl["LWI_01"]['LWI_Lenkradw_Geschw'] * (1,-1)[int(gw_cp.vl["LWI_01"]['LWI_VZ_Lenkradwinkel'])]
self.steeringTorque = gw_cp.vl["EPS_01"]['Driver_Strain'] * (1,-1)[int(gw_cp.vl["EPS_01"]['Driver_Strain_VZ'])]
self.steeringPressed = abs(self.steeringTorque) > CarControllerParams.STEER_DRIVER_ALLOWANCE
self.yawRate = gw_cp.vl["ESP_02"]['ESP_Gierrate'] * (1,-1)[int(gw_cp.vl["ESP_02"]['ESP_VZ_Gierrate'])] * CV.DEG_TO_RAD
# Update gas, brakes, and gearshift.
self.gas = gw_cp.vl["Motor_20"]['MO_Fahrpedalrohwert_01'] / 100.0
self.gasPressed = self.gas > 0
self.brake = gw_cp.vl["ESP_05"]['ESP_Bremsdruck'] / 250.0 # FIXME: this is pressure in Bar, not sure what OP expects
self.brakePressed = bool(gw_cp.vl["ESP_05"]['ESP_Fahrer_bremst'])
self.brakeLights = bool(gw_cp.vl["ESP_05"]['ESP_Status_Bremsdruck'])
# Update gear and/or clutch position data.
can_gear_shifter = int(gw_cp.vl["Getriebe_11"]['GE_Fahrstufe'])
self.gearShifter = parse_gear_shifter(can_gear_shifter, self.shifter_values)
# Update door and trunk/hatch lid open status.
self.doorOpen = any([gw_cp.vl["Gateway_72"]['ZV_FT_offen'],
gw_cp.vl["Gateway_72"]['ZV_BT_offen'],
gw_cp.vl["Gateway_72"]['ZV_HFS_offen'],
gw_cp.vl["Gateway_72"]['ZV_HBFS_offen'],
gw_cp.vl["Gateway_72"]['ZV_HD_offen']])
# Update seatbelt fastened status.
self.seatbeltUnlatched = False if gw_cp.vl["Airbag_02"]["AB_Gurtschloss_FA"] == 3 else True
# Update driver preference for metric. VW stores many different unit
# preferences, including separate units for for distance vs. speed.
# We use the speed preference for OP.
self.displayMetricUnits = not gw_cp.vl["Einheiten_01"]["KBI_MFA_v_Einheit_02"]
# Update ACC radar status.
accStatus = ex_cp.vl["ACC_06"]['ACC_Status_ACC']
if accStatus == 1:
# ACC okay but disabled
self.accFault = False
self.accAvailable = False
self.accEnabled = False
elif accStatus == 2:
# ACC okay and enabled, but not currently engaged
self.accFault = False
self.accAvailable = True
self.accEnabled = 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)
self.accFault = False
self.accAvailable = True
self.accEnabled = True
else:
# ACC fault of some sort. Seen statuses 6 or 7 for CAN comms disruptions, visibility issues, etc.
self.accFault = True
self.accAvailable = False
self.accEnabled = False
# Update ACC setpoint. When the setpoint is zero or there's an error, the
# radar sends a set-speed of ~90.69 m/s / 203mph.
self.accSetSpeed = ex_cp.vl["ACC_02"]['SetSpeed']
if self.accSetSpeed > 90: self.accSetSpeed = 0
# Update control button states for turn signals and ACC controls.
self.buttonStates["leftBlinker"] = bool(gw_cp.vl["Gateway_72"]['BH_Blinker_li'])
self.buttonStates["leftBlinker"] = bool(gw_cp.vl["Gateway_72"]['BH_Blinker_re'])
self.buttonStates["accelCruise"] = bool(gw_cp.vl["GRA_ACC_01"]['GRA_Tip_Hoch'])
self.buttonStates["decelCruise"] = bool(gw_cp.vl["GRA_ACC_01"]['GRA_Tip_Runter'])
self.buttonStates["cancel"] = bool(gw_cp.vl["GRA_ACC_01"]['GRA_Abbrechen'])
self.buttonStates["setCruise"] = bool(gw_cp.vl["GRA_ACC_01"]['GRA_Tip_Setzen'])
self.buttonStates["resumeCruise"] = bool(gw_cp.vl["GRA_ACC_01"]['GRA_Tip_Wiederaufnahme'])
self.buttonStates["gapAdjustCruise"] = bool(gw_cp.vl["GRA_ACC_01"]['GRA_Verstellung_Zeitluecke'])
# 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 = gw_cp.vl["GRA_ACC_01"]['GRA_Hauptschalter']
self.graTypHauptschalter = gw_cp.vl["GRA_ACC_01"]['GRA_Typ_Hauptschalter']
self.graButtonTypeInfo = gw_cp.vl["GRA_ACC_01"]['GRA_ButtonTypeInfo']
self.graTipStufe2 = gw_cp.vl["GRA_ACC_01"]['GRA_Tip_Stufe_2']
# Pick up the GRA_ACC_01 CAN message counter so we can sync to it for
# later cruise-control button spamming.
self.graMsgBusCounter = gw_cp.vl["GRA_ACC_01"]['COUNTER']
# Check to make sure the electric power steering rack is configured to
# accept and respond to HCA_01 messages and has not encountered a fault.
self.steeringFault = not gw_cp.vl["EPS_01"]["HCA_Ready"]
# Additional safety checks performed in CarInterface.
self.parkingBrakeSet = bool(gw_cp.vl["Kombi_01"]['KBI_Handbremse']) # FIXME: need to include an EPB check as well
self.stabilityControlDisabled = gw_cp.vl["ESP_21"]['ESP_Tastung_passiv']