Merge remote-tracking branch 'upstream/master' into toyota-fuzzy-v2

pull/28641/head
Shane Smiskol 2 years ago
commit 516f6440ba
  1. 3
      .pre-commit-config.yaml
  2. 2
      cereal
  3. 2
      docs/CARS.md
  4. 8
      poetry.lock
  5. 2
      pyproject.toml
  6. 4
      selfdrive/athena/athenad.py
  7. 11
      selfdrive/boardd/boardd.cc
  8. 5
      selfdrive/car/hyundai/values.py
  9. 4
      selfdrive/controls/lib/events.py
  10. 4
      selfdrive/debug/check_lag.py
  11. 6
      selfdrive/debug/count_events.py
  12. 4
      selfdrive/debug/dump.py
  13. 4
      selfdrive/debug/internal/qlog_size.py
  14. 6
      selfdrive/locationd/test/test_locationd.py
  15. 2
      selfdrive/modeld/models/driving.h
  16. 4
      selfdrive/modeld/models/supercombo.onnx
  17. 2
      selfdrive/test/process_replay/model_replay_ref_commit
  18. 6
      selfdrive/test/process_replay/process_replay.py
  19. 4
      selfdrive/test/profiling/lib.py
  20. 6
      selfdrive/test/test_onroad.py
  21. 7
      selfdrive/thermald/thermald.py
  22. 6
      system/camerad/test/test_camerad.py
  23. 4
      system/hardware/tici/tests/test_power_draw.py
  24. 12
      system/loggerd/tests/test_loggerd.py
  25. 21
      system/proclogd/tests/test_proclog.cc
  26. 6
      system/sensord/tests/test_pigeond.py
  27. 4
      system/sensord/tests/test_sensord.py
  28. 88
      tools/sim/bridge/carla.py
  29. 2
      tools/sim/bridge/common.py
  30. 7
      tools/sim/bridge/metadrive.py
  31. 4
      tools/sim/lib/common.py
  32. 2
      tools/sim/lib/keyboard_ctrl.py

@ -80,10 +80,9 @@ repos:
rev: '1.6.0'
hooks:
- id: poetry-check
- id: poetry-lock
name: validate poetry lock
args:
- --check
- --lock
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.26.3
hooks:

@ -1 +1 @@
Subproject commit 95485f268cacb16186163744224c9dd8644ecd49
Subproject commit 6bd65e7c7f2692d15a9b6cc97bad9345f9089c4d

