Merge remote-tracking branch 'upstream/master' into fuzzy-panda-carstate

pull/30443/head
Shane Smiskol 2 years ago
commit aa3cfd5af5
  1. 27
      .github/workflows/selfdrive_tests.yaml
  2. 4
      Jenkinsfile
  3. 2
      RELEASES.md
  4. 3
      codecov.yml
  5. 3
      common/params.cc
  6. 3
      conftest.py
  7. 4
      docs/CARS.md
  8. 2
      opendbc
  9. 2
      panda
  10. 3
      pyproject.toml
  11. 17
      selfdrive/athena/tests/test_athenad.py
  12. 3
      selfdrive/boardd/pandad.py
  13. 2
      selfdrive/car/CARS_template.md
  14. 2
      selfdrive/car/hyundai/carstate.py
  15. 4
      selfdrive/car/hyundai/values.py
  16. 2
      selfdrive/car/subaru/interface.py
  17. 3
      selfdrive/car/subaru/values.py
  18. 2
      selfdrive/car/tests/test_car_interfaces.py
  19. 5
      selfdrive/car/volkswagen/values.py
  20. 5
      selfdrive/controls/controlsd.py
  21. 27
      selfdrive/locationd/helpers.py
  22. 22
      selfdrive/locationd/torqued.py
  23. 8
      selfdrive/manager/build.py
  24. 2
      selfdrive/modeld/fill_model_msg.py
  25. 8
      selfdrive/test/process_replay/process_replay.py
  26. 2
      system/camerad/cameras/camera_common.h
  27. 13
      tools/cabana/chart/chart.cc
  28. 2
      tools/cabana/chart/chart.h
  29. 16
      tools/cabana/chart/chartswidget.cc
  30. 4
      tools/cabana/chart/chartswidget.h
  31. 9
      tools/cabana/videowidget.cc
  32. 2
      tools/cabana/videowidget.h
  33. 2
      tools/replay/replay.h

@ -26,8 +26,8 @@ env:
RUN_CL: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONWARNINGS=error -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v $GITHUB_WORKSPACE/.ci_cache/scons_cache:/tmp/scons_cache -v $GITHUB_WORKSPACE/.ci_cache/comma_download_cache:/tmp/comma_download_cache -v $GITHUB_WORKSPACE/.ci_cache/openpilot_cache:/tmp/openpilot_cache $CL_BASE_IMAGE /bin/sh -c RUN_CL: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONWARNINGS=error -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v $GITHUB_WORKSPACE/.ci_cache/scons_cache:/tmp/scons_cache -v $GITHUB_WORKSPACE/.ci_cache/comma_download_cache:/tmp/comma_download_cache -v $GITHUB_WORKSPACE/.ci_cache/openpilot_cache:/tmp/openpilot_cache $CL_BASE_IMAGE /bin/sh -c
UNIT_TEST: coverage run --append -m unittest discover PYTEST: pytest --continue-on-collection-errors --cov --cov-report=xml --cov-append --durations=0 --durations-min=5 --hypothesis-seed 0
PYTEST: pytest --continue-on-collection-errors --cov --cov-report=xml --cov-append --durations=0 --durations-min=5 XDIST: -n auto --dist=loadscope
jobs: jobs:
build_release: build_release:
@ -54,11 +54,11 @@ jobs:
cd $STRIPPED_DIR cd $STRIPPED_DIR
${{ env.RUN }} "CI=1 python selfdrive/manager/build.py" ${{ env.RUN }} "CI=1 python selfdrive/manager/build.py"
- name: Run tests - name: Run tests
timeout-minutes: 2 timeout-minutes: 3
run: | run: |
cd $STRIPPED_DIR cd $STRIPPED_DIR
${{ env.RUN }} "release/check-dirty.sh && \ ${{ env.RUN }} "release/check-dirty.sh && \
python -m unittest discover selfdrive/car" MAX_EXAMPLES=5 $PYTEST $XDIST selfdrive/car"
- name: pre-commit - name: pre-commit
timeout-minutes: 3 timeout-minutes: 3
run: | run: |
@ -176,7 +176,7 @@ jobs:
- name: Run unit tests - name: Run unit tests
timeout-minutes: 15 timeout-minutes: 15
run: | run: |
${{ env.RUN }} "$PYTEST -n auto --dist=loadscope --timeout 30 -o cpp_files=test_* -m 'not slow' && \ ${{ env.RUN }} "$PYTEST $XDIST --timeout 30 -o cpp_files=test_* -m 'not slow' && \
./selfdrive/ui/tests/create_test_translations.sh && \ ./selfdrive/ui/tests/create_test_translations.sh && \
QT_QPA_PLATFORM=offscreen ./selfdrive/ui/tests/test_translations && \ QT_QPA_PLATFORM=offscreen ./selfdrive/ui/tests/test_translations && \
./selfdrive/ui/tests/test_translations.py && \ ./selfdrive/ui/tests/test_translations.py && \
@ -184,6 +184,8 @@ jobs:
./selfdrive/test/process_replay/test_fuzzy.py" ./selfdrive/test/process_replay/test_fuzzy.py"
- name: "Upload coverage to Codecov" - name: "Upload coverage to Codecov"
uses: codecov/codecov-action@v3 uses: codecov/codecov-action@v3
with:
name: ${{ github.job }}
process_replay: process_replay:
name: process replay name: process replay
@ -211,6 +213,7 @@ jobs:
run: | run: |
${{ env.RUN }} "CI=1 coverage run selfdrive/test/process_replay/test_processes.py -j$(nproc) && \ ${{ env.RUN }} "CI=1 coverage run selfdrive/test/process_replay/test_processes.py -j$(nproc) && \
chmod -R 777 /tmp/comma_download_cache && \ chmod -R 777 /tmp/comma_download_cache && \
coverage combine && \
coverage xml" coverage xml"
- name: Print diff - name: Print diff
id: print-diff id: print-diff
@ -228,6 +231,8 @@ jobs:
${{ env.RUN }} "unset PYTHONWARNINGS && CI=1 AZURE_TOKEN='$AZURE_TOKEN' python selfdrive/test/process_replay/test_processes.py -j$(nproc) --upload-only" ${{ env.RUN }} "unset PYTHONWARNINGS && CI=1 AZURE_TOKEN='$AZURE_TOKEN' python selfdrive/test/process_replay/test_processes.py -j$(nproc) --upload-only"
- name: "Upload coverage to Codecov" - name: "Upload coverage to Codecov"
uses: codecov/codecov-action@v3 uses: codecov/codecov-action@v3
with:
name: ${{ github.job }}
regen: regen:
name: regen name: regen
@ -253,7 +258,7 @@ jobs:
- name: Run regen - name: Run regen
timeout-minutes: 30 timeout-minutes: 30
run: | run: |
${{ env.RUN_CL }} "ONNXCPU=1 $PYTEST -n auto --dist=loadscope selfdrive/test/process_replay/test_regen.py && \ ${{ env.RUN_CL }} "ONNXCPU=1 $PYTEST $XDIST selfdrive/test/process_replay/test_regen.py && \
chmod -R 777 /tmp/comma_download_cache" chmod -R 777 /tmp/comma_download_cache"
test_modeld: test_modeld:
@ -278,15 +283,17 @@ jobs:
run: | run: |
${{ env.RUN_CL }} "unset PYTHONWARNINGS && \ ${{ env.RUN_CL }} "unset PYTHONWARNINGS && \
ONNXCPU=1 CI=1 NO_NAV=1 coverage run selfdrive/test/process_replay/model_replay.py && \ ONNXCPU=1 CI=1 NO_NAV=1 coverage run selfdrive/test/process_replay/model_replay.py && \
coverage combine && \
coverage xml" coverage xml"
- name: Run unit tests - name: Run unit tests
timeout-minutes: 4 timeout-minutes: 4
run: | run: |
${{ env.RUN_CL }} "unset PYTHONWARNINGS && \ ${{ env.RUN_CL }} "unset PYTHONWARNINGS && \
$UNIT_TEST selfdrive/modeld && \ $PYTEST selfdrive/modeld"
coverage xml"
- name: "Upload coverage to Codecov" - name: "Upload coverage to Codecov"
uses: codecov/codecov-action@v3 uses: codecov/codecov-action@v3
with:
name: ${{ github.job }}
test_cars: test_cars:
name: cars name: cars
@ -311,13 +318,15 @@ jobs:
- name: Test car models - name: Test car models
timeout-minutes: 25 timeout-minutes: 25
run: | run: |
${{ env.RUN }} "$PYTEST -n auto --dist=loadscope selfdrive/car/tests/test_models.py && \ ${{ env.RUN }} "$PYTEST $XDIST selfdrive/car/tests/test_models.py && \
chmod -R 777 /tmp/comma_download_cache" chmod -R 777 /tmp/comma_download_cache"
env: env:
NUM_JOBS: 5 NUM_JOBS: 5
JOB_ID: ${{ matrix.job }} JOB_ID: ${{ matrix.job }}
- name: "Upload coverage to Codecov" - name: "Upload coverage to Codecov"
uses: codecov/codecov-action@v3 uses: codecov/codecov-action@v3
with:
name: ${{ github.job }}-${{ matrix.job }}
car_docs_diff: car_docs_diff:
name: PR comments name: PR comments

