diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index 9001ca86fc..0ccf1844d9 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -116,6 +116,8 @@ jobs: submodules: true - uses: ./.github/workflows/setup-pre-commit - uses: ./.github/workflows/setup-with-retry + - name: Build openpilot + run: ${{ env.RUN }} "scons -j$(nproc)" - name: pre-commit timeout-minutes: 4 run: ${{ env.RUN }} "unset PYTHONWARNINGS && pre-commit run --all && chmod -R 777 /tmp/pre-commit" @@ -143,7 +145,7 @@ jobs: $PYTEST --timeout 60 -m 'not slow' && \ ./selfdrive/ui/tests/create_test_translations.sh && \ QT_QPA_PLATFORM=offscreen ./selfdrive/ui/tests/test_translations && \ - ./selfdrive/ui/tests/test_translations.py" + pytest ./selfdrive/ui/tests/test_translations.py" - name: "Upload coverage to Codecov" uses: codecov/codecov-action@v4 with: diff --git a/.gitignore b/.gitignore index 693c532c54..4bc5fd3a24 100644 --- a/.gitignore +++ b/.gitignore @@ -40,8 +40,7 @@ compile_commands.json compare_runtime*.html persist -board/obj/ -selfdrive/boardd/boardd +selfdrive/pandad/pandad selfdrive/logcatd/logcatd selfdrive/mapd/default_speeds_by_region.json system/proclogd/proclogd diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 28f8acd6e2..68d303cd61 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -86,8 +86,8 @@ repos: hooks: - id: test_translations name: test translations - entry: selfdrive/ui/tests/test_translations.py - language: script + entry: pytest selfdrive/ui/tests/test_translations.py + language: system pass_filenames: false files: '^selfdrive/ui/translations/' - repo: https://github.com/python-poetry/poetry diff --git a/Jenkinsfile b/Jenkinsfile index 0a044ff039..321237716b 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -192,7 +192,7 @@ node { 'HW + Unit Tests': { deviceStage("tici-hardware", "tici-common", ["UNSAFE=1"], [ ["build", "cd system/manager && ./build.py"], - ["test pandad", "pytest selfdrive/boardd/tests/test_pandad.py"], + ["test pandad", "pytest selfdrive/pandad/tests/test_pandad.py"], ["test power draw", "pytest -s system/hardware/tici/tests/test_power_draw.py"], ["test encoder", "LD_LIBRARY_PATH=/usr/local/lib pytest system/loggerd/tests/test_encoder.py"], ["test pigeond", "pytest system/ubloxd/tests/test_pigeond.py"], @@ -202,7 +202,7 @@ node { 'loopback': { deviceStage("loopback", "tici-loopback", ["UNSAFE=1"], [ ["build openpilot", "cd system/manager && ./build.py"], - ["test boardd loopback", "pytest selfdrive/boardd/tests/test_boardd_loopback.py"], + ["test pandad loopback", "pytest selfdrive/pandad/tests/test_pandad_loopback.py"], ]) }, 'camerad': { @@ -236,9 +236,9 @@ node { 'tizi': { deviceStage("tizi", "tizi", ["UNSAFE=1"], [ ["build openpilot", "cd system/manager && ./build.py"], - ["test boardd loopback", "SINGLE_PANDA=1 pytest selfdrive/boardd/tests/test_boardd_loopback.py"], - ["test boardd spi", "pytest selfdrive/boardd/tests/test_boardd_spi.py"], - ["test pandad", "pytest selfdrive/boardd/tests/test_pandad.py"], + ["test pandad loopback", "SINGLE_PANDA=1 pytest selfdrive/pandad/tests/test_pandad_loopback.py"], + ["test pandad spi", "pytest selfdrive/pandad/tests/test_pandad_spi.py"], + ["test pandad", "pytest selfdrive/pandad/tests/test_pandad.py"], ["test amp", "pytest system/hardware/tici/tests/test_amplifier.py"], ["test hw", "pytest system/hardware/tici/tests/test_hardware.py"], ["test qcomgpsd", "pytest system/qcomgpsd/tests/test_qcomgpsd.py"], diff --git a/RELEASES.md b/RELEASES.md index da22a87a47..31fdd1561b 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,9 +1,12 @@ -Version 0.9.7 (2024-05-XX) +Version 0.9.7 (2024-06-11) ======================== * New driving model + * Inputs the past curvature for smoother and more accurate lateral control + * Simplified neural network architecture in the model's last layers + * Minor fixes to desire augmentation and weight decay * Adjust driving personality with the follow distance button -* Support for hybrid variants of supported Ford models * Added toggle to enable driver monitoring even when openpilot is not engaged +* Support for hybrid variants of supported Ford models * Fingerprinting without the OBD-II port on all cars Version 0.9.6 (2024-02-27) @@ -634,7 +637,7 @@ Version 0.5.13 (2019-05-31) * Reduce CPU utilization by 20% and improve stability * Temporarily remove mapd functionalities to improve stability * Add openpilot record-only mode for unsupported cars - * Synchronize controlsd to boardd to reduce latency + * Synchronize controlsd to pandad to reduce latency * Remove panda support for Subaru giraffe Version 0.5.12 (2019-05-16) @@ -970,7 +973,7 @@ Version 0.2.8 (2017-02-27) Version 0.2.7 (2017-02-08) =========================== * Better performance and pictures at night - * Fix ptr alignment issue in boardd + * Fix ptr alignment issue in pandad * Fix brake error light, fix crash if too cold Version 0.2.6 (2017-01-31) @@ -1002,7 +1005,7 @@ Version 0.2.2 (2017-01-10) Version 0.2.1 (2016-12-14) =========================== * Performance improvements, removal of more numpy - * Fix boardd process priority + * Fix pandad process priority * Make counter timer reset on use of steering wheel Version 0.2 (2016-12-12) diff --git a/SConstruct b/SConstruct index 1e9f2a6b5a..df34d5af99 100644 --- a/SConstruct +++ b/SConstruct @@ -226,7 +226,7 @@ env = Environment( "#cereal", "#third_party", "#opendbc/can", - "#selfdrive/boardd", + "#selfdrive/pandad", "#common", "#rednose/helpers", ], diff --git a/cereal b/cereal index 51cbf6294e..d0ceac712f 160000 --- a/cereal +++ b/cereal @@ -1 +1 @@ -Subproject commit 51cbf6294efb356347b2c18b3df9904d11a7ff43 +Subproject commit d0ceac712f531c125923cbdc4ec7bedbdc5a7baf diff --git a/common/realtime.py b/common/realtime.py index 6b8587ff06..dd97ea3d78 100644 --- a/common/realtime.py +++ b/common/realtime.py @@ -12,7 +12,7 @@ from openpilot.system.hardware import PC # time step for each process DT_CTRL = 0.01 # controlsd DT_MDL = 0.05 # model -DT_TRML = 0.5 # thermald and manager +DT_HW = 0.5 # hardwared and manager DT_DMON = 0.05 # driver monitoring @@ -23,7 +23,7 @@ class Priority: CTRL_LOW = 51 # plannerd & radard # CORE 3 - # - boardd = 55 + # - pandad = 55 CTRL_HIGH = 53 diff --git a/common/transformations/tests/test_coordinates.py b/common/transformations/tests/test_coordinates.py old mode 100755 new mode 100644 index 41076d9b3f..11a6bf70ee --- a/common/transformations/tests/test_coordinates.py +++ b/common/transformations/tests/test_coordinates.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - import numpy as np import openpilot.common.transformations.coordinates as coord diff --git a/common/transformations/tests/test_orientation.py b/common/transformations/tests/test_orientation.py old mode 100755 new mode 100644 index 695642774e..55fbc6581e --- a/common/transformations/tests/test_orientation.py +++ b/common/transformations/tests/test_orientation.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - import numpy as np from openpilot.common.transformations.orientation import euler2quat, quat2euler, euler2rot, rot2euler, \ diff --git a/docs/CARS.md b/docs/CARS.md index 899c6f8219..7861bb6542 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 device. All supported cars provide a better experience than any stock system. Supported vehicles reference the US market unless otherwise specified. -# 287 Supported Cars +# 288 Supported Cars |Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|Hardware Needed
 |Video| |---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:| @@ -93,7 +93,7 @@ A supported vehicle is one that just works when you install a comma device. All |Hyundai|Ioniq 5 (Southeast Asia only) 2022-23[5](#footnotes)|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai Q connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Hyundai|Ioniq 5 (with HDA II) 2022-23[5](#footnotes)|Highway Driving Assist II|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai Q connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Hyundai|Ioniq 5 (without HDA II) 2022-23[5](#footnotes)|Highway Driving Assist|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai K connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Hyundai|Ioniq 6 (with HDA II) 2023[5](#footnotes)|Highway Driving Assist II|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai P connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Hyundai|Ioniq 6 (with HDA II) 2023-24[5](#footnotes)|Highway Driving Assist II|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai P connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Hyundai|Ioniq Electric 2019|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai C connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Hyundai|Ioniq Electric 2020|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai H connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Hyundai|Ioniq Hybrid 2017-19|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai C connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| @@ -263,6 +263,7 @@ A supported vehicle is one that just works when you install a comma device. All |Volkswagen|Arteon 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Volkswagen|Arteon eHybrid 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Volkswagen|Arteon R 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Volkswagen|Arteon Shooting Brake 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Volkswagen|Atlas 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Volkswagen|Atlas Cross Sport 2020-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Volkswagen|California 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 J533 connector
- 1 USB-C coupler
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| diff --git a/docs/c_docs.rst b/docs/c_docs.rst index 6e8808ec20..7303c89be8 100644 --- a/docs/c_docs.rst +++ b/docs/c_docs.rst @@ -77,10 +77,10 @@ sensorsd .. autodoxygenindex:: :project: system_sensord_sensors -boardd +pandad ^^^^^^ .. autodoxygenindex:: - :project: selfdrive_boardd + :project: selfdrive_pandad rednose diff --git a/panda b/panda index d37d25e057..faa1802669 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit d37d25e0575f9f76d3ab0aaded832646ddc6459d +Subproject commit faa18026692f7714ee537261fe649dafe4882579 diff --git a/poetry.lock b/poetry.lock index 564779b6ec..23f58ec691 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0e15c700ef7dd958815caaec9f2747c560fe1a77990275354bdfe2ff3ac38457 -size 613262 +oid sha256:84ac396fe236ffaf09f9a865fa3bae19ac961db726bdc19b79e52c2f45db6abe +size 618064 diff --git a/pyproject.toml b/pyproject.toml index da7f1021e6..8642eff4cd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ markers = [ ] testpaths = [ "common", - "selfdrive/boardd", + "selfdrive/pandad", "selfdrive/car", "selfdrive/controls", "selfdrive/locationd", @@ -29,10 +29,9 @@ testpaths = [ "selfdrive/test/longitudinal_maneuvers", "selfdrive/test/process_replay/test_fuzzy.py", "system/updated", - "system/thermald", "system/athena", "system/camerad", - "system/hardware/tici", + "system/hardware", "system/loggerd", "system/proclogd", "system/tests", @@ -140,7 +139,8 @@ inputs = "*" Jinja2 = "*" lru-dict = "*" matplotlib = "*" -metadrive-simulator = { version = "0.4.2.3", markers = "platform_machine != 'aarch64'" } # no linux/aarch64 wheels for certain dependencies +# No release for this fix https://github.com/metadriverse/metadrive/issues/632. Pinned to this commit until next release +metadrive-simulator = {git = "https://github.com/metadriverse/metadrive.git", rev ="233a3a1698be7038ec3dd050ca10b547b4b3324c", markers = "platform_machine != 'aarch64'" } # no linux/aarch64 wheels for certain dependencies mpld3 = "*" mypy = "*" myst-parser = "*" @@ -164,6 +164,7 @@ pytest-timeout = "*" pytest-randomly = "*" pytest-asyncio = "*" pytest-mock = "*" +pytest-repeat = "*" rerun-sdk = "*" ruff = "*" sphinx = "*" diff --git a/release/build_devel.sh b/release/build_devel.sh index 18d99bb1cf..7fce11ca72 100755 --- a/release/build_devel.sh +++ b/release/build_devel.sh @@ -48,7 +48,6 @@ cp -pR --parents $(./release/release_files.py) $TARGET_DIR/ # in the directory cd $TARGET_DIR rm -f panda/board/obj/panda.bin.signed -git submodule status # include source commit hash and build date in commit GIT_HASH=$(git --git-dir=$SOURCE_DIR/.git rev-parse HEAD) @@ -64,6 +63,13 @@ date: $DATETIME master commit: $GIT_HASH " +# should be no submodules or LFS files +git submodule status +if [ ! -z "$(git lfs ls-files)" ]; then + echo "LFS files detected!" + exit 1 +fi + # ensure files are within GitHub's limit BIG_FILES="$(find . -type f -not -path './.git/*' -size +95M)" if [ ! -z "$BIG_FILES" ]; then diff --git a/release/build_release.sh b/release/build_release.sh index c2745ea287..b68ae455c3 100755 --- a/release/build_release.sh +++ b/release/build_release.sh @@ -1,4 +1,6 @@ -#!/usr/bin/bash -e +#!/usr/bin/bash +set -e +set -x # git diff --name-status origin/release3-staging | grep "^A" | less @@ -29,7 +31,7 @@ git checkout --orphan $RELEASE_BRANCH # do the files copy echo "[-] copying files T=$SECONDS" cd $SOURCE_DIR -cp -pR --parents $(./release/release_files.py) $TARGET_DIR/ +cp -pR --parents $(./release/release_files.py) $BUILD_DIR/ # in the directory cd $BUILD_DIR @@ -46,7 +48,7 @@ git commit -a -m "openpilot v$VERSION release" # Build export PYTHONPATH="$BUILD_DIR" -scons -j$(nproc) +scons -j$(nproc) --minimal # release panda fw CERT=/data/pandaextra/certs/release RELEASE=1 scons -j$(nproc) panda/ diff --git a/release/release_files.py b/release/release_files.py index bf6cd56a90..a6fb7d6481 100755 --- a/release/release_files.py +++ b/release/release_files.py @@ -27,11 +27,16 @@ blacklist = [ ".devcontainer/", "Darwin/", ".vscode", + + # no LFS + ".lfsconfig", + ".gitattributes", ] # gets you through the blacklist whitelist = [ "tools/lib/", + "tools/bodyteleop/", "tinygrad_repo/openpilot/compile2.py", "tinygrad_repo/extra/onnx.py", @@ -50,7 +55,7 @@ whitelist = [ "tinygrad_repo/tinygrad/runtime/ops_disk.py", "tinygrad_repo/tinygrad/runtime/ops_gpu.py", "tinygrad_repo/tinygrad/shape/*", - "tinygrad_repo/tinygrad/*.py", + "tinygrad_repo/tinygrad/.*.py", ] if __name__ == "__main__": diff --git a/selfdrive/SConscript b/selfdrive/SConscript index 6b72177d8e..52898f758f 100644 --- a/selfdrive/SConscript +++ b/selfdrive/SConscript @@ -1,4 +1,4 @@ -SConscript(['boardd/SConscript']) +SConscript(['pandad/SConscript']) SConscript(['controls/lib/lateral_mpc_lib/SConscript']) SConscript(['controls/lib/longitudinal_mpc_lib/SConscript']) SConscript(['locationd/SConscript']) diff --git a/selfdrive/boardd/.gitignore b/selfdrive/boardd/.gitignore deleted file mode 100644 index e8daa2ef27..0000000000 --- a/selfdrive/boardd/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -boardd -boardd_api_impl.cpp -tests/test_boardd_usbprotocol diff --git a/selfdrive/car/card.py b/selfdrive/car/card.py index 199c425782..330ad40e0d 100755 --- a/selfdrive/car/card.py +++ b/selfdrive/car/card.py @@ -11,7 +11,7 @@ from panda import ALTERNATIVE_EXPERIENCE from openpilot.common.params import Params from openpilot.common.realtime import config_realtime_process, Priority, Ratekeeper, DT_CTRL -from openpilot.selfdrive.boardd.boardd import can_list_to_can_capnp +from openpilot.selfdrive.pandad import can_list_to_can_capnp from openpilot.selfdrive.car.car_helpers import get_car, get_one_can from openpilot.selfdrive.car.interfaces import CarInterfaceBase from openpilot.selfdrive.controls.lib.events import Events @@ -153,7 +153,7 @@ class Car: # Initialize CarInterface, once controls are ready # TODO: this can make us miss at least a few cycles when doing an ECU knockout self.CI.init(self.CP, self.can_sock, self.pm.sock['sendcan']) - # signal boardd to switch to car safety mode + # signal pandad to switch to car safety mode self.params.put_bool_nonblocking("ControlsReady", True) if self.sm.all_alive(['carControl']): diff --git a/selfdrive/car/chrysler/fingerprints.py b/selfdrive/car/chrysler/fingerprints.py index 1789054580..01faa49bf7 100644 --- a/selfdrive/car/chrysler/fingerprints.py +++ b/selfdrive/car/chrysler/fingerprints.py @@ -557,6 +557,7 @@ FW_VERSIONS = { b'68467936AC ', b'68500630AD', b'68500630AE', + b'68500631AE', b'68502719AC ', b'68502722AC ', b'68502733AC ', @@ -603,6 +604,7 @@ FW_VERSIONS = { b'68484467AC', b'68484471AC', b'68502994AD', + b'68502996AD', b'68520867AE', b'68520867AF', b'68520870AC', diff --git a/selfdrive/car/ecu_addrs.py b/selfdrive/car/ecu_addrs.py index da5e7b4612..e7a9fbcf2c 100755 --- a/selfdrive/car/ecu_addrs.py +++ b/selfdrive/car/ecu_addrs.py @@ -6,7 +6,7 @@ import cereal.messaging as messaging from panda.python.uds import SERVICE_TYPE from openpilot.selfdrive.car import make_can_msg from openpilot.selfdrive.car.fw_query_definitions import EcuAddrBusType -from openpilot.selfdrive.boardd.boardd import can_list_to_can_capnp +from openpilot.selfdrive.pandad import can_list_to_can_capnp from openpilot.common.swaglog import cloudlog diff --git a/selfdrive/car/ford/tests/test_ford.py b/selfdrive/car/ford/tests/test_ford.py old mode 100755 new mode 100644 index 72dd69980a..b1a19017d4 --- a/selfdrive/car/ford/tests/test_ford.py +++ b/selfdrive/car/ford/tests/test_ford.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import random from collections.abc import Iterable diff --git a/selfdrive/car/fw_query_definitions.py b/selfdrive/car/fw_query_definitions.py index ad4dcdc8f1..bb2827571c 100755 --- a/selfdrive/car/fw_query_definitions.py +++ b/selfdrive/car/fw_query_definitions.py @@ -85,7 +85,7 @@ class Request: auxiliary: bool = False # FW responses from these queries will not be used for fingerprinting logging: bool = False - # boardd toggles OBD multiplexing on/off as needed + # pandad toggles OBD multiplexing on/off as needed obd_multiplexing: bool = True diff --git a/selfdrive/car/fw_versions.py b/selfdrive/car/fw_versions.py index f2aff2e6f9..4bb6413d01 100755 --- a/selfdrive/car/fw_versions.py +++ b/selfdrive/car/fw_versions.py @@ -352,7 +352,7 @@ if __name__ == "__main__": pandaStates_sock = messaging.sub_sock('pandaStates') sendcan = messaging.pub_sock('sendcan') - # Set up params for boardd + # Set up params for pandad params = Params() params.remove("FirmwareQueryDone") params.put_bool("IsOnroad", False) @@ -374,7 +374,7 @@ if __name__ == "__main__": t = time.time() print("Getting vin...") set_obd_multiplexing(params, True) - vin_rx_addr, vin_rx_bus, vin = get_vin(logcan, sendcan, (0, 1), retry=10, debug=args.debug) + vin_rx_addr, vin_rx_bus, vin = get_vin(logcan, sendcan, (0, 1), debug=args.debug) print(f'RX: {hex(vin_rx_addr)}, BUS: {vin_rx_bus}, VIN: {vin}') print(f"Getting VIN took {time.time() - t:.3f} s") print() diff --git a/selfdrive/car/gm/tests/test_gm.py b/selfdrive/car/gm/tests/test_gm.py old mode 100755 new mode 100644 index 389d0636c9..a0a4a94ffa --- a/selfdrive/car/gm/tests/test_gm.py +++ b/selfdrive/car/gm/tests/test_gm.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 from parameterized import parameterized from openpilot.selfdrive.car.gm.fingerprints import FINGERPRINTS diff --git a/selfdrive/car/honda/fingerprints.py b/selfdrive/car/honda/fingerprints.py index 4395688883..8a5b79b41e 100644 --- a/selfdrive/car/honda/fingerprints.py +++ b/selfdrive/car/honda/fingerprints.py @@ -11,43 +11,6 @@ Ecu = car.CarParams.Ecu FW_VERSIONS = { CAR.HONDA_ACCORD: { - (Ecu.programmedFuelInjection, 0x18da10f1, None): [ - b'37805-6A0-8720\x00\x00', - b'37805-6A0-9520\x00\x00', - b'37805-6A0-9620\x00\x00', - b'37805-6A0-9720\x00\x00', - b'37805-6A0-A540\x00\x00', - b'37805-6A0-A550\x00\x00', - b'37805-6A0-A640\x00\x00', - b'37805-6A0-A650\x00\x00', - b'37805-6A0-A740\x00\x00', - b'37805-6A0-A750\x00\x00', - b'37805-6A0-A840\x00\x00', - b'37805-6A0-A850\x00\x00', - b'37805-6A0-A930\x00\x00', - b'37805-6A0-AF30\x00\x00', - b'37805-6A0-AG30\x00\x00', - b'37805-6A0-AJ10\x00\x00', - b'37805-6A0-C540\x00\x00', - b'37805-6A0-CG20\x00\x00', - b'37805-6A1-H650\x00\x00', - b'37805-6B2-A550\x00\x00', - b'37805-6B2-A560\x00\x00', - b'37805-6B2-A650\x00\x00', - b'37805-6B2-A660\x00\x00', - b'37805-6B2-A720\x00\x00', - b'37805-6B2-A810\x00\x00', - b'37805-6B2-A820\x00\x00', - b'37805-6B2-A920\x00\x00', - b'37805-6B2-A960\x00\x00', - b'37805-6B2-AA10\x00\x00', - b'37805-6B2-C520\x00\x00', - b'37805-6B2-C540\x00\x00', - b'37805-6B2-C560\x00\x00', - b'37805-6B2-M520\x00\x00', - b'37805-6B2-Y810\x00\x00', - b'37805-6M4-B730\x00\x00', - ], (Ecu.shiftByWire, 0x18da0bf1, None): [ b'54008-TVC-A910\x00\x00', b'54008-TWA-A910\x00\x00', @@ -161,38 +124,6 @@ FW_VERSIONS = { ], }, CAR.HONDA_CIVIC: { - (Ecu.programmedFuelInjection, 0x18da10f1, None): [ - b'37805-5AA-A640\x00\x00', - b'37805-5AA-A650\x00\x00', - b'37805-5AA-A670\x00\x00', - b'37805-5AA-A680\x00\x00', - b'37805-5AA-A810\x00\x00', - b'37805-5AA-C640\x00\x00', - b'37805-5AA-C680\x00\x00', - b'37805-5AA-C820\x00\x00', - b'37805-5AA-L650\x00\x00', - b'37805-5AA-L660\x00\x00', - b'37805-5AA-L680\x00\x00', - b'37805-5AA-L690\x00\x00', - b'37805-5AA-L810\x00\x00', - b'37805-5AG-Q710\x00\x00', - b'37805-5AJ-A610\x00\x00', - b'37805-5AJ-A620\x00\x00', - b'37805-5AJ-L610\x00\x00', - b'37805-5BA-A310\x00\x00', - b'37805-5BA-A510\x00\x00', - b'37805-5BA-A740\x00\x00', - b'37805-5BA-A760\x00\x00', - b'37805-5BA-A930\x00\x00', - b'37805-5BA-A960\x00\x00', - b'37805-5BA-C640\x00\x00', - b'37805-5BA-C860\x00\x00', - b'37805-5BA-L410\x00\x00', - b'37805-5BA-L760\x00\x00', - b'37805-5BA-L930\x00\x00', - b'37805-5BA-L940\x00\x00', - b'37805-5BA-L960\x00\x00', - ], (Ecu.transmission, 0x18da1ef1, None): [ b'28101-5CG-A040\x00\x00', b'28101-5CG-A050\x00\x00', @@ -242,61 +173,6 @@ FW_VERSIONS = { ], }, CAR.HONDA_CIVIC_BOSCH: { - (Ecu.programmedFuelInjection, 0x18da10f1, None): [ - b'37805-5AA-A940\x00\x00', - b'37805-5AA-A950\x00\x00', - b'37805-5AA-C950\x00\x00', - b'37805-5AA-L940\x00\x00', - b'37805-5AA-L950\x00\x00', - b'37805-5AG-Z910\x00\x00', - b'37805-5AJ-A750\x00\x00', - b'37805-5AJ-L750\x00\x00', - b'37805-5AK-T530\x00\x00', - b'37805-5AN-A750\x00\x00', - b'37805-5AN-A830\x00\x00', - b'37805-5AN-A840\x00\x00', - b'37805-5AN-A930\x00\x00', - b'37805-5AN-A940\x00\x00', - b'37805-5AN-A950\x00\x00', - b'37805-5AN-AG20\x00\x00', - b'37805-5AN-AH20\x00\x00', - b'37805-5AN-AJ30\x00\x00', - b'37805-5AN-AK10\x00\x00', - b'37805-5AN-AK20\x00\x00', - b'37805-5AN-AR10\x00\x00', - b'37805-5AN-AR20\x00\x00', - b'37805-5AN-C650\x00\x00', - b'37805-5AN-CH20\x00\x00', - b'37805-5AN-E630\x00\x00', - b'37805-5AN-E720\x00\x00', - b'37805-5AN-E820\x00\x00', - b'37805-5AN-J820\x00\x00', - b'37805-5AN-L840\x00\x00', - b'37805-5AN-L930\x00\x00', - b'37805-5AN-L940\x00\x00', - b'37805-5AN-LF20\x00\x00', - b'37805-5AN-LH20\x00\x00', - b'37805-5AN-LJ20\x00\x00', - b'37805-5AN-LR20\x00\x00', - b'37805-5AN-LS20\x00\x00', - b'37805-5AW-G720\x00\x00', - b'37805-5AZ-E850\x00\x00', - b'37805-5AZ-G540\x00\x00', - b'37805-5AZ-G740\x00\x00', - b'37805-5AZ-G840\x00\x00', - b'37805-5BB-A530\x00\x00', - b'37805-5BB-A540\x00\x00', - b'37805-5BB-A620\x00\x00', - b'37805-5BB-A630\x00\x00', - b'37805-5BB-A640\x00\x00', - b'37805-5BB-C540\x00\x00', - b'37805-5BB-C630\x00\x00', - b'37805-5BB-C640\x00\x00', - b'37805-5BB-L540\x00\x00', - b'37805-5BB-L630\x00\x00', - b'37805-5BB-L640\x00\x00', - b'37805-5BF-J130\x00\x00', - ], (Ecu.transmission, 0x18da1ef1, None): [ b'28101-5CG-A920\x00\x00', b'28101-5CG-AB10\x00\x00', @@ -400,10 +276,6 @@ FW_VERSIONS = { ], }, CAR.HONDA_CIVIC_BOSCH_DIESEL: { - (Ecu.programmedFuelInjection, 0x18da10f1, None): [ - b'37805-59N-G630\x00\x00', - b'37805-59N-G830\x00\x00', - ], (Ecu.transmission, 0x18da1ef1, None): [ b'28101-59Y-G220\x00\x00', b'28101-59Y-G620\x00\x00', @@ -449,41 +321,6 @@ FW_VERSIONS = { ], }, CAR.HONDA_CRV_5G: { - (Ecu.programmedFuelInjection, 0x18da10f1, None): [ - b'37805-5PA-3060\x00\x00', - b'37805-5PA-3080\x00\x00', - b'37805-5PA-3180\x00\x00', - b'37805-5PA-4050\x00\x00', - b'37805-5PA-4150\x00\x00', - b'37805-5PA-6520\x00\x00', - b'37805-5PA-6530\x00\x00', - b'37805-5PA-6630\x00\x00', - b'37805-5PA-6640\x00\x00', - b'37805-5PA-7630\x00\x00', - b'37805-5PA-9530\x00\x00', - b'37805-5PA-9630\x00\x00', - b'37805-5PA-9640\x00\x00', - b'37805-5PA-9730\x00\x00', - b'37805-5PA-9830\x00\x00', - b'37805-5PA-9840\x00\x00', - b'37805-5PA-A650\x00\x00', - b'37805-5PA-A670\x00\x00', - b'37805-5PA-A680\x00\x00', - b'37805-5PA-A850\x00\x00', - b'37805-5PA-A870\x00\x00', - b'37805-5PA-A880\x00\x00', - b'37805-5PA-A890\x00\x00', - b'37805-5PA-AB10\x00\x00', - b'37805-5PA-AD10\x00\x00', - b'37805-5PA-AF20\x00\x00', - b'37805-5PA-AF30\x00\x00', - b'37805-5PA-AH20\x00\x00', - b'37805-5PA-BF10\x00\x00', - b'37805-5PA-C680\x00\x00', - b'37805-5PD-Q630\x00\x00', - b'37805-5PF-F730\x00\x00', - b'37805-5PF-M630\x00\x00', - ], (Ecu.transmission, 0x18da1ef1, None): [ b'28101-5RG-A020\x00\x00', b'28101-5RG-A030\x00\x00', @@ -559,10 +396,6 @@ FW_VERSIONS = { ], }, CAR.HONDA_CRV_EU: { - (Ecu.programmedFuelInjection, 0x18da10f1, None): [ - b'37805-R5Z-G740\x00\x00', - b'37805-R5Z-G780\x00\x00', - ], (Ecu.vsa, 0x18da28f1, None): [ b'57114-T1V-G920\x00\x00', ], @@ -663,24 +496,6 @@ FW_VERSIONS = { b'38897-THR-A010\x00\x00', b'38897-THR-A020\x00\x00', ], - (Ecu.programmedFuelInjection, 0x18da10f1, None): [ - b'37805-5MR-3050\x00\x00', - b'37805-5MR-3150\x00\x00', - b'37805-5MR-3250\x00\x00', - b'37805-5MR-4070\x00\x00', - b'37805-5MR-4080\x00\x00', - b'37805-5MR-4170\x00\x00', - b'37805-5MR-4180\x00\x00', - b'37805-5MR-A240\x00\x00', - b'37805-5MR-A250\x00\x00', - b'37805-5MR-A310\x00\x00', - b'37805-5MR-A740\x00\x00', - b'37805-5MR-A750\x00\x00', - b'37805-5MR-A840\x00\x00', - b'37805-5MR-C620\x00\x00', - b'37805-5MR-D530\x00\x00', - b'37805-5MR-K730\x00\x00', - ], (Ecu.eps, 0x18da30f1, None): [ b'39990-THR-A020\x00\x00', b'39990-THR-A030\x00\x00', @@ -765,39 +580,6 @@ FW_VERSIONS = { b'28101-5EZ-A700\x00\x00', b'28103-5EY-A110\x00\x00', ], - (Ecu.programmedFuelInjection, 0x18da10f1, None): [ - b'37805-RLV-4060\x00\x00', - b'37805-RLV-4070\x00\x00', - b'37805-RLV-5140\x00\x00', - b'37805-RLV-5230\x00\x00', - b'37805-RLV-5250\x00\x00', - b'37805-RLV-A630\x00\x00', - b'37805-RLV-A830\x00\x00', - b'37805-RLV-A840\x00\x00', - b'37805-RLV-B210\x00\x00', - b'37805-RLV-B220\x00\x00', - b'37805-RLV-B420\x00\x00', - b'37805-RLV-B430\x00\x00', - b'37805-RLV-B620\x00\x00', - b'37805-RLV-B710\x00\x00', - b'37805-RLV-B720\x00\x00', - b'37805-RLV-C430\x00\x00', - b'37805-RLV-C510\x00\x00', - b'37805-RLV-C520\x00\x00', - b'37805-RLV-C530\x00\x00', - b'37805-RLV-C910\x00\x00', - b'37805-RLV-F120\x00\x00', - b'37805-RLV-L080\x00\x00', - b'37805-RLV-L090\x00\x00', - b'37805-RLV-L150\x00\x00', - b'37805-RLV-L160\x00\x00', - b'37805-RLV-L180\x00\x00', - b'37805-RLV-L350\x00\x00', - b'37805-RLV-L410\x00\x00', - b'37805-RLV-L430\x00\x00', - b'37805-RLV-L830\x00\x00', - b'37805-RLV-L850\x00\x00', - ], (Ecu.gateway, 0x18daeff1, None): [ b'38897-TG7-A030\x00\x00', b'38897-TG7-A040\x00\x00', @@ -875,26 +657,6 @@ FW_VERSIONS = { ], }, CAR.ACURA_RDX_3G: { - (Ecu.programmedFuelInjection, 0x18da10f1, None): [ - b'37805-5YF-A130\x00\x00', - b'37805-5YF-A230\x00\x00', - b'37805-5YF-A320\x00\x00', - b'37805-5YF-A330\x00\x00', - b'37805-5YF-A420\x00\x00', - b'37805-5YF-A430\x00\x00', - b'37805-5YF-A750\x00\x00', - b'37805-5YF-A760\x00\x00', - b'37805-5YF-A770\x00\x00', - b'37805-5YF-A850\x00\x00', - b'37805-5YF-A860\x00\x00', - b'37805-5YF-A870\x00\x00', - b'37805-5YF-AD20\x00\x00', - b'37805-5YF-C210\x00\x00', - b'37805-5YF-C220\x00\x00', - b'37805-5YF-C410\x00\x00', - b'37805-5YF-C420\x00\x00', - b'37805-5YF-C430\x00\x00', - ], (Ecu.vsa, 0x18da28f1, None): [ b'57114-TJB-A030\x00\x00', b'57114-TJB-A040\x00\x00', @@ -1049,10 +811,6 @@ FW_VERSIONS = { b'28101-6EH-A010\x00\x00', b'28101-6JC-M310\x00\x00', ], - (Ecu.programmedFuelInjection, 0x18da10f1, None): [ - b'37805-6CT-A710\x00\x00', - b'37805-6HZ-M630\x00\x00', - ], (Ecu.electricBrakeBooster, 0x18da2bf1, None): [ b'46114-3W0-A020\x00\x00', ], @@ -1133,14 +891,5 @@ FW_VERSIONS = { b'28101-65H-A120\x00\x00', b'28101-65J-N010\x00\x00', ], - (Ecu.programmedFuelInjection, 0x18da10f1, None): [ - b'37805-64A-A540\x00\x00', - b'37805-64A-A620\x00\x00', - b'37805-64D-P510\x00\x00', - b'37805-64L-A540\x00\x00', - b'37805-64S-A540\x00\x00', - b'37805-64S-A720\x00\x00', - b'37805-64S-AA10\x00\x00', - ], }, } diff --git a/selfdrive/car/honda/tests/test_honda.py b/selfdrive/car/honda/tests/test_honda.py old mode 100755 new mode 100644 index 54d177d2ed..b8ad7872b2 --- a/selfdrive/car/honda/tests/test_honda.py +++ b/selfdrive/car/honda/tests/test_honda.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import re from openpilot.selfdrive.car.honda.fingerprints import FW_VERSIONS diff --git a/selfdrive/car/honda/values.py b/selfdrive/car/honda/values.py index 1b0da8d7de..c3005c667c 100644 --- a/selfdrive/car/honda/values.py +++ b/selfdrive/car/honda/values.py @@ -299,6 +299,7 @@ FW_QUERY_CONFIG = FwQueryConfig( ], # We lose these ECUs without the comma power on these cars. # Note that we still attempt to match with them when they are present + # This is or'd with (ALL_ECUS - ESSENTIAL_ECUS) from fw_versions.py non_essential_ecus={ Ecu.eps: [CAR.ACURA_RDX_3G, CAR.HONDA_ACCORD, CAR.HONDA_CIVIC_2022, CAR.HONDA_E, CAR.HONDA_HRV_3G], Ecu.vsa: [CAR.ACURA_RDX_3G, CAR.HONDA_ACCORD, CAR.HONDA_CIVIC, CAR.HONDA_CIVIC_BOSCH, CAR.HONDA_CIVIC_2022, CAR.HONDA_CRV_5G, CAR.HONDA_CRV_HYBRID, @@ -306,6 +307,7 @@ FW_QUERY_CONFIG = FwQueryConfig( }, extra_ecus=[ (Ecu.combinationMeter, 0x18da60f1, None), + (Ecu.programmedFuelInjection, 0x18da10f1, None), # The only other ECU on PT bus accessible by camera on radarless Civic # This is likely a manufacturer-specific sub-address implementation: the camera responds to this and 0x18dab0f1 # Unclear what the part number refers to: 8S103 is 'Camera Set Mono', while 36160 is 'Camera Monocular - Honda' diff --git a/selfdrive/car/hyundai/fingerprints.py b/selfdrive/car/hyundai/fingerprints.py index 8525d3ecaf..d115283dd5 100644 --- a/selfdrive/car/hyundai/fingerprints.py +++ b/selfdrive/car/hyundai/fingerprints.py @@ -23,9 +23,6 @@ FINGERPRINTS = { CAR.GENESIS_G90: [{ 67: 8, 68: 8, 127: 8, 304: 8, 320: 8, 339: 8, 356: 4, 358: 6, 359: 8, 544: 8, 593: 8, 608: 8, 688: 5, 809: 8, 854: 7, 870: 7, 871: 8, 872: 8, 897: 8, 902: 8, 903: 8, 916: 8, 1040: 8, 1056: 8, 1057: 8, 1078: 4, 1107: 5, 1136: 8, 1151: 6, 1162: 4, 1168: 7, 1170: 8, 1173: 8, 1184: 8, 1265: 4, 1280: 1, 1281: 3, 1287: 4, 1290: 8, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1345: 8, 1348: 8, 1363: 8, 1369: 8, 1370: 8, 1371: 8, 1378: 4, 1384: 8, 1407: 8, 1419: 8, 1425: 2, 1427: 6, 1434: 2, 1456: 4, 1470: 8, 1988: 8, 2000: 8, 2003: 8, 2004: 8, 2005: 8, 2008: 8, 2011: 8, 2012: 8, 2013: 8 }], - CAR.HYUNDAI_IONIQ_EV_2020: [{ - 127: 8, 304: 8, 320: 8, 339: 8, 352: 8, 356: 4, 524: 8, 544: 7, 593: 8, 688: 5, 832: 8, 881: 8, 882: 8, 897: 8, 902: 8, 903: 8, 905: 8, 909: 8, 916: 8, 1040: 8, 1042: 8, 1056: 8, 1057: 8, 1078: 4, 1136: 8, 1151: 6, 1155: 8, 1156: 8, 1157: 4, 1164: 8, 1168: 7, 1173: 8, 1183: 8, 1186: 2, 1191: 2, 1225: 8, 1265: 4, 1280: 1, 1287: 4, 1290: 8, 1291: 8, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1342: 6, 1345: 8, 1348: 8, 1355: 8, 1363: 8, 1369: 8, 1379: 8, 1407: 8, 1419: 8, 1426: 8, 1427: 6, 1429: 8, 1430: 8, 1456: 4, 1470: 8, 1473: 8, 1507: 8, 1535: 8, 1988: 8, 1996: 8, 2000: 8, 2004: 8, 2005: 8, 2008: 8, 2012: 8, 2013: 8 - }], CAR.HYUNDAI_KONA_EV: [{ 127: 8, 304: 8, 320: 8, 339: 8, 352: 8, 356: 4, 544: 8, 549: 8, 593: 8, 688: 5, 832: 8, 881: 8, 882: 8, 897: 8, 902: 8, 903: 8, 905: 8, 909: 8, 916: 8, 1040: 8, 1042: 8, 1056: 8, 1057: 8, 1078: 4, 1136: 8, 1151: 6, 1168: 7, 1173: 8, 1183: 8, 1186: 2, 1191: 2, 1225: 8, 1265: 4, 1280: 1, 1287: 4, 1290: 8, 1291: 8, 1292: 8, 1294: 8, 1307: 8, 1312: 8, 1322: 8, 1342: 6, 1345: 8, 1348: 8, 1355: 8, 1363: 8, 1369: 8, 1378: 4, 1407: 8, 1419: 8, 1426: 8, 1427: 6, 1429: 8, 1430: 8, 1456: 4, 1470: 8, 1473: 8, 1507: 8, 1535: 8, 2000: 8, 2004: 8, 2008: 8, 2012: 8, 1157: 4, 1193: 8, 1379: 8, 1988: 8, 1996: 8 }], @@ -135,9 +132,12 @@ FW_VERSIONS = { b'\xf1\x00AEev SCC F-CUP 1.00 1.00 99110-G7200 ', b'\xf1\x00AEev SCC F-CUP 1.00 1.00 99110-G7500 ', b'\xf1\x00AEev SCC F-CUP 1.00 1.01 99110-G7000 ', + b'\xf1\x00AEev SCC F-CUP 1.00 1.01 99110-G7100 ', + b'\xf1\x00AEev SCC FHCUP 1.00 1.01 99110-G7100 ', ], (Ecu.eps, 0x7d4, None): [ b'\xf1\x00AE MDPS C 1.00 1.01 56310/G7310 4APEC101', + b'\xf1\x00AE MDPS C 1.00 1.01 56310/G7510 4APEC101', b'\xf1\x00AE MDPS C 1.00 1.01 56310/G7560 4APEC101', ], (Ecu.fwdCamera, 0x7c4, None): [ @@ -146,6 +146,7 @@ FW_VERSIONS = { b'\xf1\x00AEE MFC AT EUR LHD 1.00 1.01 95740-G2600 190819', b'\xf1\x00AEE MFC AT EUR LHD 1.00 1.03 95740-G2500 190516', b'\xf1\x00AEE MFC AT EUR RHD 1.00 1.01 95740-G2600 190819', + b'\xf1\x00AEE MFC AT USA LHD 1.00 1.01 95740-G2600 190819', ], }, CAR.HYUNDAI_IONIQ_EV_LTD: { @@ -749,6 +750,7 @@ FW_VERSIONS = { ], (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00DEhe SCC F-CUP 1.00 1.00 99110-G5600 ', + b'\xf1\x00DEhe SCC FHCUP 1.00 1.00 99110-G5600 ', ], }, CAR.KIA_NIRO_HEV_2021: { @@ -877,6 +879,7 @@ FW_VERSIONS = { b'\xf1\x00CN7 MFC AT USA LHD 1.00 1.03 99210-AA000 200819', b'\xf1\x00CN7 MFC AT USA LHD 1.00 1.03 99210-AB000 220426', b'\xf1\x00CN7 MFC AT USA LHD 1.00 1.06 99210-AA000 220111', + b'\xf1\x00CN7 MFC AT USA LHD 1.00 1.07 99210-AA000 220426', b'\xf1\x00CN7 MFC AT USA LHD 1.00 1.08 99210-AA000 220728', ], (Ecu.abs, 0x7d1, None): [ @@ -1001,6 +1004,7 @@ FW_VERSIONS = { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00CE MFC AT CAN LHD 1.00 1.04 99211-KL000 221213', b'\xf1\x00CE MFC AT EUR LHD 1.00 1.03 99211-KL000 221011', + b'\xf1\x00CE MFC AT EUR LHD 1.00 1.04 99211-KL000 221213', b'\xf1\x00CE MFC AT USA LHD 1.00 1.04 99211-KL000 221213', ], }, @@ -1039,10 +1043,10 @@ FW_VERSIONS = { CAR.KIA_SPORTAGE_5TH_GEN: { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00NQ5 FR_CMR AT AUS RHD 1.00 1.00 99211-P1040 663', + b'\xf1\x00NQ5 FR_CMR AT EUR LHD 1.00 1.00 99211-P1040 663', b'\xf1\x00NQ5 FR_CMR AT GEN LHD 1.00 1.00 99211-P1060 665', b'\xf1\x00NQ5 FR_CMR AT USA LHD 1.00 1.00 99211-P1030 662', b'\xf1\x00NQ5 FR_CMR AT USA LHD 1.00 1.00 99211-P1040 663', - b'\xf1\x00NQ5 FR_CMR AT EUR LHD 1.00 1.00 99211-P1040 663', b'\xf1\x00NQ5 FR_CMR AT USA LHD 1.00 1.00 99211-P1060 665', b'\xf1\x00NQ5 FR_CMR AT USA LHD 1.00 1.00 99211-P1070 690', ], diff --git a/selfdrive/car/hyundai/tests/test_hyundai.py b/selfdrive/car/hyundai/tests/test_hyundai.py old mode 100755 new mode 100644 index db2110b0de..4d31d7d15e --- a/selfdrive/car/hyundai/tests/test_hyundai.py +++ b/selfdrive/car/hyundai/tests/test_hyundai.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 from hypothesis import settings, given, strategies as st import pytest diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 72513c8497..c489ea0042 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -314,7 +314,7 @@ class CAR(Platforms): flags=HyundaiFlags.EV, ) HYUNDAI_IONIQ_6 = HyundaiCanFDPlatformConfig( - [HyundaiCarDocs("Hyundai Ioniq 6 (with HDA II) 2023", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_p]))], + [HyundaiCarDocs("Hyundai Ioniq 6 (with HDA II) 2023-24", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_p]))], HYUNDAI_IONIQ_5.specs, flags=HyundaiFlags.EV | HyundaiFlags.CANFD_NO_RADAR_DISABLE, ) @@ -515,7 +515,7 @@ class CAR(Platforms): # TODO: From 3.3T Sport Advanced 2022 & Prestige 2023 Trim, 2.0T is unknown HyundaiCarDocs("Genesis G70 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_l])), ], - CarSpecs(mass=3673 * CV.LB_TO_KG, wheelbase=2.83, steerRatio=12.9), + GENESIS_G70.specs, flags=HyundaiFlags.MANDO_RADAR, ) GENESIS_GV70_1ST_GEN = HyundaiCanFDPlatformConfig( @@ -648,6 +648,8 @@ PLATFORM_CODE_ECUS = [Ecu.fwdRadar, Ecu.fwdCamera, Ecu.eps] # TODO: there are date codes in the ABS firmware versions in hex DATE_FW_ECUS = [Ecu.fwdCamera] +# Note: an ECU on CAN FD cars may sometimes send 0x30080aaaaaaaaaaa (flow control continue) while we +# are attempting to query ECUs. This currently does not seem to affect fingerprinting from the camera FW_QUERY_CONFIG = FwQueryConfig( requests=[ # TODO: add back whitelists diff --git a/selfdrive/car/interfaces.py b/selfdrive/car/interfaces.py index 982d987d61..a3572238ba 100644 --- a/selfdrive/car/interfaces.py +++ b/selfdrive/car/interfaces.py @@ -6,6 +6,7 @@ from abc import abstractmethod, ABC from enum import StrEnum from typing import Any, NamedTuple from collections.abc import Callable +from functools import cache from cereal import car from openpilot.common.basedir import BASEDIR @@ -32,6 +33,18 @@ TORQUE_PARAMS_PATH = os.path.join(BASEDIR, 'selfdrive/car/torque_data/params.tom TORQUE_OVERRIDE_PATH = os.path.join(BASEDIR, 'selfdrive/car/torque_data/override.toml') TORQUE_SUBSTITUTE_PATH = os.path.join(BASEDIR, 'selfdrive/car/torque_data/substitute.toml') +GEAR_SHIFTER_MAP: dict[str, car.CarState.GearShifter] = { + 'P': GearShifter.park, 'PARK': GearShifter.park, + 'R': GearShifter.reverse, 'REVERSE': GearShifter.reverse, + 'N': GearShifter.neutral, 'NEUTRAL': GearShifter.neutral, + 'E': GearShifter.eco, 'ECO': GearShifter.eco, + 'T': GearShifter.manumatic, 'MANUAL': GearShifter.manumatic, + 'D': GearShifter.drive, 'DRIVE': GearShifter.drive, + 'S': GearShifter.sport, 'SPORT': GearShifter.sport, + 'L': GearShifter.low, 'LOW': GearShifter.low, + 'B': GearShifter.brake, 'BRAKE': GearShifter.brake, +} + class LatControlInputs(NamedTuple): lateral_acceleration: float @@ -43,29 +56,34 @@ class LatControlInputs(NamedTuple): TorqueFromLateralAccelCallbackType = Callable[[LatControlInputs, car.CarParams.LateralTorqueTuning, float, float, bool, bool], float] -def get_torque_params(candidate): +@cache +def get_torque_params(): with open(TORQUE_SUBSTITUTE_PATH, 'rb') as f: sub = tomllib.load(f) - if candidate in sub: - candidate = sub[candidate] - with open(TORQUE_PARAMS_PATH, 'rb') as f: params = tomllib.load(f) with open(TORQUE_OVERRIDE_PATH, 'rb') as f: override = tomllib.load(f) - # Ensure no overlap - if sum([candidate in x for x in [sub, params, override]]) > 1: - raise RuntimeError(f'{candidate} is defined twice in torque config') + torque_params = {} + for candidate in (sub.keys() | params.keys() | override.keys()) - {'legend'}: + if sum([candidate in x for x in [sub, params, override]]) > 1: + raise RuntimeError(f'{candidate} is defined twice in torque config') - if candidate in override: - out = override[candidate] - elif candidate in params: - out = params[candidate] - else: - raise NotImplementedError(f"Did not find torque params for {candidate}") - return {key: out[i] for i, key in enumerate(params['legend'])} + sub_candidate = sub.get(candidate, candidate) + if sub_candidate in override: + out = override[sub_candidate] + elif sub_candidate in params: + out = params[sub_candidate] + else: + raise NotImplementedError(f"Did not find torque params for {sub_candidate}") + + torque_params[sub_candidate] = {key: out[i] for i, key in enumerate(params['legend'])} + if candidate in sub: + torque_params[candidate] = torque_params[sub_candidate] + + return torque_params # generic car and radar interfaces @@ -166,7 +184,7 @@ class CarInterfaceBase(ABC): ret.carFingerprint = candidate # Car docs fields - ret.maxLateralAccel = get_torque_params(candidate)['MAX_LAT_ACCEL_MEASURED'] + ret.maxLateralAccel = get_torque_params()[candidate]['MAX_LAT_ACCEL_MEASURED'] ret.autoResumeSng = True # describes whether car can resume from a stop automatically # standard ALC params @@ -199,7 +217,7 @@ class CarInterfaceBase(ABC): @staticmethod def configure_torque_tune(candidate, tune, steering_angle_deadzone_deg=0.0, use_steering_angle=True): - params = get_torque_params(candidate) + params = get_torque_params()[candidate] tune.init('torque') tune.torque.useSteeringAngle = use_steering_angle @@ -422,19 +440,7 @@ class CarStateBase(ABC): def parse_gear_shifter(gear: str | None) -> car.CarState.GearShifter: if gear is None: return GearShifter.unknown - - d: dict[str, car.CarState.GearShifter] = { - 'P': GearShifter.park, 'PARK': GearShifter.park, - 'R': GearShifter.reverse, 'REVERSE': GearShifter.reverse, - 'N': GearShifter.neutral, 'NEUTRAL': GearShifter.neutral, - 'E': GearShifter.eco, 'ECO': GearShifter.eco, - 'T': GearShifter.manumatic, 'MANUAL': GearShifter.manumatic, - 'D': GearShifter.drive, 'DRIVE': GearShifter.drive, - 'S': GearShifter.sport, 'SPORT': GearShifter.sport, - 'L': GearShifter.low, 'LOW': GearShifter.low, - 'B': GearShifter.brake, 'BRAKE': GearShifter.brake, - } - return d.get(gear.upper(), GearShifter.unknown) + return GEAR_SHIFTER_MAP.get(gear.upper(), GearShifter.unknown) @staticmethod def get_can_parser(CP): diff --git a/selfdrive/car/isotp_parallel_query.py b/selfdrive/car/isotp_parallel_query.py index 8fdc747e9e..447c7093c5 100644 --- a/selfdrive/car/isotp_parallel_query.py +++ b/selfdrive/car/isotp_parallel_query.py @@ -4,7 +4,7 @@ from functools import partial import cereal.messaging as messaging from openpilot.common.swaglog import cloudlog -from openpilot.selfdrive.boardd.boardd import can_list_to_can_capnp +from openpilot.selfdrive.pandad import can_list_to_can_capnp from openpilot.selfdrive.car.fw_query_definitions import AddrType from panda.python.uds import CanClient, IsoTpMessage, FUNCTIONAL_ADDRS, get_rx_addr_for_tx_addr diff --git a/selfdrive/car/subaru/fingerprints.py b/selfdrive/car/subaru/fingerprints.py index e3bd9d9099..10c713501f 100644 --- a/selfdrive/car/subaru/fingerprints.py +++ b/selfdrive/car/subaru/fingerprints.py @@ -311,6 +311,7 @@ FW_VERSIONS = { b'\x00\x00d\xd3\x1f@ \t', ], (Ecu.engine, 0x7e0, None): [ + b'\xa7"@0\x07', b'\xa7"@p\x07', b'\xa7)\xa0q\x07', b'\xba"@@\x07', @@ -319,6 +320,7 @@ FW_VERSIONS = { (Ecu.transmission, 0x7e1, None): [ b'\x1a\xf6F`\x00', b'\xda\xf2`\x80\x00', + b'\xda\xf2`p\x00', b'\xda\xfd\xe0\x80\x00', b'\xdc\xf2@`\x00', b'\xdc\xf2``\x00', diff --git a/selfdrive/car/tests/test_can_fingerprint.py b/selfdrive/car/tests/test_can_fingerprint.py old mode 100755 new mode 100644 index bb585d567f..f236986d8e --- a/selfdrive/car/tests/test_can_fingerprint.py +++ b/selfdrive/car/tests/test_can_fingerprint.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 from parameterized import parameterized from cereal import log, messaging diff --git a/selfdrive/car/tests/test_car_interfaces.py b/selfdrive/car/tests/test_car_interfaces.py old mode 100755 new mode 100644 index 618bcd9627..19096c23e5 --- a/selfdrive/car/tests/test_car_interfaces.py +++ b/selfdrive/car/tests/test_car_interfaces.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import os import math import hypothesis.strategies as st diff --git a/selfdrive/car/tests/test_docs.py b/selfdrive/car/tests/test_docs.py old mode 100755 new mode 100644 index 0ed95e18f2..40ad07b283 --- a/selfdrive/car/tests/test_docs.py +++ b/selfdrive/car/tests/test_docs.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 from collections import defaultdict import os import pytest diff --git a/selfdrive/car/tests/test_fingerprints.py b/selfdrive/car/tests/test_fingerprints.py old mode 100755 new mode 100644 index 34f30bc703..6575d3e5c5 --- a/selfdrive/car/tests/test_fingerprints.py +++ b/selfdrive/car/tests/test_fingerprints.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import os import sys diff --git a/selfdrive/car/tests/test_fw_fingerprint.py b/selfdrive/car/tests/test_fw_fingerprint.py old mode 100755 new mode 100644 index 230e6f10e1..f872972542 --- a/selfdrive/car/tests/test_fw_fingerprint.py +++ b/selfdrive/car/tests/test_fw_fingerprint.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import pytest import random import time diff --git a/selfdrive/car/tests/test_lateral_limits.py b/selfdrive/car/tests/test_lateral_limits.py index a478bc601a..e61d197f4b 100755 --- a/selfdrive/car/tests/test_lateral_limits.py +++ b/selfdrive/car/tests/test_lateral_limits.py @@ -3,6 +3,7 @@ from collections import defaultdict import importlib from parameterized import parameterized_class import pytest +import sys from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.car.car_helpers import interfaces @@ -20,8 +21,6 @@ MAX_LAT_JERK_UP_TOLERANCE = 0.5 # m/s^3 # jerk is measured over half a second JERK_MEAS_T = 0.5 -car_model_jerks: defaultdict[str, dict[str, float]] = defaultdict(dict) - @parameterized_class('car_model', [(c,) for c in sorted(CAR_MODELS)]) class TestLateralLimits: @@ -44,7 +43,7 @@ class TestLateralLimits: CarControllerParams = importlib.import_module(f'selfdrive.car.{CP.carName}.values').CarControllerParams cls.control_params = CarControllerParams(CP) - cls.torque_params = get_torque_params(cls.car_model) + cls.torque_params = get_torque_params()[cls.car_model] @staticmethod def calculate_0_5s_jerk(control_params, torque_params): @@ -64,9 +63,36 @@ class TestLateralLimits: def test_jerk_limits(self): up_jerk, down_jerk = self.calculate_0_5s_jerk(self.control_params, self.torque_params) - car_model_jerks[self.car_model] = {"up_jerk": up_jerk, "down_jerk": down_jerk} assert up_jerk <= MAX_LAT_JERK_UP + MAX_LAT_JERK_UP_TOLERANCE assert down_jerk <= MAX_LAT_JERK_DOWN def test_max_lateral_accel(self): assert self.torque_params["MAX_LAT_ACCEL_MEASURED"] <= MAX_LAT_ACCEL + + +class LatAccelReport: + car_model_jerks: defaultdict[str, dict[str, float]] = defaultdict(dict) + + def pytest_sessionfinish(self): + print(f"\n\n---- Lateral limit report ({len(CAR_MODELS)} cars) ----\n") + + max_car_model_len = max([len(car_model) for car_model in self.car_model_jerks]) + for car_model, _jerks in sorted(self.car_model_jerks.items(), key=lambda i: i[1]['up_jerk'], reverse=True): + violation = _jerks["up_jerk"] > MAX_LAT_JERK_UP + MAX_LAT_JERK_UP_TOLERANCE or \ + _jerks["down_jerk"] > MAX_LAT_JERK_DOWN + violation_str = " - VIOLATION" if violation else "" + + print(f"{car_model:{max_car_model_len}} - up jerk: {round(_jerks['up_jerk'], 2):5} " + + f"m/s^3, down jerk: {round(_jerks['down_jerk'], 2):5} m/s^3{violation_str}") + + @pytest.fixture(scope="class", autouse=True) + def class_setup(self, request): + yield + cls = request.cls + if hasattr(cls, "control_params"): + up_jerk, down_jerk = TestLateralLimits.calculate_0_5s_jerk(cls.control_params, cls.torque_params) + self.car_model_jerks[cls.car_model] = {"up_jerk": up_jerk, "down_jerk": down_jerk} + + +if __name__ == '__main__': + sys.exit(pytest.main([__file__, '-n0', '--no-summary'], plugins=[LatAccelReport()])) # noqa: TID251 diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py old mode 100755 new mode 100644 index 8807db69d9..b5d75e665b --- a/selfdrive/car/tests/test_models.py +++ b/selfdrive/car/tests/test_models.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import capnp import os import importlib diff --git a/selfdrive/car/tests/test_platform_configs.py b/selfdrive/car/tests/test_platform_configs.py old mode 100755 new mode 100644 index 217189255e..31e4be4fe6 --- a/selfdrive/car/tests/test_platform_configs.py +++ b/selfdrive/car/tests/test_platform_configs.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - from openpilot.selfdrive.car.values import PLATFORMS diff --git a/selfdrive/car/torque_data/override.toml b/selfdrive/car/torque_data/override.toml index f6f4eacc1c..993eb3fb3c 100644 --- a/selfdrive/car/torque_data/override.toml +++ b/selfdrive/car/torque_data/override.toml @@ -61,7 +61,7 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] "GMC_ACADIA" = [1.6, 1.6, 0.2] "LEXUS_IS_TSS2" = [2.0, 2.0, 0.1] "HYUNDAI_KONA_EV_2ND_GEN" = [2.5, 2.5, 0.1] -"HYUNDAI_IONIQ_6" = [2.5, 2.5, 0.1] +"HYUNDAI_IONIQ_6" = [2.5, 2.5, 0.005] "HYUNDAI_AZERA_6TH_GEN" = [1.8, 1.8, 0.1] "HYUNDAI_AZERA_HEV_6TH_GEN" = [1.8, 1.8, 0.1] "KIA_K8_HEV_1ST_GEN" = [2.5, 2.5, 0.1] diff --git a/selfdrive/car/torque_data/params.toml b/selfdrive/car/torque_data/params.toml index f91bc3abab..34cfd0e066 100644 --- a/selfdrive/car/torque_data/params.toml +++ b/selfdrive/car/torque_data/params.toml @@ -40,7 +40,7 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] "HYUNDAI_TUCSON_4TH_GEN" = [2.960174, 2.860284, 0.108745] "JEEP_GRAND_CHEROKEE_2019" = [2.30972, 1.289689569171081, 0.117048] "JEEP_GRAND_CHEROKEE" = [2.27116, 1.4057367824262523, 0.11725947414922003] -"KIA_EV6" = [3.2, 2.093457, 0.05] +"KIA_EV6" = [3.2, 2.093457, 0.005] "KIA_K5_2021" = [2.405339728085138, 1.460032270828705, 0.11650989850813716] "KIA_NIRO_EV" = [2.9215954981365337, 2.1500583840260044, 0.09236802474810267] "KIA_SORENTO" = [2.464854685101844, 1.5335274218367956, 0.12056170567599558] diff --git a/selfdrive/car/toyota/fingerprints.py b/selfdrive/car/toyota/fingerprints.py index 6319535714..0866a4d43c 100644 --- a/selfdrive/car/toyota/fingerprints.py +++ b/selfdrive/car/toyota/fingerprints.py @@ -214,6 +214,7 @@ FW_VERSIONS = { b'8646F0601400 ', b'8646F0603400 ', b'8646F0603500 ', + b'8646F0604000 ', b'8646F0604100 ', b'8646F0605000 ', b'8646F0606000 ', diff --git a/selfdrive/car/toyota/tests/test_toyota.py b/selfdrive/car/toyota/tests/test_toyota.py old mode 100755 new mode 100644 index ef49e00551..0217a0fbc1 --- a/selfdrive/car/toyota/tests/test_toyota.py +++ b/selfdrive/car/toyota/tests/test_toyota.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 from hypothesis import given, settings, strategies as st from cereal import car diff --git a/selfdrive/car/volkswagen/tests/test_volkswagen.py b/selfdrive/car/volkswagen/tests/test_volkswagen.py old mode 100755 new mode 100644 index 561d28b9fb..0002578105 --- a/selfdrive/car/volkswagen/tests/test_volkswagen.py +++ b/selfdrive/car/volkswagen/tests/test_volkswagen.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import random import re diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index eb537575fa..4d317176be 100644 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -214,10 +214,11 @@ class CAR(Platforms): VWCarDocs("Volkswagen Arteon 2018-23", video_link="https://youtu.be/FAomFKPFlDA"), VWCarDocs("Volkswagen Arteon R 2020-23", video_link="https://youtu.be/FAomFKPFlDA"), VWCarDocs("Volkswagen Arteon eHybrid 2020-23", video_link="https://youtu.be/FAomFKPFlDA"), + VWCarDocs("Volkswagen Arteon Shooting Brake 2020-23", video_link="https://youtu.be/FAomFKPFlDA"), VWCarDocs("Volkswagen CC 2018-22", video_link="https://youtu.be/FAomFKPFlDA"), ], VolkswagenCarSpecs(mass=1733, wheelbase=2.84), - chassis_codes={"AN"}, + chassis_codes={"AN", "3H"}, wmis={WMI.VOLKSWAGEN_EUROPE_CAR}, ) VOLKSWAGEN_ATLAS_MK1 = VolkswagenMQBPlatformConfig( diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 1fb7f59496..c8cc76cfc9 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -279,7 +279,7 @@ class Controls: else: safety_mismatch = pandaState.safetyModel not in IGNORED_SAFETY_MODES - # safety mismatch allows some time for boardd to set the safety mode and publish it back from panda + # safety mismatch allows some time for pandad to set the safety mode and publish it back from panda if (safety_mismatch and self.sm.frame*DT_CTRL > 10.) or pandaState.safetyRxChecksInvalid or self.mismatch_counter >= 200: self.events.add(EventName.controlsMismatch) diff --git a/selfdrive/controls/lib/events.py b/selfdrive/controls/lib/events.py index e697eb010c..b01818d704 100755 --- a/selfdrive/controls/lib/events.py +++ b/selfdrive/controls/lib/events.py @@ -51,7 +51,7 @@ class Events: def __init__(self): self.events: list[int] = [] self.static_events: list[int] = [] - self.events_prev = dict.fromkeys(EVENTS.keys(), 0) + self.event_counters = dict.fromkeys(EVENTS.keys(), 0) @property def names(self) -> list[int]: @@ -66,7 +66,7 @@ class Events: bisect.insort(self.events, event_name) def clear(self) -> None: - self.events_prev = {k: (v + 1 if k in self.events else 0) for k, v in self.events_prev.items()} + self.event_counters = {k: (v + 1 if k in self.events else 0) for k, v in self.event_counters.items()} self.events = self.static_events.copy() def contains(self, event_type: str) -> bool: @@ -85,7 +85,7 @@ class Events: if not isinstance(alert, Alert): alert = alert(*callback_args) - if DT_CTRL * (self.events_prev[e] + 1) >= alert.creation_delay: + if DT_CTRL * (self.event_counters[e] + 1) >= alert.creation_delay: alert.alert_type = f"{EVENT_NAME[e]}/{et}" alert.event_type = et ret.append(alert) diff --git a/selfdrive/controls/lib/longcontrol.py b/selfdrive/controls/lib/longcontrol.py index 2dd3390bb0..d08ee05035 100644 --- a/selfdrive/controls/lib/longcontrol.py +++ b/selfdrive/controls/lib/longcontrol.py @@ -5,6 +5,8 @@ from openpilot.selfdrive.controls.lib.drive_helpers import CONTROL_N, apply_dead from openpilot.selfdrive.controls.lib.pid import PIDController from openpilot.selfdrive.modeld.constants import ModelConstants +CONTROL_N_T_IDX = ModelConstants.T_IDXS[:CONTROL_N] + LongCtrlState = car.CarControl.Actuators.LongControlState @@ -68,19 +70,19 @@ class LongControl: # Interp control trajectory speeds = long_plan.speeds if len(speeds) == CONTROL_N: - v_target_now = interp(t_since_plan, ModelConstants.T_IDXS[:CONTROL_N], speeds) - a_target_now = interp(t_since_plan, ModelConstants.T_IDXS[:CONTROL_N], long_plan.accels) + v_target_now = interp(t_since_plan, CONTROL_N_T_IDX, speeds) + a_target_now = interp(t_since_plan, CONTROL_N_T_IDX, long_plan.accels) - v_target_lower = interp(self.CP.longitudinalActuatorDelayLowerBound + t_since_plan, ModelConstants.T_IDXS[:CONTROL_N], speeds) + v_target_lower = interp(self.CP.longitudinalActuatorDelayLowerBound + t_since_plan, CONTROL_N_T_IDX, speeds) a_target_lower = 2 * (v_target_lower - v_target_now) / self.CP.longitudinalActuatorDelayLowerBound - a_target_now - v_target_upper = interp(self.CP.longitudinalActuatorDelayUpperBound + t_since_plan, ModelConstants.T_IDXS[:CONTROL_N], speeds) + v_target_upper = interp(self.CP.longitudinalActuatorDelayUpperBound + t_since_plan, CONTROL_N_T_IDX, speeds) a_target_upper = 2 * (v_target_upper - v_target_now) / self.CP.longitudinalActuatorDelayUpperBound - a_target_now v_target = min(v_target_lower, v_target_upper) a_target = min(a_target_lower, a_target_upper) - v_target_1sec = interp(self.CP.longitudinalActuatorDelayUpperBound + t_since_plan + 1.0, ModelConstants.T_IDXS[:CONTROL_N], speeds) + v_target_1sec = interp(self.CP.longitudinalActuatorDelayUpperBound + t_since_plan + 1.0, CONTROL_N_T_IDX, speeds) else: v_target = 0.0 v_target_now = 0.0 diff --git a/selfdrive/controls/lib/longitudinal_planner.py b/selfdrive/controls/lib/longitudinal_planner.py index 9113bb5a96..ff5f901b52 100755 --- a/selfdrive/controls/lib/longitudinal_planner.py +++ b/selfdrive/controls/lib/longitudinal_planner.py @@ -62,9 +62,9 @@ class LongitudinalPlanner: @staticmethod def parse_model(model_msg, model_error): - if (len(model_msg.position.x) == 33 and - len(model_msg.velocity.x) == 33 and - len(model_msg.acceleration.x) == 33): + if (len(model_msg.position.x) == ModelConstants.IDX_N and + len(model_msg.velocity.x) == ModelConstants.IDX_N and + len(model_msg.acceleration.x) == ModelConstants.IDX_N): x = np.interp(T_IDXS_MPC, ModelConstants.T_IDXS, model_msg.position.x) - model_error * T_IDXS_MPC v = np.interp(T_IDXS_MPC, ModelConstants.T_IDXS, model_msg.velocity.x) - model_error a = np.interp(T_IDXS_MPC, ModelConstants.T_IDXS, model_msg.acceleration.x) diff --git a/selfdrive/controls/lib/tests/test_alertmanager.py b/selfdrive/controls/lib/tests/test_alertmanager.py old mode 100755 new mode 100644 index c234cc49d6..8b9c18a9d4 --- a/selfdrive/controls/lib/tests/test_alertmanager.py +++ b/selfdrive/controls/lib/tests/test_alertmanager.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import random from openpilot.selfdrive.controls.lib.events import Alert, EVENTS diff --git a/selfdrive/controls/lib/tests/test_latcontrol.py b/selfdrive/controls/lib/tests/test_latcontrol.py old mode 100755 new mode 100644 index b731bbd950..81411edec1 --- a/selfdrive/controls/lib/tests/test_latcontrol.py +++ b/selfdrive/controls/lib/tests/test_latcontrol.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 from parameterized import parameterized from cereal import car, log diff --git a/selfdrive/controls/lib/tests/test_vehicle_model.py b/selfdrive/controls/lib/tests/test_vehicle_model.py old mode 100755 new mode 100644 index 2efcf2fbbd..4d0e41805d --- a/selfdrive/controls/lib/tests/test_vehicle_model.py +++ b/selfdrive/controls/lib/tests/test_vehicle_model.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import pytest import math diff --git a/selfdrive/controls/tests/test_alerts.py b/selfdrive/controls/tests/test_alerts.py old mode 100755 new mode 100644 index e29a6322ab..38dc045949 --- a/selfdrive/controls/tests/test_alerts.py +++ b/selfdrive/controls/tests/test_alerts.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import copy import json import os diff --git a/selfdrive/controls/tests/test_cruise_speed.py b/selfdrive/controls/tests/test_cruise_speed.py old mode 100755 new mode 100644 index 6c46285e81..8f451a49bc --- a/selfdrive/controls/tests/test_cruise_speed.py +++ b/selfdrive/controls/tests/test_cruise_speed.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import pytest import itertools import numpy as np diff --git a/selfdrive/controls/tests/test_following_distance.py b/selfdrive/controls/tests/test_following_distance.py old mode 100755 new mode 100644 index 89a575a9ad..0fd543dd60 --- a/selfdrive/controls/tests/test_following_distance.py +++ b/selfdrive/controls/tests/test_following_distance.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import pytest import itertools from parameterized import parameterized_class diff --git a/selfdrive/controls/tests/test_leads.py b/selfdrive/controls/tests/test_leads.py old mode 100755 new mode 100644 index f4e97725ff..f1f4449afd --- a/selfdrive/controls/tests/test_leads.py +++ b/selfdrive/controls/tests/test_leads.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import cereal.messaging as messaging from openpilot.selfdrive.test.process_replay import replay_process_with_name diff --git a/selfdrive/controls/tests/test_startup.py b/selfdrive/controls/tests/test_startup.py index fc9f8ab125..14b0788a3d 100644 --- a/selfdrive/controls/tests/test_startup.py +++ b/selfdrive/controls/tests/test_startup.py @@ -4,7 +4,7 @@ from parameterized import parameterized from cereal import log, car import cereal.messaging as messaging from openpilot.common.params import Params -from openpilot.selfdrive.boardd.boardd_api_impl import can_list_to_can_capnp +from openpilot.selfdrive.pandad.pandad_api_impl import can_list_to_can_capnp from openpilot.selfdrive.car.fingerprints import _FINGERPRINTS from openpilot.selfdrive.car.toyota.values import CAR as TOYOTA from openpilot.selfdrive.car.mazda.values import CAR as MAZDA @@ -105,7 +105,7 @@ def test_startup_alert(expected_event, car_model, fw_versions, brand): msgs = [[addr, 0, b'\x00'*length, 0] for addr, length in finger.items()] for _ in range(1000): - # card waits for boardd to echo back that it has changed the multiplexing mode + # card waits for pandad to echo back that it has changed the multiplexing mode if not params.get_bool("ObdMultiplexingChanged"): params.put_bool("ObdMultiplexingChanged", True) diff --git a/selfdrive/controls/tests/test_state_machine.py b/selfdrive/controls/tests/test_state_machine.py old mode 100755 new mode 100644 index b92724ce43..b6ec512dc4 --- a/selfdrive/controls/tests/test_state_machine.py +++ b/selfdrive/controls/tests/test_state_machine.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - from cereal import car, log from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.car.car_helpers import interfaces diff --git a/selfdrive/debug/clear_dtc.py b/selfdrive/debug/clear_dtc.py index dea21331b7..a931c423a9 100755 --- a/selfdrive/debug/clear_dtc.py +++ b/selfdrive/debug/clear_dtc.py @@ -12,11 +12,11 @@ parser.add_argument('--debug', action='store_true') args = parser.parse_args() try: - check_output(["pidof", "boardd"]) - print("boardd is running, please kill openpilot before running this script! (aborted)") + check_output(["pidof", "pandad"]) + print("pandad is running, please kill openpilot before running this script! (aborted)") sys.exit(1) except CalledProcessError as e: - if e.returncode != 1: # 1 == no process found (boardd not running) + if e.returncode != 1: # 1 == no process found (pandad not running) raise e panda = Panda() diff --git a/selfdrive/debug/cpu_usage_stat.py b/selfdrive/debug/cpu_usage_stat.py index baf44b9082..234dfea3cc 100755 --- a/selfdrive/debug/cpu_usage_stat.py +++ b/selfdrive/debug/cpu_usage_stat.py @@ -9,10 +9,10 @@ System tools like top/htop can only show current cpu usage values, so I write th Calculate minumium/maximum/accumulated_average cpu usage as long term inspections. Monitor multiple processes simuteneously. Sample usage: - root@localhost:/data/openpilot$ python selfdrive/debug/cpu_usage_stat.py boardd,ubloxd - ('Add monitored proc:', './boardd') + root@localhost:/data/openpilot$ python selfdrive/debug/cpu_usage_stat.py pandad,ubloxd + ('Add monitored proc:', './pandad') ('Add monitored proc:', 'python locationd/ubloxd.py') - boardd: 1.96%, min: 1.96%, max: 1.96%, acc: 1.96% + pandad: 1.96%, min: 1.96%, max: 1.96%, acc: 1.96% ubloxd.py: 0.39%, min: 0.39%, max: 0.39%, acc: 0.39% ''' import psutil diff --git a/selfdrive/debug/debug_fw_fingerprinting_offline.py b/selfdrive/debug/debug_fw_fingerprinting_offline.py index 8ae9d6d347..3df2924738 100755 --- a/selfdrive/debug/debug_fw_fingerprinting_offline.py +++ b/selfdrive/debug/debug_fw_fingerprinting_offline.py @@ -1,11 +1,12 @@ #!/usr/bin/env python3 import argparse +from openpilot.tools.lib.live_logreader import live_logreader from openpilot.tools.lib.logreader import LogReader, ReadMode from panda.python import uds -def main(route: str, addrs: list[int]): +def main(route: str | None, addrs: list[int]): """ TODO: - highlight TX vs RX clearly @@ -13,7 +14,10 @@ def main(route: str, addrs: list[int]): - print as fixed width table, easier to read """ - lr = LogReader(route, default_mode=ReadMode.RLOG, sort_by_time=True) + if route is None: + lr = live_logreader() + else: + lr = LogReader(route, default_mode=ReadMode.RLOG, sort_by_time=True) start_mono_time = None prev_mono_time = 0 @@ -28,7 +32,7 @@ def main(route: str, addrs: list[int]): if msg.which() in ("can", 'sendcan'): for can in getattr(msg, msg.which()): - if can.address in addrs: + if can.address in addrs or not len(addrs): if msg.logMonoTime != prev_mono_time: print() prev_mono_time = msg.logMonoTime @@ -38,8 +42,8 @@ def main(route: str, addrs: list[int]): if __name__ == "__main__": parser = argparse.ArgumentParser(description='View back and forth ISO-TP communication between various ECUs given an address') - parser.add_argument('route', help='Route name') - parser.add_argument('addrs', nargs='*', help='List of tx address to view (0x7e0 for engine)') + parser.add_argument('route', nargs='?', help='Route name, live if not specified') + parser.add_argument('--addrs', nargs='*', default=[], help='List of tx address to view (0x7e0 for engine)') args = parser.parse_args() addrs = [int(addr, base=16) if addr.startswith('0x') else int(addr) for addr in args.addrs] diff --git a/selfdrive/debug/get_fingerprint.py b/selfdrive/debug/get_fingerprint.py index f7f7a1604f..14f6c0e33c 100755 --- a/selfdrive/debug/get_fingerprint.py +++ b/selfdrive/debug/get_fingerprint.py @@ -4,7 +4,7 @@ # Instructions: # - connect to a Panda -# - run selfdrive/boardd/boardd +# - run selfdrive/pandad/pandad # - launching this script # Note: it's very important that the car is in stock mode, in order to collect a complete fingerprint # - since some messages are published at low frequency, keep this script running for at least 30s, diff --git a/selfdrive/debug/hyundai_enable_radar_points.py b/selfdrive/debug/hyundai_enable_radar_points.py index e5cae0d470..5e7080ef64 100755 --- a/selfdrive/debug/hyundai_enable_radar_points.py +++ b/selfdrive/debug/hyundai_enable_radar_points.py @@ -79,11 +79,11 @@ if __name__ == "__main__": args = parser.parse_args() try: - check_output(["pidof", "boardd"]) - print("boardd is running, please kill openpilot before running this script! (aborted)") + check_output(["pidof", "pandad"]) + print("pandad is running, please kill openpilot before running this script! (aborted)") sys.exit(1) except CalledProcessError as e: - if e.returncode != 1: # 1 == no process found (boardd not running) + if e.returncode != 1: # 1 == no process found (pandad not running) raise e confirm = input("power on the vehicle keeping the engine off (press start button twice) then type OK to continue: ").upper().strip() diff --git a/selfdrive/debug/read_dtc_status.py b/selfdrive/debug/read_dtc_status.py index 9ad5563975..2d27dd2bb2 100755 --- a/selfdrive/debug/read_dtc_status.py +++ b/selfdrive/debug/read_dtc_status.py @@ -13,11 +13,11 @@ parser.add_argument('--debug', action='store_true') args = parser.parse_args() try: - check_output(["pidof", "boardd"]) - print("boardd is running, please kill openpilot before running this script! (aborted)") + check_output(["pidof", "pandad"]) + print("pandad is running, please kill openpilot before running this script! (aborted)") sys.exit(1) except CalledProcessError as e: - if e.returncode != 1: # 1 == no process found (boardd not running) + if e.returncode != 1: # 1 == no process found (pandad not running) raise e panda = Panda() diff --git a/selfdrive/locationd/test/test_calibrationd.py b/selfdrive/locationd/test/test_calibrationd.py old mode 100755 new mode 100644 index 598d5d2d5f..df61b6a7c7 --- a/selfdrive/locationd/test/test_calibrationd.py +++ b/selfdrive/locationd/test/test_calibrationd.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import random import numpy as np diff --git a/selfdrive/locationd/test/test_locationd.py b/selfdrive/locationd/test/test_locationd.py old mode 100755 new mode 100644 index f88f423cf1..74ac7d2962 --- a/selfdrive/locationd/test/test_locationd.py +++ b/selfdrive/locationd/test/test_locationd.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import pytest import json import random diff --git a/selfdrive/locationd/test/test_locationd_scenarios.py b/selfdrive/locationd/test/test_locationd_scenarios.py old mode 100755 new mode 100644 index be95c6fffb..ca52bffeea --- a/selfdrive/locationd/test/test_locationd_scenarios.py +++ b/selfdrive/locationd/test/test_locationd_scenarios.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import pytest import numpy as np from collections import defaultdict diff --git a/selfdrive/modeld/models/commonmodel.cc b/selfdrive/modeld/models/commonmodel.cc index 5e28e9b95d..523ce00e43 100644 --- a/selfdrive/modeld/models/commonmodel.cc +++ b/selfdrive/modeld/models/commonmodel.cc @@ -1,13 +1,10 @@ #include "selfdrive/modeld/models/commonmodel.h" -#include #include #include #include #include "common/clutil.h" -#include "common/mat.h" -#include "common/timing.h" ModelFrame::ModelFrame(cl_device_id device_id, cl_context context) { input_frames = std::make_unique(buf_size); @@ -52,21 +49,6 @@ ModelFrame::~ModelFrame() { CL_CHECK(clReleaseCommandQueue(q)); } -void softmax(const float* input, float* output, size_t len) { - const float max_val = *std::max_element(input, input + len); - float denominator = 0; - for (int i = 0; i < len; i++) { - float const v_exp = expf(input[i] - max_val); - denominator += v_exp; - output[i] = v_exp; - } - - const float inv_denominator = 1. / denominator; - for (int i = 0; i < len; i++) { - output[i] *= inv_denominator; - } -} - float sigmoid(float input) { return 1 / (1 + expf(-input)); } diff --git a/selfdrive/modeld/models/commonmodel.h b/selfdrive/modeld/models/commonmodel.h index 1a079da055..2cf79094a6 100644 --- a/selfdrive/modeld/models/commonmodel.h +++ b/selfdrive/modeld/models/commonmodel.h @@ -13,20 +13,11 @@ #endif #include "common/mat.h" -#include "cereal/messaging/messaging.h" #include "selfdrive/modeld/transforms/loadyuv.h" #include "selfdrive/modeld/transforms/transform.h" -const bool send_raw_pred = getenv("SEND_RAW_PRED") != NULL; - -void softmax(const float* input, float* output, size_t len); float sigmoid(float input); -template -constexpr const kj::ArrayPtr to_kj_array_ptr(const std::array &arr) { - return kj::ArrayPtr(arr.data(), arr.size()); -} - class ModelFrame { public: ModelFrame(cl_device_id device_id, cl_context context); diff --git a/selfdrive/modeld/tests/test_modeld.py b/selfdrive/modeld/tests/test_modeld.py old mode 100755 new mode 100644 index 5cbdbc2bb4..4130579313 --- a/selfdrive/modeld/tests/test_modeld.py +++ b/selfdrive/modeld/tests/test_modeld.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import numpy as np import random diff --git a/selfdrive/monitoring/test_monitoring.py b/selfdrive/monitoring/test_monitoring.py old mode 100755 new mode 100644 index a960a379e2..f750437dc3 --- a/selfdrive/monitoring/test_monitoring.py +++ b/selfdrive/monitoring/test_monitoring.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import numpy as np from cereal import car, log diff --git a/selfdrive/navd/tests/test_map_renderer.py b/selfdrive/navd/tests/test_map_renderer.py old mode 100755 new mode 100644 index 52b594a57e..6d66528ae3 --- a/selfdrive/navd/tests/test_map_renderer.py +++ b/selfdrive/navd/tests/test_map_renderer.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import time import numpy as np import os diff --git a/selfdrive/navd/tests/test_navd.py b/selfdrive/navd/tests/test_navd.py old mode 100755 new mode 100644 index 3d899ba282..b6580acff1 --- a/selfdrive/navd/tests/test_navd.py +++ b/selfdrive/navd/tests/test_navd.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import json import random import numpy as np diff --git a/selfdrive/pandad/.gitignore b/selfdrive/pandad/.gitignore new file mode 100644 index 0000000000..f7226cdb87 --- /dev/null +++ b/selfdrive/pandad/.gitignore @@ -0,0 +1,3 @@ +pandad +pandad_api_impl.cpp +tests/test_pandad_usbprotocol diff --git a/selfdrive/boardd/SConscript b/selfdrive/pandad/SConscript similarity index 61% rename from selfdrive/boardd/SConscript rename to selfdrive/pandad/SConscript index 666763d9b0..5e70736515 100644 --- a/selfdrive/boardd/SConscript +++ b/selfdrive/pandad/SConscript @@ -3,9 +3,9 @@ Import('env', 'envCython', 'common', 'cereal', 'messaging') libs = ['usb-1.0', common, cereal, messaging, 'pthread', 'zmq', 'capnp', 'kj'] panda = env.Library('panda', ['panda.cc', 'panda_comms.cc', 'spi.cc']) -env.Program('boardd', ['main.cc', 'boardd.cc'], LIBS=[panda] + libs) +env.Program('pandad', ['main.cc', 'pandad.cc'], LIBS=[panda] + libs) env.Library('libcan_list_to_can_capnp', ['can_list_to_can_capnp.cc']) -envCython.Program('boardd_api_impl.so', 'boardd_api_impl.pyx', LIBS=["can_list_to_can_capnp", 'capnp', 'kj'] + envCython["LIBS"]) +envCython.Program('pandad_api_impl.so', 'pandad_api_impl.pyx', LIBS=["can_list_to_can_capnp", 'capnp', 'kj'] + envCython["LIBS"]) if GetOption('extras'): - env.Program('tests/test_boardd_usbprotocol', ['tests/test_boardd_usbprotocol.cc'], LIBS=[panda] + libs) + env.Program('tests/test_pandad_usbprotocol', ['tests/test_pandad_usbprotocol.cc'], LIBS=[panda] + libs) diff --git a/selfdrive/boardd/boardd.py b/selfdrive/pandad/__init__.py similarity index 81% rename from selfdrive/boardd/boardd.py rename to selfdrive/pandad/__init__.py index 0cdaf5e912..8081a62dd0 100644 --- a/selfdrive/boardd/boardd.py +++ b/selfdrive/pandad/__init__.py @@ -1,5 +1,5 @@ # Cython, now uses scons to build -from openpilot.selfdrive.boardd.boardd_api_impl import can_list_to_can_capnp +from openpilot.selfdrive.pandad.pandad_api_impl import can_list_to_can_capnp assert can_list_to_can_capnp def can_capnp_to_can_list(can, src_filter=None): diff --git a/selfdrive/boardd/can_list_to_can_capnp.cc b/selfdrive/pandad/can_list_to_can_capnp.cc similarity index 95% rename from selfdrive/boardd/can_list_to_can_capnp.cc rename to selfdrive/pandad/can_list_to_can_capnp.cc index 72ca72688a..9fc2648da2 100644 --- a/selfdrive/boardd/can_list_to_can_capnp.cc +++ b/selfdrive/pandad/can_list_to_can_capnp.cc @@ -1,5 +1,5 @@ #include "cereal/messaging/messaging.h" -#include "selfdrive/boardd/panda.h" +#include "selfdrive/pandad/panda.h" void can_list_to_can_capnp_cpp(const std::vector &can_list, std::string &out, bool sendCan, bool valid) { MessageBuilder msg; diff --git a/selfdrive/boardd/main.cc b/selfdrive/pandad/main.cc similarity index 71% rename from selfdrive/boardd/main.cc rename to selfdrive/pandad/main.cc index cb17a584bd..b63d884a45 100644 --- a/selfdrive/boardd/main.cc +++ b/selfdrive/pandad/main.cc @@ -1,22 +1,22 @@ #include -#include "selfdrive/boardd/boardd.h" +#include "selfdrive/pandad/pandad.h" #include "common/swaglog.h" #include "common/util.h" #include "system/hardware/hw.h" int main(int argc, char *argv[]) { - LOGW("starting boardd"); + LOGW("starting pandad"); if (!Hardware::PC()) { int err; err = util::set_realtime_priority(54); assert(err == 0); - err = util::set_core_affinity({4}); + err = util::set_core_affinity({3}); assert(err == 0); } std::vector serials(argv + 1, argv + argc); - boardd_main_thread(serials); + pandad_main_thread(serials); return 0; } diff --git a/selfdrive/boardd/panda.cc b/selfdrive/pandad/panda.cc similarity index 99% rename from selfdrive/boardd/panda.cc rename to selfdrive/pandad/panda.cc index a2e5574090..f0645584a9 100644 --- a/selfdrive/boardd/panda.cc +++ b/selfdrive/pandad/panda.cc @@ -1,4 +1,4 @@ -#include "selfdrive/boardd/panda.h" +#include "selfdrive/pandad/panda.h" #include @@ -246,9 +246,9 @@ bool Panda::unpack_can_buffer(uint8_t *data, uint32_t &size, std::vector #include diff --git a/selfdrive/boardd/panda_comms.h b/selfdrive/pandad/panda_comms.h similarity index 94% rename from selfdrive/boardd/panda_comms.h rename to selfdrive/pandad/panda_comms.h index 6b64768c17..9c452faf6d 100644 --- a/selfdrive/boardd/panda_comms.h +++ b/selfdrive/pandad/panda_comms.h @@ -56,6 +56,13 @@ private: }; #ifndef __APPLE__ +struct __attribute__((packed)) spi_header { + uint8_t sync; + uint8_t endpoint; + uint16_t tx_len; + uint16_t max_rx_len; +}; + class PandaSpiHandle : public PandaCommsHandle { public: PandaSpiHandle(std::string serial); @@ -79,5 +86,8 @@ private: int spi_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t tx_len, uint8_t *rx_data, uint16_t max_rx_len, unsigned int timeout); int spi_transfer_retry(uint8_t endpoint, uint8_t *tx_data, uint16_t tx_len, uint8_t *rx_data, uint16_t max_rx_len, unsigned int timeout); int lltransfer(spi_ioc_transfer &t); + + spi_header header; + uint32_t xfer_count = 0; }; #endif diff --git a/selfdrive/boardd/boardd.cc b/selfdrive/pandad/pandad.cc similarity index 97% rename from selfdrive/boardd/boardd.cc rename to selfdrive/pandad/pandad.cc index 34737efadc..373080edb3 100644 --- a/selfdrive/boardd/boardd.cc +++ b/selfdrive/pandad/pandad.cc @@ -1,4 +1,4 @@ -#include "selfdrive/boardd/boardd.h" +#include "selfdrive/pandad/pandad.h" #include #include @@ -25,7 +25,7 @@ // - The internal panda will always be the first panda // - Consecutive pandas will be sorted based on panda type, and then serial number // Connecting: -// - If a panda connection is dropped, boardd will reconnect to all pandas +// - If a panda connection is dropped, pandad will reconnect to all pandas // - If a panda is added, we will only reconnect when we are offroad // CAN buses: // - Each panda will have it's block of 4 buses. E.g.: the second panda will use @@ -163,7 +163,7 @@ Panda *connect(std::string serial="", uint32_t index=0) { } void can_send_thread(std::vector pandas, bool fake_send) { - util::set_thread_name("boardd_can_send"); + util::set_thread_name("pandad_can_send"); AlignedBuffer aligned_buf; std::unique_ptr context(Context::create()); @@ -198,12 +198,12 @@ void can_send_thread(std::vector pandas, bool fake_send) { } void can_recv_thread(std::vector pandas) { - util::set_thread_name("boardd_can_recv"); + util::set_thread_name("pandad_can_recv"); PubMaster pm({"can"}); // run at 100Hz - RateKeeper rk("boardd_can_recv", 100); + RateKeeper rk("pandad_can_recv", 100); std::vector raw_can_data; while (!do_exit && check_all_connected(pandas)) { @@ -405,7 +405,7 @@ void send_peripheral_state(PubMaster *pm, Panda *panda) { } void panda_state_thread(std::vector pandas, bool spoofing_started) { - util::set_thread_name("boardd_panda_state"); + util::set_thread_name("pandad_panda_state"); Params params; SubMaster sm({"controlsState"}); @@ -503,7 +503,7 @@ void panda_state_thread(std::vector pandas, bool spoofing_started) { void peripheral_control_thread(Panda *panda, bool no_fan_control) { - util::set_thread_name("boardd_peripheral_control"); + util::set_thread_name("pandad_peripheral_control"); SubMaster sm({"deviceState", "driverCameraState"}); @@ -554,8 +554,8 @@ void peripheral_control_thread(Panda *panda, bool no_fan_control) { } } -void boardd_main_thread(std::vector serials) { - LOGW("launching boardd"); +void pandad_main_thread(std::vector serials) { + LOGW("launching pandad"); if (serials.size() == 0) { serials = Panda::list(); diff --git a/selfdrive/boardd/boardd.h b/selfdrive/pandad/pandad.h similarity index 53% rename from selfdrive/boardd/boardd.h rename to selfdrive/pandad/pandad.h index 0646fc6189..9d35949a8f 100644 --- a/selfdrive/boardd/boardd.h +++ b/selfdrive/pandad/pandad.h @@ -3,7 +3,7 @@ #include #include -#include "selfdrive/boardd/panda.h" +#include "selfdrive/pandad/panda.h" bool safety_setter_thread(std::vector pandas); -void boardd_main_thread(std::vector serials); +void pandad_main_thread(std::vector serials); diff --git a/selfdrive/boardd/pandad.py b/selfdrive/pandad/pandad.py similarity index 95% rename from selfdrive/boardd/pandad.py rename to selfdrive/pandad/pandad.py index b4ac2d9548..12accdbf5e 100755 --- a/selfdrive/boardd/pandad.py +++ b/selfdrive/pandad/pandad.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# simple boardd wrapper that updates the panda first +# simple pandad wrapper that updates the panda first import os import usb1 import time @@ -157,10 +157,10 @@ def main() -> NoReturn: first_run = False - # run boardd with all connected serials as arguments - os.environ['MANAGER_DAEMON'] = 'boardd' - os.chdir(os.path.join(BASEDIR, "selfdrive/boardd")) - subprocess.run(["./boardd", *panda_serials], check=True) + # run pandad with all connected serials as arguments + os.environ['MANAGER_DAEMON'] = 'pandad' + os.chdir(os.path.join(BASEDIR, "selfdrive/pandad")) + subprocess.run(["./pandad", *panda_serials], check=True) if __name__ == "__main__": main() diff --git a/selfdrive/boardd/boardd_api_impl.pyx b/selfdrive/pandad/pandad_api_impl.pyx similarity index 100% rename from selfdrive/boardd/boardd_api_impl.pyx rename to selfdrive/pandad/pandad_api_impl.pyx diff --git a/selfdrive/boardd/spi.cc b/selfdrive/pandad/spi.cc similarity index 91% rename from selfdrive/boardd/spi.cc rename to selfdrive/pandad/spi.cc index 66e6a0f0ab..f4882addf9 100644 --- a/selfdrive/boardd/spi.cc +++ b/selfdrive/pandad/spi.cc @@ -13,7 +13,7 @@ #include "common/timing.h" #include "common/swaglog.h" #include "panda/board/comms_definitions.h" -#include "selfdrive/boardd/panda_comms.h" +#include "selfdrive/pandad/panda_comms.h" #define SPI_SYNC 0x5AU @@ -28,13 +28,6 @@ enum SpiError { ACK_TIMEOUT = -3, }; -struct __attribute__((packed)) spi_header { - uint8_t sync; - uint8_t endpoint; - uint16_t tx_len; - uint16_t max_rx_len; -}; - const unsigned int SPI_ACK_TIMEOUT = 500; // milliseconds const std::string SPI_DEVICE = "/dev/spidev0.0"; @@ -55,6 +48,11 @@ private: std::recursive_mutex &m; }; +#define SPILOG(fn, fmt, ...) do { \ + fn(fmt, ## __VA_ARGS__); \ + fn(" %d / 0x%x / %d / %d", \ + xfer_count, header.endpoint, header.tx_len, header.max_rx_len); \ + } while (0) PandaSpiHandle::PandaSpiHandle(std::string serial) : PandaCommsHandle(serial) { int ret; @@ -178,7 +176,7 @@ int PandaSpiHandle::bulk_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t t } if (d < 0) { - LOGE("SPI: bulk transfer failed with %d", d); + SPILOG(LOGE, "SPI: bulk transfer failed with %d", d); comms_healthy = false; return d; } @@ -247,7 +245,7 @@ int PandaSpiHandle::spi_transfer_retry(uint8_t endpoint, uint8_t *tx_data, uint1 } while (ret < 0 && connected && !timed_out); if (ret < 0) { - LOGE("transfer failed, after %d tries, %.2fms", timeout_count, millis_since_boot() - start_time); + SPILOG(LOGE, "transfer failed, after %d tries, %.2fms", timeout_count, millis_since_boot() - start_time); } return ret; @@ -270,20 +268,20 @@ int PandaSpiHandle::wait_for_ack(uint8_t ack, uint8_t tx, unsigned int timeout, while (true) { int ret = lltransfer(transfer); if (ret < 0) { - LOGE("SPI: failed to send ACK request"); + SPILOG(LOGE, "SPI: failed to send ACK request"); return ret; } if (rx_buf[0] == ack) { break; } else if (rx_buf[0] == SPI_NACK) { - LOGD("SPI: got NACK"); + SPILOG(LOGD, "SPI: got NACK"); return SpiError::NACK; } // handle timeout if (millis_since_boot() - start_millis > timeout) { - LOGD("SPI: timed out waiting for ACK"); + SPILOG(LOGW, "SPI: timed out waiting for ACK"); return SpiError::ACK_TIMEOUT; } } @@ -334,7 +332,8 @@ int PandaSpiHandle::spi_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t tx assert(tx_len < SPI_BUF_SIZE); assert(max_rx_len < SPI_BUF_SIZE); - spi_header header = { + xfer_count++; + header = { .sync = SPI_SYNC, .endpoint = endpoint, .tx_len = tx_len, @@ -352,7 +351,7 @@ int PandaSpiHandle::spi_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t tx transfer.len = sizeof(header) + 1; ret = lltransfer(transfer); if (ret < 0) { - LOGE("SPI: failed to send header"); + SPILOG(LOGE, "SPI: failed to send header"); return ret; } @@ -370,7 +369,7 @@ int PandaSpiHandle::spi_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t tx transfer.len = tx_len + 1; ret = lltransfer(transfer); if (ret < 0) { - LOGE("SPI: failed to send data"); + SPILOG(LOGE, "SPI: failed to send data"); return ret; } @@ -383,7 +382,7 @@ int PandaSpiHandle::spi_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t tx // Read data rx_data_len = *(uint16_t *)(rx_buf+1); if (rx_data_len >= SPI_BUF_SIZE) { - LOGE("SPI: RX data len larger than buf size %d", rx_data_len); + SPILOG(LOGE, "SPI: RX data len larger than buf size %d", rx_data_len); return -1; } @@ -391,11 +390,11 @@ int PandaSpiHandle::spi_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t tx transfer.rx_buf = (uint64_t)(rx_buf + 2 + 1); ret = lltransfer(transfer); if (ret < 0) { - LOGE("SPI: failed to read rx data"); + SPILOG(LOGE, "SPI: failed to read rx data"); return ret; } if (!check_checksum(rx_buf, rx_data_len + 4)) { - LOGE("SPI: bad checksum"); + SPILOG(LOGE, "SPI: bad checksum"); return -1; } diff --git a/selfdrive/boardd/__init__.py b/selfdrive/pandad/tests/__init__.py similarity index 100% rename from selfdrive/boardd/__init__.py rename to selfdrive/pandad/tests/__init__.py diff --git a/selfdrive/boardd/tests/bootstub.panda.bin b/selfdrive/pandad/tests/bootstub.panda.bin similarity index 100% rename from selfdrive/boardd/tests/bootstub.panda.bin rename to selfdrive/pandad/tests/bootstub.panda.bin diff --git a/selfdrive/boardd/tests/bootstub.panda_h7.bin b/selfdrive/pandad/tests/bootstub.panda_h7.bin similarity index 100% rename from selfdrive/boardd/tests/bootstub.panda_h7.bin rename to selfdrive/pandad/tests/bootstub.panda_h7.bin diff --git a/selfdrive/boardd/tests/bootstub.panda_h7_spiv0.bin b/selfdrive/pandad/tests/bootstub.panda_h7_spiv0.bin similarity index 100% rename from selfdrive/boardd/tests/bootstub.panda_h7_spiv0.bin rename to selfdrive/pandad/tests/bootstub.panda_h7_spiv0.bin diff --git a/selfdrive/boardd/tests/test_pandad.py b/selfdrive/pandad/tests/test_pandad.py old mode 100755 new mode 100644 similarity index 97% rename from selfdrive/boardd/tests/test_pandad.py rename to selfdrive/pandad/tests/test_pandad.py index 581b9813a4..467c7f04c9 --- a/selfdrive/boardd/tests/test_pandad.py +++ b/selfdrive/pandad/tests/test_pandad.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import os import pytest import time @@ -40,7 +39,7 @@ class TestPandad: managed_processes['pandad'].stop() if len(sm['pandaStates']) == 0 or sm['pandaStates'][0].pandaType == log.PandaState.PandaType.unknown: - raise Exception("boardd failed to start") + raise Exception("pandad failed to start") return dt @@ -102,7 +101,7 @@ class TestPandad: ts.append(dt) # 5s for USB (due to enumeration) - # - 0.2s pandad -> boardd + # - 0.2s pandad -> pandad # - plus some buffer assert 0.1 < (sum(ts)/len(ts)) < (0.5 if self.spi else 5.0) print("startup times", ts, sum(ts) / len(ts)) diff --git a/selfdrive/boardd/tests/test_boardd_loopback.py b/selfdrive/pandad/tests/test_pandad_loopback.py old mode 100755 new mode 100644 similarity index 92% rename from selfdrive/boardd/tests/test_boardd_loopback.py rename to selfdrive/pandad/tests/test_pandad_loopback.py index fa9eb957c2..365bb7611b --- a/selfdrive/boardd/tests/test_boardd_loopback.py +++ b/selfdrive/pandad/tests/test_pandad_loopback.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import os import copy import random @@ -9,19 +8,21 @@ from pprint import pprint import cereal.messaging as messaging from cereal import car, log +from openpilot.common.retry import retry from openpilot.common.params import Params from openpilot.common.timeout import Timeout -from openpilot.selfdrive.boardd.boardd import can_list_to_can_capnp +from openpilot.selfdrive.pandad import can_list_to_can_capnp from openpilot.selfdrive.car import make_can_msg from openpilot.system.hardware import TICI from openpilot.selfdrive.test.helpers import phone_only, with_processes -def setup_boardd(num_pandas): +@retry(attempts=3) +def setup_pandad(num_pandas): params = Params() params.put_bool("IsOnroad", False) - with Timeout(90, "boardd didn't start"): + with Timeout(90, "pandad didn't start"): sm = messaging.SubMaster(['pandaStates']) while sm.recv_frame['pandaStates'] < 1 or len(sm['pandaStates']) == 0 or \ any(ps.pandaType == log.PandaState.PandaType.unknown for ps in sm['pandaStates']): @@ -31,7 +32,7 @@ def setup_boardd(num_pandas): assert num_pandas == found_pandas, "connected pandas ({found_pandas}) doesn't match expected panda count ({num_pandas}). \ connect another panda for multipanda tests." - # boardd safety setting relies on these params + # pandad safety setting relies on these params cp = car.CarParams.new_message() safety_config = car.CarParams.SafetyConfig.new_message() @@ -71,7 +72,7 @@ class TestBoarddLoopback: @with_processes(['pandad']) def test_loopback(self): num_pandas = 2 if TICI and "SINGLE_PANDA" not in os.environ else 1 - setup_boardd(num_pandas) + setup_pandad(num_pandas) sendcan = messaging.pub_sock('sendcan') can = messaging.sub_sock('can', conflate=False, timeout=100) sm = messaging.SubMaster(['pandaStates']) @@ -79,7 +80,7 @@ class TestBoarddLoopback: n = 200 for i in range(n): - print(f"boardd loopback {i}/{n}") + print(f"pandad loopback {i}/{n}") sent_msgs = send_random_can_messages(sendcan, random.randrange(20, 100), num_pandas) diff --git a/selfdrive/boardd/tests/test_boardd_spi.py b/selfdrive/pandad/tests/test_pandad_spi.py old mode 100755 new mode 100644 similarity index 54% rename from selfdrive/boardd/tests/test_boardd_spi.py rename to selfdrive/pandad/tests/test_pandad_spi.py index d384caaddd..ed81c1ea26 --- a/selfdrive/boardd/tests/test_boardd_spi.py +++ b/selfdrive/pandad/tests/test_pandad_spi.py @@ -1,15 +1,16 @@ -#!/usr/bin/env python3 import os import time import numpy as np import pytest +import random import cereal.messaging as messaging from cereal.services import SERVICE_LIST from openpilot.system.hardware import HARDWARE from openpilot.selfdrive.test.helpers import phone_only, with_processes -from openpilot.selfdrive.boardd.tests.test_boardd_loopback import setup_boardd +from openpilot.selfdrive.pandad.tests.test_pandad_loopback import setup_pandad, send_random_can_messages +JUNGLE_SPAM = "JUNGLE_SPAM" in os.environ @pytest.mark.tici class TestBoarddSpi: @@ -18,38 +19,67 @@ class TestBoarddSpi: if HARDWARE.get_device_type() == 'tici': pytest.skip("only for spi pandas") os.environ['STARTED'] = '1' - os.environ['BOARDD_LOOPBACK'] = '1' os.environ['SPI_ERR_PROB'] = '0.001' + if not JUNGLE_SPAM: + os.environ['BOARDD_LOOPBACK'] = '1' @phone_only @with_processes(['pandad']) def test_spi_corruption(self, subtests): - setup_boardd(1) + setup_pandad(1) + sendcan = messaging.pub_sock('sendcan') socks = {s: messaging.sub_sock(s, conflate=False, timeout=100) for s in ('can', 'pandaStates', 'peripheralState')} time.sleep(2) for s in socks.values(): messaging.drain_sock_raw(s) + total_recv_count = 0 + total_sent_count = 0 + sent_msgs = {bus: list() for bus in range(3)} + st = time.monotonic() ts = {s: list() for s in socks.keys()} - for _ in range(20): + for _ in range(int(os.getenv("TEST_TIME", "20"))): + # send some CAN messages + if not JUNGLE_SPAM: + sent = send_random_can_messages(sendcan, random.randrange(2, 20)) + for k, v in sent.items(): + sent_msgs[k].extend(list(v)) + total_sent_count += len(v) + for service, sock in socks.items(): for m in messaging.drain_sock(sock): ts[service].append(m.logMonoTime) # sanity check for corruption - assert m.valid + assert m.valid or (service == "can") if service == "can": - assert len(m.can) == 0 + for msg in m.can: + if JUNGLE_SPAM: + # PandaJungle.set_generated_can(True) + i = msg.address - 0x200 + assert msg.address >= 0x200 + assert msg.src == (i%3) + assert msg.dat == b"\xff"*(i%8) + total_recv_count += 1 + continue + + if msg.src > 4: + continue + key = (msg.address, msg.dat) + assert key in sent_msgs[msg.src], f"got unexpected msg: {msg.src=} {msg.address=} {msg.dat=}" + # TODO: enable this + #sent_msgs[msg.src].remove(key) + total_recv_count += 1 elif service == "pandaStates": assert len(m.pandaStates) == 1 ps = m.pandaStates[0] - assert ps.uptime < 100 + assert ps.uptime < 1000 assert ps.pandaType == "tres" assert ps.ignitionLine assert not ps.ignitionCan - assert ps.voltage < 14000 + assert 4000 < ps.voltage < 14000 elif service == "peripheralState": ps = m.peripheralState assert ps.pandaType == "tres" @@ -67,6 +97,10 @@ class TestBoarddSpi: with subtests.test(msg="timing check", service=service): edt = 1e3 / SERVICE_LIST[service].frequency assert edt*0.9 < np.mean(dts) < edt*1.1 - assert np.max(dts) < edt*3 + assert np.max(dts) < edt*20 assert np.min(dts) < edt assert len(dts) >= ((et-0.5)*SERVICE_LIST[service].frequency*0.8) + + with subtests.test(msg="CAN traffic"): + print(f"Sent {total_sent_count} CAN messages, got {total_recv_count} back. {total_recv_count/(total_sent_count+1e-4):.2%} received") + assert total_recv_count > 20 diff --git a/selfdrive/boardd/tests/test_boardd_usbprotocol.cc b/selfdrive/pandad/tests/test_pandad_usbprotocol.cc similarity index 99% rename from selfdrive/boardd/tests/test_boardd_usbprotocol.cc rename to selfdrive/pandad/tests/test_pandad_usbprotocol.cc index aa67e8cf8c..11f7184efd 100644 --- a/selfdrive/boardd/tests/test_boardd_usbprotocol.cc +++ b/selfdrive/pandad/tests/test_pandad_usbprotocol.cc @@ -4,7 +4,7 @@ #include "catch2/catch.hpp" #include "cereal/messaging/messaging.h" #include "common/util.h" -#include "selfdrive/boardd/panda.h" +#include "selfdrive/pandad/panda.h" struct PandaTest : public Panda { PandaTest(uint32_t bus_offset, int can_list_size, cereal::PandaState::PandaType hw_type); diff --git a/selfdrive/test/fuzzy_generation.py b/selfdrive/test/fuzzy_generation.py index 26c35c0c18..0dc2e44eee 100644 --- a/selfdrive/test/fuzzy_generation.py +++ b/selfdrive/test/fuzzy_generation.py @@ -2,6 +2,7 @@ import capnp import hypothesis.strategies as st from typing import Any from collections.abc import Callable +from functools import cache from cereal import log @@ -11,67 +12,62 @@ DrawType = Callable[[st.SearchStrategy], Any] class FuzzyGenerator: def __init__(self, draw: DrawType, real_floats: bool): self.draw = draw - self.real_floats = real_floats + self.native_type_map = FuzzyGenerator._get_native_type_map(real_floats) def generate_native_type(self, field: str) -> st.SearchStrategy[bool | int | float | str | bytes]: - def floats(**kwargs) -> st.SearchStrategy[float]: - allow_nan = not self.real_floats - allow_infinity = not self.real_floats - return st.floats(**kwargs, allow_nan=allow_nan, allow_infinity=allow_infinity) - - if field == 'bool': - return st.booleans() - elif field == 'int8': - return st.integers(min_value=-2**7, max_value=2**7-1) - elif field == 'int16': - return st.integers(min_value=-2**15, max_value=2**15-1) - elif field == 'int32': - return st.integers(min_value=-2**31, max_value=2**31-1) - elif field == 'int64': - return st.integers(min_value=-2**63, max_value=2**63-1) - elif field == 'uint8': - return st.integers(min_value=0, max_value=2**8-1) - elif field == 'uint16': - return st.integers(min_value=0, max_value=2**16-1) - elif field == 'uint32': - return st.integers(min_value=0, max_value=2**32-1) - elif field == 'uint64': - return st.integers(min_value=0, max_value=2**64-1) - elif field == 'float32': - return floats(width=32) - elif field == 'float64': - return floats(width=64) - elif field == 'text': - return st.text(max_size=1000) - elif field == 'data': - return st.binary(max_size=1000) - elif field == 'anyPointer': - return st.text() + value_func = self.native_type_map.get(field) + if value_func: + return value_func else: - raise NotImplementedError(f'Invalid type : {field}') + raise NotImplementedError(f'Invalid type: {field}') def generate_field(self, field: capnp.lib.capnp._StructSchemaField) -> st.SearchStrategy: def rec(field_type: capnp.lib.capnp._DynamicStructReader) -> st.SearchStrategy: - if field_type.which() == 'struct': + type_which = field_type.which() + if type_which == 'struct': return self.generate_struct(field.schema.elementType if base_type == 'list' else field.schema) - elif field_type.which() == 'list': + elif type_which == 'list': return st.lists(rec(field_type.list.elementType)) - elif field_type.which() == 'enum': + elif type_which == 'enum': schema = field.schema.elementType if base_type == 'list' else field.schema return st.sampled_from(list(schema.enumerants.keys())) else: - return self.generate_native_type(field_type.which()) + return self.generate_native_type(type_which) - if 'slot' in field.proto.to_dict(): - base_type = field.proto.slot.type.which() - return rec(field.proto.slot.type) - else: + try: + if hasattr(field.proto, 'slot'): + slot_type = field.proto.slot.type + base_type = slot_type.which() + return rec(slot_type) + else: + return self.generate_struct(field.schema) + except capnp.lib.capnp.KjException: return self.generate_struct(field.schema) def generate_struct(self, schema: capnp.lib.capnp._StructSchema, event: str = None) -> st.SearchStrategy[dict[str, Any]]: - full_fill: list[str] = list(schema.non_union_fields) - single_fill: list[str] = [event] if event else [self.draw(st.sampled_from(schema.union_fields))] if schema.union_fields else [] - return st.fixed_dictionaries({field: self.generate_field(schema.fields[field]) for field in full_fill + single_fill}) + single_fill: tuple[str, ...] = (event,) if event else (self.draw(st.sampled_from(schema.union_fields)),) if schema.union_fields else () + fields_to_generate = schema.non_union_fields + single_fill + return st.fixed_dictionaries({field: self.generate_field(schema.fields[field]) for field in fields_to_generate if not field.endswith('DEPRECATED')}) + + @staticmethod + @cache + def _get_native_type_map(real_floats: bool) -> dict[str, st.SearchStrategy]: + return { + 'bool': st.booleans(), + 'int8': st.integers(min_value=-2**7, max_value=2**7-1), + 'int16': st.integers(min_value=-2**15, max_value=2**15-1), + 'int32': st.integers(min_value=-2**31, max_value=2**31-1), + 'int64': st.integers(min_value=-2**63, max_value=2**63-1), + 'uint8': st.integers(min_value=0, max_value=2**8-1), + 'uint16': st.integers(min_value=0, max_value=2**16-1), + 'uint32': st.integers(min_value=0, max_value=2**32-1), + 'uint64': st.integers(min_value=0, max_value=2**64-1), + 'float32': st.floats(width=32, allow_nan=not real_floats, allow_infinity=not real_floats), + 'float64': st.floats(width=64, allow_nan=not real_floats, allow_infinity=not real_floats), + 'text': st.text(max_size=1000), + 'data': st.binary(max_size=1000), + 'anyPointer': st.text(), # Note: No need to define a separate function for anyPointer + } @classmethod def get_random_msg(cls, draw: DrawType, struct: capnp.lib.capnp._StructModule, real_floats: bool = False) -> dict[str, Any]: diff --git a/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py b/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py old mode 100755 new mode 100644 index 0ad6d6d4fd..62a95babeb --- a/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py +++ b/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import itertools from parameterized import parameterized_class diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 0a9a54325a..70178b8ea3 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -87aa5052e36d5cf83698b1eb6e50aef5c86df8ca \ No newline at end of file +e536df5586a71b22baa789dc584d7eab67f1fbbb diff --git a/selfdrive/test/process_replay/test_fuzzy.py b/selfdrive/test/process_replay/test_fuzzy.py old mode 100755 new mode 100644 index 6bcc94911f..c802d9c573 --- a/selfdrive/test/process_replay/test_fuzzy.py +++ b/selfdrive/test/process_replay/test_fuzzy.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import copy from hypothesis import given, HealthCheck, Phase, settings import hypothesis.strategies as st diff --git a/selfdrive/test/process_replay/test_imgproc.py b/selfdrive/test/process_replay/test_imgproc.py old mode 100755 new mode 100644 index 036f21b9e5..27d0541a50 --- a/selfdrive/test/process_replay/test_imgproc.py +++ b/selfdrive/test/process_replay/test_imgproc.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import os import numpy as np import hashlib diff --git a/selfdrive/test/process_replay/test_regen.py b/selfdrive/test/process_replay/test_regen.py old mode 100755 new mode 100644 index c27d9e8f7b..17fefcb497 --- a/selfdrive/test/process_replay/test_regen.py +++ b/selfdrive/test/process_replay/test_regen.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - from parameterized import parameterized from openpilot.selfdrive.test.process_replay.regen import regen_segment, DummyFrameReader diff --git a/selfdrive/test/setup_device_ci.sh b/selfdrive/test/setup_device_ci.sh index 5c85312f1a..84dae25821 100755 --- a/selfdrive/test/setup_device_ci.sh +++ b/selfdrive/test/setup_device_ci.sh @@ -70,6 +70,7 @@ safe_checkout() { git checkout $GIT_COMMIT git clean -xdff git submodule sync + git submodule foreach --recursive "git reset --hard && git clean -xdff" git submodule update --init --recursive git submodule foreach --recursive "git reset --hard && git clean -xdff" @@ -95,6 +96,7 @@ unsafe_checkout() { git reset --hard $GIT_COMMIT git clean -df git submodule sync + git submodule foreach --recursive "git reset --hard && git clean -df" git submodule update --init --recursive git submodule foreach --recursive "git reset --hard && git clean -df" diff --git a/selfdrive/test/test_onroad.py b/selfdrive/test/test_onroad.py old mode 100755 new mode 100644 index 8b60b9650b..75585e2f14 --- a/selfdrive/test/test_onroad.py +++ b/selfdrive/test/test_onroad.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import bz2 import math import json @@ -48,7 +47,7 @@ PROCS = { "selfdrive.controls.radard": 7.0, "selfdrive.modeld.modeld": 13.0, "selfdrive.modeld.dmonitoringmodeld": 8.0, - "system.thermald.thermald": 3.87, + "system.hardware.hardwared": 3.87, "selfdrive.locationd.calibrationd": 2.0, "selfdrive.locationd.torqued": 5.0, "selfdrive.ui.soundd": 3.5, @@ -59,7 +58,7 @@ PROCS = { "./logcatd": 0, "system.micd": 6.0, "system.timed": 0, - "selfdrive.boardd.pandad": 0, + "selfdrive.pandad.pandad": 0, "system.statsd": 0.4, "selfdrive.navd.navd": 0.4, "system.loggerd.uploader": (0.5, 15.0), @@ -68,12 +67,12 @@ PROCS = { PROCS.update({ "tici": { - "./boardd": 4.0, + "./pandad": 4.0, "./ubloxd": 0.02, "system.ubloxd.pigeond": 6.0, }, "tizi": { - "./boardd": 19.0, + "./pandad": 19.0, "system.qcomgpsd.qcomgpsd": 1.0, } }.get(HARDWARE.get_device_type(), {})) diff --git a/selfdrive/test/test_time_to_onroad.py b/selfdrive/test/test_time_to_onroad.py old mode 100755 new mode 100644 index 11de5283b5..e08d0e676c --- a/selfdrive/test/test_time_to_onroad.py +++ b/selfdrive/test/test_time_to_onroad.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import os import pytest import time diff --git a/selfdrive/test/test_updated.py b/selfdrive/test/test_updated.py old mode 100755 new mode 100644 index 12619d4246..f8eae94823 --- a/selfdrive/test/test_updated.py +++ b/selfdrive/test/test_updated.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import datetime import os import pytest diff --git a/selfdrive/ui/qt/api.cc b/selfdrive/ui/qt/api.cc index 0e321d4e10..6889b40e51 100644 --- a/selfdrive/ui/qt/api.cc +++ b/selfdrive/ui/qt/api.cc @@ -1,6 +1,5 @@ #include "selfdrive/ui/qt/api.h" -#include #include #include @@ -8,38 +7,41 @@ #include #include #include -#include #include #include +#include #include -#include "common/params.h" #include "common/util.h" #include "system/hardware/hw.h" #include "selfdrive/ui/qt/util.h" namespace CommaApi { -QByteArray rsa_sign(const QByteArray &data) { - static std::string key = util::read_file(Path::rsa_file()); - if (key.empty()) { - qDebug() << "No RSA private key found, please run manager.py or registration.py"; - return {}; +RSA *get_rsa_private_key() { + static std::unique_ptr rsa_private(nullptr, RSA_free); + if (!rsa_private) { + FILE *fp = fopen(Path::rsa_file().c_str(), "rb"); + if (!fp) { + qDebug() << "No RSA private key found, please run manager.py or registration.py"; + return nullptr; + } + rsa_private.reset(PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL)); + fclose(fp); } + return rsa_private.get(); +} + +QByteArray rsa_sign(const QByteArray &data) { + RSA *rsa_private = get_rsa_private_key(); + if (!rsa_private) return {}; - BIO* mem = BIO_new_mem_buf(key.data(), key.size()); - assert(mem); - RSA* rsa_private = PEM_read_bio_RSAPrivateKey(mem, NULL, NULL, NULL); - assert(rsa_private); - auto sig = QByteArray(); - sig.resize(RSA_size(rsa_private)); + QByteArray sig(RSA_size(rsa_private), Qt::Uninitialized); unsigned int sig_len; int ret = RSA_sign(NID_sha256, (unsigned char*)data.data(), data.size(), (unsigned char*)sig.data(), &sig_len, rsa_private); assert(ret == 1); - assert(sig_len == sig.size()); - BIO_free(mem); - RSA_free(rsa_private); + assert(sig.size() == sig_len); return sig; } @@ -57,9 +59,7 @@ QString create_jwt(const QJsonObject &payloads, int expiry) { QJsonDocument(payload).toJson(QJsonDocument::Compact).toBase64(b64_opts); auto hash = QCryptographicHash::hash(jwt.toUtf8(), QCryptographicHash::Sha256); - auto sig = rsa_sign(hash); - jwt += '.' + sig.toBase64(b64_opts); - return jwt; + return jwt + "." + rsa_sign(hash).toBase64(b64_opts); } } // namespace CommaApi diff --git a/selfdrive/ui/qt/widgets/cameraview.cc b/selfdrive/ui/qt/widgets/cameraview.cc index e4f1396268..914b04b654 100644 --- a/selfdrive/ui/qt/widgets/cameraview.cc +++ b/selfdrive/ui/qt/widgets/cameraview.cc @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -104,6 +105,7 @@ CameraWidget::CameraWidget(std::string stream_name, VisionStreamType type, bool QObject::connect(this, &CameraWidget::vipcThreadConnected, this, &CameraWidget::vipcConnected, Qt::BlockingQueuedConnection); QObject::connect(this, &CameraWidget::vipcThreadFrameReceived, this, &CameraWidget::vipcFrameReceived, Qt::QueuedConnection); QObject::connect(this, &CameraWidget::vipcAvailableStreamsUpdated, this, &CameraWidget::availableStreamsUpdated, Qt::QueuedConnection); + QObject::connect(QApplication::instance(), &QCoreApplication::aboutToQuit, this, &CameraWidget::stopVipcThread); } CameraWidget::~CameraWidget() { diff --git a/selfdrive/ui/tests/test_soundd.py b/selfdrive/ui/tests/test_soundd.py old mode 100755 new mode 100644 index d15a6c1831..468bc92cca --- a/selfdrive/ui/tests/test_soundd.py +++ b/selfdrive/ui/tests/test_soundd.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - from cereal import car from cereal import messaging from cereal.messaging import SubMaster, PubMaster diff --git a/selfdrive/ui/tests/test_translations.py b/selfdrive/ui/tests/test_translations.py old mode 100755 new mode 100644 index 57de069d0b..0967152fa4 --- a/selfdrive/ui/tests/test_translations.py +++ b/selfdrive/ui/tests/test_translations.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import pytest import json import os diff --git a/system/athena/tests/test_athenad.py b/system/athena/tests/test_athenad.py old mode 100755 new mode 100644 index 895cd8eb56..48519a0ffd --- a/system/athena/tests/test_athenad.py +++ b/system/athena/tests/test_athenad.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import pytest from functools import wraps import json diff --git a/system/athena/tests/test_athenad_ping.py b/system/athena/tests/test_athenad_ping.py old mode 100755 new mode 100644 index 4fda13dfe8..73fe7783af --- a/system/athena/tests/test_athenad_ping.py +++ b/system/athena/tests/test_athenad_ping.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import pytest import subprocess import threading diff --git a/system/athena/tests/test_registration.py b/system/athena/tests/test_registration.py old mode 100755 new mode 100644 index 85c065c1bf..4f663fbc0a --- a/system/athena/tests/test_registration.py +++ b/system/athena/tests/test_registration.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import json from Crypto.PublicKey import RSA from pathlib import Path diff --git a/system/camerad/snapshot/snapshot.py b/system/camerad/snapshot/snapshot.py index d9377eebe9..381240212b 100755 --- a/system/camerad/snapshot/snapshot.py +++ b/system/camerad/snapshot/snapshot.py @@ -83,7 +83,7 @@ def snapshot(): front_camera_allowed = params.get_bool("RecordFront") params.put_bool("IsTakingSnapshot", True) set_offroad_alert("Offroad_IsTakingSnapshot", True) - time.sleep(2.0) # Give thermald time to read the param, or if just started give camerad time to start + time.sleep(2.0) # Give hardwared time to read the param, or if just started give camerad time to start # Check if camerad is already started try: diff --git a/system/camerad/test/test_camerad.py b/system/camerad/test/test_camerad.py old mode 100755 new mode 100644 index dcc9825632..ada9594895 --- a/system/camerad/test/test_camerad.py +++ b/system/camerad/test/test_camerad.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import pytest import time import numpy as np diff --git a/system/camerad/test/test_exposure.py b/system/camerad/test/test_exposure.py old mode 100755 new mode 100644 index 36e8522b1d..dbe6f3d880 --- a/system/camerad/test/test_exposure.py +++ b/system/camerad/test/test_exposure.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import time import numpy as np diff --git a/system/thermald/fan_controller.py b/system/hardware/fan_controller.py similarity index 94% rename from system/thermald/fan_controller.py rename to system/hardware/fan_controller.py index 19c3292ce2..f32133f6bf 100755 --- a/system/thermald/fan_controller.py +++ b/system/hardware/fan_controller.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from abc import ABC, abstractmethod -from openpilot.common.realtime import DT_TRML +from openpilot.common.realtime import DT_HW from openpilot.common.numpy_fast import interp from openpilot.common.swaglog import cloudlog from openpilot.selfdrive.controls.lib.pid import PIDController @@ -18,7 +18,7 @@ class TiciFanController(BaseFanController): cloudlog.info("Setting up TICI fan handler") self.last_ignition = False - self.controller = PIDController(k_p=0, k_i=4e-3, k_f=1, rate=(1 / DT_TRML)) + self.controller = PIDController(k_p=0, k_i=4e-3, k_f=1, rate=(1 / DT_HW)) def update(self, cur_temp: float, ignition: bool) -> int: self.controller.neg_limit = -(100 if ignition else 30) diff --git a/system/thermald/thermald.py b/system/hardware/hardwared.py similarity index 96% rename from system/thermald/thermald.py rename to system/hardware/hardwared.py index 90f6494a26..e3a4c81711 100755 --- a/system/thermald/thermald.py +++ b/system/hardware/hardwared.py @@ -15,14 +15,14 @@ from cereal.services import SERVICE_LIST from openpilot.common.dict_helpers import strip_deprecated_keys from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.params import Params -from openpilot.common.realtime import DT_TRML +from openpilot.common.realtime import DT_HW from openpilot.selfdrive.controls.lib.alertmanager import set_offroad_alert from openpilot.system.hardware import HARDWARE, TICI, AGNOS from openpilot.system.loggerd.config import get_available_percent from openpilot.system.statsd import statlog from openpilot.common.swaglog import cloudlog -from openpilot.system.thermald.power_monitoring import PowerMonitoring -from openpilot.system.thermald.fan_controller import TiciFanController +from openpilot.system.hardware.power_monitoring import PowerMonitoring +from openpilot.system.hardware.fan_controller import TiciFanController from openpilot.system.version import terms_version, training_version ThermalStatus = log.DeviceState.ThermalStatus @@ -106,7 +106,7 @@ def hw_state_thread(end_event, hw_queue): while not end_event.is_set(): # these are expensive calls. update every 10s - if (count % int(10. / DT_TRML)) == 0: + if (count % int(10. / DT_HW)) == 0: try: network_type = HARDWARE.get_network_type() modem_temps = HARDWARE.get_modem_temperatures() @@ -159,10 +159,10 @@ def hw_state_thread(end_event, hw_queue): cloudlog.exception("Error getting hardware state") count += 1 - time.sleep(DT_TRML) + time.sleep(DT_HW) -def thermald_thread(end_event, hw_queue) -> None: +def hardware_thread(end_event, hw_queue) -> None: pm = messaging.PubMaster(['deviceState']) sm = messaging.SubMaster(["peripheralState", "gpsLocationExternal", "controlsState", "pandaStates"], poll="pandaStates") @@ -190,8 +190,8 @@ def thermald_thread(end_event, hw_queue) -> None: modem_temps=[], ) - all_temp_filter = FirstOrderFilter(0., TEMP_TAU, DT_TRML, initialized=False) - offroad_temp_filter = FirstOrderFilter(0., TEMP_TAU, DT_TRML, initialized=False) + all_temp_filter = FirstOrderFilter(0., TEMP_TAU, DT_HW, initialized=False) + offroad_temp_filter = FirstOrderFilter(0., TEMP_TAU, DT_HW, initialized=False) should_start_prev = False in_car = False engaged_prev = False @@ -232,7 +232,7 @@ def thermald_thread(end_event, hw_queue) -> None: # Run at 2Hz, plus rising edge of ignition ign_edge = started_ts is None and onroad_conditions["ignition"] - if (sm.frame % round(SERVICE_LIST['pandaStates'].frequency * DT_TRML) != 0) and not ign_edge: + if (sm.frame % round(SERVICE_LIST['pandaStates'].frequency * DT_HW) != 0) and not ign_edge: continue msg = read_thermal(thermal_config) @@ -349,7 +349,7 @@ def thermald_thread(end_event, hw_queue) -> None: try: with open('/dev/kmsg', 'w') as kmsg: - kmsg.write(f"<3>[thermald] engaged: {engaged}\n") + kmsg.write(f"<3>[hardware] engaged: {engaged}\n") except Exception: pass @@ -423,7 +423,7 @@ def thermald_thread(end_event, hw_queue) -> None: # report to server once every 10 minutes rising_edge_started = should_start and not should_start_prev - if rising_edge_started or (count % int(600. / DT_TRML)) == 0: + if rising_edge_started or (count % int(600. / DT_HW)) == 0: dat = { 'count': count, 'pandaStates': [strip_deprecated_keys(p.to_dict()) for p in pandaStates], @@ -452,7 +452,7 @@ def main(): threads = [ threading.Thread(target=hw_state_thread, args=(end_event, hw_queue)), - threading.Thread(target=thermald_thread, args=(end_event, hw_queue)), + threading.Thread(target=hardware_thread, args=(end_event, hw_queue)), ] for t in threads: diff --git a/system/thermald/power_monitoring.py b/system/hardware/power_monitoring.py similarity index 100% rename from system/thermald/power_monitoring.py rename to system/hardware/power_monitoring.py diff --git a/selfdrive/boardd/tests/__init__.py b/system/hardware/tests/__init__.py similarity index 100% rename from selfdrive/boardd/tests/__init__.py rename to system/hardware/tests/__init__.py diff --git a/system/thermald/tests/test_fan_controller.py b/system/hardware/tests/test_fan_controller.py old mode 100755 new mode 100644 similarity index 95% rename from system/thermald/tests/test_fan_controller.py rename to system/hardware/tests/test_fan_controller.py index 5c858132a2..002c1edfda --- a/system/thermald/tests/test_fan_controller.py +++ b/system/hardware/tests/test_fan_controller.py @@ -1,7 +1,6 @@ -#!/usr/bin/env python3 import pytest -from openpilot.system.thermald.fan_controller import TiciFanController +from openpilot.system.hardware.fan_controller import TiciFanController ALL_CONTROLLERS = [TiciFanController] diff --git a/system/thermald/tests/test_power_monitoring.py b/system/hardware/tests/test_power_monitoring.py old mode 100755 new mode 100644 similarity index 97% rename from system/thermald/tests/test_power_monitoring.py rename to system/hardware/tests/test_power_monitoring.py index 0795a29c8f..1dff6c6c5f --- a/system/thermald/tests/test_power_monitoring.py +++ b/system/hardware/tests/test_power_monitoring.py @@ -1,8 +1,7 @@ -#!/usr/bin/env python3 import pytest from openpilot.common.params import Params -from openpilot.system.thermald.power_monitoring import PowerMonitoring, CAR_BATTERY_CAPACITY_uWh, \ +from openpilot.system.hardware.power_monitoring import PowerMonitoring, CAR_BATTERY_CAPACITY_uWh, \ CAR_CHARGING_RATE_W, VBATT_PAUSE_CHARGING, DELAY_SHUTDOWN_TIME_S # Create fake time @@ -18,9 +17,9 @@ VOLTAGE_BELOW_PAUSE_CHARGING = (VBATT_PAUSE_CHARGING - 1) * 1e3 def pm_patch(mocker, name, value, constant=False): if constant: - mocker.patch(f"openpilot.system.thermald.power_monitoring.{name}", value) + mocker.patch(f"openpilot.system.hardware.power_monitoring.{name}", value) else: - mocker.patch(f"openpilot.system.thermald.power_monitoring.{name}", return_value=value) + mocker.patch(f"openpilot.system.hardware.power_monitoring.{name}", return_value=value) @pytest.fixture(autouse=True) diff --git a/system/hardware/tici/hardware.py b/system/hardware/tici/hardware.py index 45d20d976b..a5dee88b56 100644 --- a/system/hardware/tici/hardware.py +++ b/system/hardware/tici/hardware.py @@ -379,23 +379,19 @@ class Tici(HardwareBase): # *** CPU config *** - # offline big cluster, leave core 4 online for boardd - for i in range(5, 8): + # offline big cluster, leave core 4 online for pandad + for i in range(4, 8): val = '0' if powersave_enabled else '1' sudo_write(val, f'/sys/devices/system/cpu/cpu{i}/online') for n in ('0', '4'): + if powersave_enabled and n == '4': + continue gov = 'ondemand' if powersave_enabled else 'performance' sudo_write(gov, f'/sys/devices/system/cpu/cpufreq/policy{n}/scaling_governor') # *** IRQ config *** - # boardd core - affine_irq(4, "spi_geni") # SPI - affine_irq(4, "xhci-hcd:usb3") # aux panda USB (or potentially anything else on USB) - if "tici" in self.get_device_type(): - affine_irq(4, "xhci-hcd:usb1") # internal panda USB (also modem) - # GPU affine_irq(5, "kgsl-3d0") @@ -416,7 +412,7 @@ class Tici(HardwareBase): if self.amplifier is not None: self.amplifier.initialize_configuration(self.get_device_type()) - # Allow thermald to write engagement status to kmsg + # Allow hardwared to write engagement status to kmsg os.system("sudo chmod a+w /dev/kmsg") # Ensure fan gpio is enabled so fan runs until shutdown, also turned on at boot by the ABL @@ -453,6 +449,18 @@ class Tici(HardwareBase): sudo_write("N", "/sys/kernel/debug/msm_vidc/clock_scaling") sudo_write("Y", "/sys/kernel/debug/msm_vidc/disable_thermal_mitigation") + # pandad core + affine_irq(3, "spi_geni") # SPI + if "tici" in self.get_device_type(): + affine_irq(3, "xhci-hcd:usb3") # aux panda USB (or potentially anything else on USB) + affine_irq(3, "xhci-hcd:usb1") # internal panda USB (also modem) + try: + pid = subprocess.check_output(["pgrep", "-f", "spi0"], encoding='utf8').strip() + subprocess.call(["sudo", "chrt", "-f", "-p", "1", pid]) + subprocess.call(["sudo", "taskset", "-pc", "3", pid]) + except subprocess.CalledProcessException as e: + print(str(e)) + def configure_modem(self): sim_id = self.get_sim_info().get('sim_id', '') diff --git a/system/hardware/tici/tests/test_agnos_updater.py b/system/hardware/tici/tests/test_agnos_updater.py old mode 100755 new mode 100644 index 462cf6cb5c..a1bbd363fd --- a/system/hardware/tici/tests/test_agnos_updater.py +++ b/system/hardware/tici/tests/test_agnos_updater.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import json import os import requests diff --git a/system/hardware/tici/tests/test_amplifier.py b/system/hardware/tici/tests/test_amplifier.py old mode 100755 new mode 100644 index dfba84b942..3f75436db1 --- a/system/hardware/tici/tests/test_amplifier.py +++ b/system/hardware/tici/tests/test_amplifier.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import pytest import time import random diff --git a/system/hardware/tici/tests/test_hardware.py b/system/hardware/tici/tests/test_hardware.py old mode 100755 new mode 100644 index 49d4ac7699..30eed7e0d7 --- a/system/hardware/tici/tests/test_hardware.py +++ b/system/hardware/tici/tests/test_hardware.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import pytest import time import numpy as np diff --git a/system/hardware/tici/tests/test_power_draw.py b/system/hardware/tici/tests/test_power_draw.py old mode 100755 new mode 100644 index 1fe063c8e8..866f7d1188 --- a/system/hardware/tici/tests/test_power_draw.py +++ b/system/hardware/tici/tests/test_power_draw.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 from collections import defaultdict, deque import pytest import time diff --git a/system/loggerd/tests/test_deleter.py b/system/loggerd/tests/test_deleter.py old mode 100755 new mode 100644 index 3ba6ad4031..6222ea253b --- a/system/loggerd/tests/test_deleter.py +++ b/system/loggerd/tests/test_deleter.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import time import threading from collections import namedtuple diff --git a/system/loggerd/tests/test_encoder.py b/system/loggerd/tests/test_encoder.py old mode 100755 new mode 100644 index ddf074d3b5..7289d9ede3 --- a/system/loggerd/tests/test_encoder.py +++ b/system/loggerd/tests/test_encoder.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import math import os import pytest diff --git a/system/loggerd/tests/test_loggerd.py b/system/loggerd/tests/test_loggerd.py old mode 100755 new mode 100644 index d3789badb7..882ce99ed7 --- a/system/loggerd/tests/test_loggerd.py +++ b/system/loggerd/tests/test_loggerd.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import numpy as np import os import re diff --git a/system/loggerd/tests/test_uploader.py b/system/loggerd/tests/test_uploader.py old mode 100755 new mode 100644 index c0a9770e53..6591198281 --- a/system/loggerd/tests/test_uploader.py +++ b/system/loggerd/tests/test_uploader.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import os import time import threading diff --git a/system/manager/manager.py b/system/manager/manager.py index 93fab3ad17..6d1b8d9c22 100755 --- a/system/manager/manager.py +++ b/system/manager/manager.py @@ -145,7 +145,7 @@ def manager_thread() -> None: elif not started and started_prev: params.clear_all(ParamKeyType.CLEAR_ON_OFFROAD_TRANSITION) - # update onroad params, which drives boardd's safety setter thread + # update onroad params, which drives pandad's safety setter thread if started != started_prev: write_onroad_params(started, params) diff --git a/system/manager/process_config.py b/system/manager/process_config.py index 5e153ffb92..ced31077c9 100644 --- a/system/manager/process_config.py +++ b/system/manager/process_config.py @@ -60,7 +60,7 @@ procs = [ NativeProcess("ui", "selfdrive/ui", ["./ui"], always_run, watchdog_max_dt=(5 if not PC else None)), PythonProcess("soundd", "selfdrive.ui.soundd", only_onroad), NativeProcess("locationd", "selfdrive/locationd", ["./locationd"], only_onroad), - NativeProcess("boardd", "selfdrive/boardd", ["./boardd"], always_run, enabled=False), + NativeProcess("pandad", "selfdrive/pandad", ["./pandad"], always_run, enabled=False), PythonProcess("calibrationd", "selfdrive.locationd.calibrationd", only_onroad), PythonProcess("torqued", "selfdrive.locationd.torqued", only_onroad), PythonProcess("controlsd", "selfdrive.controls.controlsd", only_onroad), @@ -70,13 +70,13 @@ procs = [ PythonProcess("qcomgpsd", "system.qcomgpsd.qcomgpsd", qcomgps, enabled=TICI), #PythonProcess("ugpsd", "system.ugpsd", only_onroad, enabled=TICI), PythonProcess("navd", "selfdrive.navd.navd", only_onroad), - PythonProcess("pandad", "selfdrive.boardd.pandad", always_run), + PythonProcess("pandad", "selfdrive.pandad.pandad", always_run), PythonProcess("paramsd", "selfdrive.locationd.paramsd", only_onroad), NativeProcess("ubloxd", "system/ubloxd", ["./ubloxd"], ublox, enabled=TICI), PythonProcess("pigeond", "system.ubloxd.pigeond", ublox, enabled=TICI), PythonProcess("plannerd", "selfdrive.controls.plannerd", only_onroad), PythonProcess("radard", "selfdrive.controls.radard", only_onroad), - PythonProcess("thermald", "system.thermald.thermald", always_run), + PythonProcess("hardwared", "system.hardware.hardwared", always_run), PythonProcess("tombstoned", "system.tombstoned", always_run, enabled=not PC), PythonProcess("updated", "system.updated.updated", only_offroad, enabled=not PC), PythonProcess("uploader", "system.loggerd.uploader", always_run), diff --git a/system/manager/test/test_manager.py b/system/manager/test/test_manager.py old mode 100755 new mode 100644 index af8397b246..e5960d1113 --- a/system/manager/test/test_manager.py +++ b/system/manager/test/test_manager.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import os import pytest import signal diff --git a/system/qcomgpsd/nmeaport.py b/system/qcomgpsd/nmeaport.py index caff7af646..8b9ab51086 100644 --- a/system/qcomgpsd/nmeaport.py +++ b/system/qcomgpsd/nmeaport.py @@ -127,7 +127,7 @@ def main() -> NoReturn: print("qcomgpsd is running, please kill openpilot before running this script! (aborted)") sys.exit(1) except CalledProcessError as e: - if e.returncode != 1: # 1 == no process found (boardd not running) + if e.returncode != 1: # 1 == no process found (pandad not running) raise e print("power up antenna ...") diff --git a/system/qcomgpsd/tests/test_qcomgpsd.py b/system/qcomgpsd/tests/test_qcomgpsd.py old mode 100755 new mode 100644 index 33d6e5b78f..ef23737dd7 --- a/system/qcomgpsd/tests/test_qcomgpsd.py +++ b/system/qcomgpsd/tests/test_qcomgpsd.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import os import pytest import json diff --git a/system/sensord/tests/test_sensord.py b/system/sensord/tests/test_sensord.py old mode 100755 new mode 100644 index aed3b07b32..1871012dd6 --- a/system/sensord/tests/test_sensord.py +++ b/system/sensord/tests/test_sensord.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import os import pytest import time diff --git a/system/tests/test_logmessaged.py b/system/tests/test_logmessaged.py old mode 100755 new mode 100644 index f8c5be09b0..3baf5300c0 --- a/system/tests/test_logmessaged.py +++ b/system/tests/test_logmessaged.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import glob import os import time diff --git a/system/thermald/__init__.py b/system/thermald/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/system/thermald/tests/__init__.py b/system/thermald/tests/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/system/ubloxd/tests/test_pigeond.py b/system/ubloxd/tests/test_pigeond.py old mode 100755 new mode 100644 index cd3ad9305c..202820e412 --- a/system/ubloxd/tests/test_pigeond.py +++ b/system/ubloxd/tests/test_pigeond.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import pytest import time diff --git a/system/updated/casync/tests/test_casync.py b/system/updated/casync/tests/test_casync.py old mode 100755 new mode 100644 index 29cf78f0f1..bc171e7432 --- a/system/updated/casync/tests/test_casync.py +++ b/system/updated/casync/tests/test_casync.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import pytest import os import pathlib diff --git a/system/webrtc/tests/test_stream_session.py b/system/webrtc/tests/test_stream_session.py old mode 100755 new mode 100644 index d8defab13f..fa22915dbc --- a/system/webrtc/tests/test_stream_session.py +++ b/system/webrtc/tests/test_stream_session.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import asyncio import json # for aiortc and its dependencies diff --git a/system/webrtc/tests/test_webrtcd.py b/system/webrtc/tests/test_webrtcd.py old mode 100755 new mode 100644 index b0bc7b1966..309058fb75 --- a/system/webrtc/tests/test_webrtcd.py +++ b/system/webrtc/tests/test_webrtcd.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python import pytest import asyncio import json diff --git a/third_party/acados/acados_template/gnsf/__init__.py b/third_party/acados/acados_template/gnsf/__init__.py index 8b13789179..e69de29bb2 100644 --- a/third_party/acados/acados_template/gnsf/__init__.py +++ b/third_party/acados/acados_template/gnsf/__init__.py @@ -1 +0,0 @@ - diff --git a/tools/cabana/SConscript b/tools/cabana/SConscript index 2574e3368b..5bcfdb175a 100644 --- a/tools/cabana/SConscript +++ b/tools/cabana/SConscript @@ -39,4 +39,4 @@ output_json_file = 'tools/cabana/dbc/car_fingerprint_to_dbc.json' generate_dbc = cabana_env.Command('#' + output_json_file, ['dbc/generate_dbc_json.py'], "python3 tools/cabana/dbc/generate_dbc_json.py --out " + output_json_file) -cabana_env.Depends(generate_dbc, ["#common", "#selfdrive/boardd", '#opendbc', "#cereal", Glob("#opendbc/*.dbc")]) +cabana_env.Depends(generate_dbc, ["#common", "#selfdrive/pandad", '#opendbc', "#cereal", Glob("#opendbc/*.dbc")]) diff --git a/tools/cabana/cabana.cc b/tools/cabana/cabana.cc index bb29a7e3a4..4a3b4126dd 100644 --- a/tools/cabana/cabana.cc +++ b/tools/cabana/cabana.cc @@ -91,7 +91,6 @@ int main(int argc, char *argv[]) { w.openStream(); } w.show(); - int ret = app.exec(); - delete can; - return ret; + + return app.exec(); } diff --git a/tools/cabana/streams/abstractstream.cc b/tools/cabana/streams/abstractstream.cc index 540634b9b7..2e6ca9662e 100644 --- a/tools/cabana/streams/abstractstream.cc +++ b/tools/cabana/streams/abstractstream.cc @@ -3,6 +3,7 @@ #include #include +#include #include "common/timing.h" #include "tools/cabana/settings.h" @@ -19,6 +20,7 @@ AbstractStream::AbstractStream(QObject *parent) : QObject(parent) { assert(parent != nullptr); event_buffer_ = std::make_unique(EVENT_NEXT_BUFFER_SIZE); + QObject::connect(QApplication::instance(), &QCoreApplication::aboutToQuit, this, &AbstractStream::stop); QObject::connect(this, &AbstractStream::privateUpdateLastMsgsSignal, this, &AbstractStream::updateLastMessages, Qt::QueuedConnection); QObject::connect(this, &AbstractStream::seekedTo, this, &AbstractStream::updateLastMsgsTo); QObject::connect(dbc(), &DBCManager::DBCFileChanged, this, &AbstractStream::updateMasks); diff --git a/tools/cabana/streams/pandastream.h b/tools/cabana/streams/pandastream.h index c50407be1a..3e76247680 100644 --- a/tools/cabana/streams/pandastream.h +++ b/tools/cabana/streams/pandastream.h @@ -7,7 +7,7 @@ #include #include "tools/cabana/streams/livestream.h" -#include "selfdrive/boardd/panda.h" +#include "selfdrive/pandad/panda.h" const uint32_t speeds[] = {10U, 20U, 50U, 100U, 125U, 250U, 500U, 1000U}; const uint32_t data_speeds[] = {10U, 20U, 50U, 100U, 125U, 250U, 500U, 1000U, 2000U, 5000U}; diff --git a/tools/cabana/streams/replaystream.cc b/tools/cabana/streams/replaystream.cc index 3c3e431ce7..b1768fcdce 100644 --- a/tools/cabana/streams/replaystream.cc +++ b/tools/cabana/streams/replaystream.cc @@ -64,6 +64,10 @@ void ReplayStream::start() { replay->start(); } +void ReplayStream::stop() { + replay.reset(nullptr); +} + bool ReplayStream::eventFilter(const Event *event) { static double prev_update_ts = 0; if (event->which == cereal::Event::Which::CAN) { diff --git a/tools/cabana/streams/replaystream.h b/tools/cabana/streams/replaystream.h index e3278d9a32..049ccddafb 100644 --- a/tools/cabana/streams/replaystream.h +++ b/tools/cabana/streams/replaystream.h @@ -16,6 +16,7 @@ class ReplayStream : public AbstractStream { public: ReplayStream(QObject *parent); void start() override; + void stop() override; bool loadRoute(const QString &route, const QString &data_dir, uint32_t replay_flags = REPLAY_FLAG_NONE); bool eventFilter(const Event *event); void seekTo(double ts) override; diff --git a/tools/latencylogger/README.md b/tools/latencylogger/README.md index a961f83619..421a6a0b4a 100644 --- a/tools/latencylogger/README.md +++ b/tools/latencylogger/README.md @@ -76,7 +76,7 @@ Frame ID: 1202 Events updated 111.183541 sendcan published 112.981692 controlsState published 113.731994 - boardd + pandad sending sendcan to panda: 250027001751393037323631 81.928119 sendcan sent to panda: 250027001751393037323631 82.164834 sending sendcan to panda: 250027001751393037323631 93.569986 diff --git a/tools/latencylogger/latency_logger.py b/tools/latencylogger/latency_logger.py index 8c6af56b6e..8691149e94 100755 --- a/tools/latencylogger/latency_logger.py +++ b/tools/latencylogger/latency_logger.py @@ -12,7 +12,7 @@ from openpilot.tools.lib.logreader import LogReader DEMO_ROUTE = "9f583b1d93915c31|2022-05-18--10-49-51--0" -SERVICES = ['camerad', 'modeld', 'plannerd', 'controlsd', 'boardd'] +SERVICES = ['camerad', 'modeld', 'plannerd', 'controlsd', 'pandad'] MONOTIME_KEYS = ['modelMonoTime', 'lateralPlanMonoTime'] MSGQ_TO_SERVICE = { 'roadCameraState': 'camerad', @@ -137,7 +137,7 @@ def insert_cloudlogs(lr, timestamps, start_times, end_times): timestamps[int(jmsg['msg']['timestamp']['frame_id'])][service].append((event, time)) continue - if service == "boardd": + if service == "pandad": timestamps[latest_controls_frameid][service].append((event, time)) end_times[latest_controls_frameid][service] = time else: @@ -153,7 +153,7 @@ def insert_cloudlogs(lr, timestamps, start_times, end_times): failed_inserts += 1 if latest_controls_frameid == 0: - print("Warning: failed to bind boardd logs to a frame ID. Add a timestamp cloudlog in controlsd.") + print("Warning: failed to bind pandad logs to a frame ID. Add a timestamp cloudlog in controlsd.") elif failed_inserts > len(timestamps): print(f"Warning: failed to bind {failed_inserts} cloudlog timestamps to a frame ID") diff --git a/tools/lib/tests/test_caching.py b/tools/lib/tests/test_caching.py old mode 100755 new mode 100644 index 32f55df5d1..2bb63b4dce --- a/tools/lib/tests/test_caching.py +++ b/tools/lib/tests/test_caching.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import http.server import os import shutil diff --git a/tools/lib/tests/test_logreader.py b/tools/lib/tests/test_logreader.py old mode 100755 new mode 100644 index 58d22a07ef..6bc7ba8773 --- a/tools/lib/tests/test_logreader.py +++ b/tools/lib/tests/test_logreader.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import capnp import contextlib import io diff --git a/tools/lib/tests/test_readers.py b/tools/lib/tests/test_readers.py old mode 100755 new mode 100644 index f92554872f..624531a1a8 --- a/tools/lib/tests/test_readers.py +++ b/tools/lib/tests/test_readers.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python import pytest import requests import tempfile diff --git a/tools/lib/tests/test_route_library.py b/tools/lib/tests/test_route_library.py old mode 100755 new mode 100644 index 8f75fa19c0..491bb81327 --- a/tools/lib/tests/test_route_library.py +++ b/tools/lib/tests/test_route_library.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python from collections import namedtuple from openpilot.tools.lib.route import SegmentName diff --git a/tools/plotjuggler/test_plotjuggler.py b/tools/plotjuggler/test_plotjuggler.py old mode 100755 new mode 100644 index b9a55297e5..a2c509f943 --- a/tools/plotjuggler/test_plotjuggler.py +++ b/tools/plotjuggler/test_plotjuggler.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import os import glob import signal diff --git a/tools/replay/can_replay.py b/tools/replay/can_replay.py index c7da8caf71..3ab33a1dfd 100755 --- a/tools/replay/can_replay.py +++ b/tools/replay/can_replay.py @@ -8,7 +8,7 @@ import threading os.environ['FILEREADER_CACHE'] = '1' from openpilot.common.realtime import config_realtime_process, Ratekeeper, DT_CTRL -from openpilot.selfdrive.boardd.boardd import can_capnp_to_can_list +from openpilot.selfdrive.pandad import can_capnp_to_can_list from openpilot.tools.lib.logreader import LogReader from panda import PandaJungle diff --git a/tools/replay/replay.cc b/tools/replay/replay.cc index 6a159aa8e2..f477e327ee 100644 --- a/tools/replay/replay.cc +++ b/tools/replay/replay.cc @@ -56,6 +56,7 @@ Replay::~Replay() { stream_thread_->quit(); stream_thread_->wait(); delete stream_thread_; + stream_thread_ = nullptr; } timeline_future.waitForFinished(); rInfo("shutdown: done"); diff --git a/tools/rerun/run.py b/tools/rerun/run.py index 8a002f68ba..1c3c0a59e3 100755 --- a/tools/rerun/run.py +++ b/tools/rerun/run.py @@ -39,6 +39,7 @@ def log_msg(msg, parent_key=''): pass # Not a plottable value def createBlueprint(): + blueprint = None timeSeriesViews = [] for topic in sorted(SERVICE_LIST.keys()): timeSeriesViews.append(rrb.TimeSeriesView(name=topic, origin=f"/{topic}/", visible=False)) @@ -51,9 +52,12 @@ def log_thumbnail(thumbnailMsg): bytesImgData = thumbnailMsg.get('thumbnail') rr.log("/thumbnail", rr.ImageEncoded(contents=bytesImgData)) -def process(blueprint, lr): +@rr.shutdown_at_exit +def process(lr): + rr.init("rerun_test") + rr.connect() + ret = [] - rr.init("rerun_test", spawn=True, default_blueprint=blueprint) for msg in lr: ret.append(msg) rr.set_time_nanos("TIMELINE", msg.logMonoTime) @@ -75,8 +79,11 @@ if __name__ == '__main__': args = parser.parse_args() - route_or_segment_name = DEMO_ROUTE if args.demo else args.route_or_segment_name.strip() blueprint = createBlueprint() + rr.init("rerun_test", default_blueprint=blueprint) + rr.spawn(connect=False) # child processes stream data to Viewer + + route_or_segment_name = DEMO_ROUTE if args.demo else args.route_or_segment_name.strip() print("Getting route log paths") lr = LogReader(route_or_segment_name) - lr.run_across_segments(NUM_CPUS, partial(process, blueprint)) + lr.run_across_segments(NUM_CPUS, partial(process)) diff --git a/tools/sim/bridge/metadrive/metadrive_process.py b/tools/sim/bridge/metadrive/metadrive_process.py index 2b9203c30d..38c13a1434 100644 --- a/tools/sim/bridge/metadrive/metadrive_process.py +++ b/tools/sim/bridge/metadrive/metadrive_process.py @@ -88,7 +88,7 @@ def metadrive_process(dual_camera: bool, config: dict, camera_array, wide_camera cam.get_cam().reparentTo(env.vehicle.origin) cam.get_cam().setPos(C3_POSITION) cam.get_cam().setHpr(C3_HPR) - img = cam.perceive(clip=False) + img = cam.perceive(to_float=False) if type(img) != np.ndarray: img = img.get() # convert cupy array to numpy return img diff --git a/tools/sim/lib/simulated_car.py b/tools/sim/lib/simulated_car.py index 8c15195dcb..6d324e4780 100644 --- a/tools/sim/lib/simulated_car.py +++ b/tools/sim/lib/simulated_car.py @@ -3,7 +3,7 @@ import cereal.messaging as messaging from opendbc.can.packer import CANPacker from opendbc.can.parser import CANParser from openpilot.common.params import Params -from openpilot.selfdrive.boardd.boardd_api_impl import can_list_to_can_capnp +from openpilot.selfdrive.pandad.pandad_api_impl import can_list_to_can_capnp from openpilot.tools.sim.lib.common import SimulatorState from panda.python import Panda diff --git a/tools/sim/tests/test_metadrive_bridge.py b/tools/sim/tests/test_metadrive_bridge.py old mode 100755 new mode 100644 index f06110184b..8849e901cb --- a/tools/sim/tests/test_metadrive_bridge.py +++ b/tools/sim/tests/test_metadrive_bridge.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import pytest import warnings