@ -119,7 +119,7 @@ A supported vehicle is one that just works when you install a comma device. All
|Kia|Forte 2019-21|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai G connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 comma three<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=Kia&model=Forte 2019-21">Buy Here</a></sub></details>||
|Kia|Forte 2023|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 comma three<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=Kia&model=Forte 2023">Buy Here</a></sub></details>||
|Kia|K5 2021-22|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 comma three<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=Kia&model=K5 2021-22">Buy Here</a></sub></details>||
|Kia|K5 Hybrid 2020|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 comma three<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=Kia&model=K5 Hybrid 2020">Buy Here</a></sub></details>||
|Kia|K5 Hybrid 2020-22|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 comma three<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=Kia&model=K5 Hybrid 2020-22">Buy Here</a></sub></details>||
|Kia|K8 Hybrid (with HDA II) 2023[<sup>6</sup>](#footnotes)|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai Q connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 comma three<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=Kia&model=K8 Hybrid (with HDA II) 2023">Buy Here</a></sub></details>||
|Kia|Niro EV 2019|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai H connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 comma three<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=Kia&model=Niro EV 2019">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=lT7zcG6ZpGo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Kia|Niro EV 2020|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Hyundai F connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma power v2<br>- 1 comma three<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=Kia&model=Niro EV 2020">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=lT7zcG6ZpGo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|

8
poetry.lock generated

@ -1578,13 +1578,13 @@ files = [
[[package]]
name = "hypothesis"
version = "6.46.7"
version = "6.47.5"
description = "A library for property-based testing"
optional = false
python-versions = ">=3.7"
files = [
{file = "hypothesis-6.46.7-py3-none-any.whl", hash = "sha256:2696cdb9005946bf1d2b215cc91d3fc01625e3342eb8743ddd04b667b2f1882b"},
{file = "hypothesis-6.46.7.tar.gz", hash = "sha256:967009fa561b3a3f8363a73d71923357271c37dc7fa27b30c2d21a1b6092b240"},
{file = "hypothesis-6.47.5-py3-none-any.whl", hash = "sha256:87049b781ee11ec1c7948565b889ab02e428a1e32d427ab4de8fdb3649242d06"},
{file = "hypothesis-6.47.5.tar.gz", hash = "sha256:e0c1e253fc97e7ecdb9e2bbff2cf815d8739e0d1d3d093d67c3af5bb6a7211b0"},
]
[package.dependencies]
@ -5106,4 +5106,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p
[metadata]
lock-version = "2.0"
python-versions = "~3.11"
content-hash = "80bd9226bb8fc61c75fe8047c55ba2da3919bc8d9b32a8154ec0a40f9fe2a18e"
content-hash = "f159e93b7b57c4fad45a063d96ef97b01697fc811a51f968c7757b05808cee1c"

@ -127,7 +127,7 @@ carla = { url = "https://github.com/commaai/carla/releases/download/3.11.4/carla
coverage = "*"
dictdiffer = "*"
ft4222 = "*"
hypothesis = "==6.46.7"
hypothesis = "~6.47"
inputs = "*"
lru-dict = "*"
markdown-it-py = "*"

@ -29,7 +29,7 @@ from websocket import (ABNF, WebSocket, WebSocketException, WebSocketTimeoutExce
import cereal.messaging as messaging
from cereal import log
from cereal.services import service_list
from cereal.services import SERVICE_LIST
from openpilot.common.api import Api
from openpilot.common.basedir import PERSIST
from openpilot.common.file_helpers import CallbackReader
@ -309,7 +309,7 @@ def _do_upload(upload_item: UploadItem, callback: Optional[Callable] = None) ->
# security: user should be able to request any message from their car
@dispatcher.add_method
def getMessage(service: str, timeout: int = 1000) -> dict:
if service is None or service not in service_list:
if service is None or service not in SERVICE_LIST:
raise Exception("invalid service")
socket = messaging.sub_sock(service, timeout=timeout)

@ -472,12 +472,15 @@ void panda_state_thread(std::vector<Panda *> pandas, bool spoofing_started) {
LOGD("start panda state thread");
// run at 2hz
RateKeeper rk("panda_state_thread", 2);
// run at 10hz
RateKeeper rk("panda_state_thread", 10);
while (!do_exit && check_all_connected(pandas)) {
// send out peripheralState
send_peripheral_state(&pm, peripheral_panda);
// send out peripheralState at 2Hz
if (sm.frame % 5 == 0) {
send_peripheral_state(&pm, peripheral_panda);
}
auto ignition_opt = send_panda_states(&pm, pandas, spoofing_started);
if (!ignition_opt) {

@ -219,7 +219,7 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = {
HyundaiCarInfo("Kia Forte 2023", car_parts=CarParts.common([CarHarness.hyundai_e])),
],
CAR.KIA_K5_2021: HyundaiCarInfo("Kia K5 2021-22", car_parts=CarParts.common([CarHarness.hyundai_a])),
CAR.KIA_K5_HEV_2020: HyundaiCarInfo("Kia K5 Hybrid 2020", car_parts=CarParts.common([CarHarness.hyundai_a])),
CAR.KIA_K5_HEV_2020: HyundaiCarInfo("Kia K5 Hybrid 2020-22", car_parts=CarParts.common([CarHarness.hyundai_a])),
CAR.KIA_K8_HEV_1ST_GEN: HyundaiCarInfo("Kia K8 Hybrid (with HDA II) 2023", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_q])),
CAR.KIA_NIRO_EV: [
HyundaiCarInfo("Kia Niro EV 2019", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", car_parts=CarParts.common([CarHarness.hyundai_h])),
@ -1392,15 +1392,18 @@ FW_VERSIONS = {
],
(Ecu.eps, 0x7D4, None): [
b'\xf1\x00DL3 MDPS C 1.00 1.02 56310-L7000 4DLHC102',
b'\xf1\x00DL3 MDPS C 1.00 1.02 56310-L7220 4DLHC102',
],
(Ecu.fwdCamera, 0x7C4, None): [
b'\xf1\x00DL3HMFC AT KOR LHD 1.00 1.02 99210-L2000 200309',
b'\xf1\x00DL3HMFC AT KOR LHD 1.00 1.04 99210-L2000 210527',
],
(Ecu.engine, 0x7E0, None): [
b'\xf1\x87391162JLA0',
],
(Ecu.transmission, 0x7E1, None): [
b'\xf1\x00PSBG2323 E08\x00\x00\x00\x00\x00\x00\x00TDL2H20KA2\xe3\xc6cz',
b'\xf1\x00PSBG2333 E16\x00\x00\x00\x00\x00\x00\x00TDL2H20KA5T\xf2\xc9\xc2',
],
},
CAR.KONA_EV: {

@ -969,7 +969,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = {
if __name__ == '__main__':
# print all alerts by type and priority
from cereal.services import service_list
from cereal.services import SERVICE_LIST
from collections import defaultdict, OrderedDict
event_names = {v: k for k, v in EventName.schema.enumerants.items()}
@ -977,7 +977,7 @@ if __name__ == '__main__':
CP = car.CarParams.new_message()
CS = car.CarState.new_message()
sm = messaging.SubMaster(list(service_list.keys()))
sm = messaging.SubMaster(list(SERVICE_LIST.keys()))
for i, alerts in EVENTS.items():
for et, alert in alerts.items():

@ -2,7 +2,7 @@
from typing import Dict
import cereal.messaging as messaging
from cereal.services import service_list
from cereal.services import SERVICE_LIST
TO_CHECK = ['carState']
@ -20,7 +20,7 @@ if __name__ == "__main__":
t = sm.logMonoTime[s] / 1e9
if s in prev_t:
expected = 1.0 / (service_list[s].frequency)
expected = 1.0 / (SERVICE_LIST[s].frequency)
dt = t - prev_t[s]
if dt > 10 * expected:
print(t, s, dt)

@ -7,7 +7,7 @@ from pprint import pprint
from tqdm import tqdm
from typing import List, Tuple, cast
from cereal.services import service_list
from cereal.services import SERVICE_LIST
from openpilot.tools.lib.route import Route
from openpilot.tools.lib.logreader import LogReader
@ -17,7 +17,7 @@ if __name__ == "__main__":
cnt_valid: Counter = Counter()
cnt_events: Counter = Counter()
cams = [s for s in service_list if s.endswith('CameraState')]
cams = [s for s in SERVICE_LIST if s.endswith('CameraState')]
cnt_cameras = dict.fromkeys(cams, 0)
alerts: List[Tuple[float, str]] = []
@ -62,7 +62,7 @@ if __name__ == "__main__":
print("\n")
print("Cameras")
for k, v in cnt_cameras.items():
s = service_list[k]
s = SERVICE_LIST[k]
expected_frames = int(s.frequency * duration / cast(float, s.decimation))
print(" ", k.ljust(20), f"{v}, {v/expected_frames:.1%} of expected")

@ -8,7 +8,7 @@ import cereal.messaging as messaging
from hexdump import hexdump
from cereal import log
from cereal.services import service_list
from cereal.services import SERVICE_LIST
codecs.register_error("strict", codecs.backslashreplace_errors)
@ -31,7 +31,7 @@ if __name__ == "__main__":
poller = messaging.Poller()
for m in args.socket if len(args.socket) > 0 else service_list:
for m in args.socket if len(args.socket) > 0 else SERVICE_LIST:
messaging.sub_sock(m, poller, addr=args.addr)
values = None

@ -5,7 +5,7 @@ from collections import defaultdict
import matplotlib.pyplot as plt
from cereal.services import service_list
from cereal.services import SERVICE_LIST
from openpilot.tools.lib.logreader import LogReader
from openpilot.tools.lib.route import Route
@ -49,7 +49,7 @@ if __name__ == "__main__":
msgs_by_type[m.which()].append(m.as_builder().to_bytes())
qlog_by_type = defaultdict(list)
for name, service in service_list.items():
for name, service in SERVICE_LIST.items():
if service.decimation is None:
continue

@ -6,7 +6,7 @@ import time
import capnp
import cereal.messaging as messaging
from cereal.services import service_list
from cereal.services import SERVICE_LIST
from openpilot.common.params import Params
from openpilot.common.transformations.coordinates import ecef2geodetic
@ -74,8 +74,8 @@ class TestLocationdProc(unittest.TestCase):
msgs = []
for sec in range(65):
for name in self.LLD_MSGS:
for j in range(int(service_list[name].frequency)):
msgs.append(self.get_msg(name, int((sec + j / service_list[name].frequency) * 1e9)))
for j in range(int(SERVICE_LIST[name].frequency)):
msgs.append(self.get_msg(name, int((sec + j / SERVICE_LIST[name].frequency) * 1e9)))
for msg in sorted(msgs, key=lambda x: x.logMonoTime):
self.pm.send(msg.which(), msg)

@ -9,7 +9,7 @@
#include "selfdrive/modeld/models/commonmodel.h"
#include "selfdrive/modeld/runners/run.h"
constexpr int FEATURE_LEN = 128;
constexpr int FEATURE_LEN = 512;
constexpr int HISTORY_BUFFER_LEN = 99;
constexpr int DESIRE_LEN = 8;
constexpr int DESIRE_PRED_LEN = 4;

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c63ea3eb6c9b5a20c7420c2dc6d6d0f80a6949a39f6d8b74e574f52734154820
size 47654714
oid sha256:af5b47a763454cd56a9f16ebe51dbcf54a001898444a9557b39cedb2303d4da3
size 52272357

@ -1 +1 @@
4f59f5945633f7a6e54e6f0fcd8ecf0baafa28cd
2af877ca0ce6996a4c1cf54cd11abf5a1f4e0576

@ -14,7 +14,7 @@ import capnp
import cereal.messaging as messaging
from cereal import car
from cereal.services import service_list
from cereal.services import SERVICE_LIST
from cereal.visionipc import VisionIpcServer, get_endpoint_name as vipc_get_endpoint_name
from openpilot.common.params import Params
from openpilot.common.prefix import OpenpilotPrefix
@ -364,7 +364,7 @@ def controlsd_rcv_callback(msg, cfg, frame):
socks = [
s for s in cfg.subs if
frame % int(service_list[msg.which()].frequency / service_list[s].frequency) == 0
frame % int(SERVICE_LIST[msg.which()].frequency / SERVICE_LIST[s].frequency) == 0
]
if "sendcan" in socks and (frame - 1) < 2000:
socks.remove("sendcan")
@ -428,7 +428,7 @@ class FrequencyBasedRcvCallback:
resp_sockets = [
s for s in cfg.subs
if frame % max(1, int(service_list[msg.which()].frequency / service_list[s].frequency)) == 0
if frame % max(1, int(SERVICE_LIST[msg.which()].frequency / SERVICE_LIST[s].frequency)) == 0
]
return bool(len(resp_sockets))

@ -1,5 +1,5 @@
from collections import defaultdict, deque
from cereal.services import service_list
from cereal.services import SERVICE_LIST
import cereal.messaging as messaging
import capnp
@ -67,7 +67,7 @@ class SubMaster(messaging.SubMaster):
self.msgs = list(reversed(self.msgs))
for s in services:
self.freq[s] = service_list[s].frequency
self.freq[s] = SERVICE_LIST[s].frequency
try:
data = messaging.new_message(s)
except capnp.lib.capnp.KjException:

@ -13,7 +13,7 @@ from pathlib import Path
from cereal import car
import cereal.messaging as messaging
from cereal.services import service_list
from cereal.services import SERVICE_LIST
from openpilot.common.basedir import BASEDIR
from openpilot.common.timeout import Timeout
from openpilot.common.params import Params
@ -179,7 +179,7 @@ class TestOnroad(unittest.TestCase):
continue
with self.subTest(service=s):
assert len(msgs) >= math.floor(service_list[s].frequency*55)
assert len(msgs) >= math.floor(SERVICE_LIST[s].frequency*55)
def test_cloudlog_size(self):
msgs = [m for m in self.lr if m.which() == 'logMessage']
@ -356,7 +356,7 @@ class TestOnroad(unittest.TestCase):
raise Exception(f"missing {s}")
ts = np.diff(msgs) / 1e9
dt = 1 / service_list[s].frequency
dt = 1 / SERVICE_LIST[s].frequency
try:
np.testing.assert_allclose(np.mean(ts), dt, rtol=0.03, err_msg=f"{s} - failed mean timing check")

@ -13,6 +13,7 @@ import psutil
import cereal.messaging as messaging
from cereal import log
from cereal.services import SERVICE_LIST
from openpilot.common.dict_helpers import strip_deprecated_keys
from openpilot.common.time import MIN_DATE
from openpilot.common.filter_simple import FirstOrderFilter
@ -33,7 +34,7 @@ NetworkStrength = log.DeviceState.NetworkStrength
CURRENT_TAU = 15. # 15s time constant
TEMP_TAU = 5. # 5s time constant
DISCONNECT_TIMEOUT = 5. # wait 5 seconds before going offroad after disconnect so you get an alert
PANDA_STATES_TIMEOUT = int(1000 * 1.5 * DT_TRML) # 1.5x the expected pandaState frequency
PANDA_STATES_TIMEOUT = round(1000 / SERVICE_LIST['pandaStates'].frequency * 1.5) # 1.5x the expected pandaState frequency
ThermalBand = namedtuple("ThermalBand", ['min_temp', 'max_temp'])
HardwareState = namedtuple("HardwareState", ['network_type', 'network_info', 'network_strength', 'network_stats',
@ -210,6 +211,10 @@ def thermald_thread(end_event, hw_queue) -> None:
while not end_event.is_set():
sm.update(PANDA_STATES_TIMEOUT)
# Run at 2Hz
if sm.frame % round(SERVICE_LIST['pandaStates'].frequency * DT_TRML) != 0:
continue
pandaStates = sm['pandaStates']
peripheralState = sm['peripheralState']
peripheral_panda_present = peripheralState.pandaType != log.PandaState.PandaType.unknown

@ -6,7 +6,7 @@ from collections import defaultdict
import cereal.messaging as messaging
from cereal import log
from cereal.services import service_list
from cereal.services import SERVICE_LIST
from openpilot.selfdrive.manager.process_config import managed_processes
from openpilot.system.hardware import TICI
@ -43,10 +43,10 @@ class TestCamerad(unittest.TestCase):
for cam, msgs in cls.logs.items():
if cls.sensor_type is None:
cls.sensor_type = getattr(msgs[0], msgs[0].which()).sensor.raw
expected_frames = service_list[cam].frequency * TEST_TIMESPAN
expected_frames = SERVICE_LIST[cam].frequency * TEST_TIMESPAN
assert expected_frames*0.95 < len(msgs) < expected_frames*1.05, f"unexpected frame count {cam}: {expected_frames=}, got {len(msgs)}"
dts = np.abs(np.diff([getattr(m, m.which()).timestampSof/1e6 for m in msgs]) - 1000/service_list[cam].frequency)
dts = np.abs(np.diff([getattr(m, m.which()).timestampSof/1e6 for m in msgs]) - 1000/SERVICE_LIST[cam].frequency)
assert (dts < FRAME_DELTA_TOLERANCE[cls.sensor_type]).all(), f"{cam} dts(ms) out of spec: max diff {dts.max()}, 99 percentile {np.percentile(dts, 99)}"
for m in msgs:

@ -8,7 +8,7 @@ from tabulate import tabulate
from typing import List
import cereal.messaging as messaging
from cereal.services import service_list
from cereal.services import SERVICE_LIST
from openpilot.system.hardware import HARDWARE, TICI
from openpilot.system.hardware.tici.power_monitor import get_power
from openpilot.selfdrive.manager.process_config import managed_processes
@ -91,7 +91,7 @@ class TestPowerDraw(unittest.TestCase):
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))
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])
with self.subTest(proc=proc.name):
self.assertTrue(math.isclose(cur, expected, rel_tol=proc.rtol, abs_tol=proc.atol))

@ -12,7 +12,7 @@ from typing import Dict, List
import cereal.messaging as messaging
from cereal import log
from cereal.services import service_list
from cereal.services import SERVICE_LIST
from openpilot.common.basedir import BASEDIR
from openpilot.common.params import Params
from openpilot.common.timeout import Timeout
@ -27,8 +27,8 @@ from openpilot.common.transformations.camera import tici_f_frame_size, tici_d_fr
SentinelType = log.Sentinel.SentinelType
CEREAL_SERVICES = [f for f in log.Event.schema.union_fields if f in service_list
and service_list[f].should_log and "encode" not in f.lower()]
CEREAL_SERVICES = [f for f in log.Event.schema.union_fields if f in SERVICE_LIST
and SERVICE_LIST[f].should_log and "encode" not in f.lower()]
class TestLoggerd(unittest.TestCase):
@ -219,8 +219,8 @@ class TestLoggerd(unittest.TestCase):
self.assertEqual(expected_val, bootlog_val)
def test_qlog(self):
qlog_services = [s for s in CEREAL_SERVICES if service_list[s].decimation is not None]
no_qlog_services = [s for s in CEREAL_SERVICES if service_list[s].decimation is None]
qlog_services = [s for s in CEREAL_SERVICES if SERVICE_LIST[s].decimation is not None]
no_qlog_services = [s for s in CEREAL_SERVICES if SERVICE_LIST[s].decimation is None]
services = random.sample(qlog_services, random.randint(2, min(10, len(qlog_services)))) + \
random.sample(no_qlog_services, random.randint(2, min(10, len(no_qlog_services))))
@ -245,7 +245,7 @@ class TestLoggerd(unittest.TestCase):
self.assertEqual(recv_cnt, 0, f"got {recv_cnt} {s} msgs in qlog")
else:
# check logged message count matches decimation
expected_cnt = (len(msgs) - 1) // service_list[s].decimation + 1
expected_cnt = (len(msgs) - 1) // SERVICE_LIST[s].decimation + 1
self.assertEqual(recv_cnt, expected_cnt, f"expected {expected_cnt} msgs for {s}, got {recv_cnt}")
def test_rlog(self):

@ -33,15 +33,16 @@ TEST_CASE("Parser::procStat") {
SECTION("all processes") {
std::vector<int> pids = Parser::pids();
REQUIRE(pids.size() > 1);
int parsed_cnt = 0;
for (int pid : pids) {
if (auto stat = Parser::procStat(util::read_file("/proc/" + std::to_string(pid) + "/stat"))) {
std::string stat_path = "/proc/" + std::to_string(pid) + "/stat";
INFO(stat_path);
if (auto stat = Parser::procStat(util::read_file(stat_path))) {
REQUIRE(stat->pid == pid);
REQUIRE(allowed_states.find(stat->state) != std::string::npos);
++parsed_cnt;
} else {
REQUIRE(util::file_exists(stat_path) == false);
}
}
REQUIRE(parsed_cnt == pids.size());
}
}
@ -109,8 +110,6 @@ TEST_CASE("Parser::cmdline") {
}
TEST_CASE("buildProcLogerMessage") {
std::vector<int> current_pids = Parser::pids();
MessageBuilder msg;
buildProcLogMessage(msg);
@ -131,10 +130,7 @@ TEST_CASE("buildProcLogerMessage") {
// test cereal::ProcLog::Process
auto procs = log.getProcs();
REQUIRE(procs.size() == current_pids.size());
for (auto p : procs) {
REQUIRE_THAT(current_pids, Catch::Matchers::VectorContains(p.getPid()));
REQUIRE(allowed_states.find(p.getState()) != std::string::npos);
if (p.getPid() == ::getpid()) {
REQUIRE(p.getName() == "test_proclog");
@ -147,8 +143,11 @@ TEST_CASE("buildProcLogerMessage") {
std::ifstream stream(cmd_path);
auto cmdline = Parser::cmdline(stream);
REQUIRE(cmdline.size() == p.getCmdline().size());
for (int i = 0; i < p.getCmdline().size(); ++i) {
REQUIRE(cmdline[i] == p.getCmdline()[i].cStr());
// do not check the cmdline of pytest as it will change.
if (cmdline.size() > 0 && cmdline[0].find("[pytest") != 0) {
for (int i = 0; i < p.getCmdline().size(); ++i) {
REQUIRE(cmdline[i] == p.getCmdline()[i].cStr());
}
}
}
}

@ -3,7 +3,7 @@ import time
import unittest
import cereal.messaging as messaging
from cereal.services import service_list
from cereal.services import SERVICE_LIST
from openpilot.common.gpio import gpio_read
from openpilot.selfdrive.test.helpers import with_processes
from openpilot.selfdrive.manager.process_config import managed_processes
@ -26,10 +26,10 @@ class TestPigeond(unittest.TestCase):
sm = messaging.SubMaster(['ubloxRaw'])
# setup time
for _ in range(int(5 * service_list['ubloxRaw'].frequency)):
for _ in range(int(5 * SERVICE_LIST['ubloxRaw'].frequency)):
sm.update()
for _ in range(int(10 * service_list['ubloxRaw'].frequency)):
for _ in range(int(10 * SERVICE_LIST['ubloxRaw'].frequency)):
sm.update()
assert sm.all_checks()

@ -7,7 +7,7 @@ from collections import namedtuple, defaultdict
import cereal.messaging as messaging
from cereal import log
from cereal.services import service_list
from cereal.services import SERVICE_LIST
from openpilot.common.gpio import get_irqs_for_action
from openpilot.common.timeout import Timeout
from openpilot.system.hardware import TICI
@ -172,7 +172,7 @@ class TestSensord(unittest.TestCase):
for s, msgs in self.events.items():
with self.subTest(sensor=s):
freq = len(msgs) / self.sample_secs
ef = service_list[s].frequency
ef = SERVICE_LIST[s].frequency
assert ef*0.85 <= freq <= ef*1.15
def test_logmonottime_timestamp_diff(self):

@ -7,20 +7,49 @@ from openpilot.tools.sim.lib.camerad import W, H
class CarlaWorld(World):
def __init__(self, world, vehicle, high_quality=False, dual_camera=False):
def __init__(self, client, high_quality, dual_camera, num_selected_spawn_point, town):
super().__init__(dual_camera)
import carla
low_quality_layers = carla.MapLayer(carla.MapLayer.Ground | carla.MapLayer.Walls | carla.MapLayer.Decals)
layers = carla.MapLayer.All if high_quality else low_quality_layers
world = client.load_world(town, map_layers=layers)
settings = world.get_settings()
settings.fixed_delta_seconds = 0.01
world.apply_settings(settings)
world.set_weather(carla.WeatherParameters.ClearSunset)
self.world = world
world_map = world.get_map()
blueprint_library = world.get_blueprint_library()
vehicle_bp = blueprint_library.filter('vehicle.tesla.*')[1]
vehicle_bp.set_attribute('role_name', 'hero')
spawn_points = world_map.get_spawn_points()
assert len(spawn_points) > num_selected_spawn_point, \
f'''No spawn point {num_selected_spawn_point}, try a value between 0 and {len(spawn_points)} for this town.'''
self.spawn_point = spawn_points[num_selected_spawn_point]
self.vehicle = world.spawn_actor(vehicle_bp, self.spawn_point)
physics_control = self.vehicle.get_physics_control()
physics_control.mass = 2326
physics_control.torque_curve = [[20.0, 500.0], [5000.0, 500.0]]
physics_control.gear_switch_time = 0.0
self.vehicle.apply_physics_control(physics_control)
self.vc: carla.VehicleControl = carla.VehicleControl(throttle=0, steer=0, brake=0, reverse=False)
self.vehicle = vehicle
self.max_steer_angle: float = vehicle.get_physics_control().wheels[0].max_steer_angle
self.max_steer_angle: float = self.vehicle.get_physics_control().wheels[0].max_steer_angle
self.params = Params()
self.steer_ratio = 15
self.carla_objects = []
blueprint_library = self.world.get_blueprint_library()
transform = carla.Transform(carla.Location(x=0.8, z=1.13))
def create_camera(fov, callback):
@ -31,7 +60,7 @@ class CarlaWorld(World):
blueprint.set_attribute('sensor_tick', str(1/20))
if not high_quality:
blueprint.set_attribute('enable_postprocess_effects', 'False')
camera = world.spawn_actor(blueprint, transform, attach_to=vehicle)
camera = world.spawn_actor(blueprint, transform, attach_to=self.vehicle)
camera.listen(callback)
return camera
@ -44,13 +73,13 @@ class CarlaWorld(World):
# re-enable IMU
imu_bp = blueprint_library.find('sensor.other.imu')
imu_bp.set_attribute('sensor_tick', '0.01')
self.imu = world.spawn_actor(imu_bp, transform, attach_to=vehicle)
self.imu = world.spawn_actor(imu_bp, transform, attach_to=self.vehicle)
gps_bp = blueprint_library.find('sensor.other.gnss')
self.gps = world.spawn_actor(gps_bp, transform, attach_to=vehicle)
self.gps = world.spawn_actor(gps_bp, transform, attach_to=self.vehicle)
self.params.put_bool("UbloxAvailable", True)
self.carla_objects = [self.imu, self.gps, self.road_camera, self.road_wide_camera]
self.carla_objects = [self.imu, self.gps, self.road_camera, self.road_wide_camera, self.vehicle]
def close(self):
for s in self.carla_objects:
@ -110,6 +139,12 @@ class CarlaWorld(World):
def tick(self):
self.world.tick()
def reset(self):
import carla
self.vehicle.set_transform(self.spawn_point)
self.vehicle.set_target_velocity(carla.Vector3D())
class CarlaBridge(SimulatorBridge):
TICKS_PER_FRAME = 5
@ -126,38 +161,5 @@ class CarlaBridge(SimulatorBridge):
client = carla.Client(self.host, self.port)
client.set_timeout(5)
world = client.load_world(self.town)
settings = world.get_settings()
settings.fixed_delta_seconds = 0.01
world.apply_settings(settings)
world.set_weather(carla.WeatherParameters.ClearSunset)
if not self.high_quality:
world.unload_map_layer(carla.MapLayer.Foliage)
world.unload_map_layer(carla.MapLayer.Buildings)
world.unload_map_layer(carla.MapLayer.ParkedVehicles)
world.unload_map_layer(carla.MapLayer.Props)
world.unload_map_layer(carla.MapLayer.StreetLights)
world.unload_map_layer(carla.MapLayer.Particles)
blueprint_library = world.get_blueprint_library()
world_map = world.get_map()
vehicle_bp = blueprint_library.filter('vehicle.tesla.*')[1]
vehicle_bp.set_attribute('role_name', 'hero')
spawn_points = world_map.get_spawn_points()
assert len(spawn_points) > self.num_selected_spawn_point, \
f'''No spawn point {self.num_selected_spawn_point}, try a value between 0 and {len(spawn_points)} for this town.'''
spawn_point = spawn_points[self.num_selected_spawn_point]
vehicle = world.spawn_actor(vehicle_bp, spawn_point)
physics_control = vehicle.get_physics_control()
physics_control.mass = 2326
physics_control.torque_curve = [[20.0, 500.0], [5000.0, 500.0]]
physics_control.gear_switch_time = 0.0
vehicle.apply_physics_control(physics_control)
return CarlaWorld(world, vehicle, dual_camera=self.dual_camera)
return CarlaWorld(client, high_quality=self.high_quality, dual_camera=self.dual_camera,
num_selected_spawn_point=self.num_selected_spawn_point, town=self.town)

@ -127,6 +127,8 @@ class SimulatorBridge(ABC):
self.simulator_state.cruise_button = CruiseButtons.MAIN
elif m[0] == "ignition":
self.simulator_state.ignition = not self.simulator_state.ignition
elif m[0] == "reset":
self.world.reset()
elif m[0] == "quit":
break

@ -81,8 +81,11 @@ class MetaDriveWorld(World):
obs, _, terminated, _, info = self.env.step(self.vc)
if terminated:
self.env.reset()
self.reset_time = time.monotonic()
self.reset()
def reset(self):
self.env.reset()
self.reset_time = time.monotonic()
def close(self):
pass

@ -83,4 +83,8 @@ class World(ABC):
@abstractmethod
def close(self):
pass
@abstractmethod
def reset(self):
pass

@ -55,6 +55,8 @@ def keyboard_poll_thread(q: 'Queue[str]'):
q.put("steer_%f" % -0.15)
elif c == 'i':
q.put("ignition")
elif c == 'r':
q.put("reset")
elif c == 'q':
q.put("quit")
break

Loading…
Cancel
Save