wip
This commit is contained in:
@@ -3,15 +3,18 @@ from openpilot.common.numpy_fast import clip, interp
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.selfdrive.car import apply_meas_steer_torque_limits, apply_std_steer_angle_limits, common_fault_avoidance, \
|
||||
create_gas_interceptor_command, make_can_msg
|
||||
from openpilot.selfdrive.car.interfaces import CarControllerBase
|
||||
from openpilot.selfdrive.car.toyota import toyotacan
|
||||
from openpilot.selfdrive.car.toyota.values import CAR, STATIC_DSU_MSGS, NO_STOP_TIMER_CAR, TSS2_CAR, \
|
||||
MIN_ACC_SPEED, PEDAL_TRANSITION, CarControllerParams, ToyotaFlags, \
|
||||
UNSUPPORTED_DSU_CAR, STOP_AND_GO_CAR
|
||||
from opendbc.can.packer import CANPacker
|
||||
|
||||
from openpilot.selfdrive.frogpilot.controls.lib.frogpilot_functions import CRUISING_SPEED
|
||||
|
||||
LongCtrlState = car.CarControl.Actuators.LongControlState
|
||||
SteerControlType = car.CarParams.SteerControlType
|
||||
VisualAlert = car.CarControl.HUDControl.VisualAlert
|
||||
LongCtrlState = car.CarControl.Actuators.LongControlState
|
||||
|
||||
# LKA limits
|
||||
# EPS faults if you apply torque while the steering rate is above 100 deg/s for too long
|
||||
@@ -35,10 +38,21 @@ COMPENSATORY_CALCULATION_THRESHOLD_BP = [0., 11., 23.] # m/s
|
||||
# Lock / unlock door commands - Credit goes to AlexandreSato!
|
||||
LOCK_CMD = b'\x40\x05\x30\x11\x00\x80\x00\x00'
|
||||
UNLOCK_CMD = b'\x40\x05\x30\x11\x00\x40\x00\x00'
|
||||
|
||||
PARK = car.CarState.GearShifter.park
|
||||
|
||||
|
||||
class CarController:
|
||||
def compute_gb_toyota(accel, speed):
|
||||
creep_brake = 0.0
|
||||
creep_speed = 2.3
|
||||
creep_brake_value = 0.15
|
||||
if speed < creep_speed:
|
||||
creep_brake = (creep_speed - speed) / creep_speed * creep_brake_value
|
||||
gb = accel - creep_brake
|
||||
return gb
|
||||
|
||||
|
||||
class CarController(CarControllerBase):
|
||||
def __init__(self, dbc_name, CP, VM):
|
||||
self.CP = CP
|
||||
self.params = CarControllerParams(self.CP)
|
||||
@@ -47,9 +61,10 @@ class CarController:
|
||||
self.last_angle = 0
|
||||
self.alert_active = False
|
||||
self.last_standstill = False
|
||||
self.prohibit_neg_calculation = True
|
||||
self.standstill_req = False
|
||||
self.steer_rate_counter = 0
|
||||
self.prohibit_neg_calculation = True
|
||||
self.distance_button = 0
|
||||
|
||||
self.packer = CANPacker(dbc_name)
|
||||
self.gas = 0
|
||||
@@ -64,6 +79,8 @@ class CarController:
|
||||
self.doors_locked = False
|
||||
self.doors_unlocked = True
|
||||
|
||||
self.pcm_accel_comp = 0
|
||||
|
||||
def update(self, CC, CS, now_nanos, frogpilot_variables):
|
||||
actuators = CC.actuators
|
||||
hud_control = CC.hudControl
|
||||
@@ -136,34 +153,56 @@ class CarController:
|
||||
pedal_offset = interp(CS.out.vEgo, [0.0, 2.3, MIN_ACC_SPEED + PEDAL_TRANSITION], [-.4, 0.0, 0.2])
|
||||
pedal_command = PEDAL_SCALE * (actuators.accel + pedal_offset)
|
||||
interceptor_gas_cmd = clip(pedal_command, 0., MAX_INTERCEPTOR_GAS)
|
||||
elif self.CP.enableGasInterceptor and CC.longActive and self.CP.carFingerprint in STOP_AND_GO_CAR and actuators.accel > 0.0 \
|
||||
and CS.out.standstill:
|
||||
interceptor_gas_cmd = 0.12
|
||||
elif self.CP.enableGasInterceptor and CC.longActive and self.CP.carFingerprint in STOP_AND_GO_CAR and actuators.accel > 0.0:
|
||||
interceptor_gas_cmd = 0.12 if CS.out.standstill else 0.
|
||||
else:
|
||||
interceptor_gas_cmd = 0.
|
||||
|
||||
# prohibit negative compensatory calculations when first activating long after accelerator depression or engagement
|
||||
if not CC.longActive:
|
||||
self.prohibit_neg_calculation = True
|
||||
|
||||
comp_thresh = interp(CS.out.vEgo, COMPENSATORY_CALCULATION_THRESHOLD_BP, COMPENSATORY_CALCULATION_THRESHOLD_V)
|
||||
# don't reset until a reasonable compensatory value is reached
|
||||
if CS.pcm_neutral_force > comp_thresh * self.CP.mass:
|
||||
self.prohibit_neg_calculation = False
|
||||
# NO_STOP_TIMER_CAR will creep if compensation is applied when stopping or stopped, don't compensate when stopped or stopping
|
||||
should_compensate = True
|
||||
if (self.CP.carFingerprint in NO_STOP_TIMER_CAR and actuators.accel < 1e-3 or stopping) or CS.out.vEgo < 1e-3:
|
||||
should_compensate = False
|
||||
|
||||
# limit minimum to only positive until first positive is reached after engagement, don't calculate when long isn't active
|
||||
if CC.longActive and should_compensate and not self.prohibit_neg_calculation and (self.cydia_tune or self.frogs_go_moo_tune):
|
||||
if CC.longActive and not self.prohibit_neg_calculation and (self.cydia_tune or self.frogs_go_moo_tune):
|
||||
accel_offset = CS.pcm_neutral_force / self.CP.mass
|
||||
else:
|
||||
accel_offset = 0.
|
||||
|
||||
# only calculate pcm_accel_cmd when long is active to prevent disengagement from accelerator depression
|
||||
if CC.longActive:
|
||||
if frogpilot_variables.sport_plus:
|
||||
pcm_accel_cmd = clip(actuators.accel + accel_offset, self.params.ACCEL_MIN, self.params.ACCEL_MAX_PLUS)
|
||||
if self.frogs_go_moo_tune:
|
||||
wind_brake = interp(CS.out.vEgo, [0.0, 2.3, 35.0], [0.001, 0.002, 0.15])
|
||||
|
||||
gas_accel = compute_gb_toyota(actuators.accel, CS.out.vEgo) + wind_brake
|
||||
self.pcm_accel_comp = clip(gas_accel - CS.pcm_accel_net, self.pcm_accel_comp - 0.03, self.pcm_accel_comp + 0.03)
|
||||
pcm_accel_cmd = gas_accel + self.pcm_accel_comp
|
||||
|
||||
if not CC.longActive:
|
||||
pcm_accel_cmd = 0.0
|
||||
|
||||
pcm_accel_cmd = clip(pcm_accel_cmd, self.params.ACCEL_MIN, self.params.ACCEL_MAX_PLUS)
|
||||
else:
|
||||
pcm_accel_cmd = clip(actuators.accel + accel_offset, self.params.ACCEL_MIN, self.params.ACCEL_MAX_PLUS)
|
||||
else:
|
||||
pcm_accel_cmd = clip(actuators.accel + accel_offset, self.params.ACCEL_MIN, self.params.ACCEL_MAX)
|
||||
if self.frogs_go_moo_tune:
|
||||
wind_brake = interp(CS.out.vEgo, [0.0, 2.3, 35.0], [0.001, 0.002, 0.15])
|
||||
|
||||
gas_accel = compute_gb_toyota(actuators.accel, CS.out.vEgo) + wind_brake
|
||||
self.pcm_accel_comp = clip(gas_accel - CS.pcm_accel_net, self.pcm_accel_comp - 0.03, self.pcm_accel_comp + 0.03)
|
||||
pcm_accel_cmd = gas_accel + self.pcm_accel_comp
|
||||
|
||||
if not CC.longActive:
|
||||
pcm_accel_cmd = 0.0
|
||||
|
||||
pcm_accel_cmd = clip(pcm_accel_cmd, self.params.ACCEL_MIN, self.params.ACCEL_MAX)
|
||||
else:
|
||||
pcm_accel_cmd = clip(actuators.accel + accel_offset, self.params.ACCEL_MIN, self.params.ACCEL_MAX)
|
||||
else:
|
||||
pcm_accel_cmd = 0.
|
||||
|
||||
@@ -191,16 +230,23 @@ class CarController:
|
||||
# when stopping, send -2.5 raw acceleration immediately to prevent vehicle from creeping, else send actuators.accel
|
||||
accel_raw = -2.5 if stopping and (self.cydia_tune or self.frogs_go_moo_tune) else actuators.accel
|
||||
|
||||
# Press distance button until we are at the correct bar length. Only change while enabled to avoid skipping startup popup
|
||||
if self.frame % 6 == 0 and self.CP.openpilotLongitudinalControl:
|
||||
desired_distance = 4 - hud_control.leadDistanceBars
|
||||
if CS.out.cruiseState.enabled and CS.pcm_follow_distance != desired_distance:
|
||||
self.distance_button = not self.distance_button
|
||||
else:
|
||||
self.distance_button = 0
|
||||
|
||||
# Lexus IS uses a different cancellation message
|
||||
if pcm_cancel_cmd and self.CP.carFingerprint in UNSUPPORTED_DSU_CAR:
|
||||
can_sends.append(toyotacan.create_acc_cancel_command(self.packer))
|
||||
elif self.CP.openpilotLongitudinalControl:
|
||||
can_sends.append(toyotacan.create_accel_command(self.packer, pcm_accel_cmd, accel_raw, pcm_cancel_cmd, self.standstill_req, lead, CS.acc_type, fcw_alert,
|
||||
CS.distance_button, frogpilot_variables))
|
||||
self.distance_button, frogpilot_variables))
|
||||
self.accel = pcm_accel_cmd
|
||||
else:
|
||||
can_sends.append(toyotacan.create_accel_command(self.packer, 0, 0, pcm_cancel_cmd, False, lead, CS.acc_type, False,
|
||||
CS.distance_button, frogpilot_variables))
|
||||
can_sends.append(toyotacan.create_accel_command(self.packer, 0, 0, pcm_cancel_cmd, False, lead, CS.acc_type, False, self.distance_button, frogpilot_variables))
|
||||
|
||||
if self.frame % 2 == 0 and self.CP.enableGasInterceptor and self.CP.openpilotLongitudinalControl:
|
||||
# send exactly zero if gas cmd is zero. Interceptor will send the max between read value and gas cmd.
|
||||
@@ -247,15 +293,17 @@ class CarController:
|
||||
new_actuators.gas = self.gas
|
||||
|
||||
# Lock doors when in drive / unlock doors when in park
|
||||
if frogpilot_variables.lock_doors:
|
||||
if self.doors_unlocked and CS.out.gearShifter != PARK:
|
||||
if self.doors_unlocked and CS.out.gearShifter != PARK and CS.out.vEgo >= CRUISING_SPEED:
|
||||
if frogpilot_variables.lock_doors:
|
||||
can_sends.append(make_can_msg(0x750, LOCK_CMD, 0))
|
||||
self.doors_locked = True
|
||||
self.doors_unlocked = False
|
||||
elif self.doors_locked and CS.out.gearShifter == PARK:
|
||||
self.doors_locked = True
|
||||
self.doors_unlocked = False
|
||||
|
||||
elif self.doors_locked and CS.out.gearShifter == PARK:
|
||||
if frogpilot_variables.unlock_doors:
|
||||
can_sends.append(make_can_msg(0x750, UNLOCK_CMD, 0))
|
||||
self.doors_locked = False
|
||||
self.doors_unlocked = True
|
||||
self.doors_locked = False
|
||||
self.doors_unlocked = True
|
||||
|
||||
self.frame += 1
|
||||
return new_actuators, can_sends
|
||||
|
||||
@@ -10,9 +10,6 @@ from opendbc.can.parser import CANParser
|
||||
from openpilot.selfdrive.car.interfaces import CarStateBase
|
||||
from openpilot.selfdrive.car.toyota.values import ToyotaFlags, CAR, DBC, STEER_THRESHOLD, NO_STOP_TIMER_CAR, \
|
||||
TSS2_CAR, RADAR_ACC_CAR, EPS_SCALE, UNSUPPORTED_DSU_CAR
|
||||
from openpilot.selfdrive.controls.lib.drive_helpers import CRUISE_LONG_PRESS
|
||||
|
||||
from openpilot.selfdrive.frogpilot.functions.speed_limit_controller import SpeedLimitController
|
||||
|
||||
SteerControlType = car.CarParams.SteerControlType
|
||||
|
||||
@@ -45,19 +42,38 @@ class CarState(CarStateBase):
|
||||
self.accurate_steer_angle_seen = False
|
||||
self.angle_offset = FirstOrderFilter(None, 60.0, DT_CTRL, initialized=False)
|
||||
|
||||
self.prev_distance_button = 0
|
||||
self.distance_button = 0
|
||||
|
||||
self.pcm_follow_distance = 0
|
||||
|
||||
self.low_speed_lockout = False
|
||||
self.acc_type = 1
|
||||
self.lkas_hud = {}
|
||||
|
||||
# FrogPilot variables
|
||||
self.profile_restored = False
|
||||
self.zss_compute = False
|
||||
self.zss_cruise_active_last = False
|
||||
|
||||
self.pcm_accel_net = 0.0
|
||||
self.pcm_neutral_force = 0.0
|
||||
self.zss_angle_offset = 0
|
||||
self.zss_threshold_count = 0
|
||||
|
||||
self.traffic_signals = {}
|
||||
# Traffic signals for Speed Limit Controller - Credit goes to the DragonPilot team!
|
||||
def calculate_speed_limit(self, cp_cam, frogpilot_variables):
|
||||
signals = ["TSGN1", "SPDVAL1", "SPLSGN1", "TSGN2", "SPLSGN2", "TSGN3", "SPLSGN3", "TSGN4", "SPLSGN4"]
|
||||
traffic_signals = {signal: cp_cam.vl["RSA1"].get(signal, cp_cam.vl["RSA2"].get(signal)) for signal in signals}
|
||||
|
||||
tsgn1 = traffic_signals.get("TSGN1", None)
|
||||
spdval1 = traffic_signals.get("SPDVAL1", None)
|
||||
|
||||
if tsgn1 == 1 and not frogpilot_variables.force_mph_dashboard:
|
||||
return spdval1 * CV.KPH_TO_MS
|
||||
elif tsgn1 == 36 or frogpilot_variables.force_mph_dashboard:
|
||||
return spdval1 * CV.MPH_TO_MS
|
||||
else:
|
||||
return 0
|
||||
|
||||
def update(self, cp, cp_cam, frogpilot_variables):
|
||||
ret = car.CarState.new_message()
|
||||
@@ -182,88 +198,37 @@ class CarState(CarStateBase):
|
||||
if self.CP.carFingerprint != CAR.PRIUS_V:
|
||||
self.lkas_hud = copy.copy(cp_cam.vl["LKAS_HUD"])
|
||||
|
||||
# FrogPilot functions
|
||||
|
||||
# Switch the current state of Experimental Mode if the LKAS button is double pressed
|
||||
if frogpilot_variables.experimental_mode_via_lkas and ret.cruiseState.available and self.CP.carFingerprint != CAR.PRIUS_V:
|
||||
message_keys = ["LDA_ON_MESSAGE", "SET_ME_X02"]
|
||||
lkas_pressed = any(self.lkas_hud.get(key) == 1 for key in message_keys)
|
||||
|
||||
if lkas_pressed and not self.lkas_previously_pressed:
|
||||
if frogpilot_variables.conditional_experimental_mode:
|
||||
self.fpf.update_cestatus_lkas()
|
||||
else:
|
||||
self.fpf.update_experimental_mode()
|
||||
|
||||
self.lkas_previously_pressed = lkas_pressed
|
||||
|
||||
if self.CP.carFingerprint not in UNSUPPORTED_DSU_CAR:
|
||||
# Need to subtract by 1 to comply with the personality profiles of "0", "1", and "2"
|
||||
self.personality_profile = cp.vl["PCM_CRUISE_SM"]["DISTANCE_LINES"] - 1
|
||||
self.pcm_follow_distance = cp.vl["PCM_CRUISE_2"]["PCM_FOLLOW_DISTANCE"]
|
||||
|
||||
if self.CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR) or self.CP.flags & ToyotaFlags.SMART_DSU:
|
||||
if self.CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR) or (self.CP.flags & ToyotaFlags.SMART_DSU and not self.CP.flags & ToyotaFlags.RADAR_CAN_FILTER):
|
||||
# distance button is wired to the ACC module (camera or radar)
|
||||
self.prev_distance_button = self.distance_button
|
||||
if self.CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR):
|
||||
distance_pressed = cp_acc.vl["ACC_CONTROL"]["DISTANCE"]
|
||||
self.distance_button = cp_acc.vl["ACC_CONTROL"]["DISTANCE"]
|
||||
else:
|
||||
distance_pressed = cp.vl["SDSU"]["FD_BUTTON"]
|
||||
else:
|
||||
distance_pressed = False
|
||||
self.distance_button = cp.vl["SDSU"]["FD_BUTTON"]
|
||||
|
||||
# Distance button functions
|
||||
if ret.cruiseState.available:
|
||||
if distance_pressed:
|
||||
self.distance_pressed_counter += 1
|
||||
elif self.distance_previously_pressed:
|
||||
# Set the distance lines on the dash to match the new personality if the button was held down for less than 0.5 seconds
|
||||
if self.distance_pressed_counter < CRUISE_LONG_PRESS:
|
||||
self.previous_personality_profile = (self.personality_profile + 2) % 3
|
||||
self.fpf.distance_button_function(self.previous_personality_profile)
|
||||
self.profile_restored = False
|
||||
self.distance_pressed_counter = 0
|
||||
if self.CP.carFingerprint != CAR.PRIUS_V:
|
||||
self.lkas_previously_enabled = self.lkas_enabled
|
||||
message_keys = ["LDA_ON_MESSAGE", "SET_ME_X02"]
|
||||
self.lkas_enabled = any(self.lkas_hud.get(key) == 1 for key in message_keys)
|
||||
|
||||
# Switch the current state of Experimental Mode if the button is held down for 0.5 seconds
|
||||
if self.distance_pressed_counter == CRUISE_LONG_PRESS and frogpilot_variables.experimental_mode_via_distance:
|
||||
if frogpilot_variables.conditional_experimental_mode:
|
||||
self.fpf.update_cestatus_distance()
|
||||
else:
|
||||
self.fpf.update_experimental_mode()
|
||||
self.params_memory.put_float("CarSpeedLimit", self.calculate_speed_limit(cp_cam, frogpilot_variables))
|
||||
|
||||
# Switch the current state of Traffic Mode if the button is held down for 2.5 seconds
|
||||
if self.distance_pressed_counter == CRUISE_LONG_PRESS * 5 and frogpilot_variables.traffic_mode:
|
||||
self.fpf.update_traffic_mode()
|
||||
self.cruise_decreased_previously = self.cruise_decreased
|
||||
self.cruise_increased_previously = self.cruise_increased
|
||||
|
||||
# Revert the previous changes to Experimental Mode
|
||||
if frogpilot_variables.experimental_mode_via_distance:
|
||||
if frogpilot_variables.conditional_experimental_mode:
|
||||
self.fpf.update_cestatus_distance()
|
||||
else:
|
||||
self.fpf.update_experimental_mode()
|
||||
self.cruise_decreased = self.pcm_acc_status == 10
|
||||
self.cruise_increased = self.pcm_acc_status == 9
|
||||
|
||||
self.distance_previously_pressed = distance_pressed
|
||||
|
||||
# Update the distance lines on the dash upon ignition/onroad UI button clicked
|
||||
if frogpilot_variables.personalities_via_wheel and ret.cruiseState.available:
|
||||
# Sync with the onroad UI button
|
||||
if self.fpf.personality_changed_via_ui:
|
||||
self.profile_restored = False
|
||||
self.previous_personality_profile = self.fpf.current_personality
|
||||
self.fpf.reset_personality_changed_param()
|
||||
|
||||
# Set personality to the previous drive's personality or when the user changes it via the UI
|
||||
if self.personality_profile == self.previous_personality_profile:
|
||||
self.profile_restored = True
|
||||
if not self.profile_restored:
|
||||
self.distance_button = not self.distance_button
|
||||
|
||||
# Traffic signals for Speed Limit Controller - Credit goes to the DragonPilot team!
|
||||
self.update_traffic_signals(cp_cam)
|
||||
SpeedLimitController.car_speed_limit = self.calculate_speed_limit(frogpilot_variables)
|
||||
SpeedLimitController.write_car_state()
|
||||
self.pcm_accel_net = cp.vl["PCM_CRUISE"]["ACCEL_NET"]
|
||||
self.pcm_neutral_force = cp.vl["PCM_CRUISE"]["NEUTRAL_FORCE"]
|
||||
|
||||
# ZSS Support - Credit goes to the DragonPilot team!
|
||||
if self.CP.flags & ToyotaFlags.ZSS and self.zss_threshold_count < ZSS_THRESHOLD_COUNT:
|
||||
zorro_steer = cp.vl["SECONDARY_STEER_ANGLE"]["ZORRO_STEER"]
|
||||
|
||||
# Only compute ZSS offset when acc is active
|
||||
zss_cruise_active = ret.cruiseState.available
|
||||
if zss_cruise_active and not self.zss_cruise_active_last:
|
||||
@@ -287,24 +252,6 @@ class CarState(CarStateBase):
|
||||
|
||||
return ret
|
||||
|
||||
def update_traffic_signals(self, cp_cam):
|
||||
signals = ["TSGN1", "SPDVAL1", "SPLSGN1", "TSGN2", "SPLSGN2", "TSGN3", "SPLSGN3", "TSGN4", "SPLSGN4"]
|
||||
new_values = {signal: cp_cam.vl["RSA1"].get(signal, cp_cam.vl["RSA2"].get(signal)) for signal in signals}
|
||||
|
||||
if new_values != self.traffic_signals:
|
||||
self.traffic_signals.update(new_values)
|
||||
|
||||
def calculate_speed_limit(self, frogpilot_variables):
|
||||
tsgn1 = self.traffic_signals.get("TSGN1", None)
|
||||
spdval1 = self.traffic_signals.get("SPDVAL1", None)
|
||||
|
||||
if tsgn1 == 1 and not frogpilot_variables.force_mph_dashboard:
|
||||
return spdval1 * CV.KPH_TO_MS
|
||||
elif tsgn1 == 36 or frogpilot_variables.force_mph_dashboard:
|
||||
return spdval1 * CV.MPH_TO_MS
|
||||
else:
|
||||
return 0
|
||||
|
||||
@staticmethod
|
||||
def get_can_parser(CP):
|
||||
messages = [
|
||||
@@ -353,7 +300,7 @@ class CarState(CarStateBase):
|
||||
("PRE_COLLISION", 33),
|
||||
]
|
||||
|
||||
if CP.flags & ToyotaFlags.SMART_DSU:
|
||||
if CP.flags & ToyotaFlags.SMART_DSU and not CP.flags & ToyotaFlags.RADAR_CAN_FILTER:
|
||||
messages += [
|
||||
("SDSU", 100),
|
||||
]
|
||||
|
||||
@@ -573,6 +573,7 @@ FW_VERSIONS = {
|
||||
b'\x018821F6201400\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.fwdCamera, 0x750, 0x6d): [
|
||||
b'\x028646F12010C0\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00',
|
||||
b'\x028646F12010D0\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00',
|
||||
b'\x028646F1201100\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00',
|
||||
b'\x028646F1201200\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00',
|
||||
@@ -638,6 +639,7 @@ FW_VERSIONS = {
|
||||
(Ecu.dsu, 0x791, None): [
|
||||
b'881510E01100\x00\x00\x00\x00',
|
||||
b'881510E01200\x00\x00\x00\x00',
|
||||
b'881510E02200\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x750, 0xf): [
|
||||
b'8821F4702100\x00\x00\x00\x00',
|
||||
@@ -685,6 +687,7 @@ FW_VERSIONS = {
|
||||
b'\x01896630EB1000\x00\x00\x00\x00',
|
||||
b'\x01896630EB1100\x00\x00\x00\x00',
|
||||
b'\x01896630EB1200\x00\x00\x00\x00',
|
||||
b'\x01896630EB1300\x00\x00\x00\x00',
|
||||
b'\x01896630EB2000\x00\x00\x00\x00',
|
||||
b'\x01896630EB2100\x00\x00\x00\x00',
|
||||
b'\x01896630EB2200\x00\x00\x00\x00',
|
||||
@@ -771,16 +774,22 @@ FW_VERSIONS = {
|
||||
b'\x018966353S1000\x00\x00\x00\x00',
|
||||
b'\x018966353S2000\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.engine, 0x7e0, None): [
|
||||
b'\x02353U0000\x00\x00\x00\x00\x00\x00\x00\x0052422000\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.abs, 0x7b0, None): [
|
||||
b'\x01F15265337200\x00\x00\x00\x00',
|
||||
b'\x01F15265342000\x00\x00\x00\x00',
|
||||
b'\x01F15265343000\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.eps, 0x7a1, None): [
|
||||
b'8965B53450\x00\x00\x00\x00\x00\x00',
|
||||
b'8965B53800\x00\x00\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x750, 0xf): [
|
||||
b'\x018821F6201200\x00\x00\x00\x00',
|
||||
b'\x018821F6201300\x00\x00\x00\x00',
|
||||
b'\x018821F6201400\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.fwdCamera, 0x750, 0x6d): [
|
||||
b'\x028646F5303300\x00\x00\x00\x008646G5301200\x00\x00\x00\x00',
|
||||
@@ -843,6 +852,7 @@ FW_VERSIONS = {
|
||||
b'8965B47023\x00\x00\x00\x00\x00\x00',
|
||||
b'8965B47050\x00\x00\x00\x00\x00\x00',
|
||||
b'8965B47060\x00\x00\x00\x00\x00\x00',
|
||||
b'8965B47070\x00\x00\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.abs, 0x7b0, None): [
|
||||
b'F152647290\x00\x00\x00\x00\x00\x00',
|
||||
@@ -1024,6 +1034,7 @@ FW_VERSIONS = {
|
||||
b'\x02896634A13000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
b'\x02896634A13001\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00',
|
||||
b'\x02896634A13101\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00',
|
||||
b'\x02896634A13201\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00',
|
||||
b'\x02896634A14001\x00\x00\x00\x00897CF1203001\x00\x00\x00\x00',
|
||||
b'\x02896634A14001\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00',
|
||||
b'\x02896634A14101\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00',
|
||||
@@ -1132,6 +1143,7 @@ FW_VERSIONS = {
|
||||
b'\x01F15264283300\x00\x00\x00\x00',
|
||||
b'\x01F152642F1000\x00\x00\x00\x00',
|
||||
b'\x01F152642F8000\x00\x00\x00\x00',
|
||||
b'\x01F152642F8100\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.eps, 0x7a1, None): [
|
||||
b'\x028965B0R11000\x00\x00\x00\x008965B0R12000\x00\x00\x00\x00',
|
||||
@@ -1144,6 +1156,7 @@ FW_VERSIONS = {
|
||||
b'\x01896634AF0000\x00\x00\x00\x00',
|
||||
b'\x01896634AJ2000\x00\x00\x00\x00',
|
||||
b'\x01896634AL5000\x00\x00\x00\x00',
|
||||
b'\x01896634AL6000\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x750, 0xf): [
|
||||
b'\x018821F0R03100\x00\x00\x00\x00',
|
||||
@@ -1263,6 +1276,7 @@ FW_VERSIONS = {
|
||||
},
|
||||
CAR.LEXUS_ES: {
|
||||
(Ecu.engine, 0x7e0, None): [
|
||||
b'\x02333M4100\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
b'\x02333M4200\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
b'\x02333R0000\x00\x00\x00\x00\x00\x00\x00\x00A0C01000\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
],
|
||||
@@ -1533,6 +1547,7 @@ FW_VERSIONS = {
|
||||
b'\x018966348W5100\x00\x00\x00\x00',
|
||||
b'\x018966348W9000\x00\x00\x00\x00',
|
||||
b'\x018966348X0000\x00\x00\x00\x00',
|
||||
b'\x01896634D11000\x00\x00\x00\x00',
|
||||
b'\x01896634D12000\x00\x00\x00\x00',
|
||||
b'\x01896634D12100\x00\x00\x00\x00',
|
||||
b'\x01896634D43000\x00\x00\x00\x00',
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
from cereal import car
|
||||
from openpilot.common.conversions import Conversions as CV
|
||||
from cereal import car, custom
|
||||
from panda import Panda
|
||||
from panda.python import uds
|
||||
from openpilot.selfdrive.car.toyota.values import Ecu, CAR, DBC, ToyotaFlags, CarControllerParams, TSS2_CAR, RADAR_ACC_CAR, NO_DSU_CAR, \
|
||||
MIN_ACC_SPEED, EPS_SCALE, UNSUPPORTED_DSU_CAR, NO_STOP_TIMER_CAR, ANGLE_CONTROL_CAR, STOP_AND_GO_CAR
|
||||
from openpilot.selfdrive.car import get_safety_config
|
||||
from openpilot.selfdrive.car import create_button_events, get_safety_config
|
||||
from openpilot.selfdrive.car.disable_ecu import disable_ecu
|
||||
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
|
||||
|
||||
ButtonType = car.CarState.ButtonEvent.Type
|
||||
EventName = car.CarEvent.EventName
|
||||
SteerControlType = car.CarParams.SteerControlType
|
||||
FrogPilotButtonType = custom.FrogPilotCarState.ButtonEvent.Type
|
||||
|
||||
|
||||
class CarInterface(CarInterfaceBase):
|
||||
@@ -21,7 +22,7 @@ class CarInterface(CarInterfaceBase):
|
||||
return CarControllerParams.ACCEL_MIN, CarControllerParams.ACCEL_MAX
|
||||
|
||||
@staticmethod
|
||||
def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs):
|
||||
def _get_params(ret, params, candidate, fingerprint, car_fw, disable_openpilot_long, experimental_long, docs):
|
||||
ret.carName = "toyota"
|
||||
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.toyota)]
|
||||
ret.safetyConfigs[0].safetyParam = EPS_SCALE[candidate]
|
||||
@@ -48,8 +49,6 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
ret.stoppingControl = False # Toyota starts braking more when it thinks you want to stop
|
||||
|
||||
stop_and_go = candidate in TSS2_CAR
|
||||
|
||||
# Detect smartDSU, which intercepts ACC_CMD from the DSU (or radar) allowing openpilot to send it
|
||||
# 0x2AA is sent by a similar device which intercepts the radar instead of DSU on NO_DSU_CARs
|
||||
if 0x2FF in fingerprint[0] or (0x2AA in fingerprint[0] and candidate in NO_DSU_CAR):
|
||||
@@ -58,74 +57,22 @@ class CarInterface(CarInterfaceBase):
|
||||
if 0x2AA in fingerprint[0] and candidate in NO_DSU_CAR:
|
||||
ret.flags |= ToyotaFlags.RADAR_CAN_FILTER.value
|
||||
|
||||
# In TSS2 cars, the camera does long control
|
||||
found_ecus = [fw.ecu for fw in car_fw]
|
||||
ret.enableDsu = len(found_ecus) > 0 and Ecu.dsu not in found_ecus and candidate not in (NO_DSU_CAR | UNSUPPORTED_DSU_CAR) \
|
||||
and not (ret.flags & ToyotaFlags.SMART_DSU)
|
||||
|
||||
if candidate == CAR.PRIUS:
|
||||
ret.wheelbase = 2.70
|
||||
ret.steerRatio = 15.74 # unknown end-to-end spec
|
||||
ret.tireStiffnessFactor = 0.6371 # hand-tune
|
||||
ret.mass = 3045. * CV.LB_TO_KG
|
||||
# Only give steer angle deadzone to for bad angle sensor prius
|
||||
for fw in car_fw:
|
||||
if fw.ecu == "eps" and not fw.fwVersion == b'8965B47060\x00\x00\x00\x00\x00\x00':
|
||||
ret.steerActuatorDelay = 0.25
|
||||
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning, steering_angle_deadzone_deg=0.2)
|
||||
|
||||
elif candidate == CAR.PRIUS_V:
|
||||
ret.wheelbase = 2.78
|
||||
ret.steerRatio = 17.4
|
||||
ret.tireStiffnessFactor = 0.5533
|
||||
ret.mass = 3340. * CV.LB_TO_KG
|
||||
|
||||
elif candidate in (CAR.RAV4, CAR.RAV4H):
|
||||
ret.wheelbase = 2.65
|
||||
ret.steerRatio = 16.88 # 14.5 is spec end-to-end
|
||||
ret.tireStiffnessFactor = 0.5533
|
||||
ret.mass = 3650. * CV.LB_TO_KG # mean between normal and hybrid
|
||||
|
||||
elif candidate == CAR.COROLLA:
|
||||
ret.wheelbase = 2.70
|
||||
ret.steerRatio = 18.27
|
||||
ret.tireStiffnessFactor = 0.444 # not optimized yet
|
||||
ret.mass = 2860. * CV.LB_TO_KG # mean between normal and hybrid
|
||||
|
||||
elif candidate in (CAR.LEXUS_RX, CAR.LEXUS_RX_TSS2):
|
||||
ret.wheelbase = 2.79
|
||||
ret.steerRatio = 16. # 14.8 is spec end-to-end
|
||||
ret.wheelSpeedFactor = 1.035
|
||||
ret.tireStiffnessFactor = 0.5533
|
||||
ret.mass = 4481. * CV.LB_TO_KG # mean between min and max
|
||||
|
||||
elif candidate in (CAR.CHR, CAR.CHR_TSS2):
|
||||
ret.wheelbase = 2.63906
|
||||
ret.steerRatio = 13.6
|
||||
ret.tireStiffnessFactor = 0.7933
|
||||
ret.mass = 3300. * CV.LB_TO_KG
|
||||
|
||||
elif candidate in (CAR.CAMRY, CAR.CAMRY_TSS2):
|
||||
ret.wheelbase = 2.82448
|
||||
ret.steerRatio = 13.7
|
||||
ret.tireStiffnessFactor = 0.7933
|
||||
ret.mass = 3400. * CV.LB_TO_KG # mean between normal and hybrid
|
||||
|
||||
elif candidate in (CAR.HIGHLANDER, CAR.HIGHLANDER_TSS2):
|
||||
# TODO: TSS-P models can do stop and go, but unclear if it requires sDSU or unplugging DSU
|
||||
ret.wheelbase = 2.8194 # average of 109.8 and 112.2 in
|
||||
ret.steerRatio = 16.0
|
||||
ret.tireStiffnessFactor = 0.8
|
||||
ret.mass = 4516. * CV.LB_TO_KG # mean between normal and hybrid
|
||||
|
||||
elif candidate in (CAR.AVALON, CAR.AVALON_2019, CAR.AVALON_TSS2):
|
||||
# starting from 2019, all Avalon variants have stop and go
|
||||
# https://engage.toyota.com/static/images/toyota_safety_sense/TSS_Applicability_Chart.pdf
|
||||
ret.wheelbase = 2.82
|
||||
ret.steerRatio = 14.8 # Found at https://pressroom.toyota.com/releases/2016+avalon+product+specs.download
|
||||
ret.tireStiffnessFactor = 0.7983
|
||||
ret.mass = 3505. * CV.LB_TO_KG # mean between normal and hybrid
|
||||
|
||||
elif candidate in (CAR.RAV4_TSS2, CAR.RAV4_TSS2_2022, CAR.RAV4_TSS2_2023):
|
||||
ret.wheelbase = 2.68986
|
||||
ret.steerRatio = 14.3
|
||||
ret.tireStiffnessFactor = 0.7933
|
||||
ret.mass = 3585. * CV.LB_TO_KG # Average between ICE and Hybrid
|
||||
ret.lateralTuning.init('pid')
|
||||
ret.lateralTuning.pid.kiBP = [0.0]
|
||||
ret.lateralTuning.pid.kpBP = [0.0]
|
||||
@@ -142,92 +89,16 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.lateralTuning.pid.kf = 0.00004
|
||||
break
|
||||
|
||||
elif candidate == CAR.COROLLA_TSS2:
|
||||
ret.wheelbase = 2.67 # Average between 2.70 for sedan and 2.64 for hatchback
|
||||
ret.steerRatio = 13.9
|
||||
ret.tireStiffnessFactor = 0.444 # not optimized yet
|
||||
ret.mass = 3060. * CV.LB_TO_KG
|
||||
|
||||
elif candidate in (CAR.LEXUS_ES, CAR.LEXUS_ES_TSS2):
|
||||
ret.wheelbase = 2.8702
|
||||
ret.steerRatio = 16.0 # not optimized
|
||||
ret.tireStiffnessFactor = 0.444 # not optimized yet
|
||||
ret.mass = 3677. * CV.LB_TO_KG # mean between min and max
|
||||
|
||||
elif candidate == CAR.SIENNA:
|
||||
ret.wheelbase = 3.03
|
||||
ret.steerRatio = 15.5
|
||||
ret.tireStiffnessFactor = 0.444
|
||||
ret.mass = 4590. * CV.LB_TO_KG
|
||||
|
||||
elif candidate in (CAR.LEXUS_IS, CAR.LEXUS_IS_TSS2, CAR.LEXUS_RC):
|
||||
ret.wheelbase = 2.79908
|
||||
ret.steerRatio = 13.3
|
||||
ret.tireStiffnessFactor = 0.444
|
||||
ret.mass = 3736.8 * CV.LB_TO_KG
|
||||
|
||||
elif candidate == CAR.LEXUS_GS_F:
|
||||
ret.wheelbase = 2.84988
|
||||
ret.steerRatio = 13.3
|
||||
ret.tireStiffnessFactor = 0.444
|
||||
ret.mass = 4034. * CV.LB_TO_KG
|
||||
|
||||
elif candidate == CAR.LEXUS_CTH:
|
||||
ret.wheelbase = 2.60
|
||||
ret.steerRatio = 18.6
|
||||
ret.tireStiffnessFactor = 0.517
|
||||
ret.mass = 3108 * CV.LB_TO_KG # mean between min and max
|
||||
|
||||
elif candidate in (CAR.LEXUS_NX, CAR.LEXUS_NX_TSS2):
|
||||
ret.wheelbase = 2.66
|
||||
ret.steerRatio = 14.7
|
||||
ret.tireStiffnessFactor = 0.444 # not optimized yet
|
||||
ret.mass = 4070 * CV.LB_TO_KG
|
||||
|
||||
elif candidate == CAR.LEXUS_LC_TSS2:
|
||||
ret.wheelbase = 2.87
|
||||
ret.steerRatio = 13.0
|
||||
ret.tireStiffnessFactor = 0.444 # not optimized yet
|
||||
ret.mass = 4500 * CV.LB_TO_KG
|
||||
|
||||
elif candidate == CAR.PRIUS_TSS2:
|
||||
ret.wheelbase = 2.70002 # from toyota online sepc.
|
||||
ret.steerRatio = 13.4 # True steerRatio from older prius
|
||||
ret.tireStiffnessFactor = 0.6371 # hand-tune
|
||||
ret.mass = 3115. * CV.LB_TO_KG
|
||||
|
||||
elif candidate == CAR.MIRAI:
|
||||
ret.wheelbase = 2.91
|
||||
ret.steerRatio = 14.8
|
||||
ret.tireStiffnessFactor = 0.8
|
||||
ret.mass = 4300. * CV.LB_TO_KG
|
||||
|
||||
elif candidate == CAR.ALPHARD_TSS2:
|
||||
ret.wheelbase = 3.00
|
||||
ret.steerRatio = 14.2
|
||||
ret.tireStiffnessFactor = 0.444
|
||||
ret.mass = 4305. * CV.LB_TO_KG
|
||||
|
||||
ret.centerToFront = ret.wheelbase * 0.44
|
||||
|
||||
# TODO: Some TSS-P platforms have BSM, but are flipped based on region or driving direction.
|
||||
# Detect flipped signals and enable for C-HR and others
|
||||
ret.enableBsm = 0x3F6 in fingerprint[0] and candidate in TSS2_CAR
|
||||
|
||||
# Detect smartDSU, which intercepts ACC_CMD from the DSU (or radar) allowing openpilot to send it
|
||||
# 0x2AA is sent by a similar device which intercepts the radar instead of DSU on NO_DSU_CARs
|
||||
if 0x2FF in fingerprint[0] or (0x2AA in fingerprint[0] and candidate in NO_DSU_CAR):
|
||||
ret.flags |= ToyotaFlags.SMART_DSU.value
|
||||
|
||||
# No radar dbc for cars without DSU which are not TSS 2.0
|
||||
# TODO: make an adas dbc file for dsu-less models
|
||||
ret.radarUnavailable = DBC[candidate]['radar'] is None or candidate in (NO_DSU_CAR - TSS2_CAR)
|
||||
|
||||
# In TSS2 cars, the camera does long control
|
||||
found_ecus = [fw.ecu for fw in car_fw]
|
||||
ret.enableDsu = len(found_ecus) > 0 and Ecu.dsu not in found_ecus and candidate not in (NO_DSU_CAR | UNSUPPORTED_DSU_CAR) \
|
||||
and not (ret.flags & ToyotaFlags.SMART_DSU)
|
||||
|
||||
# if the smartDSU is detected, openpilot can send ACC_CONTROL and the smartDSU will block it from the DSU or radar.
|
||||
# since we don't yet parse radar on TSS2/TSS-P radar-based ACC cars, gate longitudinal behind experimental toggle
|
||||
use_sdsu = bool(ret.flags & ToyotaFlags.SMART_DSU)
|
||||
@@ -250,7 +121,7 @@ class CarInterface(CarInterfaceBase):
|
||||
# - TSS2 radar ACC cars w/o smartDSU installed (disables radar)
|
||||
# - TSS-P DSU-less cars w/ CAN filter installed (no radar parser yet)
|
||||
ret.openpilotLongitudinalControl = use_sdsu or ret.enableDsu or candidate in (TSS2_CAR - RADAR_ACC_CAR) or bool(ret.flags & ToyotaFlags.DISABLE_RADAR.value)
|
||||
ret.openpilotLongitudinalControl &= not params.get_bool("DisableOpenpilotLongitudinal")
|
||||
ret.openpilotLongitudinalControl &= not disable_openpilot_long
|
||||
ret.autoResumeSng = ret.openpilotLongitudinalControl and candidate in NO_STOP_TIMER_CAR
|
||||
ret.enableGasInterceptor = 0x201 in fingerprint[0] and ret.openpilotLongitudinalControl
|
||||
|
||||
@@ -271,35 +142,30 @@ class CarInterface(CarInterfaceBase):
|
||||
# on stock Toyota this is -2.5
|
||||
ret.stopAccel = -2.5
|
||||
tune.deadzoneBP = [0., 16., 20., 30.]
|
||||
tune.deadzoneV = [0., .03, .06, .15]
|
||||
ret.stoppingDecelRate = 0.17 # This is okay for TSS-P
|
||||
if candidate in TSS2_CAR:
|
||||
ret.vEgoStopping = 0.25
|
||||
ret.vEgoStarting = 0.25
|
||||
ret.stoppingDecelRate = 0.009 # reach stopping target smoothly
|
||||
tune.deadzoneV = [.04, .05, .08, .15]
|
||||
ret.stoppingDecelRate = 0.17
|
||||
tune.kpBP = [0., 5.]
|
||||
tune.kpV = [0.8, 1.]
|
||||
tune.kiBP = [0., 5.]
|
||||
tune.kiV = [0.3, 1.]
|
||||
elif params.get_bool("FrogsGoMooTune"):
|
||||
# on stock Toyota this is -2.5
|
||||
ret.stopAccel = -2.5
|
||||
ret.stoppingDecelRate = 0.3 # reach stopping target smoothly
|
||||
|
||||
tune.deadzoneBP = [0., 16., 20., 30.]
|
||||
tune.deadzoneV = [0., .03, .06, .15]
|
||||
tune.kpBP = [0., 5., 20.]
|
||||
tune.kpV = [1.3, 1.0, 0.7]
|
||||
tune.deadzoneV = [0., .03, .06, .15]
|
||||
|
||||
# In MPH = [ 0, 27, 45, 60, 89]
|
||||
tune.kiBP = [ 0., 12., 20., 27., 40.]
|
||||
tune.kiV = [.35, .215, .195, .10, .01]
|
||||
|
||||
if candidate in TSS2_CAR:
|
||||
ret.stopAccel = -2.5
|
||||
ret.stoppingDecelRate = 0.009 # reach stopping target smoothly
|
||||
else:
|
||||
ret.stopAccel = -2.5 # on stock Toyota this is -2.5
|
||||
ret.stoppingDecelRate = 0.3 # This is okay for TSS-P
|
||||
# In MPH = [ 0, 11, 45]
|
||||
tune.kpBP = [0., 5., 20.]
|
||||
tune.kpV = [1.3, 1.0, 0.7]
|
||||
|
||||
ret.vEgoStarting = 0.1
|
||||
ret.vEgoStopping = 0.1
|
||||
ret.vEgoStopping = 0.15 # car is near 0.1 to 0.2 when car starts requesting stopping accel
|
||||
ret.vEgoStarting = 0.15 # needs to be > or == vEgoStopping
|
||||
elif (candidate in TSS2_CAR or ret.enableGasInterceptor) and params.get_bool("DragonPilotTune"):
|
||||
# Credit goes to the DragonPilot team!
|
||||
tune.deadzoneBP = [0., 16., 20., 30.]
|
||||
@@ -342,8 +208,16 @@ class CarInterface(CarInterfaceBase):
|
||||
def _update(self, c, frogpilot_variables):
|
||||
ret = self.CS.update(self.cp, self.cp_cam, frogpilot_variables)
|
||||
|
||||
if self.CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR) or (self.CP.flags & ToyotaFlags.SMART_DSU and not self.CP.flags & ToyotaFlags.RADAR_CAN_FILTER):
|
||||
ret.buttonEvents = [
|
||||
*create_button_events(self.CS.cruise_increased, self.CS.cruise_increased_previously, {1: ButtonType.accelCruise}),
|
||||
*create_button_events(self.CS.cruise_decreased, self.CS.cruise_decreased_previously, {1: ButtonType.decelCruise}),
|
||||
*create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}),
|
||||
*create_button_events(self.CS.lkas_enabled, self.CS.lkas_previously_enabled, {1: FrogPilotButtonType.lkas}),
|
||||
]
|
||||
|
||||
# events
|
||||
events = self.create_common_events(ret, frogpilot_variables)
|
||||
events = self.create_common_events(ret)
|
||||
|
||||
# Lane Tracing Assist control is unavailable (EPS_STATUS->LTA_STATE=0) until
|
||||
# the more accurate angle sensor signal is initialized
|
||||
|
||||
0
selfdrive/car/toyota/tests/__init__.py
Normal file
0
selfdrive/car/toyota/tests/__init__.py
Normal file
35
selfdrive/car/toyota/tests/print_platform_codes.py
Normal file
35
selfdrive/car/toyota/tests/print_platform_codes.py
Normal file
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env python3
|
||||
from collections import defaultdict
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car.toyota.values import PLATFORM_CODE_ECUS, get_platform_codes
|
||||
from openpilot.selfdrive.car.toyota.fingerprints import FW_VERSIONS
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
ECU_NAME = {v: k for k, v in Ecu.schema.enumerants.items()}
|
||||
|
||||
if __name__ == "__main__":
|
||||
parts_for_ecu: dict = defaultdict(set)
|
||||
cars_for_code: dict = defaultdict(lambda: defaultdict(set))
|
||||
for car_model, ecus in FW_VERSIONS.items():
|
||||
print()
|
||||
print(car_model)
|
||||
for ecu in sorted(ecus, key=lambda x: int(x[0])):
|
||||
if ecu[0] not in PLATFORM_CODE_ECUS:
|
||||
continue
|
||||
|
||||
platform_codes = get_platform_codes(ecus[ecu])
|
||||
parts_for_ecu[ecu] |= {code.split(b'-')[0] for code in platform_codes if code.count(b'-') > 1}
|
||||
for code in platform_codes:
|
||||
cars_for_code[ecu][b'-'.join(code.split(b'-')[:2])] |= {car_model}
|
||||
print(f' (Ecu.{ECU_NAME[ecu[0]]}, {hex(ecu[1])}, {ecu[2]}):')
|
||||
print(f' Codes: {platform_codes}')
|
||||
|
||||
print('\nECU parts:')
|
||||
for ecu, parts in parts_for_ecu.items():
|
||||
print(f' (Ecu.{ECU_NAME[ecu[0]]}, {hex(ecu[1])}, {ecu[2]}): {parts}')
|
||||
|
||||
print('\nCar models vs. platform codes (no major versions):')
|
||||
for ecu, codes in cars_for_code.items():
|
||||
print(f' (Ecu.{ECU_NAME[ecu[0]]}, {hex(ecu[1])}, {ecu[2]}):')
|
||||
for code, cars in codes.items():
|
||||
print(f' {code!r}: {sorted(cars)}')
|
||||
174
selfdrive/car/toyota/tests/test_toyota.py
Normal file
174
selfdrive/car/toyota/tests/test_toyota.py
Normal file
@@ -0,0 +1,174 @@
|
||||
#!/usr/bin/env python3
|
||||
from hypothesis import given, settings, strategies as st
|
||||
import unittest
|
||||
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.car.fw_versions import build_fw_dict
|
||||
from openpilot.selfdrive.car.toyota.fingerprints import FW_VERSIONS
|
||||
from openpilot.selfdrive.car.toyota.values import CAR, DBC, TSS2_CAR, ANGLE_CONTROL_CAR, RADAR_ACC_CAR, \
|
||||
FW_QUERY_CONFIG, PLATFORM_CODE_ECUS, FUZZY_EXCLUDED_PLATFORMS, \
|
||||
get_platform_codes
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
ECU_NAME = {v: k for k, v in Ecu.schema.enumerants.items()}
|
||||
|
||||
|
||||
def check_fw_version(fw_version: bytes) -> bool:
|
||||
return b'?' not in fw_version
|
||||
|
||||
|
||||
class TestToyotaInterfaces(unittest.TestCase):
|
||||
def test_car_sets(self):
|
||||
self.assertTrue(len(ANGLE_CONTROL_CAR - TSS2_CAR) == 0)
|
||||
self.assertTrue(len(RADAR_ACC_CAR - TSS2_CAR) == 0)
|
||||
|
||||
def test_lta_platforms(self):
|
||||
# At this time, only RAV4 2023 is expected to use LTA/angle control
|
||||
self.assertEqual(ANGLE_CONTROL_CAR, {CAR.RAV4_TSS2_2023})
|
||||
|
||||
def test_tss2_dbc(self):
|
||||
# We make some assumptions about TSS2 platforms,
|
||||
# like looking up certain signals only in this DBC
|
||||
for car_model, dbc in DBC.items():
|
||||
if car_model in TSS2_CAR:
|
||||
self.assertEqual(dbc["pt"], "toyota_nodsu_pt_generated")
|
||||
|
||||
def test_essential_ecus(self):
|
||||
# Asserts standard ECUs exist for each platform
|
||||
common_ecus = {Ecu.fwdRadar, Ecu.fwdCamera}
|
||||
for car_model, ecus in FW_VERSIONS.items():
|
||||
with self.subTest(car_model=car_model.value):
|
||||
present_ecus = {ecu[0] for ecu in ecus}
|
||||
missing_ecus = common_ecus - present_ecus
|
||||
self.assertEqual(len(missing_ecus), 0)
|
||||
|
||||
# Some exceptions for other common ECUs
|
||||
if car_model not in (CAR.ALPHARD_TSS2,):
|
||||
self.assertIn(Ecu.abs, present_ecus)
|
||||
|
||||
if car_model not in (CAR.MIRAI,):
|
||||
self.assertIn(Ecu.engine, present_ecus)
|
||||
|
||||
if car_model not in (CAR.PRIUS_V, CAR.LEXUS_CTH):
|
||||
self.assertIn(Ecu.eps, present_ecus)
|
||||
|
||||
|
||||
class TestToyotaFingerprint(unittest.TestCase):
|
||||
def test_non_essential_ecus(self):
|
||||
# Ensures only the cars that have multiple engine ECUs are in the engine non-essential ECU list
|
||||
for car_model, ecus in FW_VERSIONS.items():
|
||||
with self.subTest(car_model=car_model.value):
|
||||
engine_ecus = {ecu for ecu in ecus if ecu[0] == Ecu.engine}
|
||||
self.assertEqual(len(engine_ecus) > 1,
|
||||
car_model in FW_QUERY_CONFIG.non_essential_ecus[Ecu.engine],
|
||||
f"Car model unexpectedly {'not ' if len(engine_ecus) > 1 else ''}in non-essential list")
|
||||
|
||||
def test_valid_fw_versions(self):
|
||||
# Asserts all FW versions are valid
|
||||
for car_model, ecus in FW_VERSIONS.items():
|
||||
with self.subTest(car_model=car_model.value):
|
||||
for fws in ecus.values():
|
||||
for fw in fws:
|
||||
self.assertTrue(check_fw_version(fw), fw)
|
||||
|
||||
# Tests for part numbers, platform codes, and sub-versions which Toyota will use to fuzzy
|
||||
# fingerprint in the absence of full FW matches:
|
||||
@settings(max_examples=100)
|
||||
@given(data=st.data())
|
||||
def test_platform_codes_fuzzy_fw(self, data):
|
||||
fw_strategy = st.lists(st.binary())
|
||||
fws = data.draw(fw_strategy)
|
||||
get_platform_codes(fws)
|
||||
|
||||
def test_platform_code_ecus_available(self):
|
||||
# Asserts ECU keys essential for fuzzy fingerprinting are available on all platforms
|
||||
for car_model, ecus in FW_VERSIONS.items():
|
||||
with self.subTest(car_model=car_model.value):
|
||||
for platform_code_ecu in PLATFORM_CODE_ECUS:
|
||||
if platform_code_ecu == Ecu.eps and car_model in (CAR.PRIUS_V, CAR.LEXUS_CTH,):
|
||||
continue
|
||||
if platform_code_ecu == Ecu.abs and car_model in (CAR.ALPHARD_TSS2,):
|
||||
continue
|
||||
self.assertIn(platform_code_ecu, [e[0] for e in ecus])
|
||||
|
||||
def test_fw_format(self):
|
||||
# Asserts:
|
||||
# - every supported ECU FW version returns one platform code
|
||||
# - every supported ECU FW version has a part number
|
||||
# - expected parsing of ECU sub-versions
|
||||
|
||||
for car_model, ecus in FW_VERSIONS.items():
|
||||
with self.subTest(car_model=car_model.value):
|
||||
for ecu, fws in ecus.items():
|
||||
if ecu[0] not in PLATFORM_CODE_ECUS:
|
||||
continue
|
||||
|
||||
codes = dict()
|
||||
for fw in fws:
|
||||
result = get_platform_codes([fw])
|
||||
# Check only one platform code and sub-version
|
||||
self.assertEqual(1, len(result), f"Unable to parse FW: {fw}")
|
||||
self.assertEqual(1, len(list(result.values())[0]), f"Unable to parse FW: {fw}")
|
||||
codes |= result
|
||||
|
||||
# Toyota places the ECU part number in their FW versions, assert all parsable
|
||||
# Note that there is only one unique part number per ECU across the fleet, so this
|
||||
# is not important for identification, just a sanity check.
|
||||
self.assertTrue(all(code.count(b"-") > 1 for code in codes),
|
||||
f"FW does not have part number: {fw} {codes}")
|
||||
|
||||
def test_platform_codes_spot_check(self):
|
||||
# Asserts basic platform code parsing behavior for a few cases
|
||||
results = get_platform_codes([
|
||||
b"F152607140\x00\x00\x00\x00\x00\x00",
|
||||
b"F152607171\x00\x00\x00\x00\x00\x00",
|
||||
b"F152607110\x00\x00\x00\x00\x00\x00",
|
||||
b"F152607180\x00\x00\x00\x00\x00\x00",
|
||||
])
|
||||
self.assertEqual(results, {b"F1526-07-1": {b"10", b"40", b"71", b"80"}})
|
||||
|
||||
results = get_platform_codes([
|
||||
b"\x028646F4104100\x00\x00\x00\x008646G5301200\x00\x00\x00\x00",
|
||||
b"\x028646F4104100\x00\x00\x00\x008646G3304000\x00\x00\x00\x00",
|
||||
])
|
||||
self.assertEqual(results, {b"8646F-41-04": {b"100"}})
|
||||
|
||||
# Short version has no part number
|
||||
results = get_platform_codes([
|
||||
b"\x0235870000\x00\x00\x00\x00\x00\x00\x00\x00A0202000\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
b"\x0235883000\x00\x00\x00\x00\x00\x00\x00\x00A0202000\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
])
|
||||
self.assertEqual(results, {b"58-70": {b"000"}, b"58-83": {b"000"}})
|
||||
|
||||
results = get_platform_codes([
|
||||
b"F152607110\x00\x00\x00\x00\x00\x00",
|
||||
b"F152607140\x00\x00\x00\x00\x00\x00",
|
||||
b"\x028646F4104100\x00\x00\x00\x008646G5301200\x00\x00\x00\x00",
|
||||
b"\x0235879000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
])
|
||||
self.assertEqual(results, {b"F1526-07-1": {b"10", b"40"}, b"8646F-41-04": {b"100"}, b"58-79": {b"000"}})
|
||||
|
||||
def test_fuzzy_excluded_platforms(self):
|
||||
# Asserts a list of platforms that will not fuzzy fingerprint with platform codes due to them being shared.
|
||||
platforms_with_shared_codes = set()
|
||||
for platform, fw_by_addr in FW_VERSIONS.items():
|
||||
car_fw = []
|
||||
for ecu, fw_versions in fw_by_addr.items():
|
||||
ecu_name, addr, sub_addr = ecu
|
||||
for fw in fw_versions:
|
||||
car_fw.append({"ecu": ecu_name, "fwVersion": fw, "address": addr,
|
||||
"subAddress": 0 if sub_addr is None else sub_addr})
|
||||
|
||||
CP = car.CarParams.new_message(carFw=car_fw)
|
||||
matches = FW_QUERY_CONFIG.match_fw_to_car_fuzzy(build_fw_dict(CP.carFw), FW_VERSIONS)
|
||||
if len(matches) == 1:
|
||||
self.assertEqual(list(matches)[0], platform)
|
||||
else:
|
||||
# If a platform has multiple matches, add it and its matches
|
||||
platforms_with_shared_codes |= {str(platform), *matches}
|
||||
|
||||
self.assertEqual(platforms_with_shared_codes, FUZZY_EXCLUDED_PLATFORMS, (len(platforms_with_shared_codes), len(FW_VERSIONS)))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -33,19 +33,19 @@ def create_lta_steer_command(packer, steer_control_type, steer_angle, steer_req,
|
||||
return packer.make_can_msg("STEERING_LTA", 0, values)
|
||||
|
||||
|
||||
def create_accel_command(packer, accel, accel_raw, pcm_cancel, standstill_req, lead, acc_type, fcw_alert, distance_button, frogpilot_variables):
|
||||
def create_accel_command(packer, accel, accel_raw, pcm_cancel, standstill_req, lead, acc_type, fcw_alert, distance, frogpilot_variables):
|
||||
# TODO: find the exact canceling bit that does not create a chime
|
||||
values = {
|
||||
"ACCEL_CMD": accel, # compensated accel command
|
||||
"ACC_TYPE": acc_type,
|
||||
"DISTANCE": distance_button,
|
||||
"DISTANCE": distance,
|
||||
"MINI_CAR": lead,
|
||||
"PERMIT_BRAKING": 1,
|
||||
"RELEASE_STANDSTILL": not standstill_req,
|
||||
"CANCEL_REQ": pcm_cancel,
|
||||
"ALLOW_LONG_PRESS": 2 if frogpilot_variables.reverse_cruise_increase else 1,
|
||||
"ACC_CUT_IN": fcw_alert, # only shown when ACC enabled
|
||||
"ACCEL_CMD_ALT": accel_raw, # raw accel command, pcm uses this to calculate a compensatory force
|
||||
"ACCEL_CMD_ALT": accel_raw, # raw accel command, pcm uses this to calculate a compensatory force
|
||||
}
|
||||
return packer.make_can_msg("ACC_CONTROL", 0, values)
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import re
|
||||
from collections import defaultdict
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum, IntFlag, StrEnum
|
||||
from typing import Dict, List, Set, Union
|
||||
from enum import Enum, IntFlag
|
||||
|
||||
from cereal import car
|
||||
from openpilot.common.conversions import Conversions as CV
|
||||
from openpilot.selfdrive.car import CarSpecs, PlatformConfig, Platforms
|
||||
from openpilot.selfdrive.car import AngleRateLimit, dbc_dict
|
||||
from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarInfo, Column, CarParts, CarHarness
|
||||
from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarDocs, Column, CarParts, CarHarness
|
||||
from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
@@ -43,52 +43,24 @@ class CarControllerParams:
|
||||
|
||||
|
||||
class ToyotaFlags(IntFlag):
|
||||
# Detected flags
|
||||
HYBRID = 1
|
||||
SMART_DSU = 2
|
||||
DISABLE_RADAR = 4
|
||||
ZSS = 8
|
||||
RADAR_CAN_FILTER = 1024
|
||||
|
||||
# Static flags
|
||||
TSS2 = 8
|
||||
NO_DSU = 16
|
||||
UNSUPPORTED_DSU = 32
|
||||
RADAR_ACC = 64
|
||||
# these cars use the Lane Tracing Assist (LTA) message for lateral control
|
||||
ANGLE_CONTROL = 128
|
||||
NO_STOP_TIMER = 256
|
||||
# these cars are speculated to allow stop and go when the DSU is unplugged or disabled with sDSU
|
||||
SNG_WITHOUT_DSU = 512
|
||||
|
||||
class CAR(StrEnum):
|
||||
# Toyota
|
||||
ALPHARD_TSS2 = "TOYOTA ALPHARD 2020"
|
||||
AVALON = "TOYOTA AVALON 2016"
|
||||
AVALON_2019 = "TOYOTA AVALON 2019"
|
||||
AVALON_TSS2 = "TOYOTA AVALON 2022" # TSS 2.5
|
||||
CAMRY = "TOYOTA CAMRY 2018"
|
||||
CAMRY_TSS2 = "TOYOTA CAMRY 2021" # TSS 2.5
|
||||
CHR = "TOYOTA C-HR 2018"
|
||||
CHR_TSS2 = "TOYOTA C-HR 2021"
|
||||
COROLLA = "TOYOTA COROLLA 2017"
|
||||
# LSS2 Lexus UX Hybrid is same as a TSS2 Corolla Hybrid
|
||||
COROLLA_TSS2 = "TOYOTA COROLLA TSS2 2019"
|
||||
HIGHLANDER = "TOYOTA HIGHLANDER 2017"
|
||||
HIGHLANDER_TSS2 = "TOYOTA HIGHLANDER 2020"
|
||||
PRIUS = "TOYOTA PRIUS 2017"
|
||||
PRIUS_V = "TOYOTA PRIUS v 2017"
|
||||
PRIUS_TSS2 = "TOYOTA PRIUS TSS2 2021"
|
||||
RAV4 = "TOYOTA RAV4 2017"
|
||||
RAV4H = "TOYOTA RAV4 HYBRID 2017"
|
||||
RAV4_TSS2 = "TOYOTA RAV4 2019"
|
||||
RAV4_TSS2_2022 = "TOYOTA RAV4 2022"
|
||||
RAV4_TSS2_2023 = "TOYOTA RAV4 2023"
|
||||
MIRAI = "TOYOTA MIRAI 2021" # TSS 2.5
|
||||
SIENNA = "TOYOTA SIENNA 2018"
|
||||
|
||||
# Lexus
|
||||
LEXUS_CTH = "LEXUS CT HYBRID 2018"
|
||||
LEXUS_ES = "LEXUS ES 2018"
|
||||
LEXUS_ES_TSS2 = "LEXUS ES 2019"
|
||||
LEXUS_IS = "LEXUS IS 2018"
|
||||
LEXUS_IS_TSS2 = "LEXUS IS 2023"
|
||||
LEXUS_NX = "LEXUS NX 2018"
|
||||
LEXUS_NX_TSS2 = "LEXUS NX 2020"
|
||||
LEXUS_LC_TSS2 = "LEXUS LC 2024"
|
||||
LEXUS_RC = "LEXUS RC 2020"
|
||||
LEXUS_RX = "LEXUS RX 2016"
|
||||
LEXUS_RX_TSS2 = "LEXUS RX 2020"
|
||||
LEXUS_GS_F = "LEXUS GS F 2016"
|
||||
|
||||
ZSS = 1024
|
||||
|
||||
class Footnote(Enum):
|
||||
CAMRY = CarFootnote(
|
||||
@@ -97,132 +69,310 @@ class Footnote(Enum):
|
||||
|
||||
|
||||
@dataclass
|
||||
class ToyotaCarInfo(CarInfo):
|
||||
class ToyotaCarDocs(CarDocs):
|
||||
package: str = "All"
|
||||
car_parts: CarParts = field(default_factory=CarParts.common([CarHarness.toyota_a]))
|
||||
|
||||
|
||||
CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = {
|
||||
@dataclass
|
||||
class ToyotaTSS2PlatformConfig(PlatformConfig):
|
||||
dbc_dict: dict = field(default_factory=lambda: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'))
|
||||
|
||||
def init(self):
|
||||
self.flags |= ToyotaFlags.TSS2 | ToyotaFlags.NO_STOP_TIMER | ToyotaFlags.NO_DSU
|
||||
|
||||
if self.flags & ToyotaFlags.RADAR_ACC:
|
||||
self.dbc_dict = dbc_dict('toyota_nodsu_pt_generated', None)
|
||||
|
||||
|
||||
class CAR(Platforms):
|
||||
# Toyota
|
||||
CAR.ALPHARD_TSS2: [
|
||||
ToyotaCarInfo("Toyota Alphard 2019-20"),
|
||||
ToyotaCarInfo("Toyota Alphard Hybrid 2021"),
|
||||
],
|
||||
CAR.AVALON: [
|
||||
ToyotaCarInfo("Toyota Avalon 2016", "Toyota Safety Sense P"),
|
||||
ToyotaCarInfo("Toyota Avalon 2017-18"),
|
||||
],
|
||||
CAR.AVALON_2019: [
|
||||
ToyotaCarInfo("Toyota Avalon 2019-21"),
|
||||
ToyotaCarInfo("Toyota Avalon Hybrid 2019-21"),
|
||||
],
|
||||
CAR.AVALON_TSS2: [
|
||||
ToyotaCarInfo("Toyota Avalon 2022"),
|
||||
ToyotaCarInfo("Toyota Avalon Hybrid 2022"),
|
||||
],
|
||||
CAR.CAMRY: [
|
||||
ToyotaCarInfo("Toyota Camry 2018-20", video_link="https://www.youtube.com/watch?v=fkcjviZY9CM", footnotes=[Footnote.CAMRY]),
|
||||
ToyotaCarInfo("Toyota Camry Hybrid 2018-20", video_link="https://www.youtube.com/watch?v=Q2DYY0AWKgk"),
|
||||
],
|
||||
CAR.CAMRY_TSS2: [
|
||||
ToyotaCarInfo("Toyota Camry 2021-24", footnotes=[Footnote.CAMRY]),
|
||||
ToyotaCarInfo("Toyota Camry Hybrid 2021-24"),
|
||||
],
|
||||
CAR.CHR: [
|
||||
ToyotaCarInfo("Toyota C-HR 2017-20"),
|
||||
ToyotaCarInfo("Toyota C-HR Hybrid 2017-20"),
|
||||
],
|
||||
CAR.CHR_TSS2: [
|
||||
ToyotaCarInfo("Toyota C-HR 2021"),
|
||||
ToyotaCarInfo("Toyota C-HR Hybrid 2021-22"),
|
||||
],
|
||||
CAR.COROLLA: ToyotaCarInfo("Toyota Corolla 2017-19"),
|
||||
CAR.COROLLA_TSS2: [
|
||||
ToyotaCarInfo("Toyota Corolla 2020-22", video_link="https://www.youtube.com/watch?v=_66pXk0CBYA"),
|
||||
ToyotaCarInfo("Toyota Corolla Cross (Non-US only) 2020-23", min_enable_speed=7.5),
|
||||
ToyotaCarInfo("Toyota Corolla Hatchback 2019-22", video_link="https://www.youtube.com/watch?v=_66pXk0CBYA"),
|
||||
# Hybrid platforms
|
||||
ToyotaCarInfo("Toyota Corolla Hybrid 2020-22"),
|
||||
ToyotaCarInfo("Toyota Corolla Hybrid (Non-US only) 2020-23", min_enable_speed=7.5),
|
||||
ToyotaCarInfo("Toyota Corolla Cross Hybrid (Non-US only) 2020-22", min_enable_speed=7.5),
|
||||
ToyotaCarInfo("Lexus UX Hybrid 2019-23"),
|
||||
],
|
||||
CAR.HIGHLANDER: [
|
||||
ToyotaCarInfo("Toyota Highlander 2017-19", video_link="https://www.youtube.com/watch?v=0wS0wXSLzoo"),
|
||||
ToyotaCarInfo("Toyota Highlander Hybrid 2017-19"),
|
||||
],
|
||||
CAR.HIGHLANDER_TSS2: [
|
||||
ToyotaCarInfo("Toyota Highlander 2020-23"),
|
||||
ToyotaCarInfo("Toyota Highlander Hybrid 2020-23"),
|
||||
],
|
||||
CAR.PRIUS: [
|
||||
ToyotaCarInfo("Toyota Prius 2016", "Toyota Safety Sense P", video_link="https://www.youtube.com/watch?v=8zopPJI8XQ0"),
|
||||
ToyotaCarInfo("Toyota Prius 2017-20", video_link="https://www.youtube.com/watch?v=8zopPJI8XQ0"),
|
||||
ToyotaCarInfo("Toyota Prius Prime 2017-20", video_link="https://www.youtube.com/watch?v=8zopPJI8XQ0"),
|
||||
],
|
||||
CAR.PRIUS_V: ToyotaCarInfo("Toyota Prius v 2017", "Toyota Safety Sense P", min_enable_speed=MIN_ACC_SPEED),
|
||||
CAR.PRIUS_TSS2: [
|
||||
ToyotaCarInfo("Toyota Prius 2021-22", video_link="https://www.youtube.com/watch?v=J58TvCpUd4U"),
|
||||
ToyotaCarInfo("Toyota Prius Prime 2021-22", video_link="https://www.youtube.com/watch?v=J58TvCpUd4U"),
|
||||
],
|
||||
CAR.RAV4: [
|
||||
ToyotaCarInfo("Toyota RAV4 2016", "Toyota Safety Sense P"),
|
||||
ToyotaCarInfo("Toyota RAV4 2017-18")
|
||||
],
|
||||
CAR.RAV4H: [
|
||||
ToyotaCarInfo("Toyota RAV4 Hybrid 2016", "Toyota Safety Sense P", video_link="https://youtu.be/LhT5VzJVfNI?t=26"),
|
||||
ToyotaCarInfo("Toyota RAV4 Hybrid 2017-18", video_link="https://youtu.be/LhT5VzJVfNI?t=26")
|
||||
],
|
||||
CAR.RAV4_TSS2: [
|
||||
ToyotaCarInfo("Toyota RAV4 2019-21", video_link="https://www.youtube.com/watch?v=wJxjDd42gGA"),
|
||||
ToyotaCarInfo("Toyota RAV4 Hybrid 2019-21"),
|
||||
],
|
||||
CAR.RAV4_TSS2_2022: [
|
||||
ToyotaCarInfo("Toyota RAV4 2022"),
|
||||
ToyotaCarInfo("Toyota RAV4 Hybrid 2022", video_link="https://youtu.be/U0nH9cnrFB0"),
|
||||
],
|
||||
CAR.RAV4_TSS2_2023: [
|
||||
ToyotaCarInfo("Toyota RAV4 2023-24"),
|
||||
ToyotaCarInfo("Toyota RAV4 Hybrid 2023-24"),
|
||||
],
|
||||
CAR.MIRAI: ToyotaCarInfo("Toyota Mirai 2021"),
|
||||
CAR.SIENNA: ToyotaCarInfo("Toyota Sienna 2018-20", video_link="https://www.youtube.com/watch?v=q1UPOo4Sh68", min_enable_speed=MIN_ACC_SPEED),
|
||||
ALPHARD_TSS2 = ToyotaTSS2PlatformConfig(
|
||||
"TOYOTA ALPHARD 2020",
|
||||
[
|
||||
ToyotaCarDocs("Toyota Alphard 2019-20"),
|
||||
ToyotaCarDocs("Toyota Alphard Hybrid 2021"),
|
||||
],
|
||||
CarSpecs(mass=4305. * CV.LB_TO_KG, wheelbase=3.0, steerRatio=14.2, tireStiffnessFactor=0.444),
|
||||
)
|
||||
AVALON = PlatformConfig(
|
||||
"TOYOTA AVALON 2016",
|
||||
[
|
||||
ToyotaCarDocs("Toyota Avalon 2016", "Toyota Safety Sense P"),
|
||||
ToyotaCarDocs("Toyota Avalon 2017-18"),
|
||||
],
|
||||
CarSpecs(mass=3505. * CV.LB_TO_KG, wheelbase=2.82, steerRatio=14.8, tireStiffnessFactor=0.7983),
|
||||
dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'),
|
||||
)
|
||||
AVALON_2019 = PlatformConfig(
|
||||
"TOYOTA AVALON 2019",
|
||||
[
|
||||
ToyotaCarDocs("Toyota Avalon 2019-21"),
|
||||
ToyotaCarDocs("Toyota Avalon Hybrid 2019-21"),
|
||||
],
|
||||
AVALON.specs,
|
||||
dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'),
|
||||
)
|
||||
AVALON_TSS2 = ToyotaTSS2PlatformConfig(
|
||||
"TOYOTA AVALON 2022", # TSS 2.5
|
||||
[
|
||||
ToyotaCarDocs("Toyota Avalon 2022"),
|
||||
ToyotaCarDocs("Toyota Avalon Hybrid 2022"),
|
||||
],
|
||||
AVALON.specs,
|
||||
)
|
||||
CAMRY = PlatformConfig(
|
||||
"TOYOTA CAMRY 2018",
|
||||
[
|
||||
ToyotaCarDocs("Toyota Camry 2018-20", video_link="https://www.youtube.com/watch?v=fkcjviZY9CM", footnotes=[Footnote.CAMRY]),
|
||||
ToyotaCarDocs("Toyota Camry Hybrid 2018-20", video_link="https://www.youtube.com/watch?v=Q2DYY0AWKgk"),
|
||||
],
|
||||
CarSpecs(mass=3400. * CV.LB_TO_KG, wheelbase=2.82448, steerRatio=13.7, tireStiffnessFactor=0.7933),
|
||||
dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'),
|
||||
flags=ToyotaFlags.NO_DSU,
|
||||
)
|
||||
CAMRY_TSS2 = ToyotaTSS2PlatformConfig(
|
||||
"TOYOTA CAMRY 2021", # TSS 2.5
|
||||
[
|
||||
ToyotaCarDocs("Toyota Camry 2021-24", footnotes=[Footnote.CAMRY]),
|
||||
ToyotaCarDocs("Toyota Camry Hybrid 2021-24"),
|
||||
],
|
||||
CAMRY.specs,
|
||||
)
|
||||
CHR = PlatformConfig(
|
||||
"TOYOTA C-HR 2018",
|
||||
[
|
||||
ToyotaCarDocs("Toyota C-HR 2017-20"),
|
||||
ToyotaCarDocs("Toyota C-HR Hybrid 2017-20"),
|
||||
],
|
||||
CarSpecs(mass=3300. * CV.LB_TO_KG, wheelbase=2.63906, steerRatio=13.6, tireStiffnessFactor=0.7933),
|
||||
dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'),
|
||||
flags=ToyotaFlags.NO_DSU,
|
||||
)
|
||||
CHR_TSS2 = ToyotaTSS2PlatformConfig(
|
||||
"TOYOTA C-HR 2021",
|
||||
[
|
||||
ToyotaCarDocs("Toyota C-HR 2021"),
|
||||
ToyotaCarDocs("Toyota C-HR Hybrid 2021-22"),
|
||||
],
|
||||
CHR.specs,
|
||||
flags=ToyotaFlags.RADAR_ACC,
|
||||
)
|
||||
COROLLA = PlatformConfig(
|
||||
"TOYOTA COROLLA 2017",
|
||||
[ToyotaCarDocs("Toyota Corolla 2017-19")],
|
||||
CarSpecs(mass=2860. * CV.LB_TO_KG, wheelbase=2.7, steerRatio=18.27, tireStiffnessFactor=0.444),
|
||||
dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'),
|
||||
)
|
||||
# LSS2 Lexus UX Hybrid is same as a TSS2 Corolla Hybrid
|
||||
COROLLA_TSS2 = ToyotaTSS2PlatformConfig(
|
||||
"TOYOTA COROLLA TSS2 2019",
|
||||
[
|
||||
ToyotaCarDocs("Toyota Corolla 2020-22", video_link="https://www.youtube.com/watch?v=_66pXk0CBYA"),
|
||||
ToyotaCarDocs("Toyota Corolla Cross (Non-US only) 2020-23", min_enable_speed=7.5),
|
||||
ToyotaCarDocs("Toyota Corolla Hatchback 2019-22", video_link="https://www.youtube.com/watch?v=_66pXk0CBYA"),
|
||||
# Hybrid platforms
|
||||
ToyotaCarDocs("Toyota Corolla Hybrid 2020-22"),
|
||||
ToyotaCarDocs("Toyota Corolla Hybrid (Non-US only) 2020-23", min_enable_speed=7.5),
|
||||
ToyotaCarDocs("Toyota Corolla Cross Hybrid (Non-US only) 2020-22", min_enable_speed=7.5),
|
||||
ToyotaCarDocs("Lexus UX Hybrid 2019-23"),
|
||||
],
|
||||
CarSpecs(mass=3060. * CV.LB_TO_KG, wheelbase=2.67, steerRatio=13.9, tireStiffnessFactor=0.444),
|
||||
)
|
||||
HIGHLANDER = PlatformConfig(
|
||||
"TOYOTA HIGHLANDER 2017",
|
||||
[
|
||||
ToyotaCarDocs("Toyota Highlander 2017-19", video_link="https://www.youtube.com/watch?v=0wS0wXSLzoo"),
|
||||
ToyotaCarDocs("Toyota Highlander Hybrid 2017-19"),
|
||||
],
|
||||
CarSpecs(mass=4516. * CV.LB_TO_KG, wheelbase=2.8194, steerRatio=16.0, tireStiffnessFactor=0.8),
|
||||
dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'),
|
||||
flags=ToyotaFlags.NO_STOP_TIMER | ToyotaFlags.SNG_WITHOUT_DSU,
|
||||
)
|
||||
HIGHLANDER_TSS2 = ToyotaTSS2PlatformConfig(
|
||||
"TOYOTA HIGHLANDER 2020",
|
||||
[
|
||||
ToyotaCarDocs("Toyota Highlander 2020-23"),
|
||||
ToyotaCarDocs("Toyota Highlander Hybrid 2020-23"),
|
||||
],
|
||||
HIGHLANDER.specs,
|
||||
)
|
||||
PRIUS = PlatformConfig(
|
||||
"TOYOTA PRIUS 2017",
|
||||
[
|
||||
ToyotaCarDocs("Toyota Prius 2016", "Toyota Safety Sense P", video_link="https://www.youtube.com/watch?v=8zopPJI8XQ0"),
|
||||
ToyotaCarDocs("Toyota Prius 2017-20", video_link="https://www.youtube.com/watch?v=8zopPJI8XQ0"),
|
||||
ToyotaCarDocs("Toyota Prius Prime 2017-20", video_link="https://www.youtube.com/watch?v=8zopPJI8XQ0"),
|
||||
],
|
||||
CarSpecs(mass=3045. * CV.LB_TO_KG, wheelbase=2.7, steerRatio=15.74, tireStiffnessFactor=0.6371),
|
||||
dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'),
|
||||
)
|
||||
PRIUS_V = PlatformConfig(
|
||||
"TOYOTA PRIUS v 2017",
|
||||
[ToyotaCarDocs("Toyota Prius v 2017", "Toyota Safety Sense P", min_enable_speed=MIN_ACC_SPEED)],
|
||||
CarSpecs(mass=3340. * CV.LB_TO_KG, wheelbase=2.78, steerRatio=17.4, tireStiffnessFactor=0.5533),
|
||||
dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'),
|
||||
flags=ToyotaFlags.NO_STOP_TIMER | ToyotaFlags.SNG_WITHOUT_DSU,
|
||||
)
|
||||
PRIUS_TSS2 = ToyotaTSS2PlatformConfig(
|
||||
"TOYOTA PRIUS TSS2 2021",
|
||||
[
|
||||
ToyotaCarDocs("Toyota Prius 2021-22", video_link="https://www.youtube.com/watch?v=J58TvCpUd4U"),
|
||||
ToyotaCarDocs("Toyota Prius Prime 2021-22", video_link="https://www.youtube.com/watch?v=J58TvCpUd4U"),
|
||||
],
|
||||
CarSpecs(mass=3115. * CV.LB_TO_KG, wheelbase=2.70002, steerRatio=13.4, tireStiffnessFactor=0.6371),
|
||||
)
|
||||
RAV4 = PlatformConfig(
|
||||
"TOYOTA RAV4 2017",
|
||||
[
|
||||
ToyotaCarDocs("Toyota RAV4 2016", "Toyota Safety Sense P"),
|
||||
ToyotaCarDocs("Toyota RAV4 2017-18")
|
||||
],
|
||||
CarSpecs(mass=3650. * CV.LB_TO_KG, wheelbase=2.65, steerRatio=16.88, tireStiffnessFactor=0.5533),
|
||||
dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'),
|
||||
)
|
||||
RAV4H = PlatformConfig(
|
||||
"TOYOTA RAV4 HYBRID 2017",
|
||||
[
|
||||
ToyotaCarDocs("Toyota RAV4 Hybrid 2016", "Toyota Safety Sense P", video_link="https://youtu.be/LhT5VzJVfNI?t=26"),
|
||||
ToyotaCarDocs("Toyota RAV4 Hybrid 2017-18", video_link="https://youtu.be/LhT5VzJVfNI?t=26")
|
||||
],
|
||||
RAV4.specs,
|
||||
dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'),
|
||||
flags=ToyotaFlags.NO_STOP_TIMER,
|
||||
)
|
||||
RAV4_TSS2 = ToyotaTSS2PlatformConfig(
|
||||
"TOYOTA RAV4 2019",
|
||||
[
|
||||
ToyotaCarDocs("Toyota RAV4 2019-21", video_link="https://www.youtube.com/watch?v=wJxjDd42gGA"),
|
||||
ToyotaCarDocs("Toyota RAV4 Hybrid 2019-21"),
|
||||
],
|
||||
CarSpecs(mass=3585. * CV.LB_TO_KG, wheelbase=2.68986, steerRatio=14.3, tireStiffnessFactor=0.7933),
|
||||
)
|
||||
RAV4_TSS2_2022 = ToyotaTSS2PlatformConfig(
|
||||
"TOYOTA RAV4 2022",
|
||||
[
|
||||
ToyotaCarDocs("Toyota RAV4 2022"),
|
||||
ToyotaCarDocs("Toyota RAV4 Hybrid 2022", video_link="https://youtu.be/U0nH9cnrFB0"),
|
||||
],
|
||||
RAV4_TSS2.specs,
|
||||
flags=ToyotaFlags.RADAR_ACC,
|
||||
)
|
||||
RAV4_TSS2_2023 = ToyotaTSS2PlatformConfig(
|
||||
"TOYOTA RAV4 2023",
|
||||
[
|
||||
ToyotaCarDocs("Toyota RAV4 2023-24"),
|
||||
ToyotaCarDocs("Toyota RAV4 Hybrid 2023-24"),
|
||||
],
|
||||
RAV4_TSS2.specs,
|
||||
flags=ToyotaFlags.RADAR_ACC | ToyotaFlags.ANGLE_CONTROL,
|
||||
)
|
||||
MIRAI = ToyotaTSS2PlatformConfig(
|
||||
"TOYOTA MIRAI 2021", # TSS 2.5
|
||||
[ToyotaCarDocs("Toyota Mirai 2021")],
|
||||
CarSpecs(mass=4300. * CV.LB_TO_KG, wheelbase=2.91, steerRatio=14.8, tireStiffnessFactor=0.8),
|
||||
)
|
||||
SIENNA = PlatformConfig(
|
||||
"TOYOTA SIENNA 2018",
|
||||
[ToyotaCarDocs("Toyota Sienna 2018-20", video_link="https://www.youtube.com/watch?v=q1UPOo4Sh68", min_enable_speed=MIN_ACC_SPEED)],
|
||||
CarSpecs(mass=4590. * CV.LB_TO_KG, wheelbase=3.03, steerRatio=15.5, tireStiffnessFactor=0.444),
|
||||
dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'),
|
||||
flags=ToyotaFlags.NO_STOP_TIMER,
|
||||
)
|
||||
|
||||
# Lexus
|
||||
CAR.LEXUS_CTH: ToyotaCarInfo("Lexus CT Hybrid 2017-18", "Lexus Safety System+"),
|
||||
CAR.LEXUS_ES: [
|
||||
ToyotaCarInfo("Lexus ES 2017-18"),
|
||||
ToyotaCarInfo("Lexus ES Hybrid 2017-18"),
|
||||
],
|
||||
CAR.LEXUS_ES_TSS2: [
|
||||
ToyotaCarInfo("Lexus ES 2019-24"),
|
||||
ToyotaCarInfo("Lexus ES Hybrid 2019-24", video_link="https://youtu.be/BZ29osRVJeg?t=12"),
|
||||
],
|
||||
CAR.LEXUS_IS: ToyotaCarInfo("Lexus IS 2017-19"),
|
||||
CAR.LEXUS_IS_TSS2: ToyotaCarInfo("Lexus IS 2022-23"),
|
||||
CAR.LEXUS_GS_F: ToyotaCarInfo("Lexus GS F 2016"),
|
||||
CAR.LEXUS_NX: [
|
||||
ToyotaCarInfo("Lexus NX 2018-19"),
|
||||
ToyotaCarInfo("Lexus NX Hybrid 2018-19"),
|
||||
],
|
||||
CAR.LEXUS_NX_TSS2: [
|
||||
ToyotaCarInfo("Lexus NX 2020-21"),
|
||||
ToyotaCarInfo("Lexus NX Hybrid 2020-21"),
|
||||
],
|
||||
CAR.LEXUS_LC_TSS2: ToyotaCarInfo("Lexus LC 2024"),
|
||||
CAR.LEXUS_RC: ToyotaCarInfo("Lexus RC 2018-20"),
|
||||
CAR.LEXUS_RX: [
|
||||
ToyotaCarInfo("Lexus RX 2016", "Lexus Safety System+"),
|
||||
ToyotaCarInfo("Lexus RX 2017-19"),
|
||||
# Hybrid platforms
|
||||
ToyotaCarInfo("Lexus RX Hybrid 2016", "Lexus Safety System+"),
|
||||
ToyotaCarInfo("Lexus RX Hybrid 2017-19"),
|
||||
],
|
||||
CAR.LEXUS_RX_TSS2: [
|
||||
ToyotaCarInfo("Lexus RX 2020-22"),
|
||||
ToyotaCarInfo("Lexus RX Hybrid 2020-22"),
|
||||
],
|
||||
}
|
||||
LEXUS_CTH = PlatformConfig(
|
||||
"LEXUS CT HYBRID 2018",
|
||||
[ToyotaCarDocs("Lexus CT Hybrid 2017-18", "Lexus Safety System+")],
|
||||
CarSpecs(mass=3108. * CV.LB_TO_KG, wheelbase=2.6, steerRatio=18.6, tireStiffnessFactor=0.517),
|
||||
dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'),
|
||||
)
|
||||
LEXUS_ES = PlatformConfig(
|
||||
"LEXUS ES 2018",
|
||||
[
|
||||
ToyotaCarDocs("Lexus ES 2017-18"),
|
||||
ToyotaCarDocs("Lexus ES Hybrid 2017-18"),
|
||||
],
|
||||
CarSpecs(mass=3677. * CV.LB_TO_KG, wheelbase=2.8702, steerRatio=16.0, tireStiffnessFactor=0.444),
|
||||
dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'),
|
||||
)
|
||||
LEXUS_ES_TSS2 = ToyotaTSS2PlatformConfig(
|
||||
"LEXUS ES 2019",
|
||||
[
|
||||
ToyotaCarDocs("Lexus ES 2019-24"),
|
||||
ToyotaCarDocs("Lexus ES Hybrid 2019-24", video_link="https://youtu.be/BZ29osRVJeg?t=12"),
|
||||
],
|
||||
LEXUS_ES.specs,
|
||||
)
|
||||
LEXUS_IS = PlatformConfig(
|
||||
"LEXUS IS 2018",
|
||||
[ToyotaCarDocs("Lexus IS 2017-19")],
|
||||
CarSpecs(mass=3736.8 * CV.LB_TO_KG, wheelbase=2.79908, steerRatio=13.3, tireStiffnessFactor=0.444),
|
||||
dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'),
|
||||
flags=ToyotaFlags.UNSUPPORTED_DSU,
|
||||
)
|
||||
LEXUS_IS_TSS2 = ToyotaTSS2PlatformConfig(
|
||||
"LEXUS IS 2023",
|
||||
[ToyotaCarDocs("Lexus IS 2022-23")],
|
||||
LEXUS_IS.specs,
|
||||
)
|
||||
LEXUS_NX = PlatformConfig(
|
||||
"LEXUS NX 2018",
|
||||
[
|
||||
ToyotaCarDocs("Lexus NX 2018-19"),
|
||||
ToyotaCarDocs("Lexus NX Hybrid 2018-19"),
|
||||
],
|
||||
CarSpecs(mass=4070. * CV.LB_TO_KG, wheelbase=2.66, steerRatio=14.7, tireStiffnessFactor=0.444),
|
||||
dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'),
|
||||
)
|
||||
LEXUS_NX_TSS2 = ToyotaTSS2PlatformConfig(
|
||||
"LEXUS NX 2020",
|
||||
[
|
||||
ToyotaCarDocs("Lexus NX 2020-21"),
|
||||
ToyotaCarDocs("Lexus NX Hybrid 2020-21"),
|
||||
],
|
||||
LEXUS_NX.specs,
|
||||
)
|
||||
LEXUS_LC_TSS2 = ToyotaTSS2PlatformConfig(
|
||||
"LEXUS LC 2024",
|
||||
[ToyotaCarDocs("Lexus LC 2024")],
|
||||
CarSpecs(mass=4500. * CV.LB_TO_KG, wheelbase=2.87, steerRatio=13.0, tireStiffnessFactor=0.444),
|
||||
)
|
||||
LEXUS_RC = PlatformConfig(
|
||||
"LEXUS RC 2020",
|
||||
[ToyotaCarDocs("Lexus RC 2018-20")],
|
||||
LEXUS_IS.specs,
|
||||
dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'),
|
||||
flags=ToyotaFlags.UNSUPPORTED_DSU,
|
||||
)
|
||||
LEXUS_RX = PlatformConfig(
|
||||
"LEXUS RX 2016",
|
||||
[
|
||||
ToyotaCarDocs("Lexus RX 2016", "Lexus Safety System+"),
|
||||
ToyotaCarDocs("Lexus RX 2017-19"),
|
||||
# Hybrid platforms
|
||||
ToyotaCarDocs("Lexus RX Hybrid 2016", "Lexus Safety System+"),
|
||||
ToyotaCarDocs("Lexus RX Hybrid 2017-19"),
|
||||
],
|
||||
CarSpecs(mass=4481. * CV.LB_TO_KG, wheelbase=2.79, steerRatio=16., tireStiffnessFactor=0.5533),
|
||||
dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'),
|
||||
)
|
||||
LEXUS_RX_TSS2 = ToyotaTSS2PlatformConfig(
|
||||
"LEXUS RX 2020",
|
||||
[
|
||||
ToyotaCarDocs("Lexus RX 2020-22"),
|
||||
ToyotaCarDocs("Lexus RX Hybrid 2020-22"),
|
||||
],
|
||||
LEXUS_RX.specs,
|
||||
)
|
||||
LEXUS_GS_F = PlatformConfig(
|
||||
"LEXUS GS F 2016",
|
||||
[ToyotaCarDocs("Lexus GS F 2016")],
|
||||
CarSpecs(mass=4034. * CV.LB_TO_KG, wheelbase=2.84988, steerRatio=13.3, tireStiffnessFactor=0.444),
|
||||
dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'),
|
||||
flags=ToyotaFlags.UNSUPPORTED_DSU,
|
||||
)
|
||||
|
||||
|
||||
# (addr, cars, bus, 1/freq*100, vl)
|
||||
STATIC_DSU_MSGS = [
|
||||
@@ -255,7 +405,7 @@ STATIC_DSU_MSGS = [
|
||||
]
|
||||
|
||||
|
||||
def get_platform_codes(fw_versions: List[bytes]) -> Dict[bytes, Set[bytes]]:
|
||||
def get_platform_codes(fw_versions: list[bytes]) -> dict[bytes, set[bytes]]:
|
||||
# Returns sub versions in a dict so comparisons can be made within part-platform-major_version combos
|
||||
codes = defaultdict(set) # Optional[part]-platform-major_version: set of sub_version
|
||||
for fw in fw_versions:
|
||||
@@ -299,7 +449,7 @@ def get_platform_codes(fw_versions: List[bytes]) -> Dict[bytes, Set[bytes]]:
|
||||
return dict(codes)
|
||||
|
||||
|
||||
def match_fw_to_car_fuzzy(live_fw_versions, offline_fw_versions) -> Set[str]:
|
||||
def match_fw_to_car_fuzzy(live_fw_versions, offline_fw_versions) -> set[str]:
|
||||
candidates = set()
|
||||
|
||||
for candidate, fws in offline_fw_versions.items():
|
||||
@@ -402,7 +552,7 @@ FW_QUERY_CONFIG = FwQueryConfig(
|
||||
Ecu.abs: [CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.SIENNA, CAR.LEXUS_IS, CAR.ALPHARD_TSS2],
|
||||
# On some models, the engine can show on two different addresses
|
||||
Ecu.engine: [CAR.HIGHLANDER, CAR.CAMRY, CAR.COROLLA_TSS2, CAR.CHR, CAR.CHR_TSS2, CAR.LEXUS_IS,
|
||||
CAR.LEXUS_RC, CAR.LEXUS_NX, CAR.LEXUS_NX_TSS2, CAR.LEXUS_RX, CAR.LEXUS_RX_TSS2],
|
||||
CAR.LEXUS_IS_TSS2, CAR.LEXUS_RC, CAR.LEXUS_NX, CAR.LEXUS_NX_TSS2, CAR.LEXUS_RX, CAR.LEXUS_RX_TSS2],
|
||||
},
|
||||
extra_ecus=[
|
||||
# All known ECUs on a late-model Toyota vehicle not queried here:
|
||||
@@ -442,66 +592,26 @@ FW_QUERY_CONFIG = FwQueryConfig(
|
||||
|
||||
STEER_THRESHOLD = 100
|
||||
|
||||
DBC = {
|
||||
CAR.RAV4H: dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'),
|
||||
CAR.RAV4: dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'),
|
||||
CAR.PRIUS: dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'),
|
||||
CAR.PRIUS_V: dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'),
|
||||
CAR.COROLLA: dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'),
|
||||
CAR.LEXUS_LC_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'),
|
||||
CAR.LEXUS_RC: dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'),
|
||||
CAR.LEXUS_RX: dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'),
|
||||
CAR.LEXUS_RX_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'),
|
||||
CAR.CHR: dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'),
|
||||
CAR.CHR_TSS2: dbc_dict('toyota_nodsu_pt_generated', None),
|
||||
CAR.CAMRY: dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'),
|
||||
CAR.CAMRY_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'),
|
||||
CAR.HIGHLANDER: dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'),
|
||||
CAR.HIGHLANDER_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'),
|
||||
CAR.AVALON: dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'),
|
||||
CAR.AVALON_2019: dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'),
|
||||
CAR.AVALON_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'),
|
||||
CAR.RAV4_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'),
|
||||
CAR.RAV4_TSS2_2022: dbc_dict('toyota_nodsu_pt_generated', None),
|
||||
CAR.RAV4_TSS2_2023: dbc_dict('toyota_nodsu_pt_generated', None),
|
||||
CAR.COROLLA_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'),
|
||||
CAR.LEXUS_ES: dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'),
|
||||
CAR.LEXUS_ES_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'),
|
||||
CAR.SIENNA: dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'),
|
||||
CAR.LEXUS_IS: dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'),
|
||||
CAR.LEXUS_IS_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'),
|
||||
CAR.LEXUS_CTH: dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'),
|
||||
CAR.LEXUS_NX: dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'),
|
||||
CAR.LEXUS_NX_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'),
|
||||
CAR.PRIUS_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'),
|
||||
CAR.MIRAI: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'),
|
||||
CAR.ALPHARD_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'),
|
||||
CAR.LEXUS_GS_F: dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'),
|
||||
}
|
||||
|
||||
# These cars have non-standard EPS torque scale factors. All others are 73
|
||||
EPS_SCALE = defaultdict(lambda: 73, {CAR.PRIUS: 66, CAR.COROLLA: 88, CAR.LEXUS_IS: 77, CAR.LEXUS_RC: 77, CAR.LEXUS_CTH: 100, CAR.PRIUS_V: 100})
|
||||
|
||||
# Toyota/Lexus Safety Sense 2.0 and 2.5
|
||||
TSS2_CAR = {CAR.RAV4_TSS2, CAR.RAV4_TSS2_2022, CAR.RAV4_TSS2_2023, CAR.COROLLA_TSS2, CAR.LEXUS_ES_TSS2,
|
||||
CAR.LEXUS_RX_TSS2, CAR.HIGHLANDER_TSS2, CAR.PRIUS_TSS2, CAR.CAMRY_TSS2, CAR.LEXUS_IS_TSS2,
|
||||
CAR.MIRAI, CAR.LEXUS_NX_TSS2, CAR.LEXUS_LC_TSS2, CAR.ALPHARD_TSS2, CAR.AVALON_TSS2,
|
||||
CAR.CHR_TSS2}
|
||||
TSS2_CAR = CAR.with_flags(ToyotaFlags.TSS2)
|
||||
|
||||
NO_DSU_CAR = TSS2_CAR | {CAR.CHR, CAR.CAMRY}
|
||||
NO_DSU_CAR = CAR.with_flags(ToyotaFlags.NO_DSU)
|
||||
|
||||
# the DSU uses the AEB message for longitudinal on these cars
|
||||
UNSUPPORTED_DSU_CAR = {CAR.LEXUS_IS, CAR.LEXUS_RC, CAR.LEXUS_GS_F}
|
||||
UNSUPPORTED_DSU_CAR = CAR.with_flags(ToyotaFlags.UNSUPPORTED_DSU)
|
||||
|
||||
# these cars have a radar which sends ACC messages instead of the camera
|
||||
RADAR_ACC_CAR = {CAR.RAV4_TSS2_2022, CAR.RAV4_TSS2_2023, CAR.CHR_TSS2}
|
||||
RADAR_ACC_CAR = CAR.with_flags(ToyotaFlags.RADAR_ACC)
|
||||
|
||||
# these cars use the Lane Tracing Assist (LTA) message for lateral control
|
||||
ANGLE_CONTROL_CAR = {CAR.RAV4_TSS2_2023}
|
||||
ANGLE_CONTROL_CAR = CAR.with_flags(ToyotaFlags.ANGLE_CONTROL)
|
||||
|
||||
# no resume button press required
|
||||
NO_STOP_TIMER_CAR = TSS2_CAR | {CAR.PRIUS_V, CAR.RAV4H, CAR.HIGHLANDER, CAR.SIENNA}
|
||||
NO_STOP_TIMER_CAR = CAR.with_flags(ToyotaFlags.NO_STOP_TIMER)
|
||||
|
||||
# stop and go
|
||||
STOP_AND_GO_CAR = TSS2_CAR | {CAR.PRIUS, CAR.PRIUS_V, CAR.RAV4H, CAR.LEXUS_RX, CAR.CHR, CAR.CAMRY, CAR.HIGHLANDER,
|
||||
CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_NX, CAR.MIRAI, CAR.AVALON_2019}
|
||||
|
||||
DBC = CAR.create_dbc_map()
|
||||
|
||||
Reference in New Issue
Block a user