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
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
PYTEST: pytest --continue-on-collection-errors --cov --cov-report=xml --cov-append --durations=0 --durations-min=5 --hypothesis-seed 0
XDIST: -n auto --dist=loadscope
jobs:
build_release:
@ -54,11 +54,11 @@ jobs:
cd $STRIPPED_DIR
${{ env.RUN }} "CI=1 python selfdrive/manager/build.py"
- name: Run tests
timeout-minutes: 2
timeout-minutes: 3
run: |
cd $STRIPPED_DIR
${{ env.RUN }} "release/check-dirty.sh && \
python -m unittest discover selfdrive/car"
MAX_EXAMPLES=5 $PYTEST $XDIST selfdrive/car"
- name: pre-commit
timeout-minutes: 3
run: |
@ -176,7 +176,7 @@ jobs:
- name: Run unit tests
timeout-minutes: 15
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 && \
QT_QPA_PLATFORM=offscreen ./selfdrive/ui/tests/test_translations && \
./selfdrive/ui/tests/test_translations.py && \
@ -184,6 +184,8 @@ jobs:
./selfdrive/test/process_replay/test_fuzzy.py"
- name: "Upload coverage to Codecov"
uses: codecov/codecov-action@v3
with:
name: ${{ github.job }}
process_replay:
name: process replay
@ -211,6 +213,7 @@ jobs:
run: |
${{ env.RUN }} "CI=1 coverage run selfdrive/test/process_replay/test_processes.py -j$(nproc) && \
chmod -R 777 /tmp/comma_download_cache && \
coverage combine && \
coverage xml"
- name: 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"
- name: "Upload coverage to Codecov"
uses: codecov/codecov-action@v3
with:
name: ${{ github.job }}
regen:
name: regen
@ -253,7 +258,7 @@ jobs:
- name: Run regen
timeout-minutes: 30
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"
test_modeld:
@ -278,15 +283,17 @@ jobs:
run: |
${{ env.RUN_CL }} "unset PYTHONWARNINGS && \
ONNXCPU=1 CI=1 NO_NAV=1 coverage run selfdrive/test/process_replay/model_replay.py && \
coverage combine && \
coverage xml"
- name: Run unit tests
timeout-minutes: 4
run: |
${{ env.RUN_CL }} "unset PYTHONWARNINGS && \
$UNIT_TEST selfdrive/modeld && \
coverage xml"
$PYTEST selfdrive/modeld"
- name: "Upload coverage to Codecov"
uses: codecov/codecov-action@v3
with:
name: ${{ github.job }}
test_cars:
name: cars
@ -311,13 +318,15 @@ jobs:
- name: Test car models
timeout-minutes: 25
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"
env:
NUM_JOBS: 5
JOB_ID: ${{ matrix.job }}
- name: "Upload coverage to Codecov"
uses: codecov/codecov-action@v3
with:
name: ${{ github.job }}-${{ matrix.job }}
car_docs_diff:
name: PR comments

4
Jenkinsfile vendored

