from cereal import car 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 from selfdrive.car.interfaces import CarInterfaceBase 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.communityFeature = True ret.radarOffCan = True if True: # pylint: disable=using-constant-test # Set global MQB parameters ret.safetyModel = car.CarParams.SafetyModel.volkswagen ret.enableBsm = 0x30F in fingerprint[0] # SWA_01 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]): # Airbag_01, LWI_01, ESP_19 ret.networkLocation = NetworkLocation.gateway else: ret.networkLocation = NetworkLocation.fwdCamera # Global 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] # Per-chassis tuning values, override tuning defaults here if desired if 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.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.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_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 # TODO: get actual value, for now starting with reasonable value for # civic and scaling by mass and wheelbase ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase) # TODO: start from empirically derived lateral slip stiffness for the civic and scale by # mass and CG position, so all cars will have approximately similar dyn behaviors 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]) # Vehicle health and operation safety checks if self.CS.parkingBrakeSet: events.add(EventName.parkBrake) 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) self.frame += 1 return can_sends