Tesla AP2 port (#20074)

* squashed the PR

* remove AP passthrough

* disengage on steer override

* bump panda

* add test routes

* bump panda

* tesla is still dashcam only

* dashcam only

* rerun CI

* add to release files
pull/21385/head
robbederks 4 years ago committed by GitHub
parent 7e6a9ce9a5
commit cdfba105ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      panda
  2. 9
      release/files_common
  3. 0
      selfdrive/car/tesla/__init__.py
  4. 53
      selfdrive/car/tesla/carcontroller.py
  5. 181
      selfdrive/car/tesla/carstate.py
  6. 62
      selfdrive/car/tesla/interface.py
  7. 5
      selfdrive/car/tesla/radar_interface.py
  8. 41
      selfdrive/car/tesla/teslacan.py
  9. 53
      selfdrive/car/tesla/values.py
  10. 3
      selfdrive/test/process_replay/test_processes.py
  11. 3
      selfdrive/test/test_routes.py

@ -1 +1 @@
Subproject commit d7b3ae02824fe67f88ee408e0d7540c1ec5bceab Subproject commit d8385413c3ecc59799f0909c7384f385a71c4431

@ -170,6 +170,13 @@ selfdrive/car/mazda/radar_interface.py
selfdrive/car/mazda/values.py selfdrive/car/mazda/values.py
selfdrive/car/mazda/carcontroller.py selfdrive/car/mazda/carcontroller.py
selfdrive/car/mazda/mazdacan.py selfdrive/car/mazda/mazdacan.py
selfdrive/car/tesla/__init__.py
selfdrive/car/tesla/teslacan.py
selfdrive/car/tesla/carcontroller.py
selfdrive/car/tesla/radar_interface.py
selfdrive/car/tesla/values.py
selfdrive/car/tesla/carstate.py
selfdrive/car/tesla/interface.py
selfdrive/car/mock/*.py selfdrive/car/mock/*.py
selfdrive/clocksd/.gitignore selfdrive/clocksd/.gitignore
@ -611,3 +618,5 @@ opendbc/toyota_adas.dbc
opendbc/toyota_tss2_adas.dbc opendbc/toyota_tss2_adas.dbc
opendbc/vw_mqb_2010.dbc opendbc/vw_mqb_2010.dbc
opendbc/tesla_can.dbc

@ -0,0 +1,53 @@
from common.numpy_fast import clip, interp
from selfdrive.car.tesla.teslacan import TeslaCAN
from opendbc.can.packer import CANPacker
from selfdrive.car.tesla.values import CANBUS, CarControllerParams
class CarController():
def __init__(self, dbc_name, CP, VM):
self.CP = CP
self.last_angle = 0
self.packer = CANPacker(dbc_name)
self.tesla_can = TeslaCAN(dbc_name, self.packer)
def update(self, enabled, CS, frame, actuators, cruise_cancel):
can_sends = []
# Temp disable steering on a hands_on_fault, and allow for user override
hands_on_fault = (CS.steer_warning == "EAC_ERROR_HANDS_ON" and CS.hands_on_level >= 3)
lkas_enabled = enabled and (not hands_on_fault)
if lkas_enabled:
apply_angle = actuators.steeringAngleDeg
# Angular rate limit based on speed
steer_up = (self.last_angle * apply_angle > 0. and abs(apply_angle) > abs(self.last_angle))
rate_limit = CarControllerParams.RATE_LIMIT_UP if steer_up else CarControllerParams.RATE_LIMIT_DOWN
max_angle_diff = interp(CS.out.vEgo, rate_limit.speed_points, rate_limit.max_angle_diff_points)
apply_angle = clip(apply_angle, (self.last_angle - max_angle_diff), (self.last_angle + max_angle_diff))
# To not fault the EPS
apply_angle = clip(apply_angle, (CS.out.steeringAngleDeg - 20), (CS.out.steeringAngleDeg + 20))
else:
apply_angle = CS.out.steeringAngleDeg
self.last_angle = apply_angle
can_sends.append(self.tesla_can.create_steering_control(apply_angle, lkas_enabled, frame))
# Cancel on user steering override, since there is no steering torque blending
if hands_on_fault:
cruise_cancel = True
# Cancel when openpilot is not enabled anymore
if not enabled and bool(CS.out.cruiseState.enabled):
cruise_cancel = True
if ((frame % 10) == 0 and cruise_cancel):
# Spam every possible counter value, otherwise it might not be accepted
for counter in range(16):
can_sends.append(self.tesla_can.create_action_request(CS.msg_stw_actn_req, cruise_cancel, CANBUS.chassis, counter))
can_sends.append(self.tesla_can.create_action_request(CS.msg_stw_actn_req, cruise_cancel, CANBUS.autopilot, counter))
# TODO: HUD control
return can_sends

@ -0,0 +1,181 @@
import copy
from cereal import car
from selfdrive.car.tesla.values import DBC, CANBUS, GEAR_MAP, DOORS, BUTTONS
from selfdrive.car.interfaces import CarStateBase
from opendbc.can.parser import CANParser
from opendbc.can.can_define import CANDefine
from selfdrive.config import Conversions as CV
class CarState(CarStateBase):
def __init__(self, CP):
super().__init__(CP)
self.button_states = {button.event_type: False for button in BUTTONS}
self.can_define = CANDefine(DBC[CP.carFingerprint]['chassis'])
# Needed by carcontroller
self.msg_stw_actn_req = None
self.hands_on_level = 0
self.steer_warning = None
def update(self, cp, cp_cam):
ret = car.CarState.new_message()
# Vehicle speed
ret.vEgoRaw = cp.vl["ESP_B"]["ESP_vehicleSpeed"] * CV.KPH_TO_MS
ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw)
ret.standstill = (ret.vEgo < 0.1)
# Gas pedal
ret.gas = cp.vl["DI_torque1"]["DI_pedalPos"] / 100.0
ret.gasPressed = (ret.gas > 0)
# Brake pedal
ret.brake = 0
ret.brakePressed = bool(cp.vl["BrakeMessage"]["driverBrakeStatus"] != 1)
# Steering wheel
self.hands_on_level = cp.vl["EPAS_sysStatus"]["EPAS_handsOnLevel"]
self.steer_warning = self.can_define.dv["EPAS_sysStatus"]["EPAS_eacErrorCode"].get(int(cp.vl["EPAS_sysStatus"]["EPAS_eacErrorCode"]), None)
steer_status = self.can_define.dv["EPAS_sysStatus"]["EPAS_eacStatus"].get(int(cp.vl["EPAS_sysStatus"]["EPAS_eacStatus"]), None)
ret.steeringAngleDeg = -cp.vl["EPAS_sysStatus"]["EPAS_internalSAS"]
ret.steeringRateDeg = -cp.vl["STW_ANGLHP_STAT"]["StW_AnglHP_Spd"] # This is from a different angle sensor, and at different rate
ret.steeringTorque = -cp.vl["EPAS_sysStatus"]["EPAS_torsionBarTorque"]
ret.steeringPressed = (self.hands_on_level > 0)
ret.steerError = steer_status in ["EAC_FAULT", "EAC_INHIBITED"]
ret.steerWarning = self.steer_warning in ["EAC_ERROR_MAX_SPEED", "EAC_ERROR_MIN_SPEED", "EAC_ERROR_TMP_FAULT", "SNA"] # TODO: not sure if this list is complete
# Cruise state
cruise_state = self.can_define.dv["DI_state"]["DI_cruiseState"].get(int(cp.vl["DI_state"]["DI_cruiseState"]), None)
speed_units = self.can_define.dv["DI_state"]["DI_speedUnits"].get(int(cp.vl["DI_state"]["DI_speedUnits"]), None)
acc_enabled = (cruise_state in ["ENABLED", "STANDSTILL", "OVERRIDE", "PRE_FAULT", "PRE_CANCEL"])
ret.cruiseState.enabled = acc_enabled
if speed_units == "KPH":
ret.cruiseState.speed = cp.vl["DI_state"]["DI_digitalSpeed"] * CV.KPH_TO_MS
elif speed_units == "MPH":
ret.cruiseState.speed = cp.vl["DI_state"]["DI_digitalSpeed"] * CV.MPH_TO_MS
ret.cruiseState.available = ((cruise_state == "STANDBY") or ret.cruiseState.enabled)
ret.cruiseState.standstill = (cruise_state == "STANDSTILL")
# Gear
ret.gearShifter = GEAR_MAP[self.can_define.dv["DI_torque2"]["DI_gear"].get(int(cp.vl["DI_torque2"]["DI_gear"]), "DI_GEAR_INVALID")]
# Buttons
buttonEvents = []
for button in BUTTONS:
state = (cp.vl[button.can_addr][button.can_msg] in button.values)
if self.button_states[button.event_type] != state:
event = car.CarState.ButtonEvent.new_message()
event.type = button.event_type
event.pressed = state
buttonEvents.append(event)
self.button_states[button.event_type] = state
ret.buttonEvents = buttonEvents
# Doors
ret.doorOpen = any([(self.can_define.dv["GTW_carState"][door].get(int(cp.vl["GTW_carState"][door]), "OPEN") == "OPEN") for door in DOORS])
# Blinkers
ret.leftBlinker = (cp.vl["GTW_carState"]["BC_indicatorLStatus"] == 1)
ret.rightBlinker = (cp.vl["GTW_carState"]["BC_indicatorRStatus"] == 1)
# Seatbelt
ret.seatbeltUnlatched = (cp.vl["SDM1"]["SDM_bcklDrivStatus"] != 1)
# TODO: blindspot
# Messages needed by carcontroller
self.msg_stw_actn_req = copy.copy(cp.vl["STW_ACTN_RQ"])
return ret
@staticmethod
def get_can_parser(CP):
signals = [
# sig_name, sig_address, default
("ESP_vehicleSpeed", "ESP_B", 0),
("DI_pedalPos", "DI_torque1", 0),
("DI_brakePedal", "DI_torque2", 0),
("StW_AnglHP", "STW_ANGLHP_STAT", 0),
("StW_AnglHP_Spd", "STW_ANGLHP_STAT", 0),
("EPAS_handsOnLevel", "EPAS_sysStatus", 0),
("EPAS_torsionBarTorque", "EPAS_sysStatus", 0),
("EPAS_internalSAS", "EPAS_sysStatus", 0),
("EPAS_eacStatus", "EPAS_sysStatus", 1),
("EPAS_eacErrorCode", "EPAS_sysStatus", 0),
("DI_cruiseState", "DI_state", 0),
("DI_digitalSpeed", "DI_state", 0),
("DI_speedUnits", "DI_state", 0),
("DI_gear", "DI_torque2", 0),
("DOOR_STATE_FL", "GTW_carState", 1),
("DOOR_STATE_FR", "GTW_carState", 1),
("DOOR_STATE_RL", "GTW_carState", 1),
("DOOR_STATE_RR", "GTW_carState", 1),
("DOOR_STATE_FrontTrunk", "GTW_carState", 1),
("BOOT_STATE", "GTW_carState", 1),
("BC_indicatorLStatus", "GTW_carState", 1),
("BC_indicatorRStatus", "GTW_carState", 1),
("SDM_bcklDrivStatus", "SDM1", 0),
("driverBrakeStatus", "BrakeMessage", 0),
# We copy this whole message when spamming cancel
("SpdCtrlLvr_Stat", "STW_ACTN_RQ", 0),
("VSL_Enbl_Rq", "STW_ACTN_RQ", 0),
("SpdCtrlLvrStat_Inv", "STW_ACTN_RQ", 0),
("DTR_Dist_Rq", "STW_ACTN_RQ", 0),
("TurnIndLvr_Stat", "STW_ACTN_RQ", 0),
("HiBmLvr_Stat", "STW_ACTN_RQ", 0),
("WprWashSw_Psd", "STW_ACTN_RQ", 0),
("WprWash_R_Sw_Posn_V2", "STW_ACTN_RQ", 0),
("StW_Lvr_Stat", "STW_ACTN_RQ", 0),
("StW_Cond_Flt", "STW_ACTN_RQ", 0),
("StW_Cond_Psd", "STW_ACTN_RQ", 0),
("HrnSw_Psd", "STW_ACTN_RQ", 0),
("StW_Sw00_Psd", "STW_ACTN_RQ", 0),
("StW_Sw01_Psd", "STW_ACTN_RQ", 0),
("StW_Sw02_Psd", "STW_ACTN_RQ", 0),
("StW_Sw03_Psd", "STW_ACTN_RQ", 0),
("StW_Sw04_Psd", "STW_ACTN_RQ", 0),
("StW_Sw05_Psd", "STW_ACTN_RQ", 0),
("StW_Sw06_Psd", "STW_ACTN_RQ", 0),
("StW_Sw07_Psd", "STW_ACTN_RQ", 0),
("StW_Sw08_Psd", "STW_ACTN_RQ", 0),
("StW_Sw09_Psd", "STW_ACTN_RQ", 0),
("StW_Sw10_Psd", "STW_ACTN_RQ", 0),
("StW_Sw11_Psd", "STW_ACTN_RQ", 0),
("StW_Sw12_Psd", "STW_ACTN_RQ", 0),
("StW_Sw13_Psd", "STW_ACTN_RQ", 0),
("StW_Sw14_Psd", "STW_ACTN_RQ", 0),
("StW_Sw15_Psd", "STW_ACTN_RQ", 0),
("WprSw6Posn", "STW_ACTN_RQ", 0),
("MC_STW_ACTN_RQ", "STW_ACTN_RQ", 0),
("CRC_STW_ACTN_RQ", "STW_ACTN_RQ", 0),
]
checks = [
# sig_address, frequency
("ESP_B", 50),
("DI_torque1", 100),
("DI_torque2", 100),
("STW_ANGLHP_STAT", 100),
("EPAS_sysStatus", 25),
("DI_state", 10),
("STW_ACTN_RQ", 10),
("GTW_carState", 10),
("SDM1", 10),
("BrakeMessage", 50),
]
return CANParser(DBC[CP.carFingerprint]['chassis'], signals, checks, CANBUS.chassis)
@staticmethod
def get_cam_can_parser(CP):
signals = [
# sig_name, sig_address, default
]
checks = [
# sig_address, frequency
]
return CANParser(DBC[CP.carFingerprint]['chassis'], signals, checks, CANBUS.autopilot)

@ -0,0 +1,62 @@
#!/usr/bin/env python3
from cereal import car
from selfdrive.car.tesla.values import CAR
from selfdrive.car import STD_CARGO_KG, gen_empty_fingerprint, scale_rot_inertia, scale_tire_stiffness
from selfdrive.car.interfaces import CarInterfaceBase
class CarInterface(CarInterfaceBase):
@staticmethod
def compute_gb(accel, speed):
# TODO: is this correct?
return accel
@staticmethod
def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None):
ret = CarInterfaceBase.get_std_params(candidate, fingerprint)
ret.carName = "tesla"
ret.safetyModel = car.CarParams.SafetyModel.tesla
# There is no safe way to do steer blending with user torque,
# so the steering behaves like autopilot. This is not
# how openpilot should be, hence dashcamOnly
ret.dashcamOnly = True
ret.steerControlType = car.CarParams.SteerControlType.angle
ret.enableCamera = True
ret.openpilotLongitudinalControl = False
ret.communityFeature = True
ret.steerActuatorDelay = 0.1
ret.steerRateCost = 0.5
if candidate == CAR.AP2_MODELS:
ret.mass = 2100. + STD_CARGO_KG
ret.wheelbase = 2.959
ret.centerToFront = ret.wheelbase * 0.5
ret.steerRatio = 13.5
else:
raise ValueError(f"Unsupported car: {candidate}")
ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase)
ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront)
return ret
def update(self, c, can_strings):
self.cp.update_strings(can_strings)
self.cp_cam.update_strings(can_strings)
ret = self.CS.update(self.cp, self.cp_cam)
ret.canValid = self.cp.can_valid and self.cp_cam.can_valid
events = self.create_common_events(ret)
ret.events = events.to_msg()
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, c.actuators, c.cruiseControl.cancel)
self.frame += 1
return can_sends

@ -0,0 +1,5 @@
#!/usr/bin/env python3
from selfdrive.car.interfaces import RadarInterfaceBase
class RadarInterface(RadarInterfaceBase):
pass

@ -0,0 +1,41 @@
import copy
import crcmod
from opendbc.can.can_define import CANDefine
from selfdrive.car.tesla.values import CANBUS
class TeslaCAN:
def __init__(self, dbc_name, packer):
self.can_define = CANDefine(dbc_name)
self.packer = packer
self.crc = crcmod.mkCrcFun(0x11d, initCrc=0x00, rev=False, xorOut=0xff)
@staticmethod
def checksum(msg_id, dat):
# TODO: get message ID from name instead
ret = (msg_id & 0xFF) + ((msg_id >> 8) & 0xFF)
ret += sum(dat)
return ret & 0xFF
def create_steering_control(self, angle, enabled, frame):
values = {
"DAS_steeringAngleRequest": -angle,
"DAS_steeringHapticRequest": 0,
"DAS_steeringControlType": 1 if enabled else 0,
"DAS_steeringControlCounter": (frame % 16),
}
data = self.packer.make_can_msg("DAS_steeringControl", CANBUS.chassis, values)[2]
values["DAS_steeringControlChecksum"] = self.checksum(0x488, data[:3])
return self.packer.make_can_msg("DAS_steeringControl", CANBUS.chassis, values)
def create_action_request(self, msg_stw_actn_req, cancel, bus, counter):
values = copy.copy(msg_stw_actn_req)
if cancel:
values["SpdCtrlLvr_Stat"] = 1
values["MC_STW_ACTN_RQ"] = counter
data = self.packer.make_can_msg("STW_ACTN_RQ", bus, values)[2]
values["CRC_STW_ACTN_RQ"] = self.crc(data[:7])
return self.packer.make_can_msg("STW_ACTN_RQ", bus, values)

@ -0,0 +1,53 @@
# flake8: noqa
from collections import namedtuple
from selfdrive.car import dbc_dict
from cereal import car
Button = namedtuple('Button', ['event_type', 'can_addr', 'can_msg', 'values'])
AngleRateLimit = namedtuple('AngleRateLimit', ['speed_points', 'max_angle_diff_points'])
class CAR:
AP2_MODELS = 'TESLA AP2 MODEL S'
FINGERPRINTS = {
CAR.AP2_MODELS: [
{
1: 8, 3: 8, 14: 8, 21: 4, 69: 8, 109: 4, 257: 3, 264: 8, 277: 6, 280: 6, 293: 4, 296: 4, 309: 5, 325: 8, 328: 5, 336: 8, 341: 8, 360: 7, 373: 8, 389: 8, 415: 8, 513: 5, 516: 8, 518: 8, 520: 4, 522: 8, 524: 8, 526: 8, 532: 3, 536: 8, 537: 3, 542: 8, 551: 5, 552: 2, 556: 8, 558: 8, 568: 8, 569: 8, 574: 8, 577: 8, 582: 5, 583: 8, 584: 4, 585: 8, 590: 8, 601: 8, 606: 8, 608: 1, 622: 8, 627: 6, 638: 8, 641: 8, 643: 8, 692: 8, 693: 8, 695: 8, 696: 8, 697: 8, 699: 8, 700: 8, 701: 8, 702: 8, 703: 8, 704: 8, 708: 8, 709: 8, 710: 8, 711: 8, 712: 8, 728: 8, 744: 8, 760: 8, 772: 8, 775: 8, 776: 8, 777: 8, 778: 8, 782: 8, 788: 8, 791: 8, 792: 8, 796: 2, 797: 8, 798: 6, 799: 8, 804: 8, 805: 8, 807: 8, 808: 1, 811: 8, 812: 8, 813: 8, 814: 5, 815: 8, 820: 8, 823: 8, 824: 8, 829: 8, 830: 5, 836: 8, 840: 8, 845: 8, 846: 5, 848: 8, 852: 8, 853: 8, 856: 4, 857: 6, 861: 8, 862: 5, 872: 8, 876: 8, 877: 8, 879: 8, 880: 8, 882: 8, 884: 8, 888: 8, 893: 8, 894: 8, 901: 6, 904: 3, 905: 8, 906: 8, 908: 2, 909: 8, 910: 8, 912: 8, 920: 8, 921: 8, 925: 4, 926: 6, 936: 8, 941: 8, 949: 8, 952: 8, 953: 6, 968: 8, 969: 6, 970: 8, 971: 8, 977: 8, 984: 8, 987: 8, 990: 8, 1000: 8, 1001: 8, 1006: 8, 1007: 8, 1008: 8, 1010: 6, 1014: 1, 1015: 8, 1016: 8, 1017: 8, 1018: 8, 1020: 8, 1026: 8, 1028: 8, 1029: 8, 1030: 8, 1032: 1, 1033: 1, 1034: 8, 1048: 1, 1049: 8, 1061: 8, 1064: 8, 1065: 8, 1070: 8, 1080: 8, 1081: 8, 1097: 8, 1113: 8, 1129: 8, 1145: 8, 1160: 4, 1177: 8, 1281: 8, 1328: 8, 1329: 8, 1332: 8, 1335: 8, 1337: 8, 1353: 8, 1368: 8, 1412: 8, 1436: 8, 1476: 8, 1481: 8, 1497: 8, 1513: 8, 1519: 8, 1601: 8, 1605: 8, 1617: 8, 1621: 8, 1800: 4, 1804: 8, 1812: 8, 1815: 8, 1816: 8, 1824: 8, 1828: 8, 1831: 8, 1832: 8, 1864: 8, 1880: 8, 1892: 8, 1896: 8, 1912: 8, 1960: 8, 1992: 8, 2008: 3, 2043: 5, 2045: 4
},
],
}
DBC = {
CAR.AP2_MODELS: dbc_dict(None, 'tesla_radar', chassis_dbc='tesla_can'),
}
class CANBUS:
chassis = 0
autopilot = 2
radar = 1
GEAR_MAP = {
"DI_GEAR_INVALID": car.CarState.GearShifter.unknown,
"DI_GEAR_P": car.CarState.GearShifter.park,
"DI_GEAR_R": car.CarState.GearShifter.reverse,
"DI_GEAR_N": car.CarState.GearShifter.neutral,
"DI_GEAR_D": car.CarState.GearShifter.drive,
"DI_GEAR_SNA": car.CarState.GearShifter.unknown,
}
DOORS = ["DOOR_STATE_FL", "DOOR_STATE_FR", "DOOR_STATE_RL", "DOOR_STATE_RR", "DOOR_STATE_FrontTrunk", "BOOT_STATE"]
# Make sure the message and addr is also in the CAN parser!
BUTTONS = [
Button(car.CarState.ButtonEvent.Type.leftBlinker, "STW_ACTN_RQ", "TurnIndLvr_Stat", [1]),
Button(car.CarState.ButtonEvent.Type.rightBlinker, "STW_ACTN_RQ", "TurnIndLvr_Stat", [2]),
Button(car.CarState.ButtonEvent.Type.accelCruise, "STW_ACTN_RQ", "SpdCtrlLvr_Stat", [4, 16]),
Button(car.CarState.ButtonEvent.Type.decelCruise, "STW_ACTN_RQ", "SpdCtrlLvr_Stat", [8, 32]),
Button(car.CarState.ButtonEvent.Type.cancel, "STW_ACTN_RQ", "SpdCtrlLvr_Stat", [2]),
Button(car.CarState.ButtonEvent.Type.resumeCruise, "STW_ACTN_RQ", "SpdCtrlLvr_Stat", [1]),
]
class CarControllerParams:
RATE_LIMIT_UP = AngleRateLimit(speed_points=[0., 5., 15.], max_angle_diff_points=[5., .8, .15])
RATE_LIMIT_DOWN = AngleRateLimit(speed_points=[0., 5., 15.], max_angle_diff_points=[5., 3.5, 0.4])

@ -25,10 +25,11 @@ segments = [
# Enable when port is tested and dascamOnly is no longer set # Enable when port is tested and dascamOnly is no longer set
#("MAZDA", "32a319f057902bb3|2020-04-27--15-18-58--2"), # MAZDA.CX5 #("MAZDA", "32a319f057902bb3|2020-04-27--15-18-58--2"), # MAZDA.CX5
#("TESLA", "bb50caf5f0945ab1|2021-06-19--17-20-18--3"), # TESLA.AP2_MODELS
] ]
# dashcamOnly makes don't need to be tested until a full port is done # dashcamOnly makes don't need to be tested until a full port is done
excluded_interfaces = ["mock", "ford", "mazda"] excluded_interfaces = ["mock", "ford", "mazda", "tesla"]
BASE_URL = "https://commadataci.blob.core.windows.net/openpilotci/" BASE_URL = "https://commadataci.blob.core.windows.net/openpilotci/"

@ -11,6 +11,7 @@ from selfdrive.car.mazda.values import CAR as MAZDA
from selfdrive.car.subaru.values import CAR as SUBARU from selfdrive.car.subaru.values import CAR as SUBARU
from selfdrive.car.toyota.values import CAR as TOYOTA from selfdrive.car.toyota.values import CAR as TOYOTA
from selfdrive.car.volkswagen.values import CAR as VOLKSWAGEN from selfdrive.car.volkswagen.values import CAR as VOLKSWAGEN
from selfdrive.car.tesla.values import CAR as TESLA
# TODO: add routes for these cars # TODO: add routes for these cars
non_tested_cars = [ non_tested_cars = [
@ -164,6 +165,8 @@ routes = [
TestRoute("10b5a4b380434151|2020-08-26--17-11-45", MAZDA.CX9), TestRoute("10b5a4b380434151|2020-08-26--17-11-45", MAZDA.CX9),
TestRoute("74f1038827005090|2020-08-26--20-05-50", MAZDA.MAZDA3), TestRoute("74f1038827005090|2020-08-26--20-05-50", MAZDA.MAZDA3),
TestRoute("fb53c640f499b73d|2021-06-01--04-17-56", MAZDA.MAZDA6), TestRoute("fb53c640f499b73d|2021-06-01--04-17-56", MAZDA.MAZDA6),
TestRoute("bb50caf5f0945ab1|2021-06-19--17-20-18", TESLA.AP2_MODELS),
] ]
forced_dashcam_routes = [ forced_dashcam_routes = [

Loading…
Cancel
Save