From 1f37eda0ffc2e6f0ff1279d275035b094861daee Mon Sep 17 00:00:00 2001 From: Martin Lillepuu Date: Sun, 23 Apr 2023 19:09:44 +0300 Subject: [PATCH 01/11] Subaru: Add stop and go using CC.cruiseControl.resume --- selfdrive/car/subaru/carcontroller.py | 24 ++++++++++++++++++++++++ selfdrive/car/subaru/carstate.py | 25 +++++++++++++++++++++++++ selfdrive/car/subaru/subarucan.py | 18 ++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/selfdrive/car/subaru/carcontroller.py b/selfdrive/car/subaru/carcontroller.py index c4246b3806c40c..11b7bf7fe7541a 100644 --- a/selfdrive/car/subaru/carcontroller.py +++ b/selfdrive/car/subaru/carcontroller.py @@ -16,6 +16,9 @@ def __init__(self, dbc_name, CP, VM): self.infotainmentstatus_cnt = -1 self.cruise_button_prev = 0 self.last_cancel_frame = 0 + self.acc_resume = False + self.acc_resume_cnt = 0 + self.throttle_cnt = -1 self.p = CarControllerParams(CP) self.packer = CANPacker(DBC[CP.carFingerprint]['pt']) @@ -47,6 +50,19 @@ def update(self, CC, CS, now_nanos): self.apply_steer_last = apply_steer + # *** stop and go *** + + throttle_cmd = False + + if CC.cruiseControl.resume: + self.acc_resume = True + + if CC.enabled and self.acc_resume: + if self.acc_resume_cnt < 6: + throttle_cmd = True + self.acc_resume_cnt += 1 + else: + self.acc_resume_cnt = 0 # *** alerts and pcm cancel *** @@ -70,6 +86,10 @@ def update(self, CC, CS, now_nanos): can_sends.append(subarucan.create_preglobal_es_distance(self.packer, cruise_button, CS.es_distance_msg)) self.es_distance_cnt = CS.es_distance_msg["COUNTER"] + if self.throttle_cnt != CS.throttle_msg["COUNTER"]: + can_sends.append(subarucan.create_preglobal_throttle(self.packer, CS.throttle_msg, throttle_cmd)) + self.throttle_cnt = CS.throttle_msg["COUNTER"] + else: if pcm_cancel_cmd and (self.frame - self.last_cancel_frame) > 0.2: bus = 1 if self.CP.carFingerprint in GLOBAL_GEN2 else 0 @@ -90,6 +110,10 @@ def update(self, CC, CS, now_nanos): can_sends.append(subarucan.create_infotainmentstatus(self.packer, CS.es_infotainmentstatus_msg, hud_control.visualAlert)) self.infotainmentstatus_cnt = CS.es_infotainmentstatus_msg["COUNTER"] + if self.throttle_cnt != CS.throttle_msg["COUNTER"]: + can_sends.append(subarucan.create_throttle(self.packer, CS.throttle_msg, throttle_cmd)) + self.throttle_cnt = CS.throttle_msg["COUNTER"] + new_actuators = actuators.copy() new_actuators.steer = self.apply_steer_last / self.p.STEER_MAX new_actuators.steerOutputCan = self.apply_steer_last diff --git a/selfdrive/car/subaru/carstate.py b/selfdrive/car/subaru/carstate.py index e83129a71dc485..eab374b8b39ca6 100644 --- a/selfdrive/car/subaru/carstate.py +++ b/selfdrive/car/subaru/carstate.py @@ -79,6 +79,7 @@ def update(self, cp, cp_cam, cp_body): ret.stockFcw = cp_cam.vl["ES_LKAS_State"]["LKAS_Alert"] == 2 self.es_lkas_state_msg = copy.copy(cp_cam.vl["ES_LKAS_State"]) + self.throttle_msg = copy.copy(cp.vl["Throttle"]) 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"]) @@ -180,6 +181,16 @@ def get_can_parser(CP): checks += CarState.get_common_global_signals()[1] signals += [ + ("COUNTER", "Throttle"), + ("Signal1", "Throttle"), + ("Engine_RPM", "Throttle"), + ("Signal2", "Throttle"), + ("Throttle_Pedal", "Throttle"), + ("Throttle_Cruise", "Throttle"), + ("Throttle_Combo", "Throttle"), + ("Signal1", "Throttle"), + ("Off_Accel", "Throttle"), + ("Steer_Warning", "Steering_Torque"), ("UNITS", "Dashlights"), ] @@ -190,6 +201,20 @@ def get_can_parser(CP): ] else: signals += [ + ("Throttle_Pedal", "Throttle"), + ("COUNTER", "Throttle"), + ("Signal1", "Throttle"), + ("Not_Full_Throttle", "Throttle"), + ("Signal2", "Throttle"), + ("Engine_RPM", "Throttle"), + ("Off_Throttle", "Throttle"), + ("Signal3", "Throttle"), + ("Throttle_Cruise", "Throttle"), + ("Throttle_Combo", "Throttle"), + ("Throttle_Body", "Throttle"), + ("Off_Throttle_2", "Throttle"), + ("Signal4", "Throttle"), + ("FL", "Wheel_Speeds"), ("FR", "Wheel_Speeds"), ("RL", "Wheel_Speeds"), diff --git a/selfdrive/car/subaru/subarucan.py b/selfdrive/car/subaru/subarucan.py index 166166a50b4876..12a5eee5841d4b 100644 --- a/selfdrive/car/subaru/subarucan.py +++ b/selfdrive/car/subaru/subarucan.py @@ -64,6 +64,14 @@ def create_es_lkas_state(packer, es_lkas_state_msg, enabled, visual_alert, left_ return packer.make_can_msg("ES_LKAS_State", 0, values) +def create_throttle(packer, throttle_msg, throttle_cmd): + + values = copy.copy(throttle_msg) + if throttle_cmd: + values["Throttle_Pedal"] = 5 + + return packer.make_can_msg("Throttle", 2, values) + def create_es_dashstatus(packer, dashstatus_msg): values = copy.copy(dashstatus_msg) @@ -111,3 +119,13 @@ def create_preglobal_es_distance(packer, cruise_button, es_distance_msg): values["Checksum"] = subaru_preglobal_checksum(packer, values, "ES_Distance") return packer.make_can_msg("ES_Distance", 0, values) + +def create_preglobal_throttle(packer, throttle_msg, throttle_cmd): + + values = copy.copy(throttle_msg) + if throttle_cmd: + values["Throttle_Pedal"] = 5 + + values["Checksum"] = subaru_preglobal_checksum(packer, values, "Throttle") + + return packer.make_can_msg("Throttle", 2, values) From 6a3909807a3df4115d6f4a5270402affc370a87a Mon Sep 17 00:00:00 2001 From: Martin Lillepuu Date: Sun, 23 Apr 2023 19:11:28 +0300 Subject: [PATCH 02/11] bump panda --- .gitmodules | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitmodules b/.gitmodules index 26f93ef164e782..2cecf69e99971b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,7 @@ [submodule "panda"] path = panda url = ../../commaai/panda.git + branch = subaru-long-sng [submodule "opendbc"] path = opendbc url = ../../commaai/opendbc.git From cd0d94fb1f7f4717d9625094eb1196f10f751dbf Mon Sep 17 00:00:00 2001 From: Martin Lillepuu Date: Sun, 23 Apr 2023 20:32:06 +0300 Subject: [PATCH 03/11] bump panda --- .gitmodules | 2 +- panda | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 2cecf69e99971b..de7fbc4cf80f4a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "panda"] path = panda - url = ../../commaai/panda.git + url = ../../martinl/panda.git branch = subaru-long-sng [submodule "opendbc"] path = opendbc diff --git a/panda b/panda index cf307348af6eb5..544be66708cf38 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit cf307348af6eb5d7bf4dc3f5a11e2d1f3feadfad +Subproject commit 544be66708cf38e228aac33bb221e63da131b94c From 85bf5a63461a5037ed5b22260e335bf627eff39d Mon Sep 17 00:00:00 2001 From: Martin Lillepuu Date: Sun, 23 Apr 2023 21:18:10 +0300 Subject: [PATCH 04/11] Clean up acc resume --- selfdrive/car/subaru/carcontroller.py | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/selfdrive/car/subaru/carcontroller.py b/selfdrive/car/subaru/carcontroller.py index 11b7bf7fe7541a..523224a630d143 100644 --- a/selfdrive/car/subaru/carcontroller.py +++ b/selfdrive/car/subaru/carcontroller.py @@ -16,8 +16,6 @@ def __init__(self, dbc_name, CP, VM): self.infotainmentstatus_cnt = -1 self.cruise_button_prev = 0 self.last_cancel_frame = 0 - self.acc_resume = False - self.acc_resume_cnt = 0 self.throttle_cnt = -1 self.p = CarControllerParams(CP) @@ -52,17 +50,7 @@ def update(self, CC, CS, now_nanos): # *** stop and go *** - throttle_cmd = False - - if CC.cruiseControl.resume: - self.acc_resume = True - - if CC.enabled and self.acc_resume: - if self.acc_resume_cnt < 6: - throttle_cmd = True - self.acc_resume_cnt += 1 - else: - self.acc_resume_cnt = 0 + throttle_cmd = True if CC.enabled and CC.cruiseControl.resume else False # *** alerts and pcm cancel *** From f10cbafd78214bb2dcbba9346a2156ce90d6de4f Mon Sep 17 00:00:00 2001 From: Martin Lillepuu Date: Sun, 23 Apr 2023 21:31:28 +0300 Subject: [PATCH 05/11] disable dashcam only for preglobal for testing --- selfdrive/car/subaru/interface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/car/subaru/interface.py b/selfdrive/car/subaru/interface.py index 8cd3239a0e9e30..f9d768f115bfc0 100644 --- a/selfdrive/car/subaru/interface.py +++ b/selfdrive/car/subaru/interface.py @@ -12,7 +12,7 @@ class CarInterface(CarInterfaceBase): def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): ret.carName = "subaru" ret.radarUnavailable = True - ret.dashcamOnly = candidate in PREGLOBAL_CARS + #ret.dashcamOnly = candidate in PREGLOBAL_CARS ret.autoResumeSng = False # Detect infotainment message sent from the camera From 3f53a988e046de610f551a754142878d4b179ba4 Mon Sep 17 00:00:00 2001 From: Martin Lillepuu Date: Sun, 23 Apr 2023 22:10:33 +0300 Subject: [PATCH 06/11] Update supported cars docs --- docs/CARS.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/CARS.md b/docs/CARS.md index 7ae8c06646e1a4..44987885aa9bd4 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -4,7 +4,7 @@ A supported vehicle is one that just works when you install a comma three. All supported cars provide a better experience than any stock system. Supported vehicles reference the US market unless otherwise specified. -# 244 Supported Cars +# 248 Supported Cars |Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|Harness|Video| |---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:| @@ -159,10 +159,14 @@ A supported vehicle is one that just works when you install a comma three. All s |Subaru|Ascent 2019-21|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| |Subaru|Crosstrek 2018-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| |Subaru|Crosstrek 2020-23|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| +|Subaru|Forester 2017-18|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| |Subaru|Forester 2019-21|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| |Subaru|Impreza 2017-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| |Subaru|Impreza 2020-22|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| +|Subaru|Legacy 2015-18|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| |Subaru|Legacy 2020-22|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru B|| +|Subaru|Outback 2015-17|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| +|Subaru|Outback 2018-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| |Subaru|Outback 2020-22|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru B|| |Subaru|XV 2018-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| |Subaru|XV 2020-21|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| From 887418a32283575ff0b467d5ea7095264e2107fb Mon Sep 17 00:00:00 2001 From: Martin Lillepuu Date: Sun, 23 Apr 2023 22:38:42 +0300 Subject: [PATCH 07/11] Add manual hold support --- selfdrive/car/subaru/carcontroller.py | 12 +++++++++++- selfdrive/car/subaru/carstate.py | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/selfdrive/car/subaru/carcontroller.py b/selfdrive/car/subaru/carcontroller.py index 523224a630d143..aa9c430bf74cda 100644 --- a/selfdrive/car/subaru/carcontroller.py +++ b/selfdrive/car/subaru/carcontroller.py @@ -15,8 +15,10 @@ def __init__(self, dbc_name, CP, VM): self.es_dashstatus_cnt = -1 self.infotainmentstatus_cnt = -1 self.cruise_button_prev = 0 + self.prev_cruise_state = 0 self.last_cancel_frame = 0 self.throttle_cnt = -1 + self.manual_hold = False self.p = CarControllerParams(CP) self.packer = CANPacker(DBC[CP.carFingerprint]['pt']) @@ -50,7 +52,15 @@ def update(self, CC, CS, now_nanos): # *** stop and go *** - throttle_cmd = True if CC.enabled and CC.cruiseControl.resume else False + if self.CP.carFingerprint not in PREGLOBAL_CARS: + # Record manual hold set while in standstill and no car in front + if CS.out.standstill and self.prev_cruise_state == 1 and CS.cruise_state == 3 and CS.car_follow == 0: + self.manual_hold = True + if not CS.out.standstill: + self.manual_hold = False + self.prev_cruise_state = CS.cruise_state + + throttle_cmd = True if CC.enabled and CC.cruiseControl.resume and not self.manual_hold else False # *** alerts and pcm cancel *** diff --git a/selfdrive/car/subaru/carstate.py b/selfdrive/car/subaru/carstate.py index eab374b8b39ca6..a35cd6b6d14f6a 100644 --- a/selfdrive/car/subaru/carstate.py +++ b/selfdrive/car/subaru/carstate.py @@ -78,6 +78,8 @@ def update(self, cp, cp_cam, cp_body): ret.cruiseState.standstill = cp_cam.vl["ES_DashStatus"]["Cruise_State"] == 3 ret.stockFcw = cp_cam.vl["ES_LKAS_State"]["LKAS_Alert"] == 2 self.es_lkas_state_msg = copy.copy(cp_cam.vl["ES_LKAS_State"]) + self.cruise_state = cp_cam.vl["ES_DashStatus"]["Cruise_State"] + self.car_follow = cp_cam.vl["ES_Distance"]["Car_Follow"] self.throttle_msg = copy.copy(cp.vl["Throttle"]) cp_es_distance = cp_body if self.car_fingerprint in GLOBAL_GEN2 else cp_cam From 3faa3c3fc90e972b7e0e8e466aa26f033bfc94a9 Mon Sep 17 00:00:00 2001 From: Martin Lillepuu Date: Sun, 23 Apr 2023 23:52:50 +0300 Subject: [PATCH 08/11] Update car_follow for gen2 --- selfdrive/car/subaru/carstate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/car/subaru/carstate.py b/selfdrive/car/subaru/carstate.py index a35cd6b6d14f6a..58374cc16356f4 100644 --- a/selfdrive/car/subaru/carstate.py +++ b/selfdrive/car/subaru/carstate.py @@ -79,10 +79,10 @@ def update(self, cp, cp_cam, cp_body): ret.stockFcw = cp_cam.vl["ES_LKAS_State"]["LKAS_Alert"] == 2 self.es_lkas_state_msg = copy.copy(cp_cam.vl["ES_LKAS_State"]) self.cruise_state = cp_cam.vl["ES_DashStatus"]["Cruise_State"] - self.car_follow = cp_cam.vl["ES_Distance"]["Car_Follow"] self.throttle_msg = copy.copy(cp.vl["Throttle"]) cp_es_distance = cp_body if self.car_fingerprint in GLOBAL_GEN2 else cp_cam + self.car_follow = cp_es_distance.vl["ES_Distance"]["Car_Follow"] self.es_distance_msg = copy.copy(cp_es_distance.vl["ES_Distance"]) self.es_dashstatus_msg = copy.copy(cp_cam.vl["ES_DashStatus"]) if self.CP.flags & SubaruFlags.SEND_INFOTAINMENT: From fb2c4585eea3ca28529fe4722f1e4f3d43e2e65b Mon Sep 17 00:00:00 2001 From: Martin Lillepuu Date: Sat, 29 Apr 2023 13:09:01 +0300 Subject: [PATCH 09/11] bump panda --- panda | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda b/panda index 544be66708cf38..590a8319d07df9 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 544be66708cf38e228aac33bb221e63da131b94c +Subproject commit 590a8319d07df9fcc9b2dea2aed1940a2b447081 From d3f74b0cc565ed08ffb29f109c1c9b980f50f831 Mon Sep 17 00:00:00 2001 From: Martin Lillepuu Date: Tue, 2 May 2023 20:25:52 +0300 Subject: [PATCH 10/11] Revert "disable dashcam only for preglobal for testing" This reverts commit f10cbafd78214bb2dcbba9346a2156ce90d6de4f. --- selfdrive/car/subaru/interface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/car/subaru/interface.py b/selfdrive/car/subaru/interface.py index f9d768f115bfc0..8cd3239a0e9e30 100644 --- a/selfdrive/car/subaru/interface.py +++ b/selfdrive/car/subaru/interface.py @@ -12,7 +12,7 @@ class CarInterface(CarInterfaceBase): def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): ret.carName = "subaru" ret.radarUnavailable = True - #ret.dashcamOnly = candidate in PREGLOBAL_CARS + ret.dashcamOnly = candidate in PREGLOBAL_CARS ret.autoResumeSng = False # Detect infotainment message sent from the camera From 102683da778a54203c1f29325626490234104069 Mon Sep 17 00:00:00 2001 From: Martin Lillepuu Date: Wed, 17 May 2023 04:54:30 +0300 Subject: [PATCH 11/11] Update supported cars list --- docs/CARS.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index 3299b6f2182627..42305a964a369e 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -4,7 +4,7 @@ A supported vehicle is one that just works when you install a comma three. All supported cars provide a better experience than any stock system. Supported vehicles reference the US market unless otherwise specified. -# 248 Supported Cars +# 244 Supported Cars |Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|Harness|Video| |---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:| @@ -159,14 +159,10 @@ A supported vehicle is one that just works when you install a comma three. All s |Subaru|Ascent 2019-21|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| |Subaru|Crosstrek 2018-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| |Subaru|Crosstrek 2020-23|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| -|Subaru|Forester 2017-18|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| |Subaru|Forester 2019-21|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| |Subaru|Impreza 2017-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| |Subaru|Impreza 2020-22|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| -|Subaru|Legacy 2015-18|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| |Subaru|Legacy 2020-22|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru B|| -|Subaru|Outback 2015-17|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| -|Subaru|Outback 2018-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| |Subaru|Outback 2020-22|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru B|| |Subaru|XV 2018-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| |Subaru|XV 2020-21|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A||