Skip to content

Commit

Permalink
Merge branch 'commaai:master' into PA-testing
Browse files Browse the repository at this point in the history
  • Loading branch information
Edison-CBS authored Feb 7, 2024
2 parents 85249cc + 92025ec commit 887df27
Show file tree
Hide file tree
Showing 14 changed files with 121 additions and 46 deletions.
19 changes: 0 additions & 19 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -259,25 +259,6 @@ node {
])
},

// *** PC tests ***
'PC tests': {
pcStage("PC tests") {
// tests that our build system's dependencies are configured properly,
// needs a machine with lots of cores
sh label: "test multi-threaded build",
script: '''#!/bin/bash
scons --no-cache --random -j$(nproc)'''
}
},
'car tests': {
pcStage("car tests") {
sh label: "build", script: "selfdrive/manager/build.py"
sh label: "test_models", script: "INTERNAL_SEG_CNT=300 FILEREADER_CACHE=1 INTERNAL_SEG_LIST=selfdrive/car/tests/test_models_segs.txt \
pytest selfdrive/car/tests/test_models.py"
sh label: "test_car_interfaces", script: "MAX_EXAMPLES=300 pytest selfdrive/car/tests/test_car_interfaces.py"
}
},

)
}
} catch (Exception e) {
Expand Down
1 change: 1 addition & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Version 0.9.6 (2024-02-XX)
* Improved fuzzy fingerprinting for many makes and models
* Hyundai Staria 2023 support thanks to sunnyhaibin!
* Kia Niro Plug-in Hybrid 2022 support thanks to sunnyhaibin!
* Lexus LC 2024 support thanks to nelsonjchen!
* Toyota RAV4 2023-24 support
* Toyota RAV4 Hybrid 2023-24 support

Expand Down
6 changes: 6 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import gc
import os
import pytest
import random
Expand Down Expand Up @@ -45,6 +46,11 @@ def openpilot_function_fixture(request):
# cleanup any started processes
manager.manager_cleanup()

# some processes disable gc for performance, re-enable here
if not gc.isenabled():
gc.enable()
gc.collect()

# If you use setUpClass, the environment variables won't be cleared properly,
# so we need to hook both the function and class pytest fixtures
@pytest.fixture(scope="class", autouse=True)
Expand Down
3 changes: 2 additions & 1 deletion docs/CARS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

A supported vehicle is one that just works when you install a comma device. All supported cars provide a better experience than any stock system. Supported vehicles reference the US market unless otherwise specified.

# 276 Supported Cars
# 277 Supported Cars

|Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|<a href="##"><img width=2000></a>Hardware Needed<br>&nbsp;|Video|
|---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
Expand Down Expand Up @@ -162,6 +162,7 @@ A supported vehicle is one that just works when you install a comma device. All
|Lexus|GS F 2016|All|Stock|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=GS F 2016">Buy Here</a></sub></details>||
|Lexus|IS 2017-19|All|Stock|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=IS 2017-19">Buy Here</a></sub></details>||
|Lexus|IS 2022-23|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=IS 2022-23">Buy Here</a></sub></details>||
|Lexus|LC 2024|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=LC 2024">Buy Here</a></sub></details>||
|Lexus|NX 2018-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=NX 2018-19">Buy Here</a></sub></details>||
|Lexus|NX 2020-21|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=NX 2020-21">Buy Here</a></sub></details>||
|Lexus|NX Hybrid 2018-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=NX Hybrid 2018-19">Buy Here</a></sub></details>||
Expand Down
2 changes: 1 addition & 1 deletion launch_env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export OPENBLAS_NUM_THREADS=1
export VECLIB_MAXIMUM_THREADS=1

if [ -z "$AGNOS_VERSION" ]; then
export AGNOS_VERSION="9.3"
export AGNOS_VERSION="9.5"
fi

export STAGING_ROOT="/data/safe_staging"
8 changes: 8 additions & 0 deletions selfdrive/car/tests/big_cars_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

MAX_EXAMPLES=300
INTERNAL_SEG_CNT=300
FILEREADER_CACHE=1
INTERNAL_SEG_LIST=selfdrive/car/tests/test_models_segs.txt

cd selfdrive/car/tests && pytest test_models.py test_car_interfaces.py
1 change: 1 addition & 0 deletions selfdrive/car/tests/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ class CarTestRoute(NamedTuple):
CarTestRoute("ec429c0f37564e3c|2020-02-01--17-28-12", TOYOTA.LEXUS_NX), # hybrid
CarTestRoute("3fd5305f8b6ca765|2021-04-28--19-26-49", TOYOTA.LEXUS_NX_TSS2),
CarTestRoute("09ae96064ed85a14|2022-06-09--12-22-31", TOYOTA.LEXUS_NX_TSS2), # hybrid
CarTestRoute("4765fbbf59e3cd88|2024-02-06--17-45-32", TOYOTA.LEXUS_LC_TSS2),
CarTestRoute("0a302ffddbb3e3d3|2020-02-08--16-19-08", TOYOTA.HIGHLANDER_TSS2),
CarTestRoute("437e4d2402abf524|2021-05-25--07-58-50", TOYOTA.HIGHLANDER_TSS2), # hybrid
CarTestRoute("3183cd9b021e89ce|2021-05-25--10-34-44", TOYOTA.HIGHLANDER),
Expand Down
1 change: 1 addition & 0 deletions selfdrive/car/torque_data/substitute.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"]
"LEXUS CT HYBRID 2018" = "LEXUS NX 2018"
"LEXUS ES 2018" = "TOYOTA CAMRY 2018"
"LEXUS RC 2020" = "LEXUS NX 2020"
"LEXUS LC 2024" = "LEXUS NX 2020"

"KIA OPTIMA 4TH GEN" = "HYUNDAI SONATA 2020"
"KIA OPTIMA 4TH GEN FACELIFT" = "HYUNDAI SONATA 2020"
Expand Down
17 changes: 17 additions & 0 deletions selfdrive/car/toyota/fingerprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -1383,6 +1383,23 @@
b'\x028646F7803100\x00\x00\x00\x008646G2601400\x00\x00\x00\x00',
],
},
CAR.LEXUS_LC_TSS2: {
(Ecu.engine, 0x7e0, None): [
b'\x0131130000\x00\x00\x00\x00\x00\x00\x00\x00',
],
(Ecu.abs, 0x7b0, None): [
b'F152611390\x00\x00\x00\x00\x00\x00',
],
(Ecu.eps, 0x7a1, None): [
b'8965B11091\x00\x00\x00\x00\x00\x00',
],
(Ecu.fwdRadar, 0x750, 0xf): [
b'\x018821F6201400\x00\x00\x00\x00',
],
(Ecu.fwdCamera, 0x750, 0x6d): [
b'\x028646F1105200\x00\x00\x00\x008646G3304000\x00\x00\x00\x00',
],
},
CAR.LEXUS_RC: {
(Ecu.engine, 0x700, None): [
b'\x01896632461100\x00\x00\x00\x00',
Expand Down
6 changes: 6 additions & 0 deletions selfdrive/car/toyota/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,12 @@ def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
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
Expand Down
6 changes: 5 additions & 1 deletion selfdrive/car/toyota/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class CAR(StrEnum):
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"
Expand Down Expand Up @@ -206,6 +207,7 @@ class ToyotaCarInfo(CarInfo):
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+"),
Expand Down Expand Up @@ -444,6 +446,7 @@ def match_fw_to_car_fuzzy(live_fw_versions, offline_fw_versions) -> Set[str]:
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'),
Expand Down Expand Up @@ -480,7 +483,8 @@ def match_fw_to_car_fuzzy(live_fw_versions, offline_fw_versions) -> Set[str]:
# 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.ALPHARD_TSS2, CAR.AVALON_TSS2, CAR.CHR_TSS2}
CAR.MIRAI, CAR.LEXUS_NX_TSS2, CAR.LEXUS_LC_TSS2, CAR.ALPHARD_TSS2, CAR.AVALON_TSS2,
CAR.CHR_TSS2}

NO_DSU_CAR = TSS2_CAR | {CAR.CHR, CAR.CAMRY}

Expand Down
6 changes: 6 additions & 0 deletions selfdrive/test/scons_build_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

# tests that our build system's dependencies are configured properly,
# needs a machine with lots of cores
scons --clean
scons --no-cache --random -j$(nproc)
18 changes: 9 additions & 9 deletions system/hardware/tici/agnos.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[
{
"name": "boot",
"url": "https://commadist.azureedge.net/agnosupdate/boot-1cc21f31a7c09772fd759e6f2a614974bf4f2fc320c91a799ffadd11abc1f85f.img.xz",
"hash": "1cc21f31a7c09772fd759e6f2a614974bf4f2fc320c91a799ffadd11abc1f85f",
"hash_raw": "1cc21f31a7c09772fd759e6f2a614974bf4f2fc320c91a799ffadd11abc1f85f",
"url": "https://commadist.azureedge.net/agnosupdate/boot-f0de74e139b8b99224738d4e72a5b1831758f20b09ff6bb28f3aaaae1c4c1ebe.img.xz",
"hash": "f0de74e139b8b99224738d4e72a5b1831758f20b09ff6bb28f3aaaae1c4c1ebe",
"hash_raw": "f0de74e139b8b99224738d4e72a5b1831758f20b09ff6bb28f3aaaae1c4c1ebe",
"size": 15636480,
"sparse": false,
"full_check": true,
Expand Down Expand Up @@ -61,17 +61,17 @@
},
{
"name": "system",
"url": "https://commadist.azureedge.net/agnosupdate/system-38402b90b65729f8a4feb729c8a862cdf306659a85f27431d3ff7e52d4027082.img.xz",
"hash": "5dc1718e21c49e4fa910fbb3b2321381f497b38335a0cf3ca923157d589abe89",
"hash_raw": "38402b90b65729f8a4feb729c8a862cdf306659a85f27431d3ff7e52d4027082",
"url": "https://commadist.azureedge.net/agnosupdate/system-de20b4b540657e5edc01e127abd20fdfd402f68b4c89b5478cdc53aa44567a85.img.xz",
"hash": "8b7efc3fc218a1b8ee94b756dbafc1c03d2b92d693027f8850a6268924f6f04e",
"hash_raw": "de20b4b540657e5edc01e127abd20fdfd402f68b4c89b5478cdc53aa44567a85",
"size": 10737418240,
"sparse": true,
"full_check": false,
"has_ab": true,
"alt": {
"hash": "1809e36d8e376e0a0c8348e3f684aba4100fe0382042c051efd0e946af1ce696",
"url": "https://commadist.azureedge.net/agnosupdate/system-skip-chunks-38402b90b65729f8a4feb729c8a862cdf306659a85f27431d3ff7e52d4027082.img.xz",
"size": 4077270244
"hash": "a2b2d5307866536894b7cc5af9cb682b7da6f691205c772a2f6287d76da661cf",
"url": "https://commadist.azureedge.net/agnosupdate/system-skip-chunks-de20b4b540657e5edc01e127abd20fdfd402f68b4c89b5478cdc53aa44567a85.img.xz",
"size": 4538871788
}
}
]
73 changes: 58 additions & 15 deletions system/hardware/tici/tests/test_power_draw.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#!/usr/bin/env python3
from collections import defaultdict, deque
import sys
import pytest
import unittest
import time
Expand All @@ -15,7 +17,8 @@
from openpilot.selfdrive.manager.process_config import managed_processes
from openpilot.selfdrive.manager.manager import manager_cleanup

SAMPLE_TIME = 8 # seconds to sample power
SAMPLE_TIME = 8 # seconds to sample power
MAX_WARMUP_TIME = 30 # seconds to wait for SAMPLE_TIME consecutive valid samples

@dataclass
class Proc:
Expand All @@ -24,7 +27,6 @@ class Proc:
msgs: List[str]
rtol: float = 0.05
atol: float = 0.12
warmup: float = 6.

PROCS = [
Proc('camerad', 2.1, msgs=['roadCameraState', 'wideRoadCameraState', 'driverCameraState']),
Expand All @@ -48,41 +50,82 @@ def setUp(self):
def tearDown(self):
manager_cleanup()

def get_expected_messages(self, proc):
return int(sum(SAMPLE_TIME * SERVICE_LIST[msg].frequency for msg in proc.msgs))

def valid_msg_count(self, proc, msg_counts):
msgs_received = sum(msg_counts[msg] for msg in proc.msgs)
msgs_expected = self.get_expected_messages(proc)
return np.core.numeric.isclose(msgs_expected, msgs_received, rtol=.02, atol=2)

def valid_power_draw(self, proc, used):
return np.core.numeric.isclose(used, proc.power, rtol=proc.rtol, atol=proc.atol)

def tabulate_msg_counts(self, msgs_and_power):
msg_counts = defaultdict(lambda: 0)
for _, counts in msgs_and_power:
for msg, count in counts.items():
msg_counts[msg] += count
return msg_counts

def get_power_with_warmup_for_target(self, proc, prev):
socks = {msg: messaging.sub_sock(msg) for msg in proc.msgs}
for sock in socks.values():
messaging.drain_sock_raw(sock)

msgs_and_power = deque([], maxlen=SAMPLE_TIME)

start_time = time.monotonic()

while (time.monotonic() - start_time) < MAX_WARMUP_TIME:
power = get_power(1)
iteration_msg_counts = {}
for msg,sock in socks.items():
iteration_msg_counts[msg] = len(messaging.drain_sock_raw(sock))
msgs_and_power.append((power, iteration_msg_counts))

if len(msgs_and_power) < SAMPLE_TIME:
continue

msg_counts = self.tabulate_msg_counts(msgs_and_power)
now = np.mean([m[0] for m in msgs_and_power])

if self.valid_msg_count(proc, msg_counts) and self.valid_power_draw(proc, now - prev):
break

return now, msg_counts, time.monotonic() - start_time - SAMPLE_TIME

@mock_messages(['liveLocationKalman'])
def test_camera_procs(self):
baseline = get_power()

prev = baseline
used = {}
warmup_time = {}
msg_counts = {}

for proc in PROCS:
socks = {msg: messaging.sub_sock(msg) for msg in proc.msgs}
managed_processes[proc.name].start()
time.sleep(proc.warmup)
for sock in socks.values():
messaging.drain_sock_raw(sock)
now, local_msg_counts, warmup_time[proc.name] = self.get_power_with_warmup_for_target(proc, prev)
msg_counts.update(local_msg_counts)

now = get_power(SAMPLE_TIME)
used[proc.name] = now - prev
prev = now
for msg,sock in socks.items():
msg_counts[msg] = len(messaging.drain_sock_raw(sock))

manager_cleanup()

tab = [['process', 'expected (W)', 'measured (W)', '# msgs expected', '# msgs received']]
tab = [['process', 'expected (W)', 'measured (W)', '# msgs expected', '# msgs received', "warmup time (s)"]]
for proc in PROCS:
cur = used[proc.name]
expected = proc.power
msgs_received = sum(msg_counts[msg] for msg in proc.msgs)
msgs_expected = int(sum(SAMPLE_TIME * SERVICE_LIST[msg].frequency for msg in proc.msgs))
tab.append([proc.name, round(expected, 2), round(cur, 2), msgs_expected, msgs_received])
tab.append([proc.name, round(expected, 2), round(cur, 2), self.get_expected_messages(proc), msgs_received, round(warmup_time[proc.name], 2)])
with self.subTest(proc=proc.name):
np.testing.assert_allclose(msgs_expected, msgs_received, rtol=.02, atol=2)
np.testing.assert_allclose(cur, expected, rtol=proc.rtol, atol=proc.atol)
self.assertTrue(self.valid_msg_count(proc, msg_counts), f"expected {self.get_expected_messages(proc)} msgs, got {msgs_received} msgs")
self.assertTrue(self.valid_power_draw(proc, cur), f"expected {expected:.2f}W, got {cur:.2f}W")
print(tabulate(tab))
print(f"Baseline {baseline:.2f}W\n")


if __name__ == "__main__":
pytest.main()
pytest.main(sys.argv)

0 comments on commit 887df27

Please sign in to comment.