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.
 
 
 
 
 
 

252 lines
8.9 KiB

from cereal import car
from common.params import Params
from panda import Panda
from selfdrive.car.volkswagen.values import CAR, BUTTON_STATES, CANBUS, NetworkLocation, TransmissionType, GearShifter
from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config
from selfdrive.car.interfaces import CarInterfaceBase
ButtonType = car.CarState.ButtonEvent.Type
EventName = car.CarEvent.EventName
class CarInterface(CarInterfaceBase):
def __init__(self, CP, CarController, CarState):
super().__init__(CP, CarController, CarState)
self.displayMetricUnitsPrev = None
self.buttonStatesPrev = BUTTON_STATES.copy()
if CP.networkLocation == NetworkLocation.fwdCamera:
self.ext_bus = CANBUS.pt
self.cp_ext = self.cp
else:
self.ext_bus = CANBUS.cam
self.cp_ext = self.cp_cam
@staticmethod
def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None):
ret = CarInterfaceBase.get_std_params(candidate, fingerprint)
ret.carName = "volkswagen"
ret.radarOffCan = True
if True: # pylint: disable=using-constant-test
# Set global MQB parameters
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.volkswagen)]
ret.enableBsm = 0x30F in fingerprint[0] # SWA_01
# Disable the radar and let openpilot control longitudinal
# WARNING: THIS DISABLES FACTORY FCW/AEB!
if Params().get_bool("DisableRadar"):
ret.pcmCruise = False
ret.openpilotLongitudinalControl = True
ret.directAccelControl = True
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_VOLKSWAGEN_LONGITUDINAL
if 0xAD in fingerprint[0]: # Getriebe_11
ret.transmissionType = TransmissionType.automatic
elif 0x187 in fingerprint[0]: # EV_Gearshift
ret.transmissionType = TransmissionType.direct
else:
ret.transmissionType = TransmissionType.manual
if any(msg in fingerprint[1] for msg in [0x40, 0x86, 0xB2, 0xFD]): # Airbag_01, LWI_01, ESP_19, ESP_21
ret.networkLocation = NetworkLocation.gateway
else:
ret.networkLocation = NetworkLocation.fwdCamera
# Global lateral tuning defaults, can be overridden per-vehicle
ret.steerActuatorDelay = 0.05
ret.steerRateCost = 1.0
ret.steerLimitTimer = 0.4
ret.steerRatio = 15.6 # Let the params learner figure this out
tire_stiffness_factor = 1.0 # Let the params learner figure this out
ret.lateralTuning.pid.kpBP = [0.]
ret.lateralTuning.pid.kiBP = [0.]
ret.lateralTuning.pid.kf = 0.00006
ret.lateralTuning.pid.kpV = [0.6]
ret.lateralTuning.pid.kiV = [0.2]
# Global longitudinal tuning defaults, can be overridden per-vehicle
ret.longitudinalActuatorDelayUpperBound = 1.0 # s
ret.minSpeedCan = 0.0
ret.stoppingControl = True
ret.vEgoStopping = 1.0
ret.stopAccel = 0.0
ret.startAccel = 0.0
ret.longitudinalTuning.kpV = [0.1]
ret.longitudinalTuning.kiV = [0.0]
# Per-chassis tuning values, override tuning defaults here if desired
if candidate == CAR.ARTEON_MK1:
ret.mass = 1733 + STD_CARGO_KG
ret.wheelbase = 2.84
elif candidate == CAR.ATLAS_MK1:
ret.mass = 2011 + STD_CARGO_KG
ret.wheelbase = 2.98
elif candidate == CAR.GOLF_MK7:
ret.mass = 1397 + STD_CARGO_KG
ret.wheelbase = 2.62
elif candidate == CAR.JETTA_MK7:
ret.mass = 1328 + STD_CARGO_KG
ret.wheelbase = 2.71
elif candidate == CAR.PASSAT_MK8:
ret.mass = 1551 + STD_CARGO_KG
ret.wheelbase = 2.79
elif candidate == CAR.POLO_MK6:
ret.mass = 1230 + STD_CARGO_KG
ret.wheelbase = 2.55
elif candidate == CAR.TAOS_MK1:
ret.mass = 1498 + STD_CARGO_KG
ret.wheelbase = 2.69
elif candidate == CAR.TCROSS_MK1:
ret.mass = 1150 + STD_CARGO_KG
ret.wheelbase = 2.60
elif candidate == CAR.TIGUAN_MK2:
ret.mass = 1715 + STD_CARGO_KG
ret.wheelbase = 2.74
elif candidate == CAR.TOURAN_MK2:
ret.mass = 1516 + STD_CARGO_KG
ret.wheelbase = 2.79
elif candidate == CAR.TRANSPORTER_T61:
ret.mass = 1926 + STD_CARGO_KG
ret.wheelbase = 3.00 # SWB, LWB is 3.40, TBD how to detect difference
ret.minSteerSpeed = 14.0
elif candidate == CAR.AUDI_A3_MK3:
ret.mass = 1335 + STD_CARGO_KG
ret.wheelbase = 2.61
elif candidate == CAR.AUDI_Q2_MK1:
ret.mass = 1205 + STD_CARGO_KG
ret.wheelbase = 2.61
elif candidate == CAR.SEAT_ATECA_MK1:
ret.mass = 1900 + STD_CARGO_KG
ret.wheelbase = 2.64
elif candidate == CAR.SEAT_LEON_MK3:
ret.mass = 1227 + STD_CARGO_KG
ret.wheelbase = 2.64
elif candidate == CAR.SKODA_KAMIQ_MK1:
ret.mass = 1265 + STD_CARGO_KG
ret.wheelbase = 2.66
elif candidate == CAR.SKODA_KAROQ_MK1:
ret.mass = 1278 + STD_CARGO_KG
ret.wheelbase = 2.66
elif candidate == CAR.SKODA_KODIAQ_MK1:
ret.mass = 1569 + STD_CARGO_KG
ret.wheelbase = 2.79
elif candidate == CAR.SKODA_OCTAVIA_MK3:
ret.mass = 1388 + STD_CARGO_KG
ret.wheelbase = 2.68
elif candidate == CAR.SKODA_SCALA_MK1:
ret.mass = 1192 + STD_CARGO_KG
ret.wheelbase = 2.65
elif candidate == CAR.SKODA_SUPERB_MK3:
ret.mass = 1505 + STD_CARGO_KG
ret.wheelbase = 2.84
else:
raise ValueError("unsupported car %s" % candidate)
ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase)
ret.centerToFront = ret.wheelbase * 0.45
ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront,
tire_stiffness_factor=tire_stiffness_factor)
return ret
# returns a car.CarState
def update(self, c, can_strings):
buttonEvents = []
# Process the most recent CAN message traffic, and check for validity
# The camera CAN has no signals we use at this time, but we process it
# anyway so we can test connectivity with can_valid
self.cp.update_strings(can_strings)
self.cp_cam.update_strings(can_strings)
ret = self.CS.update(self.cp, self.cp_cam, self.cp_ext, self.CP.transmissionType)
ret.canValid = self.cp.can_valid and self.cp_cam.can_valid
ret.steeringRateLimited = self.CC.steer_rate_limited if self.CC is not None else False
# TODO: add a field for this to carState, car interface code shouldn't write params
# Update the device metric configuration to match the car at first startup,
# or if there's been a change.
#if self.CS.displayMetricUnits != self.displayMetricUnitsPrev:
# put_nonblocking("IsMetric", "1" if self.CS.displayMetricUnits else "0")
# Check for and process state-change events (button press or release) from
# the turn stalk switch or ACC steering wheel/control stalk buttons.
for button in self.CS.buttonStates:
if self.CS.buttonStates[button] != self.buttonStatesPrev[button]:
be = car.CarState.ButtonEvent.new_message()
be.type = button
be.pressed = self.CS.buttonStates[button]
buttonEvents.append(be)
events = self.create_common_events(ret, extra_gears=[GearShifter.eco, GearShifter.sport, GearShifter.manumatic],
pcm_enable=not self.CS.CP.openpilotLongitudinalControl)
# Vehicle health and operation safety checks
if self.CS.parkingBrakeSet:
events.add(EventName.parkBrake)
if self.CS.tsk_status in [6, 7]:
events.add(EventName.accFaulted)
# Low speed steer alert hysteresis logic
if self.CP.minSteerSpeed > 0. and ret.vEgo < (self.CP.minSteerSpeed + 1.):
self.low_speed_alert = True
elif ret.vEgo > (self.CP.minSteerSpeed + 2.):
self.low_speed_alert = False
if self.low_speed_alert:
events.add(EventName.belowSteerSpeed)
if self.CS.CP.openpilotLongitudinalControl:
for b in buttonEvents:
# do enable on falling edge of both accel and decel buttons
if b.type in [ButtonType.setCruise, ButtonType.resumeCruise] and not b.pressed:
events.add(EventName.buttonEnable)
# do disable on rising edge of cancel
if b.type == "cancel" and b.pressed:
events.add(EventName.buttonCancel)
ret.events = events.to_msg()
ret.buttonEvents = buttonEvents
# update previous car states
self.displayMetricUnitsPrev = self.CS.displayMetricUnits
self.buttonStatesPrev = self.CS.buttonStates.copy()
self.CS.out = ret.as_reader()
return self.CS.out
def apply(self, c):
can_sends = self.CC.update(c.enabled, self.CS, self.frame, self.ext_bus, c.actuators,
c.hudControl.visualAlert,
c.hudControl.leftLaneVisible,
c.hudControl.rightLaneVisible,
c.hudControl.leftLaneDepart,
c.hudControl.rightLaneDepart,
c.hudControl.leadVisible,
c.hudControl.setSpeed)
self.frame += 1
return can_sends