4
Jenkinsfile vendored

@ -85,7 +85,7 @@ def pcStage(String stageName, Closure body) {
checkout scm checkout scm
def dockerArgs = '--user=batman -v /tmp/comma_download_cache:/tmp/comma_download_cache -v /tmp/scons_cache:/tmp/scons_cache'; def dockerArgs = "--user=batman -v /tmp/comma_download_cache:/tmp/comma_download_cache -v /tmp/scons_cache:/tmp/scons_cache -e PYTHONPATH=${env.WORKSPACE}";
docker.build("openpilot-base:build-${env.GIT_COMMIT}", "-f Dockerfile.openpilot_base .").inside(dockerArgs) { docker.build("openpilot-base:build-${env.GIT_COMMIT}", "-f Dockerfile.openpilot_base .").inside(dockerArgs) {
timeout(time: 20, unit: 'MINUTES') { timeout(time: 20, unit: 'MINUTES') {
try { try {
@ -228,7 +228,7 @@ node {
}, },
'car tests': { 'car tests': {
pcStage("car tests") { pcStage("car tests") {
sh "scons -j30" sh label: "build", script: "selfdrive/manager/build.py"
sh label: "test_models.py", script: "INTERNAL_SEG_CNT=250 INTERNAL_SEG_LIST=selfdrive/car/tests/test_models_segs.txt FILEREADER_CACHE=1 \ sh label: "test_models.py", script: "INTERNAL_SEG_CNT=250 INTERNAL_SEG_LIST=selfdrive/car/tests/test_models_segs.txt FILEREADER_CACHE=1 \
pytest -n42 --dist=loadscope selfdrive/car/tests/test_models.py" pytest -n42 --dist=loadscope selfdrive/car/tests/test_models.py"
sh label: "test_car_interfaces.py", script: "MAX_EXAMPLES=100 pytest -n42 selfdrive/car/tests/test_car_interfaces.py" sh label: "test_car_interfaces.py", script: "MAX_EXAMPLES=100 pytest -n42 selfdrive/car/tests/test_car_interfaces.py"

@ -1,4 +1,4 @@
Version 0.9.5 (2023-XX-XX) Version 0.9.5 (2023-11-16)
======================== ========================
* New driving model * New driving model
* Improved navigate on openpilot performance using navigation instructions as an additional model input * Improved navigate on openpilot performance using navigation instructions as an additional model input

@ -8,4 +8,5 @@ coverage:
ignore: ignore:
- "**/test_*.py" - "**/test_*.py"
- "selfdrive/test/**" - "selfdrive/test/**"
- "system/version.py" # codecov changes depending on if we are in a branch or not

@ -99,6 +99,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"CarParams", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION}, {"CarParams", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
{"CarParamsCache", CLEAR_ON_MANAGER_START}, {"CarParamsCache", CLEAR_ON_MANAGER_START},
{"CarParamsPersistent", PERSISTENT}, {"CarParamsPersistent", PERSISTENT},
{"CarParamsPrevRoute", PERSISTENT},
{"CarVin", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION}, {"CarVin", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
{"CompletedTrainingVersion", PERSISTENT}, {"CompletedTrainingVersion", PERSISTENT},
{"ControlsReady", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION}, {"ControlsReady", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
@ -154,7 +155,6 @@ std::unordered_map<std::string, uint32_t> keys = {
{"LastUpdateException", CLEAR_ON_MANAGER_START}, {"LastUpdateException", CLEAR_ON_MANAGER_START},
{"LastUpdateTime", PERSISTENT}, {"LastUpdateTime", PERSISTENT},
{"LiveParameters", PERSISTENT}, {"LiveParameters", PERSISTENT},
{"LiveTorqueCarParams", PERSISTENT},
{"LiveTorqueParameters", PERSISTENT | DONT_LOG}, {"LiveTorqueParameters", PERSISTENT | DONT_LOG},
{"LongitudinalPersonality", PERSISTENT}, {"LongitudinalPersonality", PERSISTENT},
{"NavDestination", CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION}, {"NavDestination", CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION},
@ -180,6 +180,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"Offroad_UpdateFailed", CLEAR_ON_MANAGER_START}, {"Offroad_UpdateFailed", CLEAR_ON_MANAGER_START},
{"OpenpilotEnabledToggle", PERSISTENT}, {"OpenpilotEnabledToggle", PERSISTENT},
{"PandaHeartbeatLost", CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION}, {"PandaHeartbeatLost", CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION},
{"PandaSomResetTriggered", CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION},
{"PandaSignatures", CLEAR_ON_MANAGER_START}, {"PandaSignatures", CLEAR_ON_MANAGER_START},
{"Passive", PERSISTENT}, {"Passive", PERSISTENT},
{"PrimeType", PERSISTENT}, {"PrimeType", PERSISTENT},

@ -1,5 +1,6 @@
import os import os
import pytest import pytest
import random
from openpilot.common.prefix import OpenpilotPrefix from openpilot.common.prefix import OpenpilotPrefix
from openpilot.system.hardware import TICI from openpilot.system.hardware import TICI
@ -9,6 +10,8 @@ from openpilot.system.hardware import TICI
def openpilot_function_fixture(): def openpilot_function_fixture():
starting_env = dict(os.environ) starting_env = dict(os.environ)
random.seed(0)
# setup a clean environment for each test # setup a clean environment for each test
with OpenpilotPrefix(): with OpenpilotPrefix():
prefix = os.environ["OPENPILOT_PREFIX"] prefix = os.environ["OPENPILOT_PREFIX"]

@ -244,7 +244,7 @@ A supported vehicle is one that just works when you install a comma device. All
|Volkswagen|Arteon eHybrid 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 J533 connector<br>- 1 USB-C coupler<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Volkswagen&model=Arteon eHybrid 2020-23">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>| |Volkswagen|Arteon eHybrid 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 J533 connector<br>- 1 USB-C coupler<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Volkswagen&model=Arteon eHybrid 2020-23">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Volkswagen|Arteon R 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 J533 connector<br>- 1 USB-C coupler<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Volkswagen&model=Arteon R 2020-23">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>| |Volkswagen|Arteon R 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 J533 connector<br>- 1 USB-C coupler<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Volkswagen&model=Arteon R 2020-23">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Volkswagen|Atlas 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 J533 connector<br>- 1 USB-C coupler<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Volkswagen&model=Atlas 2018-23">Buy Here</a></sub></details>|| |Volkswagen|Atlas 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 J533 connector<br>- 1 USB-C coupler<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Volkswagen&model=Atlas 2018-23">Buy Here</a></sub></details>||
|Volkswagen|Atlas Cross Sport 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 J533 connector<br>- 1 USB-C coupler<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Volkswagen&model=Atlas Cross Sport 2021-22">Buy Here</a></sub></details>|| |Volkswagen|Atlas Cross Sport 2020-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 J533 connector<br>- 1 USB-C coupler<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Volkswagen&model=Atlas Cross Sport 2020-22">Buy Here</a></sub></details>||
|Volkswagen|California 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 J533 connector<br>- 1 USB-C coupler<br>- 1 angled mount (8 degrees)<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Volkswagen&model=California 2021-23">Buy Here</a></sub></details>|| |Volkswagen|California 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 J533 connector<br>- 1 USB-C coupler<br>- 1 angled mount (8 degrees)<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Volkswagen&model=California 2021-23">Buy Here</a></sub></details>||
|Volkswagen|Caravelle 2020|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 J533 connector<br>- 1 USB-C coupler<br>- 1 angled mount (8 degrees)<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Volkswagen&model=Caravelle 2020">Buy Here</a></sub></details>|| |Volkswagen|Caravelle 2020|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 J533 connector<br>- 1 USB-C coupler<br>- 1 angled mount (8 degrees)<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Volkswagen&model=Caravelle 2020">Buy Here</a></sub></details>||
|Volkswagen|CC 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 J533 connector<br>- 1 USB-C coupler<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Volkswagen&model=CC 2018-22">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>| |Volkswagen|CC 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 J533 connector<br>- 1 USB-C coupler<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Volkswagen&model=CC 2018-22">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
@ -318,7 +318,7 @@ If your car has the following packages or features, then it's a good candidate f
### FlexRay ### FlexRay
All the cars that openpilot supports use a [CAN bus](https://en.wikipedia.org/wiki/CAN_bus) for communication between all the car's computers, however a CAN bus isn't the only way that the cars in your computer can communicate. Most, if not all, vehicles from the following manufacturers use [FlexRay](https://en.wikipedia.org/wiki/FlexRay) instead of a CAN bus: **BMW, Mercedes, Audi, Land Rover, and some Volvo**. These cars may one day be supported, but we have no immediate plans to support FlexRay. All the cars that openpilot supports use a [CAN bus](https://en.wikipedia.org/wiki/CAN_bus) for communication between all the car's computers, however a CAN bus isn't the only way that the computers in your car can communicate. Most, if not all, vehicles from the following manufacturers use [FlexRay](https://en.wikipedia.org/wiki/FlexRay) instead of a CAN bus: **BMW, Mercedes, Audi, Land Rover, and some Volvo**. These cars may one day be supported, but we have no immediate plans to support FlexRay.
### Toyota Security ### Toyota Security

@ -1 +1 @@
Subproject commit 75a15b6f32ae86810f0065ecf2470c5a50a15ec1 Subproject commit f3eaf877a65f5323d431ec434d19c83f2e1ffea6

@ -1 +1 @@
Subproject commit 074855040a632737dd6472a4dee70173e870d09f Subproject commit 0f40708e248121ff0843a753081c618e919760c2

@ -199,3 +199,6 @@ flake8-implicit-str-concat.allow-multiline=false
"system".msg = "Use openpilot.system" "system".msg = "Use openpilot.system"
"third_party".msg = "Use openpilot.third_party" "third_party".msg = "Use openpilot.third_party"
"tools".msg = "Use openpilot.tools" "tools".msg = "Use openpilot.tools"
[tool.coverage.run]
concurrency = ["multiprocessing", "thread"]

@ -1,5 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import json import json
import multiprocessing
import os import os
import requests import requests
import shutil import shutil
@ -12,7 +13,6 @@ from datetime import datetime, timedelta
from parameterized import parameterized from parameterized import parameterized
from typing import Optional from typing import Optional
from multiprocessing import Process
from pympler.tracker import SummaryTracker from pympler.tracker import SummaryTracker
from unittest import mock from unittest import mock
from websocket import ABNF from websocket import ABNF
@ -75,24 +75,25 @@ class TestAthenadMethods(unittest.TestCase):
with self.assertRaises(TimeoutError) as _: with self.assertRaises(TimeoutError) as _:
dispatcher["getMessage"]("controlsState") dispatcher["getMessage"]("controlsState")
def send_deviceState(): end_event = multiprocessing.Event()
messaging.context = messaging.Context()
pub_sock = messaging.pub_sock("deviceState") pub_sock = messaging.pub_sock("deviceState")
start = time.time()
while time.time() - start < 1: def send_deviceState():
while not end_event.is_set():
msg = messaging.new_message('deviceState') msg = messaging.new_message('deviceState')
pub_sock.send(msg.to_bytes()) pub_sock.send(msg.to_bytes())
time.sleep(0.01) time.sleep(0.01)
p = Process(target=send_deviceState) p = multiprocessing.Process(target=send_deviceState)
p.start() p.start()
time.sleep(0.1) time.sleep(0.1)
try: try:
deviceState = dispatcher["getMessage"]("deviceState") deviceState = dispatcher["getMessage"]("deviceState")
assert deviceState['deviceState'] assert deviceState['deviceState']
finally: finally:
p.terminate() end_event.set()
p.join()
def test_listDataDirectory(self): def test_listDataDirectory(self):
route = '2021-03-29--13-32-47' route = '2021-03-29--13-32-47'

@ -144,6 +144,9 @@ def main() -> NoReturn:
if health["heartbeat_lost"]: if health["heartbeat_lost"]:
params.put_bool("PandaHeartbeatLost", True) params.put_bool("PandaHeartbeatLost", True)
cloudlog.event("heartbeat lost", deviceState=health, serial=panda.get_usb_serial()) cloudlog.event("heartbeat lost", deviceState=health, serial=panda.get_usb_serial())
if health["som_reset_triggered"]:
params.put_bool("PandaSomResetTriggered", True)
cloudlog.event("panda.som_reset_triggered", health=health, serial=panda.get_usb_serial())
if first_run: if first_run:
if panda.is_internal(): if panda.is_internal():

@ -53,7 +53,7 @@ If your car has the following packages or features, then it's a good candidate f
### FlexRay ### FlexRay
All the cars that openpilot supports use a [CAN bus](https://en.wikipedia.org/wiki/CAN_bus) for communication between all the car's computers, however a CAN bus isn't the only way that the cars in your computer can communicate. Most, if not all, vehicles from the following manufacturers use [FlexRay](https://en.wikipedia.org/wiki/FlexRay) instead of a CAN bus: **BMW, Mercedes, Audi, Land Rover, and some Volvo**. These cars may one day be supported, but we have no immediate plans to support FlexRay. All the cars that openpilot supports use a [CAN bus](https://en.wikipedia.org/wiki/CAN_bus) for communication between all the car's computers, however a CAN bus isn't the only way that the computers in your car can communicate. Most, if not all, vehicles from the following manufacturers use [FlexRay](https://en.wikipedia.org/wiki/FlexRay) instead of a CAN bus: **BMW, Mercedes, Audi, Land Rover, and some Volvo**. These cars may one day be supported, but we have no immediate plans to support FlexRay.
### Toyota Security ### Toyota Security

@ -115,7 +115,7 @@ class CarState(CarStateBase):
# TODO: Find brake pressure # TODO: Find brake pressure
ret.brake = 0 ret.brake = 0
ret.brakePressed = cp.vl["TCS13"]["DriverBraking"] != 0 ret.brakePressed = cp.vl["TCS13"]["DriverOverride"] == 2 # 2 includes regen braking by user on HEV/EV
ret.brakeHoldActive = cp.vl["TCS15"]["AVH_LAMP"] == 2 # 0 OFF, 1 ERROR, 2 ACTIVE, 3 READY ret.brakeHoldActive = cp.vl["TCS15"]["AVH_LAMP"] == 2 # 0 OFF, 1 ERROR, 2 ACTIVE, 3 READY
ret.parkingBrake = cp.vl["TCS13"]["PBRAKE_ACT"] == 1 ret.parkingBrake = cp.vl["TCS13"]["PBRAKE_ACT"] == 1
ret.accFaulted = cp.vl["TCS13"]["ACCEnable"] != 0 # 0 ACC CONTROL ENABLED, 1-3 ACC CONTROL DISABLED ret.accFaulted = cp.vl["TCS13"]["ACCEnable"] != 0 # 0 ACC CONTROL ENABLED, 1-3 ACC CONTROL DISABLED

@ -1327,20 +1327,24 @@ FW_VERSIONS = {
CAR.GENESIS_G80: { CAR.GENESIS_G80: {
(Ecu.fwdRadar, 0x7d0, None): [ (Ecu.fwdRadar, 0x7d0, None): [
b'\xf1\x00DH__ SCC F-CUP 1.00 1.01 96400-B1120 ', b'\xf1\x00DH__ SCC F-CUP 1.00 1.01 96400-B1120 ',
b'\xf1\x00DH__ SCC FHCUP 1.00 1.01 96400-B1110 ',
], ],
(Ecu.fwdCamera, 0x7c4, None): [ (Ecu.fwdCamera, 0x7c4, None): [
b'\xf1\x00DH LKAS AT USA LHD 1.01 1.03 95895-B1500 180713', b'\xf1\x00DH LKAS AT USA LHD 1.01 1.03 95895-B1500 180713',
b'\xf1\x00DH LKAS AT USA LHD 1.01 1.02 95895-B1500 170810', b'\xf1\x00DH LKAS AT USA LHD 1.01 1.02 95895-B1500 170810',
b'\xf1\x00DH LKAS AT USA LHD 1.01 1.01 95895-B1500 161014', b'\xf1\x00DH LKAS AT USA LHD 1.01 1.01 95895-B1500 161014',
b'\xf1\x00DH LKAS AT KOR LHD 1.01 1.02 95895-B1500 170810',
], ],
(Ecu.transmission, 0x7e1, None): [ (Ecu.transmission, 0x7e1, None): [
b'\xf1\x00bcsh8p54 E21\x00\x00\x00\x00\x00\x00\x00SDH0T33NH4\xd7O\x9e\xc9', b'\xf1\x00bcsh8p54 E21\x00\x00\x00\x00\x00\x00\x00SDH0T33NH4\xd7O\x9e\xc9',
b'\xf1\x00bcsh8p54 E18\x00\x00\x00\x00\x00\x00\x00TDH0G38NH3:-\xa9n', b'\xf1\x00bcsh8p54 E18\x00\x00\x00\x00\x00\x00\x00TDH0G38NH3:-\xa9n',
b'\xf1\x00bcsh8p54 E18\x00\x00\x00\x00\x00\x00\x00SDH0G38NH2j\x9dA\x1c', b'\xf1\x00bcsh8p54 E18\x00\x00\x00\x00\x00\x00\x00SDH0G38NH2j\x9dA\x1c',
b'\xf1\x00bcsh8p54 E18\x00\x00\x00\x00\x00\x00\x00SDH0T33NH3\x97\xe6\xbc\xb8', b'\xf1\x00bcsh8p54 E18\x00\x00\x00\x00\x00\x00\x00SDH0T33NH3\x97\xe6\xbc\xb8',
b'\xf1\x00bcsh8p54 E18\x00\x00\x00\x00\x00\x00\x00SDH0G33KH2\xae\xde\xd5!',
], ],
(Ecu.engine, 0x7e0, None): [ (Ecu.engine, 0x7e0, None): [
b'\xf1\x81640F0051\x00\x00\x00\x00\x00\x00\x00\x00', b'\xf1\x81640F0051\x00\x00\x00\x00\x00\x00\x00\x00',
b'\xf1\x81640A4051\x00\x00\x00\x00\x00\x00\x00\x00',
], ],
}, },
CAR.GENESIS_G90: { CAR.GENESIS_G90: {

@ -97,7 +97,7 @@ class CarInterface(CarInterfaceBase):
ret.steerActuatorDelay = 0.1 ret.steerActuatorDelay = 0.1
elif candidate in (CAR.FORESTER_PREGLOBAL, CAR.OUTBACK_PREGLOBAL_2018): elif candidate in (CAR.FORESTER_PREGLOBAL, CAR.OUTBACK_PREGLOBAL_2018):
ret.safetyConfigs[0].safetyParam = 1 # Outback 2018-2019 and Forester have reversed driver torque signal ret.safetyConfigs[0].safetyParam = Panda.FLAG_SUBARU_PREGLOBAL_REVERSED_DRIVER_TORQUE # Outback 2018-2019 and Forester have reversed driver torque signal
ret.mass = 1568 ret.mass = 1568
ret.wheelbase = 2.67 ret.wheelbase = 2.67
ret.centerToFront = ret.wheelbase * 0.5 ret.centerToFront = ret.wheelbase * 0.5

@ -207,6 +207,7 @@ FW_VERSIONS = {
b'\xa1\\ x04\x01', b'\xa1\\ x04\x01',
b'\xa1 \x03\x03', b'\xa1 \x03\x03',
b'\xa1 \x02\x01', b'\xa1 \x02\x01',
b'\xa1 \x02\x02',
], ],
(Ecu.eps, 0x746, None): [ (Ecu.eps, 0x746, None): [
b'\x9b\xc0\x11\x00', b'\x9b\xc0\x11\x00',
@ -220,11 +221,13 @@ FW_VERSIONS = {
b'\xde\"a0\x07', b'\xde\"a0\x07',
b'\xe2"aq\x07', b'\xe2"aq\x07',
b'\xde,\xa0@\x07', b'\xde,\xa0@\x07',
b'\xe2,\xa0@\x07',
], ],
(Ecu.transmission, 0x7e1, None): [ (Ecu.transmission, 0x7e1, None): [
b'\xa5\xf6\x05@\x00', b'\xa5\xf6\x05@\x00',
b'\xa7\xf6\x04@\x00', b'\xa7\xf6\x04@\x00',
b'\xa5\xfe\xc7@\x00', b'\xa5\xfe\xc7@\x00',
b'\xa7\xfe\xc4@\x00',
], ],
}, },
CAR.IMPREZA: { CAR.IMPREZA: {

@ -18,7 +18,7 @@ from openpilot.selfdrive.test.fuzzy_generation import DrawType, FuzzyGenerator
ALL_ECUS = list({ecu for ecus in FW_VERSIONS.values() for ecu in ecus.keys()}) ALL_ECUS = list({ecu for ecus in FW_VERSIONS.values() for ecu in ecus.keys()})
MAX_EXAMPLES = int(os.environ.get('MAX_EXAMPLES', '5')) MAX_EXAMPLES = int(os.environ.get('MAX_EXAMPLES', '20'))
def get_fuzzy_car_interface_args(draw: DrawType) -> dict: def get_fuzzy_car_interface_args(draw: DrawType) -> dict:

@ -196,7 +196,7 @@ CAR_INFO: Dict[str, Union[VWCarInfo, List[VWCarInfo]]] = {
], ],
CAR.ATLAS_MK1: [ CAR.ATLAS_MK1: [
VWCarInfo("Volkswagen Atlas 2018-23"), VWCarInfo("Volkswagen Atlas 2018-23"),
VWCarInfo("Volkswagen Atlas Cross Sport 2021-22"), VWCarInfo("Volkswagen Atlas Cross Sport 2020-22"),
VWCarInfo("Volkswagen Teramont 2018-22"), VWCarInfo("Volkswagen Teramont 2018-22"),
VWCarInfo("Volkswagen Teramont Cross Sport 2021-22"), VWCarInfo("Volkswagen Teramont Cross Sport 2021-22"),
VWCarInfo("Volkswagen Teramont X 2021-22"), VWCarInfo("Volkswagen Teramont X 2021-22"),
@ -350,6 +350,7 @@ FW_VERSIONS = {
CAR.ATLAS_MK1: { CAR.ATLAS_MK1: {
(Ecu.engine, 0x7e0, None): [ (Ecu.engine, 0x7e0, None): [
b'\xf1\x8703H906026AA\xf1\x899970', b'\xf1\x8703H906026AA\xf1\x899970',
b'\xf1\x8703H906026AG\xf1\x899973',
b'\xf1\x8703H906026AJ\xf1\x890638', b'\xf1\x8703H906026AJ\xf1\x890638',
b'\xf1\x8703H906026AJ\xf1\x891017', b'\xf1\x8703H906026AJ\xf1\x891017',
b'\xf1\x8703H906026AT\xf1\x891922', b'\xf1\x8703H906026AT\xf1\x891922',
@ -375,6 +376,7 @@ FW_VERSIONS = {
(Ecu.srs, 0x715, None): [ (Ecu.srs, 0x715, None): [
b'\xf1\x873Q0959655BC\xf1\x890503\xf1\x82\0161914151912001103111122031200', b'\xf1\x873Q0959655BC\xf1\x890503\xf1\x82\0161914151912001103111122031200',
b'\xf1\x873Q0959655BN\xf1\x890713\xf1\x82\0162214152212001105141122052900', b'\xf1\x873Q0959655BN\xf1\x890713\xf1\x82\0162214152212001105141122052900',
b'\xf1\x873Q0959655DB\xf1\x890720\xf1\x82\x0e1114151112001105111122052900',
b'\xf1\x873Q0959655DB\xf1\x890720\xf1\x82\0162214152212001105141122052900', b'\xf1\x873Q0959655DB\xf1\x890720\xf1\x82\0162214152212001105141122052900',
b'\xf1\x873Q0959655DM\xf1\x890732\xf1\x82\x0e1114151112001105161122052J00', b'\xf1\x873Q0959655DM\xf1\x890732\xf1\x82\x0e1114151112001105161122052J00',
b'\xf1\x873Q0959655DM\xf1\x890732\xf1\x82\x0e1115151112001105171122052J00', b'\xf1\x873Q0959655DM\xf1\x890732\xf1\x82\x0e1115151112001105171122052J00',
@ -382,6 +384,7 @@ FW_VERSIONS = {
(Ecu.eps, 0x712, None): [ (Ecu.eps, 0x712, None): [
b'\xf1\x873QF909144B \xf1\x891582\xf1\x82\00571B60924A1', b'\xf1\x873QF909144B \xf1\x891582\xf1\x82\00571B60924A1',
b'\xf1\x873QF909144B \xf1\x891582\xf1\x82\x0571B6G920A1', b'\xf1\x873QF909144B \xf1\x891582\xf1\x82\x0571B6G920A1',
b'\xf1\x873QF909144B \xf1\x891582\xf1\x82\x0571B6M921A1',
b'\xf1\x875Q0909143P \xf1\x892051\xf1\x820528B6080105', b'\xf1\x875Q0909143P \xf1\x892051\xf1\x820528B6080105',
b'\xf1\x875Q0909143P \xf1\x892051\xf1\x820528B6090105', b'\xf1\x875Q0909143P \xf1\x892051\xf1\x820528B6090105',
], ],

@ -121,6 +121,11 @@ class Controls:
safety_config.safetyModel = car.CarParams.SafetyModel.noOutput safety_config.safetyModel = car.CarParams.SafetyModel.noOutput
self.CP.safetyConfigs = [safety_config] self.CP.safetyConfigs = [safety_config]
# Write previous route's CarParams
prev_cp = self.params.get("CarParamsPersistent")
if prev_cp is not None:
self.params.put("CarParamsPrevRoute", prev_cp)
# Write CarParams for radard # Write CarParams for radard
cp_bytes = self.CP.to_bytes() cp_bytes = self.CP.to_bytes()
self.params.put("CarParams", cp_bytes) self.params.put("CarParams", cp_bytes)

@ -1,6 +1,12 @@
import numpy as np import numpy as np
import signal
import sys
from typing import List, Optional, Tuple, Any from typing import List, Optional, Tuple, Any
from cereal import log
from openpilot.common.params import Params
from openpilot.system.swaglog import cloudlog
class NPQueue: class NPQueue:
def __init__(self, maxlen: int, rowsize: int) -> None: def __init__(self, maxlen: int, rowsize: int) -> None:
@ -48,3 +54,24 @@ class PointBuckets:
def load_points(self, points: List[List[float]]) -> None: def load_points(self, points: List[List[float]]) -> None:
for point in points: for point in points:
self.add_point(*point) self.add_point(*point)
class ParameterEstimator:
""" Base class for parameter estimators """
def reset(self) -> None:
raise NotImplementedError
def handle_log(self, t: int, which: str, msg: log.Event) -> None:
raise NotImplementedError
def get_msg(self, valid: bool, with_points: bool) -> log.Event:
raise NotImplementedError
def cache_points_onexit(param_name, estimator, sig, frame):
signal.signal(sig, signal.SIG_DFL)
cloudlog.warning(f"Caching {param_name} param")
params = Params()
msg = estimator.get_msg(valid=True, with_points=True)
params.put(param_name, msg.to_bytes())
sys.exit(0)

@ -1,9 +1,9 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import os import os
import sys
import signal import signal
import numpy as np import numpy as np
from collections import deque, defaultdict from collections import deque, defaultdict
from functools import partial
import cereal.messaging as messaging import cereal.messaging as messaging
from cereal import car, log from cereal import car, log
@ -12,7 +12,7 @@ from openpilot.common.realtime import config_realtime_process, DT_MDL
from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.filter_simple import FirstOrderFilter
from openpilot.system.swaglog import cloudlog from openpilot.system.swaglog import cloudlog
from openpilot.selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_GRAVITY from openpilot.selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_GRAVITY
from openpilot.selfdrive.locationd.helpers import PointBuckets from openpilot.selfdrive.locationd.helpers import PointBuckets, ParameterEstimator, cache_points_onexit
HISTORY = 5 # secs HISTORY = 5 # secs
POINTS_PER_BUCKET = 1500 POINTS_PER_BUCKET = 1500
@ -52,7 +52,7 @@ class TorqueBuckets(PointBuckets):
break break
class TorqueEstimator: class TorqueEstimator(ParameterEstimator):
def __init__(self, CP, decimated=False): def __init__(self, CP, decimated=False):
self.hist_len = int(HISTORY / DT_MDL) self.hist_len = int(HISTORY / DT_MDL)
self.lag = CP.steerActuatorDelay + .2 # from controlsd self.lag = CP.steerActuatorDelay + .2 # from controlsd
@ -95,7 +95,7 @@ class TorqueEstimator:
# try to restore cached params # try to restore cached params
params = Params() params = Params()
params_cache = params.get("LiveTorqueCarParams") params_cache = params.get("CarParamsPrevRoute")
torque_cache = params.get("LiveTorqueParameters") torque_cache = params.get("LiveTorqueParameters")
if params_cache is not None and torque_cache is not None: if params_cache is not None and torque_cache is not None:
try: try:
@ -116,7 +116,6 @@ class TorqueEstimator:
cloudlog.info("restored torque params from cache") cloudlog.info("restored torque params from cache")
except Exception: except Exception:
cloudlog.exception("failed to restore cached torque params") cloudlog.exception("failed to restore cached torque params")
params.remove("LiveTorqueCarParams")
params.remove("LiveTorqueParameters") params.remove("LiveTorqueParameters")
self.filtered_params = {} self.filtered_params = {}
@ -228,19 +227,8 @@ def main():
with car.CarParams.from_bytes(params.get("CarParams", block=True)) as CP: with car.CarParams.from_bytes(params.get("CarParams", block=True)) as CP:
estimator = TorqueEstimator(CP) estimator = TorqueEstimator(CP)
def cache_params(sig, frame):
signal.signal(sig, signal.SIG_DFL)
cloudlog.warning("caching torque params")
params = Params()
params.put("LiveTorqueCarParams", CP.as_builder().to_bytes())
msg = estimator.get_msg(with_points=True)
params.put("LiveTorqueParameters", msg.to_bytes())
sys.exit(0)
if "REPLAY" not in os.environ: if "REPLAY" not in os.environ:
signal.signal(signal.SIGINT, cache_params) signal.signal(signal.SIGINT, partial(cache_points_onexit, "LiveTorqueParameters", estimator))
while True: while True:
sm.update() sm.update()

@ -19,19 +19,21 @@ TOTAL_SCONS_NODES = 2560
MAX_BUILD_PROGRESS = 100 MAX_BUILD_PROGRESS = 100
PREBUILT = os.path.exists(os.path.join(BASEDIR, 'prebuilt')) PREBUILT = os.path.exists(os.path.join(BASEDIR, 'prebuilt'))
def build(spinner: Spinner, dirty: bool = False) -> None: def build(spinner: Spinner, dirty: bool = False, minimal: bool = False) -> None:
env = os.environ.copy() env = os.environ.copy()
env['SCONS_PROGRESS'] = "1" env['SCONS_PROGRESS'] = "1"
nproc = os.cpu_count() nproc = os.cpu_count()
if nproc is None: if nproc is None:
nproc = 2 nproc = 2
extra_args = ["--minimal"] if minimal else []
# building with all cores can result in using too # building with all cores can result in using too
# much memory, so retry with less parallelism # much memory, so retry with less parallelism
compile_output: List[bytes] = [] compile_output: List[bytes] = []
for n in (nproc, nproc/2, 1): for n in (nproc, nproc/2, 1):
compile_output.clear() compile_output.clear()
scons: subprocess.Popen = subprocess.Popen(["scons", f"-j{int(n)}", "--cache-populate", "--minimal"], cwd=BASEDIR, env=env, stderr=subprocess.PIPE) scons: subprocess.Popen = subprocess.Popen(["scons", f"-j{int(n)}", "--cache-populate", *extra_args], cwd=BASEDIR, env=env, stderr=subprocess.PIPE)
assert scons.stderr is not None assert scons.stderr is not None
# Read progress from stderr and update spinner # Read progress from stderr and update spinner
@ -86,4 +88,4 @@ def build(spinner: Spinner, dirty: bool = False) -> None:
if __name__ == "__main__" and not PREBUILT: if __name__ == "__main__" and not PREBUILT:
spinner = Spinner() spinner = Spinner()
spinner.update_progress(0, 100) spinner.update_progress(0, 100)
build(spinner, is_dirty()) build(spinner, is_dirty(), minimal = AGNOS)

@ -92,7 +92,7 @@ def fill_model_msg(msg: capnp._DynamicStructBuilder, net_output_data: Dict[str,
# interpolate to find `t` for the current xidx # interpolate to find `t` for the current xidx
current_x_val = plan_x[tidx] current_x_val = plan_x[tidx]
next_x_val = plan_x[tidx+1] next_x_val = plan_x[tidx+1]
p = (ModelConstants.X_IDXS[xidx] - current_x_val) / (next_x_val - current_x_val) p = (ModelConstants.X_IDXS[xidx] - current_x_val) / (next_x_val - current_x_val) if abs(next_x_val - current_x_val) > 1e-9 else float('nan')
PLAN_T_IDXS[xidx] = p * ModelConstants.T_IDXS[tidx+1] + (1 - p) * ModelConstants.T_IDXS[tidx] PLAN_T_IDXS[xidx] = p * ModelConstants.T_IDXS[tidx+1] + (1 - p) * ModelConstants.T_IDXS[tidx]
# lane lines # lane lines

@ -594,10 +594,13 @@ def get_custom_params_from_lr(lr: LogIterable, initial_state: str = "first") ->
assert initial_state in ["first", "last"] assert initial_state in ["first", "last"]
msg_index = 0 if initial_state == "first" else -1 msg_index = 0 if initial_state == "first" else -1
assert len(car_params) > 0, "carParams required for initial state of liveParameters and liveTorqueCarParams" assert len(car_params) > 0, "carParams required for initial state of liveParameters and CarParamsPrevRoute"
CP = car_params[msg_index].carParams CP = car_params[msg_index].carParams
custom_params = {} custom_params = {
"CarParamsPrevRoute": CP.as_builder().to_bytes()
}
if len(live_calibration) > 0: if len(live_calibration) > 0:
custom_params["CalibrationParams"] = live_calibration[msg_index].as_builder().to_bytes() custom_params["CalibrationParams"] = live_calibration[msg_index].as_builder().to_bytes()
if len(live_parameters) > 0: if len(live_parameters) > 0:
@ -605,7 +608,6 @@ def get_custom_params_from_lr(lr: LogIterable, initial_state: str = "first") ->
lp_dict["carFingerprint"] = CP.carFingerprint lp_dict["carFingerprint"] = CP.carFingerprint
custom_params["LiveParameters"] = json.dumps(lp_dict) custom_params["LiveParameters"] = json.dumps(lp_dict)
if len(live_torque_parameters) > 0: if len(live_torque_parameters) > 0:
custom_params["LiveTorqueCarParams"] = CP.as_builder().to_bytes()
custom_params["LiveTorqueParameters"] = live_torque_parameters[msg_index].as_builder().to_bytes() custom_params["LiveTorqueParameters"] = live_torque_parameters[msg_index].as_builder().to_bytes()
return custom_params return custom_params

@ -26,7 +26,7 @@
#define CAMERA_ID_OX03C10 9 #define CAMERA_ID_OX03C10 9
#define CAMERA_ID_MAX 10 #define CAMERA_ID_MAX 10
const int YUV_BUFFER_COUNT = 40; const int YUV_BUFFER_COUNT = 20;
enum CameraType { enum CameraType {
RoadCam = 0, RoadCam = 0,

@ -25,7 +25,7 @@ const int AXIS_X_TOP_MARGIN = 4;
static inline bool xLessThan(const QPointF &p, float x) { return p.x() < x; } static inline bool xLessThan(const QPointF &p, float x) { return p.x() < x; }
ChartView::ChartView(const std::pair<double, double> &x_range, ChartsWidget *parent) ChartView::ChartView(const std::pair<double, double> &x_range, ChartsWidget *parent)
: charts_widget(parent), tip_label(this), QChartView(parent) { : charts_widget(parent), QChartView(parent) {
series_type = (SeriesType)settings.chart_series_type; series_type = (SeriesType)settings.chart_series_type;
chart()->setBackgroundVisible(false); chart()->setBackgroundVisible(false);
axis_x = new QValueAxis(this); axis_x = new QValueAxis(this);
@ -38,6 +38,7 @@ ChartView::ChartView(const std::pair<double, double> &x_range, ChartsWidget *par
axis_x->setRange(x_range.first, x_range.second); axis_x->setRange(x_range.first, x_range.second);
tip_label = new TipLabel(this);
createToolButtons(); createToolButtons();
setRubberBand(QChartView::HorizontalRubberBand); setRubberBand(QChartView::HorizontalRubberBand);
setMouseTracking(true); setMouseTracking(true);
@ -416,7 +417,7 @@ qreal ChartView::niceNumber(qreal x, bool ceiling) {
} }
void ChartView::leaveEvent(QEvent *event) { void ChartView::leaveEvent(QEvent *event) {
if (tip_label.isVisible()) { if (tip_label->isVisible()) {
charts_widget->showValueTip(-1); charts_widget->showValueTip(-1);
} }
QChartView::leaveEvent(event); QChartView::leaveEvent(event);
@ -543,7 +544,7 @@ void ChartView::mouseMoveEvent(QMouseEvent *ev) {
if (!is_zooming && plot_area.contains(ev->pos())) { if (!is_zooming && plot_area.contains(ev->pos())) {
const double sec = chart()->mapToValue(ev->pos()).x(); const double sec = chart()->mapToValue(ev->pos()).x();
charts_widget->showValueTip(sec); charts_widget->showValueTip(sec);
} else if (tip_label.isVisible()) { } else if (tip_label->isVisible()) {
charts_widget->showValueTip(-1); charts_widget->showValueTip(-1);
} }
@ -563,7 +564,7 @@ void ChartView::showTip(double sec) {
QRect tip_area(0, chart()->plotArea().top(), rect().width(), chart()->plotArea().height()); QRect tip_area(0, chart()->plotArea().top(), rect().width(), chart()->plotArea().height());
QRect visible_rect = charts_widget->chartVisibleRect(this).intersected(tip_area); QRect visible_rect = charts_widget->chartVisibleRect(this).intersected(tip_area);
if (visible_rect.isEmpty()) { if (visible_rect.isEmpty()) {
tip_label.hide(); tip_label->hide();
return; return;
} }
@ -593,14 +594,14 @@ void ChartView::showTip(double sec) {
QPoint pt(x, chart()->plotArea().top()); QPoint pt(x, chart()->plotArea().top());
text_list.push_front(QString::number(chart()->mapToValue({x, 0}).x(), 'f', 3)); text_list.push_front(QString::number(chart()->mapToValue({x, 0}).x(), 'f', 3));
QString text = "<p style='white-space:pre'>" % text_list.join("<br />") % "</p>"; QString text = "<p style='white-space:pre'>" % text_list.join("<br />") % "</p>";
tip_label.showText(pt, text, this, visible_rect); tip_label->showText(pt, text, this, visible_rect);
viewport()->update(); viewport()->update();
} }
void ChartView::hideTip() { void ChartView::hideTip() {
clearTrackPoints(); clearTrackPoints();
tooltip_x = -1; tooltip_x = -1;
tip_label.hide(); tip_label->hide();
viewport()->update(); viewport()->update();
} }

@ -108,7 +108,7 @@ private:
QGraphicsPixmapItem *move_icon; QGraphicsPixmapItem *move_icon;
QGraphicsProxyWidget *close_btn_proxy; QGraphicsProxyWidget *close_btn_proxy;
QGraphicsProxyWidget *manage_btn_proxy; QGraphicsProxyWidget *manage_btn_proxy;
TipLabel tip_label; TipLabel *tip_label;
std::vector<SigItem> sigs; std::vector<SigItem> sigs;
double cur_sec = 0; double cur_sec = 0;
SeriesType series_type = SeriesType::Line; SeriesType series_type = SeriesType::Line;

@ -14,7 +14,9 @@
const int MAX_COLUMN_COUNT = 4; const int MAX_COLUMN_COUNT = 4;
const int CHART_SPACING = 4; const int CHART_SPACING = 4;
ChartsWidget::ChartsWidget(QWidget *parent) : align_timer(this), auto_scroll_timer(this), QFrame(parent) { ChartsWidget::ChartsWidget(QWidget *parent) : QFrame(parent) {
align_timer = new QTimer(this);
auto_scroll_timer = new QTimer(this);
setFrameStyle(QFrame::StyledPanel | QFrame::Plain); setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
QVBoxLayout *main_layout = new QVBoxLayout(this); QVBoxLayout *main_layout = new QVBoxLayout(this);
main_layout->setContentsMargins(0, 0, 0, 0); main_layout->setContentsMargins(0, 0, 0, 0);
@ -95,9 +97,9 @@ ChartsWidget::ChartsWidget(QWidget *parent) : align_timer(this), auto_scroll_tim
range_slider->setValue(max_chart_range); range_slider->setValue(max_chart_range);
updateToolBar(); updateToolBar();
align_timer.setSingleShot(true); align_timer->setSingleShot(true);
QObject::connect(&align_timer, &QTimer::timeout, this, &ChartsWidget::alignCharts); QObject::connect(align_timer, &QTimer::timeout, this, &ChartsWidget::alignCharts);
QObject::connect(&auto_scroll_timer, &QTimer::timeout, this, &ChartsWidget::doAutoScroll); QObject::connect(auto_scroll_timer, &QTimer::timeout, this, &ChartsWidget::doAutoScroll);
QObject::connect(dbc(), &DBCManager::DBCFileChanged, this, &ChartsWidget::removeAll); QObject::connect(dbc(), &DBCManager::DBCFileChanged, this, &ChartsWidget::removeAll);
QObject::connect(can, &AbstractStream::eventsMerged, this, &ChartsWidget::eventsMerged); QObject::connect(can, &AbstractStream::eventsMerged, this, &ChartsWidget::eventsMerged);
QObject::connect(can, &AbstractStream::msgsReceived, this, &ChartsWidget::updateState); QObject::connect(can, &AbstractStream::msgsReceived, this, &ChartsWidget::updateState);
@ -253,7 +255,7 @@ ChartView *ChartsWidget::createChart() {
chart->setFixedHeight(settings.chart_height); chart->setFixedHeight(settings.chart_height);
chart->setMinimumWidth(CHART_MIN_WIDTH); chart->setMinimumWidth(CHART_MIN_WIDTH);
chart->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); chart->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
QObject::connect(chart, &ChartView::axisYLabelWidthChanged, &align_timer, qOverload<>(&QTimer::start)); QObject::connect(chart, &ChartView::axisYLabelWidthChanged, align_timer, qOverload<>(&QTimer::start));
charts.push_front(chart); charts.push_front(chart);
currentCharts().push_front(chart); currentCharts().push_front(chart);
updateLayout(true); updateLayout(true);
@ -334,11 +336,11 @@ void ChartsWidget::updateLayout(bool force) {
} }
void ChartsWidget::startAutoScroll() { void ChartsWidget::startAutoScroll() {
auto_scroll_timer.start(50); auto_scroll_timer->start(50);
} }
void ChartsWidget::stopAutoScroll() { void ChartsWidget::stopAutoScroll() {
auto_scroll_timer.stop(); auto_scroll_timer->stop();
auto_scroll_count = 0; auto_scroll_count = 0;
} }

@ -109,8 +109,8 @@ private:
int column_count = 1; int column_count = 1;
int current_column_count = 0; int current_column_count = 0;
int auto_scroll_count = 0; int auto_scroll_count = 0;
QTimer auto_scroll_timer; QTimer *auto_scroll_timer;
QTimer align_timer; QTimer *align_timer;
int current_theme = 0; int current_theme = 0;
friend class ZoomCommand; friend class ZoomCommand;
friend class ChartView; friend class ChartView;

@ -232,7 +232,8 @@ void VideoWidget::updatePlayBtnState() {
// Slider // Slider
Slider::Slider(QWidget *parent) : thumbnail_label(parent), QSlider(Qt::Horizontal, parent) { Slider::Slider(QWidget *parent) : QSlider(Qt::Horizontal, parent) {
thumbnail_label = new InfoLabel(parent);
setMouseTracking(true); setMouseTracking(true);
} }
@ -321,9 +322,9 @@ void Slider::mouseMoveEvent(QMouseEvent *e) {
if (!thumb.isNull()) { if (!thumb.isNull()) {
int x = std::clamp(pos - thumb.width() / 2, THUMBNAIL_MARGIN, width() - thumb.width() - THUMBNAIL_MARGIN + 1); int x = std::clamp(pos - thumb.width() / 2, THUMBNAIL_MARGIN, width() - thumb.width() - THUMBNAIL_MARGIN + 1);
int y = -thumb.height() - THUMBNAIL_MARGIN; int y = -thumb.height() - THUMBNAIL_MARGIN;
thumbnail_label.showPixmap(mapToParent(QPoint(x, y)), utils::formatSeconds(seconds), thumb, alertInfo(seconds)); thumbnail_label->showPixmap(mapToParent(QPoint(x, y)), utils::formatSeconds(seconds), thumb, alertInfo(seconds));
} else { } else {
thumbnail_label.hide(); thumbnail_label->hide();
} }
QSlider::mouseMoveEvent(e); QSlider::mouseMoveEvent(e);
} }
@ -335,7 +336,7 @@ bool Slider::event(QEvent *event) {
case QEvent::FocusIn: case QEvent::FocusIn:
case QEvent::FocusOut: case QEvent::FocusOut:
case QEvent::Leave: case QEvent::Leave:
thumbnail_label.hide(); thumbnail_label->hide();
break; break;
default: default:
break; break;

@ -56,7 +56,7 @@ private:
QMap<uint64_t, QPixmap> thumbnails; QMap<uint64_t, QPixmap> thumbnails;
std::map<uint64_t, AlertInfo> alerts; std::map<uint64_t, AlertInfo> alerts;
InfoLabel thumbnail_label; InfoLabel *thumbnail_label;
}; };
class VideoWidget : public QFrame { class VideoWidget : public QFrame {

@ -144,7 +144,7 @@ protected:
std::vector<std::tuple<double, double, TimelineType>> timeline; std::vector<std::tuple<double, double, TimelineType>> timeline;
std::set<cereal::Event::Which> allow_list; std::set<cereal::Event::Which> allow_list;
std::string car_fingerprint_; std::string car_fingerprint_;
float speed_ = 1.0; std::atomic<float> speed_ = 1.0;
replayEventFilter event_filter = nullptr; replayEventFilter event_filter = nullptr;
void *filter_opaque = nullptr; void *filter_opaque = nullptr;
int segment_cache_limit = MIN_SEGMENTS_CACHE; int segment_cache_limit = MIN_SEGMENTS_CACHE;

Loading…
Cancel
Save