diff --git a/RELEASES.md b/RELEASES.md
index de57d520d3f2fe..87e5adb584e8cf 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -6,6 +6,7 @@ Version 0.8.15 (2022-XX-XX)
* Effective feedforward that uses road roll
* Simplified tuning, all car-specific parameters can be derived from data
* AGNOS 5
+* Lexus NX Hybrid 2020 support thanks to AlexandreSato!
Version 0.8.14 (2022-06-01)
========================
diff --git a/docs/CARS.md b/docs/CARS.md
index 2aa624d8495cf6..9a0788d8758e24 100644
--- a/docs/CARS.md
+++ b/docs/CARS.md
@@ -51,6 +51,7 @@ How We Rate The Cars
|Lexus|ES 2019-21|All||||||
|Lexus|ES Hybrid 2019-22|All||||||
|Lexus|NX 2020|All||||||
+|Lexus|NX Hybrid 2020|All||||||
|Lexus|UX Hybrid 2019-21|All||||||
|Toyota|Camry 2021-22|All||[4](#footnotes)||||
|Toyota|Camry Hybrid 2021-22|All||||||
diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py
index d2ec6b68d72fa2..e7942f517c1896 100644
--- a/selfdrive/car/tests/routes.py
+++ b/selfdrive/car/tests/routes.py
@@ -144,6 +144,7 @@
TestRoute("ec429c0f37564e3c|2020-02-01--17-28-12", TOYOTA.LEXUS_NXH),
TestRoute("964c09eb11ca8089|2020-11-03--22-04-00", TOYOTA.LEXUS_NX),
TestRoute("3fd5305f8b6ca765|2021-04-28--19-26-49", TOYOTA.LEXUS_NX_TSS2),
+ TestRoute("09ae96064ed85a14|2022-06-09--12-22-31", TOYOTA.LEXUS_NXH_TSS2),
TestRoute("0a302ffddbb3e3d3|2020-02-08--16-19-08", TOYOTA.HIGHLANDER_TSS2),
TestRoute("437e4d2402abf524|2021-05-25--07-58-50", TOYOTA.HIGHLANDERH_TSS2),
TestRoute("3183cd9b021e89ce|2021-05-25--10-34-44", TOYOTA.HIGHLANDER),
diff --git a/selfdrive/car/toyota/interface.py b/selfdrive/car/toyota/interface.py
index a1ce8c4980cd73..9440c73f5d8bf1 100644
--- a/selfdrive/car/toyota/interface.py
+++ b/selfdrive/car/toyota/interface.py
@@ -186,7 +186,7 @@ def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[], disabl
ret.mass = 3108 * CV.LB_TO_KG + STD_CARGO_KG # mean between min and max
set_lat_tune(ret.lateralTuning, LatTunes.PID_M)
- elif candidate in (CAR.LEXUS_NXH, CAR.LEXUS_NX, CAR.LEXUS_NX_TSS2):
+ elif candidate in (CAR.LEXUS_NX, CAR.LEXUS_NXH, CAR.LEXUS_NX_TSS2, CAR.LEXUS_NXH_TSS2):
stop_and_go = True
ret.wheelbase = 2.66
ret.steerRatio = 14.7
diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py
index 70a94be167c8e9..412a9c93905f2e 100644
--- a/selfdrive/car/toyota/values.py
+++ b/selfdrive/car/toyota/values.py
@@ -77,6 +77,7 @@ class CAR:
LEXUS_NX = "LEXUS NX 2018"
LEXUS_NXH = "LEXUS NX HYBRID 2018"
LEXUS_NX_TSS2 = "LEXUS NX 2020"
+ LEXUS_NXH_TSS2 = "LEXUS NX HYBRID 2020"
LEXUS_RC = "LEXUS RC 2020"
LEXUS_RX = "LEXUS RX 2016"
LEXUS_RXH = "LEXUS RX HYBRID 2017"
@@ -158,6 +159,7 @@ class ToyotaCarInfo(CarInfo):
CAR.LEXUS_NX: ToyotaCarInfo("Lexus NX 2018-19", footnotes=[Footnote.DSU]),
CAR.LEXUS_NXH: ToyotaCarInfo("Lexus NX Hybrid 2018-19", footnotes=[Footnote.DSU]),
CAR.LEXUS_NX_TSS2: ToyotaCarInfo("Lexus NX 2020"),
+ CAR.LEXUS_NXH_TSS2: ToyotaCarInfo("Lexus NX Hybrid 2020"),
CAR.LEXUS_RC: ToyotaCarInfo("Lexus RC 2020"),
CAR.LEXUS_RX: ToyotaCarInfo("Lexus RX 2016-18", footnotes=[Footnote.DSU]),
CAR.LEXUS_RXH: ToyotaCarInfo("Lexus RX Hybrid 2016-19", footnotes=[Footnote.DSU]),
@@ -1584,6 +1586,23 @@ class ToyotaCarInfo(CarInfo):
b'\x028646F7803100\x00\x00\x00\x008646G2601400\x00\x00\x00\x00',
],
},
+ CAR.LEXUS_NXH_TSS2: {
+ (Ecu.engine, 0x700, None): [
+ b'\x0237887000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00',
+ ],
+ (Ecu.esp, 0x7b0, None): [
+ b'F152678210\x00\x00\x00\x00\x00\x00',
+ ],
+ (Ecu.eps, 0x7a1, None): [
+ b'8965B78120\x00\x00\x00\x00\x00\x00',
+ ],
+ (Ecu.fwdRadar, 0x750, 0xf): [
+ b'\x018821F3301400\x00\x00\x00\x00',
+ ],
+ (Ecu.fwdCamera, 0x750, 0x6d): [
+ b'\x028646F78030A0\x00\x00\x00\x008646G2601200\x00\x00\x00\x00',
+ ],
+ },
CAR.LEXUS_NXH: {
(Ecu.engine, 0x7e0, None): [
b'\x0237841000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00',
@@ -1914,6 +1933,7 @@ class ToyotaCarInfo(CarInfo):
CAR.LEXUS_NXH: dbc_dict('toyota_tnga_k_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.LEXUS_NXH_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'),
@@ -1926,7 +1946,7 @@ class ToyotaCarInfo(CarInfo):
# Toyota/Lexus Safety Sense 2.0 and 2.5
TSS2_CAR = {CAR.RAV4_TSS2, CAR.RAV4_TSS2_2022, CAR.COROLLA_TSS2, CAR.COROLLAH_TSS2, CAR.LEXUS_ES_TSS2, CAR.LEXUS_ESH_TSS2, CAR.RAV4H_TSS2, CAR.RAV4H_TSS2_2022,
CAR.LEXUS_RX_TSS2, CAR.LEXUS_RXH_TSS2, CAR.HIGHLANDER_TSS2, CAR.HIGHLANDERH_TSS2, CAR.PRIUS_TSS2, CAR.CAMRY_TSS2, CAR.CAMRYH_TSS2,
- CAR.MIRAI, CAR.LEXUS_NX_TSS2, CAR.ALPHARD_TSS2, CAR.AVALON_TSS2, CAR.AVALONH_TSS2, CAR.ALPHARDH_TSS2}
+ CAR.MIRAI, CAR.LEXUS_NX_TSS2, CAR.LEXUS_NXH_TSS2, CAR.ALPHARD_TSS2, CAR.AVALON_TSS2, CAR.AVALONH_TSS2, CAR.ALPHARDH_TSS2}
NO_DSU_CAR = TSS2_CAR | {CAR.CHR, CAR.CHRH, CAR.CAMRY, CAR.CAMRYH}
@@ -1935,7 +1955,7 @@ class ToyotaCarInfo(CarInfo):
EV_HYBRID_CAR = {CAR.AVALONH_2019, CAR.AVALONH_TSS2, CAR.CAMRYH, CAR.CAMRYH_TSS2, CAR.CHRH, CAR.COROLLAH_TSS2, CAR.HIGHLANDERH, CAR.HIGHLANDERH_TSS2, CAR.PRIUS,
CAR.PRIUS_V, CAR.RAV4H, CAR.RAV4H_TSS2, CAR.RAV4H_TSS2_2022, CAR.LEXUS_CTH, CAR.MIRAI, CAR.LEXUS_ESH, CAR.LEXUS_ESH_TSS2, CAR.LEXUS_NXH, CAR.LEXUS_RXH,
- CAR.LEXUS_RXH_TSS2, CAR.PRIUS_TSS2, CAR.ALPHARDH_TSS2}
+ CAR.LEXUS_RXH_TSS2, CAR.LEXUS_NXH_TSS2, CAR.PRIUS_TSS2, CAR.ALPHARDH_TSS2}
# no resume button press required
NO_STOP_TIMER_CAR = TSS2_CAR | {CAR.PRIUS_V, CAR.RAV4H, CAR.HIGHLANDERH, CAR.HIGHLANDER, CAR.SIENNA, CAR.LEXUS_ESH}