mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-02-18 15:23:57 +08:00
Subaru: 2020 Outback support (#25248)
* Subaru: 2020 Outback support * bump panda * bump panda * update refs * update refs
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
Version 0.8.16 (2022-XX-XX)
|
||||
========================
|
||||
* Subaru Outback 2020-22 support
|
||||
|
||||
Version 0.8.15 (2022-07-20)
|
||||
========================
|
||||
|
||||
@@ -19,7 +19,7 @@ A supported vehicle is one that just works when you install a comma device. Ever
|
||||
- [](##) - Limited ability to make tighter turns.
|
||||
|
||||
|
||||
# 196 Supported Cars
|
||||
# 197 Supported Cars
|
||||
|
||||
|Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque|
|
||||
|---|---|---|:---:|:---:|:---:|:---:|
|
||||
@@ -139,6 +139,7 @@ A supported vehicle is one that just works when you install a comma device. Ever
|
||||
|Subaru|Forester 2019-21|All|[](##)|[](##)|[](##)|[](##)|
|
||||
|Subaru|Impreza 2017-19|EyeSight|[](##)|[](##)|[](##)|[](##)|
|
||||
|Subaru|Impreza 2020-22|EyeSight|[](##)|[](##)|[](##)|[](##)|
|
||||
|Subaru|Outback 2020-22|All|[](##)|[](##)|[](##)|[](##)|
|
||||
|Subaru|XV 2018-19|EyeSight|[](##)|[](##)|[](##)|[](##)|
|
||||
|Subaru|XV 2020-21|EyeSight|[](##)|[](##)|[](##)|[](##)|
|
||||
|Škoda|Kamiq 2021[<sup>6</sup>](#footnotes)|Driver Assistance|[](##)|[](##)|[](##)|[](##)|
|
||||
|
||||
2
panda
2
panda
Submodule panda updated: a1686ca3ca...4b86b83991
@@ -1,18 +1,21 @@
|
||||
from opendbc.can.packer import CANPacker
|
||||
from selfdrive.car import apply_std_steer_torque_limits
|
||||
from selfdrive.car.subaru import subarucan
|
||||
from selfdrive.car.subaru.values import DBC, PREGLOBAL_CARS, CarControllerParams
|
||||
from selfdrive.car.subaru.values import DBC, GLOBAL_GEN2, PREGLOBAL_CARS, CarControllerParams
|
||||
|
||||
|
||||
class CarController:
|
||||
def __init__(self, dbc_name, CP, VM):
|
||||
self.CP = CP
|
||||
self.apply_steer_last = 0
|
||||
self.es_distance_cnt = -1
|
||||
self.es_lkas_cnt = -1
|
||||
self.cruise_button_prev = 0
|
||||
self.frame = 0
|
||||
|
||||
self.es_lkas_cnt = -1
|
||||
self.es_distance_cnt = -1
|
||||
self.es_dashstatus_cnt = -1
|
||||
self.cruise_button_prev = 0
|
||||
self.last_cancel_frame = 0
|
||||
|
||||
self.p = CarControllerParams(CP)
|
||||
self.packer = CANPacker(DBC[CP.carFingerprint]['pt'])
|
||||
|
||||
@@ -67,9 +70,14 @@ class CarController:
|
||||
self.es_distance_cnt = CS.es_distance_msg["COUNTER"]
|
||||
|
||||
else:
|
||||
if self.es_distance_cnt != CS.es_distance_msg["COUNTER"]:
|
||||
can_sends.append(subarucan.create_es_distance(self.packer, CS.es_distance_msg, pcm_cancel_cmd))
|
||||
self.es_distance_cnt = CS.es_distance_msg["COUNTER"]
|
||||
if pcm_cancel_cmd and (self.frame - self.last_cancel_frame) > 0.2:
|
||||
bus = 1 if self.CP.carFingerprint in GLOBAL_GEN2 else 0
|
||||
can_sends.append(subarucan.create_es_distance(self.packer, CS.es_distance_msg, bus, pcm_cancel_cmd))
|
||||
self.last_cancel_frame = self.frame
|
||||
|
||||
if self.es_dashstatus_cnt != CS.es_dashstatus_msg["COUNTER"]:
|
||||
can_sends.append(subarucan.create_es_dashstatus(self.packer, CS.es_dashstatus_msg))
|
||||
self.es_dashstatus_cnt = CS.es_dashstatus_msg["COUNTER"]
|
||||
|
||||
if self.es_lkas_cnt != CS.es_lkas_msg["COUNTER"]:
|
||||
can_sends.append(subarucan.create_es_lkas(self.packer, CS.es_lkas_msg, CC.enabled, hud_control.visualAlert,
|
||||
|
||||
@@ -4,7 +4,7 @@ from opendbc.can.can_define import CANDefine
|
||||
from common.conversions import Conversions as CV
|
||||
from selfdrive.car.interfaces import CarStateBase
|
||||
from opendbc.can.parser import CANParser
|
||||
from selfdrive.car.subaru.values import DBC, STEER_THRESHOLD, CAR, PREGLOBAL_CARS
|
||||
from selfdrive.car.subaru.values import DBC, STEER_THRESHOLD, CAR, GLOBAL_GEN2, PREGLOBAL_CARS
|
||||
|
||||
|
||||
class CarState(CarStateBase):
|
||||
@@ -13,7 +13,7 @@ class CarState(CarStateBase):
|
||||
can_define = CANDefine(DBC[CP.carFingerprint]["pt"])
|
||||
self.shifter_values = can_define.dv["Transmission"]["Gear"]
|
||||
|
||||
def update(self, cp, cp_cam):
|
||||
def update(self, cp, cp_cam, cp_body):
|
||||
ret = car.CarState.new_message()
|
||||
|
||||
ret.gas = cp.vl["Throttle"]["Throttle_Pedal"] / 255.
|
||||
@@ -21,13 +21,15 @@ class CarState(CarStateBase):
|
||||
if self.car_fingerprint in PREGLOBAL_CARS:
|
||||
ret.brakePressed = cp.vl["Brake_Pedal"]["Brake_Pedal"] > 2
|
||||
else:
|
||||
ret.brakePressed = cp.vl["Brake_Status"]["Brake"] == 1
|
||||
cp_brakes = cp_body if self.car_fingerprint in GLOBAL_GEN2 else cp
|
||||
ret.brakePressed = cp_brakes.vl["Brake_Status"]["Brake"] == 1
|
||||
|
||||
cp_wheels = cp_body if self.car_fingerprint in GLOBAL_GEN2 else cp
|
||||
ret.wheelSpeeds = self.get_wheel_speeds(
|
||||
cp.vl["Wheel_Speeds"]["FL"],
|
||||
cp.vl["Wheel_Speeds"]["FR"],
|
||||
cp.vl["Wheel_Speeds"]["RL"],
|
||||
cp.vl["Wheel_Speeds"]["RR"],
|
||||
cp_wheels.vl["Wheel_Speeds"]["FL"],
|
||||
cp_wheels.vl["Wheel_Speeds"]["FR"],
|
||||
cp_wheels.vl["Wheel_Speeds"]["RL"],
|
||||
cp_wheels.vl["Wheel_Speeds"]["RR"],
|
||||
)
|
||||
ret.vEgoRaw = (ret.wheelSpeeds.fl + ret.wheelSpeeds.fr + ret.wheelSpeeds.rl + ret.wheelSpeeds.rr) / 4.
|
||||
# Kalman filter, even though Subaru raw wheel speed is heaviliy filtered by default
|
||||
@@ -35,8 +37,8 @@ class CarState(CarStateBase):
|
||||
ret.standstill = ret.vEgoRaw < 0.01
|
||||
|
||||
# continuous blinker signals for assisted lane change
|
||||
ret.leftBlinker, ret.rightBlinker = self.update_blinker_from_lamp(
|
||||
50, cp.vl["Dashlights"]["LEFT_BLINKER"], cp.vl["Dashlights"]["RIGHT_BLINKER"])
|
||||
ret.leftBlinker, ret.rightBlinker = self.update_blinker_from_lamp(50, cp.vl["Dashlights"]["LEFT_BLINKER"],
|
||||
cp.vl["Dashlights"]["RIGHT_BLINKER"])
|
||||
|
||||
if self.CP.enableBsm:
|
||||
ret.leftBlindspot = (cp.vl["BSD_RCTA"]["L_ADJACENT"] == 1) or (cp.vl["BSD_RCTA"]["L_APPROACHING"] == 1)
|
||||
@@ -50,8 +52,9 @@ class CarState(CarStateBase):
|
||||
ret.steeringTorqueEps = cp.vl["Steering_Torque"]["Steer_Torque_Output"]
|
||||
ret.steeringPressed = abs(ret.steeringTorque) > STEER_THRESHOLD[self.car_fingerprint]
|
||||
|
||||
ret.cruiseState.enabled = cp.vl["CruiseControl"]["Cruise_Activated"] != 0
|
||||
ret.cruiseState.available = cp.vl["CruiseControl"]["Cruise_On"] != 0
|
||||
cp_cruise = cp_body if self.car_fingerprint in GLOBAL_GEN2 else cp
|
||||
ret.cruiseState.enabled = cp_cruise.vl["CruiseControl"]["Cruise_Activated"] != 0
|
||||
ret.cruiseState.available = cp_cruise.vl["CruiseControl"]["Cruise_On"] != 0
|
||||
ret.cruiseState.speed = cp_cam.vl["ES_DashStatus"]["Cruise_Set_Speed"] * CV.KPH_TO_MS
|
||||
|
||||
if (self.car_fingerprint in PREGLOBAL_CARS and cp.vl["Dash_State2"]["UNITS"] == 1) or \
|
||||
@@ -72,10 +75,59 @@ class CarState(CarStateBase):
|
||||
ret.steerFaultTemporary = cp.vl["Steering_Torque"]["Steer_Warning"] == 1
|
||||
ret.cruiseState.nonAdaptive = cp_cam.vl["ES_DashStatus"]["Conventional_Cruise"] == 1
|
||||
self.es_lkas_msg = copy.copy(cp_cam.vl["ES_LKAS_State"])
|
||||
self.es_distance_msg = copy.copy(cp_cam.vl["ES_Distance"])
|
||||
|
||||
cp_es_distance = cp_body if self.car_fingerprint in GLOBAL_GEN2 else cp_cam
|
||||
self.es_distance_msg = copy.copy(cp_es_distance.vl["ES_Distance"])
|
||||
self.es_dashstatus_msg = copy.copy(cp_cam.vl["ES_DashStatus"])
|
||||
|
||||
return ret
|
||||
|
||||
@staticmethod
|
||||
def get_common_global_signals():
|
||||
signals = [
|
||||
("Cruise_On", "CruiseControl"),
|
||||
("Cruise_Activated", "CruiseControl"),
|
||||
("FL", "Wheel_Speeds"),
|
||||
("FR", "Wheel_Speeds"),
|
||||
("RL", "Wheel_Speeds"),
|
||||
("RR", "Wheel_Speeds"),
|
||||
("Brake", "Brake_Status"),
|
||||
]
|
||||
checks = [
|
||||
("CruiseControl", 20),
|
||||
("Wheel_Speeds", 50),
|
||||
("Brake_Status", 50),
|
||||
]
|
||||
|
||||
return signals, checks
|
||||
|
||||
@staticmethod
|
||||
def get_global_es_distance_signals():
|
||||
signals = [
|
||||
("COUNTER", "ES_Distance"),
|
||||
("Signal1", "ES_Distance"),
|
||||
("Cruise_Fault", "ES_Distance"),
|
||||
("Cruise_Throttle", "ES_Distance"),
|
||||
("Signal2", "ES_Distance"),
|
||||
("Car_Follow", "ES_Distance"),
|
||||
("Signal3", "ES_Distance"),
|
||||
("Cruise_Brake_Active", "ES_Distance"),
|
||||
("Distance_Swap", "ES_Distance"),
|
||||
("Cruise_EPB", "ES_Distance"),
|
||||
("Signal4", "ES_Distance"),
|
||||
("Close_Distance", "ES_Distance"),
|
||||
("Signal5", "ES_Distance"),
|
||||
("Cruise_Cancel", "ES_Distance"),
|
||||
("Cruise_Set", "ES_Distance"),
|
||||
("Cruise_Resume", "ES_Distance"),
|
||||
("Signal6", "ES_Distance"),
|
||||
]
|
||||
checks = [
|
||||
("ES_Distance", 20),
|
||||
]
|
||||
|
||||
return signals, checks
|
||||
|
||||
@staticmethod
|
||||
def get_can_parser(CP):
|
||||
signals = [
|
||||
@@ -84,17 +136,11 @@ class CarState(CarStateBase):
|
||||
("Steer_Torque_Output", "Steering_Torque"),
|
||||
("Steering_Angle", "Steering_Torque"),
|
||||
("Steer_Error_1", "Steering_Torque"),
|
||||
("Cruise_On", "CruiseControl"),
|
||||
("Cruise_Activated", "CruiseControl"),
|
||||
("Brake_Pedal", "Brake_Pedal"),
|
||||
("Throttle_Pedal", "Throttle"),
|
||||
("LEFT_BLINKER", "Dashlights"),
|
||||
("RIGHT_BLINKER", "Dashlights"),
|
||||
("SEATBELT_FL", "Dashlights"),
|
||||
("FL", "Wheel_Speeds"),
|
||||
("FR", "Wheel_Speeds"),
|
||||
("RL", "Wheel_Speeds"),
|
||||
("RR", "Wheel_Speeds"),
|
||||
("DOOR_OPEN_FR", "BodyInfo"),
|
||||
("DOOR_OPEN_FL", "BodyInfo"),
|
||||
("DOOR_OPEN_RR", "BodyInfo"),
|
||||
@@ -107,7 +153,6 @@ class CarState(CarStateBase):
|
||||
("Throttle", 100),
|
||||
("Dashlights", 10),
|
||||
("Brake_Pedal", 50),
|
||||
("Wheel_Speeds", 50),
|
||||
("Transmission", 100),
|
||||
("Steering_Torque", 50),
|
||||
("BodyInfo", 1),
|
||||
@@ -123,35 +168,46 @@ class CarState(CarStateBase):
|
||||
checks.append(("BSD_RCTA", 17))
|
||||
|
||||
if CP.carFingerprint not in PREGLOBAL_CARS:
|
||||
if CP.carFingerprint not in GLOBAL_GEN2:
|
||||
signals += CarState.get_common_global_signals()[0]
|
||||
checks += CarState.get_common_global_signals()[1]
|
||||
|
||||
signals += [
|
||||
("Steer_Warning", "Steering_Torque"),
|
||||
("Brake", "Brake_Status"),
|
||||
("UNITS", "Dashlights"),
|
||||
]
|
||||
|
||||
checks += [
|
||||
("Dashlights", 10),
|
||||
("BodyInfo", 10),
|
||||
("Brake_Status", 50),
|
||||
("CruiseControl", 20),
|
||||
]
|
||||
else:
|
||||
signals.append(("UNITS", "Dash_State2"))
|
||||
|
||||
checks.append(("Dash_State2", 1))
|
||||
|
||||
if CP.carFingerprint == CAR.FORESTER_PREGLOBAL:
|
||||
signals += [
|
||||
("FL", "Wheel_Speeds"),
|
||||
("FR", "Wheel_Speeds"),
|
||||
("RL", "Wheel_Speeds"),
|
||||
("RR", "Wheel_Speeds"),
|
||||
("UNITS", "Dash_State2"),
|
||||
("Cruise_On", "CruiseControl"),
|
||||
("Cruise_Activated", "CruiseControl"),
|
||||
]
|
||||
checks += [
|
||||
("Dashlights", 20),
|
||||
("BodyInfo", 1),
|
||||
("CruiseControl", 50),
|
||||
("Wheel_Speeds", 50),
|
||||
("Dash_State2", 1),
|
||||
]
|
||||
|
||||
if CP.carFingerprint in (CAR.LEGACY_PREGLOBAL, CAR.OUTBACK_PREGLOBAL, CAR.OUTBACK_PREGLOBAL_2018):
|
||||
checks += [
|
||||
("Dashlights", 10),
|
||||
("CruiseControl", 50),
|
||||
]
|
||||
if CP.carFingerprint == CAR.FORESTER_PREGLOBAL:
|
||||
checks += [
|
||||
("Dashlights", 20),
|
||||
("BodyInfo", 1),
|
||||
("CruiseControl", 50),
|
||||
]
|
||||
|
||||
if CP.carFingerprint in (CAR.LEGACY_PREGLOBAL, CAR.OUTBACK_PREGLOBAL, CAR.OUTBACK_PREGLOBAL_2018):
|
||||
checks += [
|
||||
("Dashlights", 10),
|
||||
("CruiseControl", 50),
|
||||
]
|
||||
|
||||
return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 0)
|
||||
|
||||
@@ -187,26 +243,32 @@ class CarState(CarStateBase):
|
||||
]
|
||||
else:
|
||||
signals = [
|
||||
("Cruise_Set_Speed", "ES_DashStatus"),
|
||||
("Counter", "ES_DashStatus"),
|
||||
("PCB_Off", "ES_DashStatus"),
|
||||
("LDW_Off", "ES_DashStatus"),
|
||||
("Signal1", "ES_DashStatus"),
|
||||
("Cruise_State_Msg", "ES_DashStatus"),
|
||||
("LKAS_State_Msg", "ES_DashStatus"),
|
||||
("Signal2", "ES_DashStatus"),
|
||||
("Cruise_Soft_Disable", "ES_DashStatus"),
|
||||
("EyeSight_Status_Msg", "ES_DashStatus"),
|
||||
("Signal3", "ES_DashStatus"),
|
||||
("Cruise_Distance", "ES_DashStatus"),
|
||||
("Signal4", "ES_DashStatus"),
|
||||
("Conventional_Cruise", "ES_DashStatus"),
|
||||
|
||||
("COUNTER", "ES_Distance"),
|
||||
("Signal1", "ES_Distance"),
|
||||
("Cruise_Fault", "ES_Distance"),
|
||||
("Cruise_Throttle", "ES_Distance"),
|
||||
("Signal2", "ES_Distance"),
|
||||
("Car_Follow", "ES_Distance"),
|
||||
("Signal3", "ES_Distance"),
|
||||
("Cruise_Brake_Active", "ES_Distance"),
|
||||
("Distance_Swap", "ES_Distance"),
|
||||
("Cruise_EPB", "ES_Distance"),
|
||||
("Signal4", "ES_Distance"),
|
||||
("Close_Distance", "ES_Distance"),
|
||||
("Signal5", "ES_Distance"),
|
||||
("Cruise_Cancel", "ES_Distance"),
|
||||
("Cruise_Set", "ES_Distance"),
|
||||
("Cruise_Resume", "ES_Distance"),
|
||||
("Signal6", "ES_Distance"),
|
||||
("Signal5", "ES_DashStatus"),
|
||||
("Cruise_Disengaged", "ES_DashStatus"),
|
||||
("Cruise_Activated", "ES_DashStatus"),
|
||||
("Signal6", "ES_DashStatus"),
|
||||
("Cruise_Set_Speed", "ES_DashStatus"),
|
||||
("Cruise_Fault", "ES_DashStatus"),
|
||||
("Cruise_On", "ES_DashStatus"),
|
||||
("Display_Own_Car", "ES_DashStatus"),
|
||||
("Brake_Lights", "ES_DashStatus"),
|
||||
("Car_Follow", "ES_DashStatus"),
|
||||
("Signal7", "ES_DashStatus"),
|
||||
("Far_Distance", "ES_DashStatus"),
|
||||
("Cruise_State", "ES_DashStatus"),
|
||||
|
||||
("COUNTER", "ES_LKAS_State"),
|
||||
("LKAS_Alert_Msg", "ES_LKAS_State"),
|
||||
@@ -227,8 +289,21 @@ class CarState(CarStateBase):
|
||||
|
||||
checks = [
|
||||
("ES_DashStatus", 10),
|
||||
("ES_Distance", 20),
|
||||
("ES_LKAS_State", 10),
|
||||
]
|
||||
|
||||
if CP.carFingerprint not in GLOBAL_GEN2:
|
||||
signals += CarState.get_global_es_distance_signals()[0]
|
||||
checks += CarState.get_global_es_distance_signals()[1]
|
||||
|
||||
return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 2)
|
||||
|
||||
@staticmethod
|
||||
def get_body_can_parser(CP):
|
||||
if CP.carFingerprint in GLOBAL_GEN2:
|
||||
signals, checks = CarState.get_common_global_signals()
|
||||
signals += CarState.get_global_es_distance_signals()[0]
|
||||
checks += CarState.get_global_es_distance_signals()[1]
|
||||
return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 1)
|
||||
|
||||
return None
|
||||
@@ -1,8 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
from cereal import car
|
||||
from panda import Panda
|
||||
from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config
|
||||
from selfdrive.car.interfaces import CarInterfaceBase
|
||||
from selfdrive.car.subaru.values import CAR, PREGLOBAL_CARS
|
||||
from selfdrive.car.subaru.values import CAR, GLOBAL_GEN2, PREGLOBAL_CARS
|
||||
|
||||
|
||||
class CarInterface(CarInterfaceBase):
|
||||
@@ -16,11 +17,13 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.dashcamOnly = candidate in PREGLOBAL_CARS
|
||||
|
||||
if candidate in PREGLOBAL_CARS:
|
||||
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.subaruLegacy)]
|
||||
ret.enableBsm = 0x25c in fingerprint[0]
|
||||
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.subaruLegacy)]
|
||||
else:
|
||||
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.subaru)]
|
||||
ret.enableBsm = 0x228 in fingerprint[0]
|
||||
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.subaru)]
|
||||
if candidate in GLOBAL_GEN2:
|
||||
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_SUBARU_GEN2
|
||||
|
||||
ret.steerLimitTimer = 0.4
|
||||
ret.steerActuatorDelay = 0.1
|
||||
@@ -68,6 +71,14 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0., 14., 23.], [0., 14., 23.]]
|
||||
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.01, 0.065, 0.2], [0.001, 0.015, 0.025]]
|
||||
|
||||
elif candidate == CAR.OUTBACK:
|
||||
ret.mass = 1568. + STD_CARGO_KG
|
||||
ret.wheelbase = 2.67
|
||||
ret.centerToFront = ret.wheelbase * 0.5
|
||||
ret.steerRatio = 17
|
||||
ret.steerActuatorDelay = 0.1
|
||||
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
|
||||
|
||||
elif candidate in (CAR.FORESTER_PREGLOBAL, CAR.OUTBACK_PREGLOBAL_2018):
|
||||
ret.safetyConfigs[0].safetyParam = 1 # Outback 2018-2019 and Forester have reversed driver torque signal
|
||||
ret.mass = 1568 + STD_CARGO_KG
|
||||
@@ -88,6 +99,9 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.centerToFront = ret.wheelbase * 0.5
|
||||
ret.steerRatio = 20 # learned, 14 stock
|
||||
|
||||
else:
|
||||
raise ValueError(f"unknown car: {candidate}")
|
||||
|
||||
# TODO: get actual value, for now starting with reasonable value for
|
||||
# civic and scaling by mass and wheelbase
|
||||
ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase)
|
||||
@@ -101,7 +115,7 @@ class CarInterface(CarInterfaceBase):
|
||||
# returns a car.CarState
|
||||
def _update(self, c):
|
||||
|
||||
ret = self.CS.update(self.cp, self.cp_cam)
|
||||
ret = self.CS.update(self.cp, self.cp_cam, self.cp_body)
|
||||
|
||||
ret.events = self.create_common_events(ret).to_msg()
|
||||
|
||||
|
||||
@@ -14,13 +14,12 @@ def create_steering_control(packer, apply_steer):
|
||||
def create_steering_status(packer):
|
||||
return packer.make_can_msg("ES_LKAS_State", 0, {})
|
||||
|
||||
def create_es_distance(packer, es_distance_msg, pcm_cancel_cmd):
|
||||
|
||||
def create_es_distance(packer, es_distance_msg, bus, pcm_cancel_cmd):
|
||||
values = copy.copy(es_distance_msg)
|
||||
values["COUNTER"] = (values["COUNTER"] + 1) % 0x10
|
||||
if pcm_cancel_cmd:
|
||||
values["Cruise_Cancel"] = 1
|
||||
|
||||
return packer.make_can_msg("ES_Distance", 0, values)
|
||||
return packer.make_can_msg("ES_Distance", bus, values)
|
||||
|
||||
def create_es_lkas(packer, es_lkas_msg, enabled, visual_alert, left_line, right_line, left_lane_depart, right_lane_depart):
|
||||
|
||||
@@ -34,6 +33,18 @@ def create_es_lkas(packer, es_lkas_msg, enabled, visual_alert, left_line, right_
|
||||
if values["LKAS_Alert"] == 27:
|
||||
values["LKAS_Alert"] = 0
|
||||
|
||||
# Filter the stock LKAS sending an audible alert when "Keep hands on wheel" alert is active (2020+ models)
|
||||
if values["LKAS_Alert"] == 28 and values["LKAS_Alert_Msg"] == 7:
|
||||
values["LKAS_Alert"] = 0
|
||||
|
||||
# Filter the stock LKAS sending an audible alert when "Keep hands on wheel OFF" alert is active (2020+ models)
|
||||
if values["LKAS_Alert"] == 30:
|
||||
values["LKAS_Alert"] = 0
|
||||
|
||||
# Filter the stock LKAS sending "Keep hands on wheel OFF" alert (2020+ models)
|
||||
if values["LKAS_Alert_Msg"] == 7:
|
||||
values["LKAS_Alert_Msg"] = 0
|
||||
|
||||
# Show Keep hands on wheel alert for openpilot steerRequired alert
|
||||
if visual_alert == VisualAlert.steerRequired:
|
||||
values["LKAS_Alert_Msg"] = 1
|
||||
@@ -56,6 +67,15 @@ def create_es_lkas(packer, es_lkas_msg, enabled, visual_alert, left_line, right_
|
||||
|
||||
return packer.make_can_msg("ES_LKAS_State", 0, values)
|
||||
|
||||
def create_es_dashstatus(packer, dashstatus_msg):
|
||||
values = copy.copy(dashstatus_msg)
|
||||
|
||||
# Filter stock LKAS disabled and Keep hands on steering wheel OFF alerts
|
||||
if values["LKAS_State_Msg"] in [2, 3]:
|
||||
values["LKAS_State_Msg"] = 0
|
||||
|
||||
return packer.make_can_msg("ES_DashStatus", 0, values)
|
||||
|
||||
# *** Subaru Pre-global ***
|
||||
|
||||
def subaru_preglobal_checksum(packer, values, addr):
|
||||
|
||||
@@ -11,23 +11,32 @@ Ecu = car.CarParams.Ecu
|
||||
|
||||
class CarControllerParams:
|
||||
def __init__(self, CP):
|
||||
if CP.carFingerprint == CAR.IMPREZA_2020:
|
||||
self.STEER_MAX = 1439
|
||||
else:
|
||||
self.STEER_MAX = 2047
|
||||
self.STEER_STEP = 2 # how often we update the steer cmd
|
||||
self.STEER_DELTA_UP = 50 # torque increase per refresh, 0.8s to max
|
||||
self.STEER_DELTA_DOWN = 70 # torque decrease per refresh
|
||||
self.STEER_DRIVER_ALLOWANCE = 60 # allowed driver torque before start limiting
|
||||
self.STEER_DRIVER_MULTIPLIER = 10 # weight driver torque heavily
|
||||
self.STEER_DRIVER_MULTIPLIER = 50 # weight driver torque heavily
|
||||
self.STEER_DRIVER_FACTOR = 1 # from dbc
|
||||
|
||||
if CP.carFingerprint in GLOBAL_GEN2:
|
||||
self.STEER_MAX = 1000
|
||||
self.STEER_DELTA_UP = 40
|
||||
self.STEER_DELTA_DOWN = 40
|
||||
elif CP.carFingerprint == CAR.IMPREZA_2020:
|
||||
self.STEER_MAX = 1439
|
||||
else:
|
||||
self.STEER_MAX = 2047
|
||||
|
||||
|
||||
class CAR:
|
||||
# Global platform
|
||||
ASCENT = "SUBARU ASCENT LIMITED 2019"
|
||||
IMPREZA = "SUBARU IMPREZA LIMITED 2019"
|
||||
IMPREZA_2020 = "SUBARU IMPREZA SPORT 2020"
|
||||
FORESTER = "SUBARU FORESTER 2019"
|
||||
OUTBACK = "SUBARU OUTBACK 6TH GEN"
|
||||
|
||||
# Pre-global
|
||||
FORESTER_PREGLOBAL = "SUBARU FORESTER 2017 - 2018"
|
||||
LEGACY_PREGLOBAL = "SUBARU LEGACY 2015 - 2018"
|
||||
OUTBACK_PREGLOBAL = "SUBARU OUTBACK 2015 - 2017"
|
||||
@@ -42,6 +51,7 @@ class SubaruCarInfo(CarInfo):
|
||||
|
||||
CAR_INFO: Dict[str, Union[SubaruCarInfo, List[SubaruCarInfo]]] = {
|
||||
CAR.ASCENT: SubaruCarInfo("Subaru Ascent 2019-21", "All"),
|
||||
CAR.OUTBACK: SubaruCarInfo("Subaru Outback 2020-22", "All"),
|
||||
CAR.IMPREZA: [
|
||||
SubaruCarInfo("Subaru Impreza 2017-19"),
|
||||
SubaruCarInfo("Subaru Crosstrek 2018-19", video_link="https://youtu.be/Agww7oE1k-s?t=26"),
|
||||
@@ -396,6 +406,47 @@ FW_VERSIONS = {
|
||||
b'\xbb\xfb\xe0`\000',
|
||||
],
|
||||
},
|
||||
CAR.OUTBACK: {
|
||||
(Ecu.esp, 0x7b0, None): [
|
||||
b'\xa1 \x06\x01',
|
||||
b'\xa1 \a\x00',
|
||||
b'\xa1 \b\001',
|
||||
b'\xa1 \x06\x00',
|
||||
b'\xa1 "\t\x01',
|
||||
b'\xa1 \x08\x02',
|
||||
b'\xa1 \x06\x02',
|
||||
b'\xa1 \x08\x00',
|
||||
],
|
||||
(Ecu.eps, 0x746, None): [
|
||||
b'\x9b\xc0\x10\x00',
|
||||
b'\x9b\xc0\x20\x00',
|
||||
b'\x1b\xc0\x10\x00',
|
||||
],
|
||||
(Ecu.fwdCamera, 0x787, None): [
|
||||
b'\x00\x00eJ\x00\x1f@ \x19\x00',
|
||||
b'\000\000e\x80\000\037@ \031\000',
|
||||
b'\x00\x00e\x9a\x00\x1f@ 1\x00',
|
||||
b'\x00\x00eJ\x00\x00\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.engine, 0x7e0, None): [
|
||||
b'\xbc,\xa0q\x07',
|
||||
b'\xbc\"`@\a',
|
||||
b'\xde"`0\a',
|
||||
b'\xf1\x82\xbc,\xa0q\a',
|
||||
b'\xf1\x82\xe3,\xa0@\x07',
|
||||
b'\xe2"`p\x07',
|
||||
b'\xf1\x82\xe2,\xa0@\x07',
|
||||
b'\xbc"`q\x07',
|
||||
],
|
||||
(Ecu.transmission, 0x7e1, None): [
|
||||
b'\xa5\xfe\xf7@\x00',
|
||||
b'\xa5\xf6D@\x00',
|
||||
b'\xa5\xfe\xf6@\x00',
|
||||
b'\xa7\x8e\xf40\x00',
|
||||
b'\xf1\x82\xa7\xf6D@\x00',
|
||||
b'\xa7\xfe\xf4@\x00',
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
STEER_THRESHOLD = {
|
||||
@@ -403,6 +454,7 @@ STEER_THRESHOLD = {
|
||||
CAR.IMPREZA: 80,
|
||||
CAR.IMPREZA_2020: 80,
|
||||
CAR.FORESTER: 80,
|
||||
CAR.OUTBACK: 80,
|
||||
CAR.FORESTER_PREGLOBAL: 75,
|
||||
CAR.LEGACY_PREGLOBAL: 75,
|
||||
CAR.OUTBACK_PREGLOBAL: 75,
|
||||
@@ -414,10 +466,12 @@ DBC = {
|
||||
CAR.IMPREZA: dbc_dict('subaru_global_2017_generated', None),
|
||||
CAR.IMPREZA_2020: dbc_dict('subaru_global_2017_generated', None),
|
||||
CAR.FORESTER: dbc_dict('subaru_global_2017_generated', None),
|
||||
CAR.OUTBACK: dbc_dict('subaru_global_2017_generated', None),
|
||||
CAR.FORESTER_PREGLOBAL: dbc_dict('subaru_forester_2017_generated', None),
|
||||
CAR.LEGACY_PREGLOBAL: dbc_dict('subaru_outback_2015_generated', None),
|
||||
CAR.OUTBACK_PREGLOBAL: dbc_dict('subaru_outback_2015_generated', None),
|
||||
CAR.OUTBACK_PREGLOBAL_2018: dbc_dict('subaru_outback_2019_generated', None),
|
||||
}
|
||||
|
||||
PREGLOBAL_CARS = [CAR.FORESTER_PREGLOBAL, CAR.LEGACY_PREGLOBAL, CAR.OUTBACK_PREGLOBAL, CAR.OUTBACK_PREGLOBAL_2018]
|
||||
GLOBAL_GEN2 = (CAR.OUTBACK, )
|
||||
PREGLOBAL_CARS = (CAR.FORESTER_PREGLOBAL, CAR.LEGACY_PREGLOBAL, CAR.OUTBACK_PREGLOBAL, CAR.OUTBACK_PREGLOBAL_2018)
|
||||
@@ -187,13 +187,11 @@ routes = [
|
||||
TestRoute("c321c6b697c5a5ff|2020-06-23--11-04-33", SUBARU.FORESTER),
|
||||
TestRoute("791340bc01ed993d|2019-03-10--16-28-08", SUBARU.IMPREZA),
|
||||
TestRoute("8bf7e79a3ce64055|2021-05-24--09-36-27", SUBARU.IMPREZA_2020),
|
||||
# Dashcam
|
||||
TestRoute("1bbe6bf2d62f58a8|2022-07-14--17-11-43", SUBARU.OUTBACK, segment=3),
|
||||
# Pre-global, dashcam
|
||||
TestRoute("95441c38ae8c130e|2020-06-08--12-10-17", SUBARU.FORESTER_PREGLOBAL),
|
||||
# Dashcam
|
||||
TestRoute("df5ca7660000fba8|2020-06-16--17-37-19", SUBARU.LEGACY_PREGLOBAL),
|
||||
# Dashcam
|
||||
TestRoute("5ab784f361e19b78|2020-06-08--16-30-41", SUBARU.OUTBACK_PREGLOBAL),
|
||||
# Dashcam
|
||||
TestRoute("e19eb5d5353b1ac1|2020-08-09--14-37-56", SUBARU.OUTBACK_PREGLOBAL_2018),
|
||||
|
||||
TestRoute("fbbfa6af821552b9|2020-03-03--08-09-43", NISSAN.XTRAIL),
|
||||
|
||||
@@ -22,6 +22,7 @@ COMMA BODY: [.nan, 1000, .nan]
|
||||
# Totally new cars
|
||||
KIA EV6 2022: [3.5, 2.5, 0.0]
|
||||
RAM 1500 5TH GEN: [2.0, 2.0, 0.0]
|
||||
SUBARU OUTBACK 6TH GEN: [2.3, 2.3, 0.11]
|
||||
|
||||
# Dashcam or fallback configured as ideal car
|
||||
mock: [10.0, 10, 0.0]
|
||||
|
||||
@@ -1 +1 @@
|
||||
912413daa4c36a788cf2c801fc49829d46ae3072
|
||||
01e23eec1394b07d2c537f0e28493b10e05923c2
|
||||
Reference in New Issue
Block a user