@ -85,7 +85,7 @@ def pcStage(String stageName, Closure body) {
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) {
timeout(time: 20, unit: 'MINUTES') {
try {
@ -228,7 +228,7 @@ node {
},
'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 \
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"

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

@ -8,4 +8,5 @@ coverage:
ignore:
- "**/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},
{"CarParamsCache", CLEAR_ON_MANAGER_START},
{"CarParamsPersistent", PERSISTENT},
{"CarParamsPrevRoute", PERSISTENT},
{"CarVin", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
{"CompletedTrainingVersion", PERSISTENT},
{"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},
{"LastUpdateTime", PERSISTENT},
{"LiveParameters", PERSISTENT},
{"LiveTorqueCarParams", PERSISTENT},
{"LiveTorqueParameters", PERSISTENT | DONT_LOG},
{"LongitudinalPersonality", PERSISTENT},
{"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},
{"OpenpilotEnabledToggle", PERSISTENT},
{"PandaHeartbeatLost", CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION},
{"PandaSomResetTriggered", CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION},
{"PandaSignatures", CLEAR_ON_MANAGER_START},
{"Passive", PERSISTENT},
{"PrimeType", PERSISTENT},

@ -1,5 +1,6 @@
import os
import pytest
import random
from openpilot.common.prefix import OpenpilotPrefix
from openpilot.system.hardware import TICI
@ -9,6 +10,8 @@ from openpilot.system.hardware import TICI
def openpilot_function_fixture():
starting_env = dict(os.environ)
random.seed(0)
# setup a clean environment for each test
with OpenpilotPrefix():
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 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 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|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>|
@ -318,7 +318,7 @@ If your car has the following packages or features, then it's a good candidate f
### 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

@ -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"
"third_party".msg = "Use openpilot.third_party"
"tools".msg = "Use openpilot.tools"
[tool.coverage.run]
concurrency = ["multiprocessing", "thread"]

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

@ -144,6 +144,9 @@ def main() -> NoReturn:
if health["heartbeat_lost"]:
params.put_bool("PandaHeartbeatLost", True)
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 panda.is_internal():

@ -53,7 +53,7 @@ If your car has the following packages or features, then it's a good candidate f
### 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

@ -115,7 +115,7 @@ class CarState(CarStateBase):
# TODO: Find brake pressure
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.parkingBrake = cp.vl["TCS13"]["PBRAKE_ACT"] == 1
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: {
(Ecu.fwdRadar, 0x7d0, None): [
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): [
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.01 95895-B1500 161014',
b'\xf1\x00DH LKAS AT KOR LHD 1.01 1.02 95895-B1500 170810',
],
(Ecu.transmission, 0x7e1, None): [
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\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\x00SDH0G33KH2\xae\xde\xd5!',
],
(Ecu.engine, 0x7e0, None): [
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: {

@ -97,7 +97,7 @@ class CarInterface(CarInterfaceBase):
ret.steerActuatorDelay = 0.1
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.wheelbase = 2.67
ret.centerToFront = ret.wheelbase * 0.5

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

@ -196,7 +196,7 @@ CAR_INFO: Dict[str, Union[VWCarInfo, List[VWCarInfo]]] = {
],
CAR.ATLAS_MK1: [
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 Cross Sport 2021-22"),
VWCarInfo("Volkswagen Teramont X 2021-22"),
@ -350,6 +350,7 @@ FW_VERSIONS = {
CAR.ATLAS_MK1: {
(Ecu.engine, 0x7e0, None): [
b'\xf1\x8703H906026AA\xf1\x899970',
b'\xf1\x8703H906026AG\xf1\x899973',
b'\xf1\x8703H906026AJ\xf1\x890638',
b'\xf1\x8703H906026AJ\xf1\x891017',
b'\xf1\x8703H906026AT\xf1\x891922',
@ -375,6 +376,7 @@ FW_VERSIONS = {
(Ecu.srs, 0x715, None): [
b'\xf1\x873Q0959655BC\xf1\x890503\xf1\x82\0161914151912001103111122031200',
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\x873Q0959655DM\xf1\x890732\xf1\x82\x0e1114151112001105161122052J00',
b'\xf1\x873Q0959655DM\xf1\x890732\xf1\x82\x0e1115151112001105171122052J00',
@ -382,6 +384,7 @@ FW_VERSIONS = {
(Ecu.eps, 0x712, None): [
b'\xf1\x873QF909144B \xf1\x891582\xf1\x82\00571B60924A1',
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\x820528B6090105',
],

@ -121,6 +121,11 @@ class Controls:
safety_config.safetyModel = car.CarParams.SafetyModel.noOutput
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
cp_bytes = self.CP.to_bytes()
self.params.put("CarParams", cp_bytes)

@ -1,6 +1,12 @@
import numpy as np
import signal
import sys
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:
def __init__(self, maxlen: int, rowsize: int) -> None:
@ -48,3 +54,24 @@ class PointBuckets:
def load_points(self, points: List[List[float]]) -> None:
for point in points:
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
import os
import sys
import signal
import numpy as np
from collections import deque, defaultdict
from functools import partial
import cereal.messaging as messaging
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.system.swaglog import cloudlog
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
POINTS_PER_BUCKET = 1500
@ -52,7 +52,7 @@ class TorqueBuckets(PointBuckets):
break
class TorqueEstimator:
class TorqueEstimator(ParameterEstimator):
def __init__(self, CP, decimated=False):
self.hist_len = int(HISTORY / DT_MDL)
self.lag = CP.steerActuatorDelay + .2 # from controlsd
@ -95,7 +95,7 @@ class TorqueEstimator:
# try to restore cached params
params = Params()
params_cache = params.get("LiveTorqueCarParams")
params_cache = params.get("CarParamsPrevRoute")
torque_cache = params.get("LiveTorqueParameters")
if params_cache is not None and torque_cache is not None:
try:
@ -116,7 +116,6 @@ class TorqueEstimator:
cloudlog.info("restored torque params from cache")
except Exception:
cloudlog.exception("failed to restore cached torque params")
params.remove("LiveTorqueCarParams")
params.remove("LiveTorqueParameters")
self.filtered_params = {}
@ -228,19 +227,8 @@ def main():
with car.CarParams.from_bytes(params.get("CarParams", block=True)) as 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:
signal.signal(signal.SIGINT, cache_params)
signal.signal(signal.SIGINT, partial(cache_points_onexit, "LiveTorqueParameters", estimator))
while True:
sm.update()

@ -19,19 +19,21 @@ TOTAL_SCONS_NODES = 2560
MAX_BUILD_PROGRESS = 100
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['SCONS_PROGRESS'] = "1"
nproc = os.cpu_count()
if nproc is None:
nproc = 2
extra_args = ["--minimal"] if minimal else []
# building with all cores can result in using too
# much memory, so retry with less parallelism
compile_output: List[bytes] = []
for n in (nproc, nproc/2, 1):
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
# 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:
spinner = Spinner()
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
current_x_val = plan_x[tidx]
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]
# lane lines

@ -594,10 +594,13 @@ def get_custom_params_from_lr(lr: LogIterable, initial_state: str = "first") ->
assert initial_state in ["first", "last"]
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
custom_params = {}
custom_params = {
"CarParamsPrevRoute": CP.as_builder().to_bytes()
}
if len(live_calibration) > 0:
custom_params["CalibrationParams"] = live_calibration[msg_index].as_builder().to_bytes()
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
custom_params["LiveParameters"] = json.dumps(lp_dict)
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()
return custom_params

@ -26,7 +26,7 @@
#define CAMERA_ID_OX03C10 9
#define CAMERA_ID_MAX 10
const int YUV_BUFFER_COUNT = 40;
const int YUV_BUFFER_COUNT = 20;
enum CameraType {
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; }
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;
chart()->setBackgroundVisible(false);
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);
tip_label = new TipLabel(this);
createToolButtons();
setRubberBand(QChartView::HorizontalRubberBand);
setMouseTracking(true);
@ -416,7 +417,7 @@ qreal ChartView::niceNumber(qreal x, bool ceiling) {
}
void ChartView::leaveEvent(QEvent *event) {
if (tip_label.isVisible()) {
if (tip_label->isVisible()) {
charts_widget->showValueTip(-1);
}
QChartView::leaveEvent(event);
@ -543,7 +544,7 @@ void ChartView::mouseMoveEvent(QMouseEvent *ev) {
if (!is_zooming && plot_area.contains(ev->pos())) {
const double sec = chart()->mapToValue(ev->pos()).x();
charts_widget->showValueTip(sec);
} else if (tip_label.isVisible()) {
} else if (tip_label->isVisible()) {
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 visible_rect = charts_widget->chartVisibleRect(this).intersected(tip_area);
if (visible_rect.isEmpty()) {
tip_label.hide();
tip_label->hide();
return;
}
@ -593,14 +594,14 @@ void ChartView::showTip(double sec) {
QPoint pt(x, chart()->plotArea().top());
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>";
tip_label.showText(pt, text, this, visible_rect);
tip_label->showText(pt, text, this, visible_rect);
viewport()->update();
}
void ChartView::hideTip() {
clearTrackPoints();
tooltip_x = -1;
tip_label.hide();
tip_label->hide();
viewport()->update();
}

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

@ -14,7 +14,9 @@
const int MAX_COLUMN_COUNT = 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);
QVBoxLayout *main_layout = new QVBoxLayout(this);
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);
updateToolBar();
align_timer.setSingleShot(true);
QObject::connect(&align_timer, &QTimer::timeout, this, &ChartsWidget::alignCharts);
QObject::connect(&auto_scroll_timer, &QTimer::timeout, this, &ChartsWidget::doAutoScroll);
align_timer->setSingleShot(true);
QObject::connect(align_timer, &QTimer::timeout, this, &ChartsWidget::alignCharts);
QObject::connect(auto_scroll_timer, &QTimer::timeout, this, &ChartsWidget::doAutoScroll);
QObject::connect(dbc(), &DBCManager::DBCFileChanged, this, &ChartsWidget::removeAll);
QObject::connect(can, &AbstractStream::eventsMerged, this, &ChartsWidget::eventsMerged);
QObject::connect(can, &AbstractStream::msgsReceived, this, &ChartsWidget::updateState);
@ -253,7 +255,7 @@ ChartView *ChartsWidget::createChart() {
chart->setFixedHeight(settings.chart_height);
chart->setMinimumWidth(CHART_MIN_WIDTH);
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);
currentCharts().push_front(chart);
updateLayout(true);
@ -334,11 +336,11 @@ void ChartsWidget::updateLayout(bool force) {
}
void ChartsWidget::startAutoScroll() {
auto_scroll_timer.start(50);
auto_scroll_timer->start(50);
}
void ChartsWidget::stopAutoScroll() {
auto_scroll_timer.stop();
auto_scroll_timer->stop();
auto_scroll_count = 0;
}

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

@ -232,7 +232,8 @@ void VideoWidget::updatePlayBtnState() {
// 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);
}
@ -321,9 +322,9 @@ void Slider::mouseMoveEvent(QMouseEvent *e) {
if (!thumb.isNull()) {
int x = std::clamp(pos - thumb.width() / 2, THUMBNAIL_MARGIN, width() - thumb.width() - THUMBNAIL_MARGIN + 1);
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 {
thumbnail_label.hide();
thumbnail_label->hide();
}
QSlider::mouseMoveEvent(e);
}
@ -335,7 +336,7 @@ bool Slider::event(QEvent *event) {
case QEvent::FocusIn:
case QEvent::FocusOut:
case QEvent::Leave:
thumbnail_label.hide();
thumbnail_label->hide();
break;
default:
break;

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

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

Loading…
Cancel
Save