Subaru: Forester Hybrid 2020 dashcam (#24770)

* Add support for Forester Hybrid 2020

Co-authored-by: martinl <martin@mlp.ee>

* it's a param now

* make it work

* fix

* merge and cleanup

* remove duplicate

* should be forester

* bump submodules

* should be abs

* add missing params

* still need a test route

* still need a test route

* consitent

* here too

* todo

* more

* Update selfdrive/car/tests/routes.py

* clean up

---------

Co-authored-by: martinl <martin@mlp.ee>
Co-authored-by: Justin Newberry <jnewberry0502@gmail.com>
old-commit-hash: 3719be8b76
beeps
Shane Smiskol 2 years ago committed by GitHub
parent 1a787910a8
commit acec4fc22f
  1. 3
      selfdrive/car/subaru/carcontroller.py
  2. 10
      selfdrive/car/subaru/carstate.py
  3. 8
      selfdrive/car/subaru/interface.py
  4. 22
      selfdrive/car/subaru/values.py
  5. 1
      selfdrive/car/tests/routes.py
  6. 1
      selfdrive/car/torque_data/substitute.yaml

@ -2,8 +2,7 @@ from openpilot.common.numpy_fast import clip, interp
from opendbc.can.packer import CANPacker from opendbc.can.packer import CANPacker
from openpilot.selfdrive.car import apply_driver_steer_torque_limits from openpilot.selfdrive.car import apply_driver_steer_torque_limits
from openpilot.selfdrive.car.subaru import subarucan from openpilot.selfdrive.car.subaru import subarucan
from openpilot.selfdrive.car.subaru.values import DBC, GLOBAL_GEN2, PREGLOBAL_CARS, CanBus, CarControllerParams, SubaruFlags from openpilot.selfdrive.car.subaru.values import DBC, GLOBAL_GEN2, PREGLOBAL_CARS, HYBRID_CARS, CanBus, CarControllerParams, SubaruFlags
from selfdrive.car.subaru.values import HYBRID_CARS
class CarController: class CarController:

@ -4,9 +4,8 @@ from opendbc.can.can_define import CANDefine
from openpilot.common.conversions import Conversions as CV from openpilot.common.conversions import Conversions as CV
from openpilot.selfdrive.car.interfaces import CarStateBase from openpilot.selfdrive.car.interfaces import CarStateBase
from opendbc.can.parser import CANParser from opendbc.can.parser import CANParser
from openpilot.selfdrive.car.subaru.values import DBC, CAR, GLOBAL_GEN2, PREGLOBAL_CARS, CanBus, SubaruFlags from openpilot.selfdrive.car.subaru.values import DBC, CAR, GLOBAL_GEN2, PREGLOBAL_CARS, HYBRID_CARS, CanBus, SubaruFlags
from openpilot.selfdrive.car import CanSignalRateCalculator from openpilot.selfdrive.car import CanSignalRateCalculator
from selfdrive.car.subaru.values import HYBRID_CARS
class CarState(CarStateBase): class CarState(CarStateBase):
@ -101,17 +100,18 @@ class CarState(CarStateBase):
self.es_brake_msg = copy.copy(cp_es_brake.vl["ES_Brake"]) self.es_brake_msg = copy.copy(cp_es_brake.vl["ES_Brake"])
cp_es_status = cp_body if self.car_fingerprint in GLOBAL_GEN2 else cp_cam cp_es_status = cp_body if self.car_fingerprint in GLOBAL_GEN2 else cp_cam
if self.car_fingerprint not in HYBRID_CARS: # Hybrid cars don't have es_distance, need a replacement # TODO: Hybrid cars don't have ES_Distance, need a replacement
if self.car_fingerprint not in HYBRID_CARS:
# 8 is known AEB, there are a few other values related to AEB we ignore # 8 is known AEB, there are a few other values related to AEB we ignore
ret.stockAeb = (cp_es_distance.vl["ES_Brake"]["AEB_Status"] == 8) and \ ret.stockAeb = (cp_es_distance.vl["ES_Brake"]["AEB_Status"] == 8) and \
(cp_es_distance.vl["ES_Brake"]["Brake_Pressure"] != 0) (cp_es_distance.vl["ES_Brake"]["Brake_Pressure"] != 0)
self.es_distance_msg = copy.copy(cp_es_distance.vl["ES_Distance"])
self.es_status_msg = copy.copy(cp_es_status.vl["ES_Status"]) self.es_status_msg = copy.copy(cp_es_status.vl["ES_Status"])
self.cruise_control_msg = copy.copy(cp_cruise.vl["CruiseControl"]) self.cruise_control_msg = copy.copy(cp_cruise.vl["CruiseControl"])
if self.car_fingerprint not in HYBRID_CARS: if self.car_fingerprint not in HYBRID_CARS:
self.es_distance_msg = copy.copy(cp_es_distance.vl["ES_Distance"]) self.es_distance_msg = copy.copy(cp_es_distance.vl["ES_Distance"])
self.es_dashstatus_msg = copy.copy(cp_cam.vl["ES_DashStatus"]) self.es_dashstatus_msg = copy.copy(cp_cam.vl["ES_DashStatus"])
if self.CP.flags & SubaruFlags.SEND_INFOTAINMENT: if self.CP.flags & SubaruFlags.SEND_INFOTAINMENT:
self.es_infotainment_msg = copy.copy(cp_cam.vl["ES_Infotainment"]) self.es_infotainment_msg = copy.copy(cp_cam.vl["ES_Infotainment"])

@ -13,9 +13,9 @@ class CarInterface(CarInterfaceBase):
ret.carName = "subaru" ret.carName = "subaru"
ret.radarUnavailable = True ret.radarUnavailable = True
# for HYBRID CARS to be upstreamed, we need: # for HYBRID CARS to be upstreamed, we need:
# - replacement for ES_Distance so we can cancel the cruise control # - replacement for ES_Distance so we can cancel the cruise control
# - to find the Cruise_Activated bit from the car # - to find the Cruise_Activated bit from the car
# - proper panda safety setup (use the correct cruise_activated bit, throttle from Throttle_Hybrid, etc) # - proper panda safety setup (use the correct cruise_activated bit, throttle from Throttle_Hybrid, etc)
ret.dashcamOnly = candidate in (PREGLOBAL_CARS | LKAS_ANGLE | HYBRID_CARS) ret.dashcamOnly = candidate in (PREGLOBAL_CARS | LKAS_ANGLE | HYBRID_CARS)
ret.autoResumeSng = False ret.autoResumeSng = False
@ -79,7 +79,7 @@ class CarInterface(CarInterfaceBase):
ret.steerRatio = 17 ret.steerRatio = 17
ret.steerActuatorDelay = 0.1 ret.steerActuatorDelay = 0.1
elif candidate in (CAR.FORESTER, CAR.FORESTER_2022): elif candidate in (CAR.FORESTER, CAR.FORESTER_2022, CAR.FORESTER_HYBRID):
ret.mass = 1568. ret.mass = 1568.
ret.wheelbase = 2.67 ret.wheelbase = 2.67
ret.centerToFront = ret.wheelbase * 0.5 ret.centerToFront = ret.wheelbase * 0.5

@ -71,6 +71,7 @@ class CAR:
FORESTER = "SUBARU FORESTER 2019" FORESTER = "SUBARU FORESTER 2019"
OUTBACK = "SUBARU OUTBACK 6TH GEN" OUTBACK = "SUBARU OUTBACK 6TH GEN"
CROSSTREK_HYBRID = "SUBARU CROSSTREK HYBRID 2020" CROSSTREK_HYBRID = "SUBARU CROSSTREK HYBRID 2020"
FORESTER_HYBRID = "SUBARU FORESTER HYBRID 2020"
LEGACY = "SUBARU LEGACY 7TH GEN" LEGACY = "SUBARU LEGACY 7TH GEN"
FORESTER_2022 = "SUBARU FORESTER 2022" FORESTER_2022 = "SUBARU FORESTER 2022"
OUTBACK_2023 = "SUBARU OUTBACK 7TH GEN" OUTBACK_2023 = "SUBARU OUTBACK 7TH GEN"
@ -113,6 +114,7 @@ CAR_INFO: Dict[str, Union[SubaruCarInfo, List[SubaruCarInfo]]] = {
], ],
# TODO: is there an XV and Impreza too? # TODO: is there an XV and Impreza too?
CAR.CROSSTREK_HYBRID: SubaruCarInfo("Subaru Crosstrek Hybrid 2020"), CAR.CROSSTREK_HYBRID: SubaruCarInfo("Subaru Crosstrek Hybrid 2020"),
CAR.FORESTER_HYBRID: SubaruCarInfo("Subaru Forester Hybrid 2020"),
CAR.FORESTER: SubaruCarInfo("Subaru Forester 2019-21", "All"), CAR.FORESTER: SubaruCarInfo("Subaru Forester 2019-21", "All"),
CAR.FORESTER_PREGLOBAL: SubaruCarInfo("Subaru Forester 2017-18"), CAR.FORESTER_PREGLOBAL: SubaruCarInfo("Subaru Forester 2017-18"),
CAR.LEGACY_PREGLOBAL: SubaruCarInfo("Subaru Legacy 2015-18"), CAR.LEGACY_PREGLOBAL: SubaruCarInfo("Subaru Legacy 2015-18"),
@ -389,6 +391,23 @@ FW_VERSIONS = {
b'\x1a\xe6F1\x00', b'\x1a\xe6F1\x00',
], ],
}, },
CAR.FORESTER_HYBRID: {
(Ecu.abs, 0x7b0, None): [
b'\xa3 \x19T\x00',
],
(Ecu.eps, 0x746, None): [
b'\x8d\xc2\x00\x00',
],
(Ecu.fwdCamera, 0x787, None): [
b'\x00\x00eY\x1f@ !',
],
(Ecu.engine, 0x7e0, None): [
b'\xd2\xa1`r\x07',
],
(Ecu.transmission, 0x7e1, None): [
b'\x1b\xa7@a\x00',
],
},
CAR.FORESTER_PREGLOBAL: { CAR.FORESTER_PREGLOBAL: {
(Ecu.abs, 0x7b0, None): [ (Ecu.abs, 0x7b0, None): [
b'\x7d\x97\x14\x40', b'\x7d\x97\x14\x40',
@ -649,6 +668,7 @@ DBC = {
CAR.FORESTER: dbc_dict('subaru_global_2017_generated', None), CAR.FORESTER: dbc_dict('subaru_global_2017_generated', None),
CAR.FORESTER_2022: dbc_dict('subaru_global_2017_generated', None), CAR.FORESTER_2022: dbc_dict('subaru_global_2017_generated', None),
CAR.OUTBACK: dbc_dict('subaru_global_2017_generated', None), CAR.OUTBACK: dbc_dict('subaru_global_2017_generated', None),
CAR.FORESTER_HYBRID: dbc_dict('subaru_global_2020_hybrid_generated', None),
CAR.CROSSTREK_HYBRID: dbc_dict('subaru_global_2020_hybrid_generated', None), CAR.CROSSTREK_HYBRID: dbc_dict('subaru_global_2020_hybrid_generated', None),
CAR.OUTBACK_2023: dbc_dict('subaru_global_2017_generated', None), CAR.OUTBACK_2023: dbc_dict('subaru_global_2017_generated', None),
CAR.LEGACY: dbc_dict('subaru_global_2017_generated', None), CAR.LEGACY: dbc_dict('subaru_global_2017_generated', None),
@ -661,4 +681,4 @@ DBC = {
LKAS_ANGLE = {CAR.FORESTER_2022, CAR.OUTBACK_2023} LKAS_ANGLE = {CAR.FORESTER_2022, CAR.OUTBACK_2023}
GLOBAL_GEN2 = {CAR.OUTBACK, CAR.LEGACY, CAR.OUTBACK_2023} GLOBAL_GEN2 = {CAR.OUTBACK, CAR.LEGACY, CAR.OUTBACK_2023}
PREGLOBAL_CARS = {CAR.FORESTER_PREGLOBAL, CAR.LEGACY_PREGLOBAL, CAR.OUTBACK_PREGLOBAL, CAR.OUTBACK_PREGLOBAL_2018} PREGLOBAL_CARS = {CAR.FORESTER_PREGLOBAL, CAR.LEGACY_PREGLOBAL, CAR.OUTBACK_PREGLOBAL, CAR.OUTBACK_PREGLOBAL_2018}
HYBRID_CARS = {CAR.CROSSTREK_HYBRID, } HYBRID_CARS = {CAR.CROSSTREK_HYBRID, CAR.FORESTER_HYBRID}

@ -28,6 +28,7 @@ non_tested_cars = [
VOLKSWAGEN.CRAFTER_MK2, # need a route from an ACC-equipped Crafter VOLKSWAGEN.CRAFTER_MK2, # need a route from an ACC-equipped Crafter
TOYOTA.RAV4_TSS2_2023, TOYOTA.RAV4_TSS2_2023,
TOYOTA.RAV4H_TSS2_2023, TOYOTA.RAV4H_TSS2_2023,
SUBARU.FORESTER_HYBRID,
] ]

@ -77,6 +77,7 @@ SEAT LEON 3RD GEN: VOLKSWAGEN GOLF 7TH GEN
SEAT ATECA 1ST GEN: VOLKSWAGEN GOLF 7TH GEN SEAT ATECA 1ST GEN: VOLKSWAGEN GOLF 7TH GEN
SUBARU CROSSTREK HYBRID 2020: SUBARU IMPREZA SPORT 2020 SUBARU CROSSTREK HYBRID 2020: SUBARU IMPREZA SPORT 2020
SUBARU FORESTER HYBRID 2020: SUBARU IMPREZA SPORT 2020
SUBARU LEGACY 7TH GEN: SUBARU OUTBACK 6TH GEN SUBARU LEGACY 7TH GEN: SUBARU OUTBACK 6TH GEN
# Old subarus don't have much data guessing it's like low torque impreza # Old subarus don't have much data guessing it's like low torque impreza

Loading…
Cancel
Save