diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index a0ff582e68..a7a63658ed 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -11,7 +11,6 @@
"DISPLAY": "${localEnv:DISPLAY}",
"PYTHONPATH": "${containerWorkspaceFolder}",
"TERM": "xterm-256color",
- "CARLA_HOST": "host.docker.internal",
"force_color_prompt": "1"
},
"runArgs": [
diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml
index 4b412455e8..dce2fe0fb7 100644
--- a/.github/workflows/selfdrive_tests.yaml
+++ b/.github/workflows/selfdrive_tests.yaml
@@ -208,20 +208,30 @@ jobs:
run: |
${{ env.RUN }} "scons -j$(nproc)"
- name: Run replay
- id: run-replay
timeout-minutes: 30
run: |
- ${{ env.RUN }} "CI=1 $PYTEST -n auto --dist=loadscope selfdrive/test/process_replay/test_processes.py --long-diff && \
- chmod -R 777 /tmp/comma_download_cache"
+ ${{ 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
+ if: always()
+ run: cat selfdrive/test/process_replay/diff.txt
+ - uses: actions/upload-artifact@v3
+ if: always()
+ continue-on-error: true
+ with:
+ name: process_replay_diff.txt
+ path: selfdrive/test/process_replay/diff.txt
+ - name: Upload reference logs
+ if: ${{ failure() && steps.print-diff.outcome == 'success' && github.repository == 'commaai/openpilot' && env.AZURE_TOKEN != '' }}
+ run: |
+ ${{ 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 }}
- - name: Upload reference logs
- if: ${{ failure() && github.repository == 'commaai/openpilot' && env.AZURE_TOKEN != '' }}
- run: |
- ${{ env.RUN }} "unset PYTHONWARNINGS && CI=1 AZURE_TOKEN='$AZURE_TOKEN' \
- pytest -n auto --dist=loadscope selfdrive/test/process_replay/test_processes.py --upload-only"
regen:
name: regen
diff --git a/.gitignore b/.gitignore
index e414e4301a..3e91531d08 100644
--- a/.gitignore
+++ b/.gitignore
@@ -46,7 +46,6 @@ selfdrive/boardd/boardd
selfdrive/logcatd/logcatd
selfdrive/mapd/default_speeds_by_region.json
system/proclogd/proclogd
-selfdrive/ui/_ui
selfdrive/ui/translations/alerts_generated.h
selfdrive/ui/translations/tmp
selfdrive/test/longitudinal_maneuvers/out
diff --git a/Jenkinsfile b/Jenkinsfile
index 0765c44950..fe2c662f89 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -1,3 +1,14 @@
+def retryWithDelay(int maxRetries, int delay, Closure body) {
+ for (int i = 0; i < maxRetries; i++) {
+ try {
+ return body()
+ } catch (Exception e) {
+ sleep(delay)
+ }
+ }
+ throw Exception("Failed after ${maxRetries} retries")
+}
+
def device(String ip, String step_label, String cmd) {
withCredentials([file(credentialsId: 'id_rsa', variable: 'key_file')]) {
def ssh_cmd = """
@@ -89,25 +100,28 @@ 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 -e PYTHONPATH=${env.WORKSPACE}";
- docker.build("openpilot-base:build-${env.GIT_COMMIT}", "-f Dockerfile.openpilot_base .").inside(dockerArgs) {
+
+ def openpilot_base = retryWithDelay (3, 15) {
+ return docker.build("openpilot-base:build-${env.GIT_COMMIT}", "-f Dockerfile.openpilot_base .")
+ }
+
+ openpilot_base.inside(dockerArgs) {
timeout(time: 20, unit: 'MINUTES') {
try {
- // TODO: remove these after all jenkins jobs are running as batman (merged with master)
- sh "sudo chown -R batman:batman /tmp/scons_cache"
- sh "sudo chown -R batman:batman /tmp/comma_download_cache"
-
- sh "git config --global --add safe.directory '*'"
- sh "git submodule update --init --recursive"
- sh "git lfs pull"
+ retryWithDelay (3, 15) {
+ sh "git config --global --add safe.directory '*'"
+ sh "git submodule update --init --recursive"
+ sh "git lfs pull"
+ }
body()
} finally {
- sh "rm -rf ${env.WORKSPACE}/* || true"
- sh "rm -rf .* || true"
+ sh "rm -rf ${env.WORKSPACE}/* || true"
+ sh "rm -rf .* || true"
+ }
}
}
}
}
- }
}
def setupCredentials() {
diff --git a/README.md b/README.md
index 7d051ada14..d85d1e5676 100644
--- a/README.md
+++ b/README.md
@@ -58,7 +58,7 @@ All openpilot services can run as usual on a PC without requiring special hardwa
With openpilot's tools, you can plot logs, replay drives, and watch the full-res camera streams. See [the tools README](tools/README.md) for more information.
-You can also run openpilot in simulation [with the CARLA simulator](tools/sim/README.md). This allows openpilot to drive around a virtual car on your Ubuntu machine. The whole setup should only take a few minutes but does require a decent GPU.
+You can also run openpilot in simulation [with the MetaDrive simulator](tools/sim/README.md). This allows openpilot to drive around a virtual car on your Ubuntu machine. The whole setup should only take a few minutes but does require a decent GPU.
A PC running openpilot can also control your vehicle if it is connected to a [webcam](https://github.com/commaai/openpilot/tree/master/tools/webcam), a [black panda](https://comma.ai/shop/products/panda), and a [harness](https://comma.ai/shop/products/car-harness).
diff --git a/RELEASES.md b/RELEASES.md
index 07f70cdaff..41b9b946d8 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,7 +1,11 @@
Version 0.9.6 (2023-12-14)
========================
+* New driving model
+ * Vision model trained on more data
+ * Improved driving performance
* AGNOS 9
* comma body streaming and controls over WebRTC
+* Kia Niro Plug-in Hybrid 2022 support thanks to sunnyhaibin!
* Toyota RAV4 2023 support
* Toyota RAV4 Hybrid 2023 support
diff --git a/cereal b/cereal
index a3a6e4969e..d11688a90a 160000
--- a/cereal
+++ b/cereal
@@ -1 +1 @@
-Subproject commit a3a6e4969e58875f7cdfc9e6cc6b1af3ee2392b5
+Subproject commit d11688a90a1cebacb3fe00dcfbba5f27551b2d89
diff --git a/common/basedir.py b/common/basedir.py
index c840b86f7f..6b4811e53c 100644
--- a/common/basedir.py
+++ b/common/basedir.py
@@ -1,4 +1,4 @@
import os
-BASEDIR = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../"))
\ No newline at end of file
+BASEDIR = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../"))
diff --git a/common/kalman/simple_kalman.py b/common/kalman/simple_kalman.py
index 5e1b6ce1fb..cd3b5a1df9 100644
--- a/common/kalman/simple_kalman.py
+++ b/common/kalman/simple_kalman.py
@@ -9,4 +9,4 @@ def get_kalman_gain(dt, A, C, Q, R, iterations=100):
S = C.dot(P).dot(C.T) + R
K = P.dot(C.T).dot(np.linalg.inv(S))
P = (np.eye(len(P)) - K.dot(C)).dot(P)
- return K
\ No newline at end of file
+ return K
diff --git a/common/prefix.py b/common/prefix.py
index c5ae4393cd..c1744e8ff7 100644
--- a/common/prefix.py
+++ b/common/prefix.py
@@ -21,7 +21,6 @@ class OpenpilotPrefix:
except FileExistsError:
pass
os.makedirs(Paths.log_root(), exist_ok=True)
- os.makedirs(Paths.download_cache_root(), exist_ok=True)
return self
diff --git a/common/time.py b/common/time.py
index b9da106fd0..c8ef9cd383 100644
--- a/common/time.py
+++ b/common/time.py
@@ -3,4 +3,4 @@ import datetime
MIN_DATE = datetime.datetime(year=2023, month=6, day=1)
def system_time_valid():
- return datetime.datetime.now() > MIN_DATE
\ No newline at end of file
+ return datetime.datetime.now() > MIN_DATE
diff --git a/conftest.py b/conftest.py
index d1787c24ef..3c566e3672 100644
--- a/conftest.py
+++ b/conftest.py
@@ -6,6 +6,12 @@ from openpilot.common.prefix import OpenpilotPrefix
from openpilot.system.hardware import TICI
+def pytest_sessionstart(session):
+ # TODO: fix tests and enable test order randomization
+ if session.config.pluginmanager.hasplugin('randomly'):
+ session.config.option.randomly_reorganize = False
+
+
@pytest.fixture(scope="function", autouse=True)
def openpilot_function_fixture():
starting_env = dict(os.environ)
@@ -52,7 +58,7 @@ def pytest_collection_modifyitems(config, items):
@pytest.hookimpl(trylast=True)
def pytest_configure(config):
- config_line = (
- "xdist_group_class_property: group tests by a property of the class that contains them"
- )
- config.addinivalue_line("markers", config_line)
\ No newline at end of file
+ config_line = (
+ "xdist_group_class_property: group tests by a property of the class that contains them"
+ )
+ config.addinivalue_line("markers", config_line)
diff --git a/docs/CARS.md b/docs/CARS.md
index 647b1b15c5..490fb59e13 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.
-# 271 Supported Cars
+# 272 Supported Cars
|Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|
Hardware Needed
|Video|
|---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
@@ -99,7 +99,7 @@ A supported vehicle is one that just works when you install a comma device. All
|Hyundai|Kona Electric (with HDA II, Korea only) 2023[6](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai R 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|Kona Hybrid 2020|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai I 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|Palisade 2020-22|All|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|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|Santa Cruz 2022-23[6](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai N 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|Santa Cruz 2022-23[6](#footnotes)|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai N 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|Santa Fe 2019-20|All|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai D 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|Santa Fe 2021-23|All|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai L 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|Santa Fe Hybrid 2022-23|All|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai L 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 ||
@@ -108,14 +108,14 @@ A supported vehicle is one that just works when you install a comma device. All
|Hyundai|Sonata 2020-23|All|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai A 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|Sonata Hybrid 2020-23|All|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai A 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|Tucson 2021|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|19 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai L 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|Tucson 2022[6](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai N 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|Tucson 2023[6](#footnotes)|All|Stock|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai N 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|Tucson 2022[6](#footnotes)|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai N 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|Tucson 2023[6](#footnotes)|All|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai N 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|Tucson Diesel 2019|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai L 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|Tucson Hybrid 2022-24[6](#footnotes)|All|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai N 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|Veloster 2019-20|Smart Cruise Control (SCC)|Stock|5 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai E 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 ||
|Jeep|Grand Cherokee 2016-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[](##)|[](##)|Parts
- 1 FCA 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 |
|
|Jeep|Grand Cherokee 2019-21|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[](##)|[](##)|Parts
- 1 FCA 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 |
|
-|Kia|Carnival 2023-24[6](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai A 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 ||
+|Kia|Carnival 2022-24[6](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai A 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 ||
|Kia|Carnival (China only) 2023[6](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|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 ||
|Kia|Ceed 2019|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai E 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 ||
|Kia|EV6 (Southeast Asia only) 2022-23[6](#footnotes)|All|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|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 ||
@@ -135,6 +135,7 @@ A supported vehicle is one that just works when you install a comma device. All
|Kia|Niro Hybrid 2023[6](#footnotes)|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai A 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 ||
|Kia|Niro Plug-in Hybrid 2018-19|All|Stock|10 mph|32 mph|[](##)|[](##)|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 ||
|Kia|Niro Plug-in Hybrid 2020|All|Stock|0 mph|32 mph|[](##)|[](##)|Parts
- 1 Hyundai D 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 ||
+|Kia|Niro Plug-in Hybrid 2022|All|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai F 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 ||
|Kia|Optima 2017|Advanced Smart Cruise Control|Stock|0 mph|32 mph|[](##)|[](##)|Parts
- 1 Hyundai B 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 ||
|Kia|Optima 2019-20|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai G 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 ||
|Kia|Optima Hybrid 2019|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|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 ||
@@ -144,7 +145,7 @@ A supported vehicle is one that just works when you install a comma device. All
|Kia|Sorento 2021-23[6](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|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 ||
|Kia|Sorento Hybrid 2021-23[6](#footnotes)|All|Stock|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai A 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 ||
|Kia|Sorento Plug-in Hybrid 2022-23[6](#footnotes)|All|Stock|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai A 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 ||
-|Kia|Sportage 2023[6](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai N 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 ||
+|Kia|Sportage 2023[6](#footnotes)|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai N 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 ||
|Kia|Sportage Hybrid 2023[6](#footnotes)|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai N 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 ||
|Kia|Stinger 2018-20|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|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 |
|
|Kia|Stinger 2022-23|All|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|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 ||
@@ -276,7 +277,7 @@ A supported vehicle is one that just works when you install a comma device. All
|Volkswagen|Teramont 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[](##)|[](##)|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|Teramont Cross Sport 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[](##)|[](##)|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|Teramont X 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[](##)|[](##)|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|Tiguan 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[](##)|[](##)|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|Tiguan 2018-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[](##)|[](##)|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|Tiguan eHybrid 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[](##)|[](##)|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|Touran 2016-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[](##)|[](##)|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 ||
diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md
index 7a074f12de..777788630b 100644
--- a/docs/CONTRIBUTING.md
+++ b/docs/CONTRIBUTING.md
@@ -1,26 +1,46 @@
# How to contribute
-Our software is open source so you can solve your own problems without needing help from others. And if you solve a problem and are so kind, you can upstream it for the rest of the world to use. Check out our [post about externalization](https://blog.comma.ai/a-2020-theme-externalization/).
-
-Most open source development activity is coordinated through our [GitHub Discussions](https://github.com/commaai/openpilot/discussions) and [Discord](https://discord.comma.ai). A lot of documentation is available at https://docs.comma.ai and on our [blog](https://blog.comma.ai/).
+Our software is open source so you can solve your own problems without needing help from others. And if you solve a problem and are so kind, you can upstream it for the rest of the world to use. Check out our [post about externalization](https://blog.comma.ai/a-2020-theme-externalization/). Development activity is coordinated through our GitHub Issues, [GitHub Discussions](https://github.com/commaai/openpilot/discussions), and [Discord](https://discord.comma.ai).
### Getting Started
- * Setup your [development environment](../tools/)
- * Join our [Discord](https://discord.comma.ai)
- * Make sure you have a [GitHub account](https://github.com/signup/free)
- * Fork [our repositories](https://github.com/commaai) on GitHub
+* Setup your [development environment](../tools/)
+* Read about the [development workflow](WORKFLOW.md)
+* Join our [Discord](https://discord.comma.ai)
+* Docs are at https://docs.comma.ai and https://blog.comma.ai
+
+### What contributions are we looking for?
+
+**openpilot's priorities are [safety](SAFETY.md), stability, quality, and features, in that order.** openpilot is part of comma's mission to *solve self-driving cars while delivering shippable intermediaries*, and all developoment is towards that goal.
+
+The probability of a pull request being merged is a function of its value to the project and the effort it will take us to get it merged.
+If a PR offers *some* value but will take lots of time to get merged, it will be closed.
+Simple, well-tested bug fixes are the easiest to merge, and new features are the hardest to get merged.
+
+All of these are examples of good PRs:
+* typo fix: https://github.com/commaai/openpilot/pull/30678
+* removing unused code: https://github.com/commaai/openpilot/pull/30573
+* simple car model port: https://github.com/commaai/openpilot/pull/30245
+* car brand port: https://github.com/commaai/openpilot/pull/23331
+
+### What doesn't get merged?
+
+* arbitrary style changes
+* PRs without a clear goal
+* 500+ line PRs: it should be either cleaned up, broken up into smaller PRs, or both
### First contribution
-Try out some of these first pull requests ideas to dive into the codebase:
-* Increase our [mypy](http://mypy-lang.org/) coverage
-* Write some documentation
-* Tackle an open [good first issue](https://github.com/commaai/openpilot/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
+Check out any [good first issue](https://github.com/commaai/openpilot/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) to get started.
+
+### What do I need to contribute?
+
+A lot of openpilot work requires only a PC, and some requires a comma device.
+Most car-related contributions require access to that car, plus a comma device installed in the car.
## Pull Requests
-Pull requests should be against the master branch. Welcomed contributions include bug reports, car ports, and any [open issue](https://github.com/commaai/openpilot/issues). If you're unsure about a contribution, feel free to open a discussion, issue, or draft PR to discuss the problem you're trying to solve.
+Pull requests should be against the master branch. If you're unsure about a contribution, feel free to open a discussion, issue, or draft PR to discuss the problem you're trying to solve.
A good pull request has all of the following:
* a clearly stated purpose
@@ -37,12 +57,10 @@ We've released a [Model Port guide](https://blog.comma.ai/openpilot-port-guide-f
If you port openpilot to a substantially new car brand, see this more generic [Brand Port guide](https://blog.comma.ai/how-to-write-a-car-port-for-openpilot/).
-## Testing
-
-### Automated Testing
-
-All PRs and commits are automatically checked by GitHub Actions. Check out `.github/workflows/` for what GitHub Actions runs. Any new tests should be added to GitHub Actions.
-
-### Code Style and Linting
+## Contributing without Code
-Code is automatically checked for style by GitHub Actions as part of the automated tests. You can also run these tests yourself by running `pre-commit run --all`.
+* Report bugs in GitHub issues.
+* Report driving issues in the `#driving-feedback` Discord channel.
+* Consider opting into driver camera uploads to improve the driver monitoring model.
+* Connect your device to Wi-Fi regularly, so that we can pull data for training better driving models.
+* Run the `nightly` branch and report issues. This branch is like `master` but it's built just like a release.
diff --git a/docs/WORKFLOW.md b/docs/WORKFLOW.md
new file mode 100644
index 0000000000..85ae8d86f4
--- /dev/null
+++ b/docs/WORKFLOW.md
@@ -0,0 +1,42 @@
+# openpilot development workflow
+
+Aside from the ML models, most tools used for openpilot development are in this repo.
+
+Most development happens on normal Ubuntu workstations, and not in cars or directly on comma devices. See the [setup guide](../tools) for getting your PC setup for openpilot development.
+
+## Quick start
+
+```bash
+# get the latest stuff
+git pull
+git submodule update --init --recursive
+
+# update dependencies
+tools/ubuntu_setup.sh
+
+# build everything
+scons -j$(nproc)
+
+# build just the ui with either of these
+scons -j8 selfdrive/ui/
+cd selfdrive/ui/ && scons -u -j8
+
+# test everything
+pytest .
+
+# test just logging services
+cd system/loggerd && pytest .
+
+# run the linter
+pre-commit run --all
+```
+
+## Testing
+
+### Automated Testing
+
+All PRs and commits are automatically checked by GitHub Actions. Check out `.github/workflows/` for what GitHub Actions runs. Any new tests should be added to GitHub Actions.
+
+### Code Style and Linting
+
+Code is automatically checked for style by GitHub Actions as part of the automated tests. You can also run these tests yourself by running `pre-commit run --all`.
diff --git a/launch_chffrplus.sh b/launch_chffrplus.sh
index a91bd677aa..7578c0296a 100755
--- a/launch_chffrplus.sh
+++ b/launch_chffrplus.sh
@@ -9,6 +9,11 @@ source "$BASEDIR/launch_env.sh"
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
function agnos_init {
+ # wait longer for weston to come up
+ if [ -f "$BASEDIR/prebuilt" ]; then
+ sleep 5
+ fi
+
# TODO: move this to agnos
sudo rm -f /data/etc/NetworkManager/system-connections/*.nmmeta
diff --git a/opendbc b/opendbc
index 5b0c73977f..93b983d49a 160000
--- a/opendbc
+++ b/opendbc
@@ -1 +1 @@
-Subproject commit 5b0c73977f1428700d0344d52874a90a4c5168fb
+Subproject commit 93b983d49a2d6d5c67e15ce7650f55e4f121485d
diff --git a/panda b/panda
index a5753a2077..a88fe8c883 160000
--- a/panda
+++ b/panda
@@ -1 +1 @@
-Subproject commit a5753a2077288b066e441dc2ba2f96d8062e5e49
+Subproject commit a88fe8c883758951ba2854eb2f6726d5365df099
diff --git a/poetry.lock b/poetry.lock
index 1461d5457c..44e07568b3 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand.
[[package]]
name = "aiohttp"
@@ -346,20 +346,6 @@ files = [
docutils = ">=0.12"
Sphinx = ">=4.0,<5.0.0 || >5.0.0"
-[[package]]
-name = "carla"
-version = "0.9.14"
-description = "Python API for communicating with the CARLA server."
-optional = false
-python-versions = "*"
-files = [
- {file = "carla-0.9.14-cp311-cp311-linux_x86_64.whl", hash = "sha256:f0a8ce0c760d1fef3577e2ef90e9d468e3d85e65bd6d68b44bce51f0d5a0723a"},
-]
-
-[package.source]
-type = "url"
-url = "https://github.com/commaai/carla/releases/download/3.11.4/carla-0.9.14-cp311-cp311-linux_x86_64.whl"
-
[[package]]
name = "casadi"
version = "3.6.3"
@@ -2081,16 +2067,6 @@ files = [
{file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"},
{file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"},
{file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"},
{file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"},
{file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"},
{file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"},
@@ -2671,7 +2647,14 @@ files = [
]
[package.dependencies]
-numpy = {version = ">=1.23.5", markers = "python_version >= \"3.11\""}
+numpy = [
+ {version = ">=1.21.2", markers = "python_version >= \"3.10\""},
+ {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\""},
+ {version = ">=1.23.5", markers = "python_version >= \"3.11\""},
+ {version = ">=1.19.3", markers = "python_version >= \"3.6\" and platform_system == \"Linux\" and platform_machine == \"aarch64\" or python_version >= \"3.9\""},
+ {version = ">=1.17.0", markers = "python_version >= \"3.7\""},
+ {version = ">=1.17.3", markers = "python_version >= \"3.8\""},
+]
[[package]]
name = "opencv-python-headless"
@@ -2690,7 +2673,14 @@ files = [
]
[package.dependencies]
-numpy = {version = ">=1.23.5", markers = "python_version >= \"3.11\""}
+numpy = [
+ {version = ">=1.21.2", markers = "python_version >= \"3.10\""},
+ {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\""},
+ {version = ">=1.23.5", markers = "python_version >= \"3.11\""},
+ {version = ">=1.19.3", markers = "python_version >= \"3.6\" and platform_system == \"Linux\" and platform_machine == \"aarch64\" or python_version >= \"3.9\""},
+ {version = ">=1.17.0", markers = "python_version >= \"3.7\""},
+ {version = ">=1.17.3", markers = "python_version >= \"3.8\""},
+]
[[package]]
name = "packaging"
@@ -3309,8 +3299,6 @@ files = [
{file = "pygame-2.5.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e24d05184e4195fe5ebcdce8b18ecb086f00182b9ae460a86682d312ce8d31f"},
{file = "pygame-2.5.2-cp311-cp311-win32.whl", hash = "sha256:f02c1c7505af18d426d355ac9872bd5c916b27f7b0fe224749930662bea47a50"},
{file = "pygame-2.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:6d58c8cf937815d3b7cdc0fa9590c5129cb2c9658b72d00e8a4568dea2ff1d42"},
- {file = "pygame-2.5.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1a2a43802bb5e89ce2b3b775744e78db4f9a201bf8d059b946c61722840ceea8"},
- {file = "pygame-2.5.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1c289f2613c44fe70a1e40769de4a49c5ab5a29b9376f1692bb1a15c9c1c9bfa"},
{file = "pygame-2.5.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:074aa6c6e110c925f7f27f00c7733c6303407edc61d738882985091d1eb2ef17"},
{file = "pygame-2.5.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe0228501ec616779a0b9c4299e837877783e18df294dd690b9ab0eed3d8aaab"},
{file = "pygame-2.5.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31648d38ecdc2335ffc0e38fb18a84b3339730521505dac68514f83a1092e3f4"},
@@ -3719,18 +3707,18 @@ colorama = "*"
pytest = ">=7.0"
[[package]]
-name = "pytest-random-order"
-version = "1.1.0"
-description = "Randomise the order in which pytest tests are run with some control over the randomness"
+name = "pytest-randomly"
+version = "3.15.0"
+description = "Pytest plugin to randomly order tests and control random.seed."
optional = false
-python-versions = ">=3.5.0"
+python-versions = ">=3.8"
files = [
- {file = "pytest-random-order-1.1.0.tar.gz", hash = "sha256:dbe6debb9353a7af984cc9eddbeb3577dd4dbbcc1529a79e3d21f68ed9b45605"},
- {file = "pytest_random_order-1.1.0-py3-none-any.whl", hash = "sha256:6cb1e59ab0f798bb0c3488c11ae0c70d7d3340306a466d28b28ccd8ef8c20b7e"},
+ {file = "pytest_randomly-3.15.0-py3-none-any.whl", hash = "sha256:0516f4344b29f4e9cdae8bce31c4aeebf59d0b9ef05927c33354ff3859eeeca6"},
+ {file = "pytest_randomly-3.15.0.tar.gz", hash = "sha256:b908529648667ba5e54723088edd6f82252f540cc340d748d1fa985539687047"},
]
[package.dependencies]
-pytest = ">=3.0.0"
+pytest = "*"
[[package]]
name = "pytest-subtests"
@@ -3871,7 +3859,6 @@ files = [
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"},
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"},
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"},
- {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"},
{file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"},
{file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"},
{file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"},
@@ -3879,15 +3866,8 @@ files = [
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"},
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"},
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"},
- {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"},
{file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"},
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
- {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
- {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
- {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
- {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
- {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
- {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"},
{file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"},
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"},
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"},
@@ -3904,7 +3884,6 @@ files = [
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"},
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"},
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"},
- {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"},
{file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"},
{file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"},
{file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"},
@@ -3912,7 +3891,6 @@ files = [
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"},
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"},
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"},
- {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"},
{file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"},
{file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"},
{file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
@@ -5011,4 +4989,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p
[metadata]
lock-version = "2.0"
python-versions = "~3.11"
-content-hash = "f0abc0f53443c3b98eb06fc4dd0ff736e39197bc68c79db9aeffb4736657b676"
+content-hash = "08910461234279f3339c1692bd0cc2732f6e17f61ca9e3ffa53d461526e3dce4"
diff --git a/pyproject.toml b/pyproject.toml
index ffbd5d43b7..58c506e378 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -151,7 +151,7 @@ pytest-subtests = "*"
pytest-xdist = "*"
pytest-timeout = "*"
pytest-timeouts = "*"
-pytest-random-order = "*"
+pytest-randomly = "*"
ruff = "*"
scipy = "*"
sphinx = "*"
@@ -168,12 +168,6 @@ types-tabulate = "*"
# this is only pinned since 5.15.11 is broken
pyqt5 = { version = "==5.15.2", markers = "platform_machine == 'x86_64'" } # no aarch64 wheels for macOS/linux
-[tool.poetry.group.carla]
-optional = true
-
-[tool.poetry.group.carla.dependencies]
-carla = { url = "https://github.com/commaai/carla/releases/download/3.11.4/carla-0.9.14-cp311-cp311-linux_x86_64.whl", platform = "linux", markers = "platform_machine == 'x86_64'" }
-
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
@@ -181,7 +175,7 @@ build-backend = "poetry.core.masonry.api"
# https://beta.ruff.rs/docs/configuration/#using-pyprojecttoml
[tool.ruff]
select = ["E", "F", "W", "PIE", "C4", "ISC", "RUF008", "RUF100", "A", "B", "TID251"]
-ignore = ["W292", "E741", "E402", "C408", "ISC003", "B027", "B024"]
+ignore = ["E741", "E402", "C408", "ISC003", "B027", "B024"]
line-length = 160
target-version="py311"
exclude = [
@@ -202,4 +196,4 @@ flake8-implicit-str-concat.allow-multiline=false
"tools".msg = "Use openpilot.tools"
[tool.coverage.run]
-concurrency = ["multiprocessing", "thread"]
\ No newline at end of file
+concurrency = ["multiprocessing", "thread"]
diff --git a/release/files_common b/release/files_common
index 637f8bd7d7..10bfe4e1f1 100644
--- a/release/files_common
+++ b/release/files_common
@@ -285,7 +285,6 @@ selfdrive/ui/.gitignore
selfdrive/ui/SConscript
selfdrive/ui/*.cc
selfdrive/ui/*.h
-selfdrive/ui/ui
selfdrive/ui/text
selfdrive/ui/spinner
selfdrive/ui/soundd.py
diff --git a/scripts/apply-pr.sh b/scripts/apply-pr.sh
index 65805b8485..74f765391a 100755
--- a/scripts/apply-pr.sh
+++ b/scripts/apply-pr.sh
@@ -8,4 +8,4 @@ fi
BASE="https://github.com/commaai/openpilot/pull/"
PR_NUM="$(echo $1 | grep -o -E '[0-9]+')"
-curl -L $BASE/$PR_NUM.patch | git apply
+curl -L $BASE/$PR_NUM.patch | git apply -3
diff --git a/scripts/build_small.sh b/scripts/build_small.sh
new file mode 100755
index 0000000000..d53c7a6c78
--- /dev/null
+++ b/scripts/build_small.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+set -ex
+
+DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
+cd $DIR
+
+# git clone --mirror
+SRC=/tmp/openpilot.git/
+OUT=/tmp/smallpilot/
+
+echo "starting size $(du -hs .git/)"
+
+rm -rf $OUT
+
+cd $SRC
+git remote update
+
+# copy contents
+#rsync -a --exclude='.git/' $DIR $OUT
+
+cp -r $SRC $OUT
+
+cd $OUT
+
+# remove all tags
+git tag -l | xargs git tag -d
+
+# remove non-master branches
+BRANCHES="release2 dashcam dashcam3 release3 devel master-ci nightly"
+for branch in $BRANCHES; do
+ git branch -D $branch
+ git branch -D ${branch}-staging || true
+done
+
+#git gc
+git reflog expire --expire=now --all
+git gc --prune=now
+git gc --aggressive --prune=now
+echo "new one is $(du -hs .)"
diff --git a/selfdrive/boardd/boardd.cc b/selfdrive/boardd/boardd.cc
index 0ec33c1a27..61e2424744 100644
--- a/selfdrive/boardd/boardd.cc
+++ b/selfdrive/boardd/boardd.cc
@@ -1,11 +1,5 @@
#include "selfdrive/boardd/boardd.h"
-#include
-#include
-#include
-#include
-#include
-
#include
#include
#include
@@ -13,10 +7,6 @@
#include
#include
#include
-#include
-#include
-#include
-#include
#include
#include
#include
diff --git a/selfdrive/boardd/tests/test_pandad.py b/selfdrive/boardd/tests/test_pandad.py
index 4036766faa..21cc0b5f37 100755
--- a/selfdrive/boardd/tests/test_pandad.py
+++ b/selfdrive/boardd/tests/test_pandad.py
@@ -116,4 +116,4 @@ class TestPandad(unittest.TestCase):
if __name__ == "__main__":
- unittest.main()
\ No newline at end of file
+ unittest.main()
diff --git a/selfdrive/car/README.MD b/selfdrive/car/README.MD
index de4db0ee50..2dcbf56059 100644
--- a/selfdrive/car/README.MD
+++ b/selfdrive/car/README.MD
@@ -1,11 +1,77 @@
-## Port structure
-##### interface.py
+# selfdrive/car
+
+### Check out this blogpost for a high level overview of car ports
+https://blog.comma.ai/how-to-write-a-car-port-for-openpilot/
+
+## Useful car porting utilities
+
+Testing car ports in your car is very time consuming! Checkout these utilities to do basic checks on your work before running it in your car.
+
+### [Cabana](/tools/cabana/README.md)
+
+View your car's CAN signals through DBC files, which openpilot uses to parse and create messages that talk to the car.
+
+Example:
+```bash
+> tools/cabana/cabana '1bbe6bf2d62f58a8|2022-07-14--17-11-43'
+```
+
+### [selfdrive/debug/auto_fingerprint.py](/selfdrive/debug/auto_fingerprint.py)
+
+Given a route and platform, automatically inserts FW fingerprints from the platform into the correct place in values.py
+
+Example:
+```bash
+> python selfdrive/debug/auto_fingerprint.py '1bbe6bf2d62f58a8|2022-07-14--17-11-43' 'SUBARU OUTBACK 6TH GEN'
+Attempting to add fw version for: SUBARU OUTBACK 6TH GEN
+```
+
+### [selfdrive/car/tests/test_car_interfaces.py](/selfdrive/car/tests/test_car_interfaces.py)
+
+Finds common bugs for car interfaces, without even requiring a route!
+
+
+#### Example: Typo in signal name
+```bash
+> pytest selfdrive/car/tests/test_car_interfaces.py -k subaru # (replace with the brand you are working on!)
+
+=====================================================================
+FAILED selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_165_SUBARU_LEGACY_7TH_GEN - KeyError: 'CruiseControlOOPS'
+
+```
+
+### [selfdrive/debug/test_car_model.py](/selfdrive/debug/test_car_model.py)
+
+Given a route, runs most of the car interface to check for common errors like missing signals, blocked panda messages, and mismatches.
+
+#### Example: Panda safety mismatch for gasPressed
+```bash
+> python selfdrive/debug/test_car_model.py '4822a427b188122a|2023-08-14--16-22-21'
+
+=====================================================================
+FAIL: test_panda_safety_carstate (__main__.CarModelTestCase.test_panda_safety_carstate)
+Assert that panda safety matches openpilot's carState
+----------------------------------------------------------------------
+Traceback (most recent call last):
+ File "/home/batman/xx/openpilot/openpilot/selfdrive/car/tests/test_models.py", line 380, in test_panda_safety_carstate
+ self.assertFalse(len(failed_checks), f"panda safety doesn't agree with openpilot: {failed_checks}")
+AssertionError: 1 is not false : panda safety doesn't agree with openpilot: {'gasPressed': 116}
+```
+
+
+## Car Port structure
+
+### interface.py
Generic interface to send and receive messages from CAN (controlsd uses this to communicate with car)
-##### carcontroller.py
+
+### carcontroller.py
Builds CAN messages to send to car
+
##### carstate.py
Reads CAN from car and builds openpilot CarState message
+
##### values.py
-Fingerprints and absolute limits
+Fingerprints, limits for actuation, car doc information, etc
+
##### radar_interface.py
-Radar interface
+Interface for parsing radar points from the car
diff --git a/selfdrive/car/ford/values.py b/selfdrive/car/ford/values.py
index 301847b7ea..68f276d4b5 100644
--- a/selfdrive/car/ford/values.py
+++ b/selfdrive/car/ford/values.py
@@ -1,12 +1,12 @@
from collections import defaultdict
-from dataclasses import dataclass, field
+from dataclasses import dataclass
from enum import Enum, StrEnum
from typing import Dict, List, Union
from cereal import car
from openpilot.selfdrive.car import AngleRateLimit, dbc_dict
from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarInfo, CarParts, Column, \
- Device
+ Device
from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries
Ecu = car.CarParams.Ecu
@@ -74,11 +74,13 @@ class Footnote(Enum):
@dataclass
class FordCarInfo(CarInfo):
package: str = "Co-Pilot360 Assist+"
- car_parts: CarParts = field(default_factory=CarParts.common([CarHarness.ford_q3]))
def init_make(self, CP: car.CarParams):
- if CP.carFingerprint in (CAR.BRONCO_SPORT_MK1, CAR.MAVERICK_MK1):
- self.car_parts = CarParts([Device.threex_angled_mount, CarHarness.ford_q3])
+ harness = CarHarness.ford_q4 if CP.carFingerprint in CANFD_CAR else CarHarness.ford_q3
+ if CP.carFingerprint in (CAR.BRONCO_SPORT_MK1, CAR.MAVERICK_MK1, CAR.F_150_MK14):
+ self.car_parts = CarParts([Device.threex_angled_mount, harness])
+ else:
+ self.car_parts = CarParts([Device.threex, harness])
CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = {
diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py
index 26b3491358..d04743502c 100644
--- a/selfdrive/car/hyundai/interface.py
+++ b/selfdrive/car/hyundai/interface.py
@@ -156,7 +156,7 @@ class CarInterface(CarInterfaceBase):
ret.mass = 1985.
ret.wheelbase = 2.78
ret.steerRatio = 14.4 * 1.1 # 10% higher at the center seems reasonable
- elif candidate in (CAR.KIA_NIRO_EV, CAR.KIA_NIRO_EV_2ND_GEN, CAR.KIA_NIRO_PHEV, CAR.KIA_NIRO_HEV_2021, CAR.KIA_NIRO_HEV_2ND_GEN):
+ elif candidate in (CAR.KIA_NIRO_EV, CAR.KIA_NIRO_EV_2ND_GEN, CAR.KIA_NIRO_PHEV, CAR.KIA_NIRO_HEV_2021, CAR.KIA_NIRO_HEV_2ND_GEN, CAR.KIA_NIRO_PHEV_2022):
ret.mass = 3543. * CV.LB_TO_KG # average of all the cars
ret.wheelbase = 2.7
ret.steerRatio = 13.6 # average of all the cars
@@ -260,8 +260,7 @@ class CarInterface(CarInterfaceBase):
if candidate in CANFD_CAR:
ret.longitudinalTuning.kpV = [0.1]
ret.longitudinalTuning.kiV = [0.0]
- ret.experimentalLongitudinalAvailable = (candidate in (HYBRID_CAR | EV_CAR) and candidate not in
- (CANFD_UNSUPPORTED_LONGITUDINAL_CAR | CANFD_RADAR_SCC_CAR))
+ ret.experimentalLongitudinalAvailable = candidate not in (CANFD_UNSUPPORTED_LONGITUDINAL_CAR | CANFD_RADAR_SCC_CAR)
else:
ret.longitudinalTuning.kpV = [0.5]
ret.longitudinalTuning.kiV = [0.0]
diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py
index 7c6fa7cb4f..840f6d7a42 100644
--- a/selfdrive/car/hyundai/values.py
+++ b/selfdrive/car/hyundai/values.py
@@ -112,6 +112,7 @@ class CAR(StrEnum):
KIA_NIRO_EV = "KIA NIRO EV 2020"
KIA_NIRO_EV_2ND_GEN = "KIA NIRO EV 2ND GEN"
KIA_NIRO_PHEV = "KIA NIRO HYBRID 2019"
+ KIA_NIRO_PHEV_2022 = "KIA NIRO PLUG-IN HYBRID 2022"
KIA_NIRO_HEV_2021 = "KIA NIRO HYBRID 2021"
KIA_NIRO_HEV_2ND_GEN = "KIA NIRO HYBRID 2ND GEN"
KIA_OPTIMA_G4 = "KIA OPTIMA 4TH GEN"
@@ -248,6 +249,7 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = {
HyundaiCarInfo("Kia Niro Plug-in Hybrid 2018-19", "All", min_enable_speed=10. * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_c])),
HyundaiCarInfo("Kia Niro Plug-in Hybrid 2020", "All", car_parts=CarParts.common([CarHarness.hyundai_d])),
],
+ CAR.KIA_NIRO_PHEV_2022: HyundaiCarInfo("Kia Niro Plug-in Hybrid 2022", "All", car_parts=CarParts.common([CarHarness.hyundai_f])),
CAR.KIA_NIRO_HEV_2021: [
HyundaiCarInfo("Kia Niro Hybrid 2021-22", car_parts=CarParts.common([CarHarness.hyundai_f])), # TODO: 2021 could be hyundai_d, verify
],
@@ -279,7 +281,7 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = {
HyundaiCarInfo("Kia EV6 (with HDA II) 2022-23", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_p]))
],
CAR.KIA_CARNIVAL_4TH_GEN: [
- HyundaiCarInfo("Kia Carnival 2023-24", car_parts=CarParts.common([CarHarness.hyundai_a])),
+ HyundaiCarInfo("Kia Carnival 2022-24", car_parts=CarParts.common([CarHarness.hyundai_a])),
HyundaiCarInfo("Kia Carnival (China only) 2023", car_parts=CarParts.common([CarHarness.hyundai_k]))
],
@@ -1140,6 +1142,7 @@ FW_VERSIONS = {
b'\xf1\x00CK__ SCC F-CUP 1.00 1.00 99110-J5500 ',
b'\xf1\x00CK__ SCC FHCUP 1.00 1.00 99110-J5500 ',
b'\xf1\x00CK__ SCC FHCUP 1.00 1.00 99110-J5600 ',
+ b'\xf1\x00CK__ SCC FHCUP 1.00 1.01 99110-J5100 ',
],
(Ecu.engine, 0x7e0, None): [
b'\xf1\x81640R0051\x00\x00\x00\x00\x00\x00\x00\x00',
@@ -1149,17 +1152,20 @@ FW_VERSIONS = {
(Ecu.eps, 0x7d4, None): [
b'\xf1\x00CK MDPS R 1.00 5.03 57700-J5380 4C2VR503',
b'\xf1\x00CK MDPS R 1.00 5.03 57700-J5300 4C2CL503',
+ b'\xf1\x00CK MDPS R 1.00 5.03 57700-J5320 4C2VL503',
b'\xf1\x00CK MDPS R 1.00 5.04 57700-J5520 4C4VL504',
],
(Ecu.fwdCamera, 0x7c4, None): [
b'\xf1\x00CK MFC AT AUS RHD 1.00 1.00 99211-J5500 210622',
b'\xf1\x00CK MFC AT KOR LHD 1.00 1.00 99211-J5500 210622',
b'\xf1\x00CK MFC AT USA LHD 1.00 1.00 99211-J5500 210622',
+ b'\xf1\x00CK MFC AT USA LHD 1.00 1.03 99211-J5000 201209',
],
(Ecu.transmission, 0x7e1, None): [
b'\xf1\x87VCNLF11383972DK1vffV\x99\x99\x89\x98\x86eUU\x88wg\x89vfff\x97fff\x99\x87o\xff"\xc1\xf1\x81E30\x00\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 E30\x00\x00\x00\x00\x00\x00\x00SCK0T33GH0\xbe`\xfb\xc6',
b'\xf1\x00bcsh8p54 E31\x00\x00\x00\x00\x00\x00\x00SCK0T33NH07\xdf\xf0\xc1',
b'\xf1\x00bcsh8p54 E31\x00\x00\x00\x00\x00\x00\x00SCK0T25KH2B\xfbI\xe2',
+ b'\xf1\x00bcsh8p54 E31\x00\x00\x00\x00\x00\x00\x00TCK0T33NH0%g~\xd3',
],
},
CAR.PALISADE: {
@@ -1619,6 +1625,23 @@ FW_VERSIONS = {
b'\xf1\x00DEhe SCC F-CUP 1.00 1.02 99110-G5100 ',
],
},
+ CAR.KIA_NIRO_PHEV_2022: {
+ (Ecu.engine, 0x7e0, None): [
+ b'\xf1\x816H6G6051\x00\x00\x00\x00\x00\x00\x00\x00',
+ ],
+ (Ecu.transmission, 0x7e1, None): [
+ b'\xf1\x006U3H1_C2\x00\x006U3J9051\x00\x00PDE0G16NL3\x00\x00\x00\x00',
+ ],
+ (Ecu.eps, 0x7D4, None): [
+ b'\xf1\x00DE MDPS C 1.00 1.01 56310G5520\x00 4DEPC101',
+ ],
+ (Ecu.fwdCamera, 0x7C4, None): [
+ b'\xf1\x00DEP MFC AT USA LHD 1.00 1.00 99211-G5500 210428',
+ ],
+ (Ecu.fwdRadar, 0x7D0, None): [
+ b'\xf1\x00DEhe SCC F-CUP 1.00 1.00 99110-G5600 ',
+ ],
+ },
CAR.KIA_NIRO_HEV_2021: {
(Ecu.engine, 0x7e0, None): [
b'\xf1\x816H6G5051\x00\x00\x00\x00\x00\x00\x00\x00',
@@ -2078,6 +2101,7 @@ FW_VERSIONS = {
b'\xf1\x00KA4CMFC AT CHN LHD 1.00 1.01 99211-I4000 210525',
b'\xf1\x00KA4 MFC AT USA LHD 1.00 1.00 99210-R0100 230105',
b'\xf1\x00KA4 MFC AT KOR LHD 1.00 1.06 99210-R0000 220221',
+ b'\xf1\x00KA4 MFC AT USA LHD 1.00 1.05 99210-R0000 201221',
],
(Ecu.fwdRadar, 0x7d0, None): [
b'\xf1\x00KA4_ SCC FHCUP 1.00 1.03 99110-R0000 ',
@@ -2140,7 +2164,7 @@ HYBRID_CAR = {CAR.IONIQ_PHEV, CAR.ELANTRA_HEV_2021, CAR.KIA_NIRO_PHEV, CAR.KIA_N
CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.IONIQ_PHEV_2019, CAR.TUCSON_HYBRID_4TH_GEN,
CAR.KIA_SPORTAGE_HYBRID_5TH_GEN, CAR.KIA_SORENTO_PHEV_4TH_GEN, CAR.KIA_K5_HEV_2020, CAR.KIA_NIRO_HEV_2ND_GEN,
CAR.KIA_SORENTO_HEV_4TH_GEN, CAR.KIA_OPTIMA_H, CAR.KIA_OPTIMA_H_G4_FL, CAR.KIA_K8_HEV_1ST_GEN,
- CAR.AZERA_HEV_6TH_GEN}
+ CAR.AZERA_HEV_6TH_GEN, CAR.KIA_NIRO_PHEV_2022}
EV_CAR = {CAR.IONIQ_EV_2020, CAR.IONIQ_EV_LTD, CAR.KONA_EV, CAR.KIA_NIRO_EV, CAR.KIA_NIRO_EV_2ND_GEN, CAR.KONA_EV_2022,
CAR.KIA_EV6, CAR.IONIQ_5, CAR.IONIQ_6, CAR.GENESIS_GV60_EV_1ST_GEN, CAR.KONA_EV_2ND_GEN}
@@ -2223,4 +2247,5 @@ DBC = {
CAR.KONA_EV_2ND_GEN: dbc_dict('hyundai_canfd', None),
CAR.KIA_K8_HEV_1ST_GEN: dbc_dict('hyundai_canfd', None),
CAR.CUSTIN_1ST_GEN: dbc_dict('hyundai_kia_generic', None),
+ CAR.KIA_NIRO_PHEV_2022: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar_generated'),
}
diff --git a/selfdrive/car/mazda/values.py b/selfdrive/car/mazda/values.py
index 1547f69b04..4dc5726f34 100644
--- a/selfdrive/car/mazda/values.py
+++ b/selfdrive/car/mazda/values.py
@@ -132,6 +132,7 @@ FW_VERSIONS = {
b'PYFC-188K2-J\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'PYFD-188K2-J\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'PYNF-188K2-F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
+ b'PX2E-188K2-F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'PX2F-188K2-C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'PX2G-188K2-D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'PX2H-188K2-B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py
index 9802524886..66dafc1312 100755
--- a/selfdrive/car/tests/routes.py
+++ b/selfdrive/car/tests/routes.py
@@ -153,10 +153,12 @@ routes = [
CarTestRoute("50c6c9b85fd1ff03|2020-10-26--17-56-06", HYUNDAI.KIA_NIRO_EV),
CarTestRoute("b153671049a867b3|2023-04-05--10-00-30", HYUNDAI.KIA_NIRO_EV_2ND_GEN),
CarTestRoute("173219cf50acdd7b|2021-07-05--10-27-41", HYUNDAI.KIA_NIRO_PHEV),
+ CarTestRoute("23349923ba5c4e3b|2023-12-02--08-51-54", HYUNDAI.KIA_NIRO_PHEV_2022),
CarTestRoute("34a875f29f69841a|2021-07-29--13-02-09", HYUNDAI.KIA_NIRO_HEV_2021),
CarTestRoute("db04d2c63990e3ba|2023-02-08--16-52-39", HYUNDAI.KIA_NIRO_HEV_2ND_GEN),
CarTestRoute("50a2212c41f65c7b|2021-05-24--16-22-06", HYUNDAI.KIA_FORTE),
CarTestRoute("192283cdbb7a58c2|2022-10-15--01-43-18", HYUNDAI.KIA_SPORTAGE_5TH_GEN),
+ CarTestRoute("09559f1fcaed4704|2023-11-16--02-24-57", HYUNDAI.KIA_SPORTAGE_5TH_GEN), # openpilot longitudinal
CarTestRoute("c5ac319aa9583f83|2021-06-01--18-18-31", HYUNDAI.ELANTRA),
CarTestRoute("734ef96182ddf940|2022-10-02--16-41-44", HYUNDAI.ELANTRA_GT_I30),
CarTestRoute("82e9cdd3f43bf83e|2021-05-15--02-42-51", HYUNDAI.ELANTRA_2021),
diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py
index 8229cf239b..e602ad47b3 100755
--- a/selfdrive/car/tests/test_models.py
+++ b/selfdrive/car/tests/test_models.py
@@ -55,12 +55,10 @@ def get_test_cases() -> List[Tuple[str, Optional[CarTestRoute]]]:
with open(os.path.join(BASEDIR, INTERNAL_SEG_LIST), "r") as f:
seg_list = f.read().splitlines()
- cnt = INTERNAL_SEG_CNT or len(seg_list)
- seg_list_iter = iter(seg_list[:cnt])
-
- for platform in seg_list_iter:
- platform = platform[2:] # get rid of comment
- segment_name = SegmentName(next(seg_list_iter))
+ seg_list_grouped = [(platform[2:], segment) for platform, segment in zip(seg_list[::2], seg_list[1::2], strict=True)]
+ seg_list_grouped = random.sample(seg_list_grouped, INTERNAL_SEG_CNT or len(seg_list_grouped))
+ for platform, segment in seg_list_grouped:
+ segment_name = SegmentName(segment)
test_cases.append((platform, CarTestRoute(segment_name.route_name.canonical_name, platform,
segment=segment_name.segment_num)))
return test_cases
diff --git a/selfdrive/car/torque_data/substitute.yaml b/selfdrive/car/torque_data/substitute.yaml
index c7a1566b32..242a38b3d0 100644
--- a/selfdrive/car/torque_data/substitute.yaml
+++ b/selfdrive/car/torque_data/substitute.yaml
@@ -20,6 +20,7 @@ KIA FORTE E 2018 & GT 2021: HYUNDAI SONATA 2020
KIA CEED INTRO ED 2019: HYUNDAI SONATA 2020
KIA SELTOS 2021: HYUNDAI SONATA 2020
KIA NIRO HYBRID 2019: KIA NIRO EV 2020
+KIA NIRO PLUG-IN HYBRID 2022: KIA NIRO EV 2020
KIA NIRO HYBRID 2021: KIA NIRO EV 2020
HYUNDAI VELOSTER 2019: HYUNDAI SONATA 2019
HYUNDAI KONA 2020: HYUNDAI KONA ELECTRIC 2019
diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py
index c8e6daaef8..c47dd2d161 100644
--- a/selfdrive/car/volkswagen/values.py
+++ b/selfdrive/car/volkswagen/values.py
@@ -239,7 +239,7 @@ CAR_INFO: Dict[str, Union[VWCarInfo, List[VWCarInfo]]] = {
CAR.TAOS_MK1: VWCarInfo("Volkswagen Taos 2022-23"),
CAR.TCROSS_MK1: VWCarInfo("Volkswagen T-Cross 2021", footnotes=[Footnote.VW_MQB_A0]),
CAR.TIGUAN_MK2: [
- VWCarInfo("Volkswagen Tiguan 2018-23"),
+ VWCarInfo("Volkswagen Tiguan 2018-24"),
VWCarInfo("Volkswagen Tiguan eHybrid 2021-23"),
],
CAR.TOURAN_MK2: VWCarInfo("Volkswagen Touran 2016-23"),
@@ -667,6 +667,7 @@ FW_VERSIONS = {
b'\xf1\x8704L906026GA\xf1\x892013',
b'\xf1\x8704L906026KD\xf1\x894798',
b'\xf1\x873G0906259B \xf1\x890002',
+ b'\xf1\x873G0906259 \xf1\x890004',
b'\xf1\x873G0906264 \xf1\x890004',
],
(Ecu.transmission, 0x7e1, None): [
@@ -682,6 +683,7 @@ FW_VERSIONS = {
b'\xf1\x870CW300042H \xf1\x891607',
b'\xf1\x870GC300042H \xf1\x891404',
b'\xf1\x870D9300018C \xf1\x895297',
+ b'\xf1\x870D9300042H \xf1\x894901',
b'\xf1\x870GC300043 \xf1\x892301',
],
(Ecu.srs, 0x715, None): [
@@ -696,6 +698,7 @@ FW_VERSIONS = {
b'\xf1\x873Q0959655BK\xf1\x890703\xf1\x82\0165915005914001344701311442900',
b'\xf1\x873Q0959655BK\xf1\x890703\xf1\x82\x0e5915005914001354701311542900',
b'\xf1\x873Q0959655CN\xf1\x890720\xf1\x82\x0e5915005914001305701311052900',
+ b'\xf1\x873Q0959655BA\xf1\x890195\xf1\x82\r56140056130012416612124111',
b'\xf1\x875Q0959655S \xf1\x890870\xf1\x82\02315120011111200631145171716121691132111',
],
(Ecu.eps, 0x712, None): [
@@ -709,6 +712,7 @@ FW_VERSIONS = {
b'\xf1\x875Q0909144S \xf1\x891063\xf1\x82\00516B00501A1',
b'\xf1\x875Q0909144T \xf1\x891072\xf1\x82\00521B00703A1',
b'\xf1\x875Q0910143B \xf1\x892201\xf1\x82\x0563B0000600',
+ b'\xf1\x875Q0909144T \xf1\x891072\xf1\x82\x0521B00603A1',
b'\xf1\x875Q0910143C \xf1\x892211\xf1\x82\x0567B0020600',
],
(Ecu.fwdRadar, 0x757, None): [
@@ -718,6 +722,7 @@ FW_VERSIONS = {
b'\xf1\x873Q0907572C \xf1\x890195',
b'\xf1\x873Q0907572C \xf1\x890196',
b'\xf1\x875Q0907572P \xf1\x890682',
+ b'\xf1\x873Q0907572B \xf1\x890194',
b'\xf1\x875Q0907572R \xf1\x890771',
],
},
@@ -843,6 +848,7 @@ FW_VERSIONS = {
b'\xf1\x8783A907115K \xf1\x890002',
b'\xf1\x8704E906024AP\xf1\x891461',
b'\xf1\x8783A907115 \xf1\x890007',
+ b'\xf1\x8783A907115Q \xf1\x890001',
],
(Ecu.transmission, 0x7e1, None): [
b'\xf1\x8709G927158DT\xf1\x893698',
@@ -851,6 +857,7 @@ FW_VERSIONS = {
b'\xf1\x8709G927158GD\xf1\x893820',
b'\xf1\x8709G927158GM\xf1\x893936',
b'\xf1\x8709G927158GN\xf1\x893938',
+ b'\xf1\x8709G927158HB\xf1\x894069',
b'\xf1\x870D9300043 \xf1\x895202',
b'\xf1\x870DL300011N \xf1\x892001',
b'\xf1\x870DL300011N \xf1\x892012',
@@ -1265,6 +1272,7 @@ FW_VERSIONS = {
b'\xf1\x875NA907115E \xf1\x890003',
b'\xf1\x875NA907115E \xf1\x890005',
b'\xf1\x875NA906259E \xf1\x890003',
+ b'\xf1\x8704E906027LD\xf1\x893433',
],
(Ecu.transmission, 0x7e1, None): [
b'\xf1\x870D9300043 \xf1\x895202',
@@ -1275,6 +1283,7 @@ FW_VERSIONS = {
b'\xf1\x870GC300014N \xf1\x892801',
b'\xf1\x870GC300019H \xf1\x892806',
b'\xf1\x870GC300046Q \xf1\x892802',
+ b'\xf1\x870D9300014S \xf1\x895201',
],
(Ecu.srs, 0x715, None): [
b'\xf1\x873Q0959655AP\xf1\x890306\xf1\x82\r11110011110011421111314211',
@@ -1284,6 +1293,7 @@ FW_VERSIONS = {
b'\xf1\x873Q0959655CQ\xf1\x890720\xf1\x82\x0e1213111211001205212112052111',
b'\xf1\x873Q0959655DJ\xf1\x890731\xf1\x82\x0e1513001511001205232113052J00',
b'\xf1\x875QF959655AT\xf1\x890755\xf1\x82\x1311110011110011111100010200--1121240749',
+ b'\xf1\x873Q0959655BH\xf1\x890703\xf1\x82\x0e1213001211001205212111052100',
],
(Ecu.eps, 0x712, None): [
b'\xf1\x875Q0909143P \xf1\x892051\xf1\x820527T6050405',
@@ -1299,6 +1309,7 @@ FW_VERSIONS = {
b'\xf1\x872Q0907572T \xf1\x890383',
b'\xf1\x872Q0907572AA\xf1\x890396',
b'\xf1\x872Q0907572AB\xf1\x890397',
+ b'\xf1\x872Q0907572M \xf1\x890233',
],
},
CAR.SKODA_OCTAVIA_MK3: {
@@ -1383,6 +1394,7 @@ FW_VERSIONS = {
b'\xf1\x8704L906026KB\xf1\x894071',
b'\xf1\x8704L906026KD\xf1\x894798',
b'\xf1\x8704L906026MT\xf1\x893076',
+ b'\xf1\x8705L906022BK\xf1\x899971',
b'\xf1\x873G0906259 \xf1\x890004',
b'\xf1\x873G0906259B \xf1\x890002',
b'\xf1\x873G0906259L \xf1\x890003',
@@ -1403,6 +1415,7 @@ FW_VERSIONS = {
b'\xf1\x870GC300014M \xf1\x892801',
b'\xf1\x870GC300019G \xf1\x892803',
b'\xf1\x870GC300043 \xf1\x892301',
+ b'\xf1\x870GC300046D \xf1\x892402',
],
(Ecu.srs, 0x715, None): [
b'\xf1\x875Q0959655AE\xf1\x890130\xf1\x82\x12111200111121001121110012211292221111',
@@ -1412,6 +1425,7 @@ FW_VERSIONS = {
b'\xf1\x875Q0959655AT\xf1\x890317\xf1\x82\x1331310031313100313131013131319331313100',
b'\xf1\x875Q0959655BH\xf1\x890336\xf1\x82\02331310031313100313131013141319331413100',
b'\xf1\x875Q0959655BK\xf1\x890336\xf1\x82\x1331310031313100313131013141319331413100',
+ b'\xf1\x875Q0959655BS\xf1\x890403\xf1\x82\x1333310031313100313152015351539331423100',
b'\xf1\x875Q0959655CA\xf1\x890403\xf1\x82\x1331310031313100313151013141319331423100',
b'\xf1\x875Q0959655CA\xf1\x890403\xf1\x82\x1331310031313100313151823143319331423100',
b'\xf1\x875Q0959655CH\xf1\x890421\xf1\x82\x1333310031313100313152025350539331463100',
diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py
index 41866efc3d..bbfde95cd6 100755
--- a/selfdrive/controls/controlsd.py
+++ b/selfdrive/controls/controlsd.py
@@ -93,8 +93,7 @@ class Controls:
else:
self.CI, self.CP = CI, CI.CP
- self.joystick_enabled = self.params.get_bool("JoystickDebugMode")
- self.joystick_mode = self.joystick_enabled or self.CP.notCar
+ self.joystick_mode = self.params.get_bool("JoystickDebugMode")
# set alternative experiences from parameters
self.disengage_on_accelerator = self.params.get_bool("DisengageOnAccelerator")
@@ -192,9 +191,6 @@ class Controls:
set_offroad_alert("Offroad_NoFirmware", True)
elif self.CP.passive:
self.events.add(EventName.dashcamMode, static=True)
- elif self.joystick_mode:
- self.events.add(EventName.joystickDebug, static=True)
- self.startup_event = None
# controlsd is driven by can recv, expected at 100Hz
self.rk = Ratekeeper(100, print_delay_threshold=None)
@@ -215,6 +211,11 @@ class Controls:
self.events.clear()
+ # Add joystick event, static on cars, dynamic on nonCars
+ if self.joystick_mode:
+ self.events.add(EventName.joystickDebug)
+ self.startup_event = None
+
# Add startup event
if self.startup_event is not None:
self.events.add(self.startup_event)
@@ -371,7 +372,7 @@ class Controls:
else:
self.logged_comm_issue = None
- if not (self.CP.notCar and self.joystick_enabled):
+ if not (self.CP.notCar and self.joystick_mode):
if not self.sm['lateralPlan'].mpcSolutionValid:
self.events.add(EventName.plannerError)
if not self.sm['liveLocationKalman'].posenetOK:
@@ -853,6 +854,8 @@ class Controls:
self.is_metric = self.params.get_bool("IsMetric")
self.experimental_mode = self.params.get_bool("ExperimentalMode") and self.CP.openpilotLongitudinalControl
+ if self.CP.notCar:
+ self.joystick_mode = self.params.get_bool("JoystickDebugMode")
# Sample data from sockets and get a carState
CS = self.data_sample()
diff --git a/selfdrive/debug/auto_fingerprint.py b/selfdrive/debug/auto_fingerprint.py
index 78b109b0bd..10e438e546 100755
--- a/selfdrive/debug/auto_fingerprint.py
+++ b/selfdrive/debug/auto_fingerprint.py
@@ -102,4 +102,4 @@ if __name__ == "__main__":
if not new_fw_versions:
print("No new fw versions found...")
- add_fw_versions(brand, platform, new_fw_versions)
\ No newline at end of file
+ add_fw_versions(brand, platform, new_fw_versions)
diff --git a/selfdrive/debug/run_process_on_route.py b/selfdrive/debug/run_process_on_route.py
index c7b6250d3f..8209b409ca 100755
--- a/selfdrive/debug/run_process_on_route.py
+++ b/selfdrive/debug/run_process_on_route.py
@@ -10,6 +10,8 @@ from openpilot.tools.lib.helpers import save_log
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Run process on route and create new logs",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+ parser.add_argument("--qlog", help="Use qlog instead of log", action="store_true")
+ parser.add_argument("--fingerprint", help="The fingerprint to use")
parser.add_argument("route", help="The route name to use")
parser.add_argument("process", help="The process to run")
args = parser.parse_args()
@@ -17,10 +19,10 @@ if __name__ == "__main__":
cfg = [c for c in CONFIGS if c.proc_name == args.process][0]
route = Route(args.route)
- lr = MultiLogIterator(route.log_paths())
+ lr = MultiLogIterator(route.qlog_paths() if args.qlog else route.log_paths())
inputs = list(lr)
- outputs = replay_process(cfg, inputs)
+ outputs = replay_process(cfg, inputs, fingerprint=args.fingerprint)
# Remove message generated by the process under test and merge in the new messages
produces = {o.which() for o in outputs}
diff --git a/selfdrive/modeld/models/supercombo.onnx b/selfdrive/modeld/models/supercombo.onnx
index e2897b08a5..9697c01793 100644
--- a/selfdrive/modeld/models/supercombo.onnx
+++ b/selfdrive/modeld/models/supercombo.onnx
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:0b7184d46dc2ba3f84eb748252634205105a3742bac29942ae4380b0332fa850
-size 52524758
+oid sha256:cf6133c5bff295a3ee69eeb01297ba77adb6b83dbc1d774442a48117dbaf4626
+size 48457192
diff --git a/selfdrive/test/cpp_harness.py b/selfdrive/test/cpp_harness.py
index a16b5707f5..f9d3e681a5 100755
--- a/selfdrive/test/cpp_harness.py
+++ b/selfdrive/test/cpp_harness.py
@@ -8,4 +8,4 @@ from openpilot.common.prefix import OpenpilotPrefix
with OpenpilotPrefix():
ret = subprocess.call(sys.argv[1:])
-exit(ret)
\ No newline at end of file
+exit(ret)
diff --git a/selfdrive/test/helpers.py b/selfdrive/test/helpers.py
index 552070f024..78b01c983f 100644
--- a/selfdrive/test/helpers.py
+++ b/selfdrive/test/helpers.py
@@ -71,4 +71,4 @@ def with_processes(processes, init_time=0, ignore_stopped=None):
def noop(*args, **kwargs):
- pass
\ No newline at end of file
+ pass
diff --git a/selfdrive/test/process_replay/conftest.py b/selfdrive/test/process_replay/conftest.py
deleted file mode 100644
index 3f9744ed61..0000000000
--- a/selfdrive/test/process_replay/conftest.py
+++ /dev/null
@@ -1,37 +0,0 @@
-import pytest
-
-from openpilot.selfdrive.test.process_replay.helpers import ALL_PROCS
-from openpilot.selfdrive.test.process_replay.test_processes import ALL_CARS
-
-
-def pytest_addoption(parser: pytest.Parser):
- parser.addoption("--whitelist-procs", type=str, nargs="*", default=ALL_PROCS,
- help="Whitelist given processes from the test (e.g. controlsd)")
- parser.addoption("--whitelist-cars", type=str, nargs="*", default=ALL_CARS,
- help="Whitelist given cars from the test (e.g. HONDA)")
- parser.addoption("--blacklist-procs", type=str, nargs="*", default=[],
- help="Blacklist given processes from the test (e.g. controlsd)")
- parser.addoption("--blacklist-cars", type=str, nargs="*", default=[],
- help="Blacklist given cars from the test (e.g. HONDA)")
- parser.addoption("--ignore-fields", type=str, nargs="*", default=[],
- help="Extra fields or msgs to ignore (e.g. carState.events)")
- parser.addoption("--ignore-msgs", type=str, nargs="*", default=[],
- help="Msgs to ignore (e.g. onroadEvents)")
- parser.addoption("--update-refs", action="store_true",
- help="Updates reference logs using current commit")
- parser.addoption("--upload-only", action="store_true",
- help="Skips testing processes and uploads logs from previous test run")
- parser.addoption("--long-diff", action="store_true",
- help="Outputs diff in long format")
-
-
-@pytest.fixture(scope="class", autouse=True)
-def process_replay_test_arguments(request):
- if hasattr(request.cls, "segment"): # check if a subclass of TestProcessReplayBase
- request.cls.tested_procs = list(set(request.config.getoption("--whitelist-procs")) - set(request.config.getoption("--blacklist-procs")))
- request.cls.tested_cars = list({c.upper() for c in set(request.config.getoption("--whitelist-cars")) - set(request.config.getoption("--blacklist-cars"))})
- request.cls.ignore_fields = request.config.getoption("--ignore-fields")
- request.cls.ignore_msgs = request.config.getoption("--ignore-msgs")
- request.cls.upload_only = request.config.getoption("--upload-only")
- request.cls.update_refs = request.config.getoption("--update-refs")
- request.cls.long_diff = request.config.getoption("--long-diff")
\ No newline at end of file
diff --git a/selfdrive/test/process_replay/helpers.py b/selfdrive/test/process_replay/helpers.py
deleted file mode 100755
index 0952a01870..0000000000
--- a/selfdrive/test/process_replay/helpers.py
+++ /dev/null
@@ -1,150 +0,0 @@
-#!/usr/bin/env python3
-import os
-import sys
-import unittest
-
-from parameterized import parameterized
-from typing import Optional, Union, List
-
-
-from openpilot.selfdrive.test.openpilotci import get_url, upload_file
-from openpilot.selfdrive.test.process_replay.compare_logs import compare_logs, format_process_diff
-from openpilot.selfdrive.test.process_replay.process_replay import CONFIGS, PROC_REPLAY_DIR, FAKEDATA, replay_process
-from openpilot.system.version import get_commit
-from openpilot.tools.lib.filereader import FileReader
-from openpilot.tools.lib.helpers import save_log
-from openpilot.tools.lib.logreader import LogReader, LogIterable
-
-
-BASE_URL = "https://commadataci.blob.core.windows.net/openpilotci/"
-REF_COMMIT_FN = os.path.join(PROC_REPLAY_DIR, "ref_commit")
-EXCLUDED_PROCS = {"modeld", "dmonitoringmodeld"}
-
-
-def get_log_data(segment):
- r, n = segment.rsplit("--", 1)
- with FileReader(get_url(r, n)) as f:
- return f.read()
-
-
-ALL_PROCS = sorted({cfg.proc_name for cfg in CONFIGS if cfg.proc_name not in EXCLUDED_PROCS})
-PROC_TO_CFG = {cfg.proc_name: cfg for cfg in CONFIGS}
-
-cpu_count = os.cpu_count() or 1
-
-
-class TestProcessReplayBase(unittest.TestCase):
- """
- Base class that replays all processes within test_proceses from a segment,
- and puts the log messages in self.log_msgs for analysis by other tests.
- """
- segment: Optional[Union[str, LogIterable]] = None
- tested_procs: List[str] = ALL_PROCS
-
- @classmethod
- def setUpClass(cls, create_logs=True):
- if "Base" in cls.__name__:
- raise unittest.SkipTest("skipping base class")
-
- if isinstance(cls.segment, str):
- cls.log_reader = LogReader.from_bytes(get_log_data(cls.segment))
- else:
- cls.log_reader = cls.segment
-
- if create_logs:
- cls._create_log_msgs()
-
- @classmethod
- def _run_replay(cls, cfg):
- try:
- return replay_process(cfg, cls.log_reader, disable_progress=True)
- except Exception as e:
- raise Exception(f"failed on segment: {cls.segment} \n{e}") from e
-
- @classmethod
- def _create_log_msgs(cls):
- cls.log_msgs = {}
- cls.proc_cfg = {}
-
- for proc in cls.tested_procs:
- cfg = PROC_TO_CFG[proc]
-
- log_msgs = cls._run_replay(cfg)
-
- cls.log_msgs[proc] = log_msgs
- cls.proc_cfg[proc] = cfg
-
-
-class TestProcessReplayDiffBase(TestProcessReplayBase):
- """
- Base class for checking for diff between process outputs.
- """
- update_refs = False
- upload_only = False
- long_diff = False
- ignore_msgs: List[str] = []
- ignore_fields: List[str] = []
-
- def setUp(self):
- super().setUp()
- if self.upload_only:
- raise unittest.SkipTest("skipping test, uploading only")
-
- @classmethod
- def setUpClass(cls):
- super().setUpClass(not cls.upload_only)
-
- if cls.long_diff:
- cls.maxDiff = None
-
- os.makedirs(os.path.dirname(FAKEDATA), exist_ok=True)
-
- cls.cur_commit = get_commit()
- cls.assertNotEqual(cls.cur_commit, None, "Couldn't get current commit")
-
- cls.upload = cls.update_refs or cls.upload_only
-
- try:
- with open(REF_COMMIT_FN) as f:
- cls.ref_commit = f.read().strip()
- except FileNotFoundError:
- print("Couldn't find reference commit")
- sys.exit(1)
-
- cls._create_ref_log_msgs()
-
- @classmethod
- def _create_ref_log_msgs(cls):
- cls.ref_log_msgs = {}
-
- for proc in cls.tested_procs:
- cur_log_fn = os.path.join(FAKEDATA, f"{cls.segment}_{proc}_{cls.cur_commit}.bz2")
- if cls.update_refs: # reference logs will not exist if routes were just regenerated
- ref_log_path = get_url(*cls.segment.rsplit("--", 1))
- else:
- ref_log_fn = os.path.join(FAKEDATA, f"{cls.segment}_{proc}_{cls.ref_commit}.bz2")
- ref_log_path = ref_log_fn if os.path.exists(ref_log_fn) else BASE_URL + os.path.basename(ref_log_fn)
-
- if not cls.upload_only:
- save_log(cur_log_fn, cls.log_msgs[proc])
- cls.ref_log_msgs[proc] = list(LogReader(ref_log_path))
-
- if cls.upload:
- assert os.path.exists(cur_log_fn), f"Cannot find log to upload: {cur_log_fn}"
- upload_file(cur_log_fn, os.path.basename(cur_log_fn))
- os.remove(cur_log_fn)
-
- @parameterized.expand(ALL_PROCS)
- def test_process_diff(self, proc):
- if proc not in self.tested_procs:
- raise unittest.SkipTest(f"{proc} was not requested to be tested")
-
- cfg = self.proc_cfg[proc]
- log_msgs = self.log_msgs[proc]
- ref_log_msgs = self.ref_log_msgs[proc]
-
- diff = compare_logs(ref_log_msgs, log_msgs, self.ignore_fields + cfg.ignore, self.ignore_msgs)
-
- diff_short, diff_long = format_process_diff(diff)
-
- self.assertEqual(len(diff), 0, "\n" + diff_long if self.long_diff else diff_short)
\ No newline at end of file
diff --git a/selfdrive/test/process_replay/model_replay_ref_commit b/selfdrive/test/process_replay/model_replay_ref_commit
index 977f19e7bc..bb111e22e2 100644
--- a/selfdrive/test/process_replay/model_replay_ref_commit
+++ b/selfdrive/test/process_replay/model_replay_ref_commit
@@ -1 +1 @@
-35a05ff1b68062c9478b2adfe96f1c294bee1b6c
+91cd2bf71771c2770c0effc26c0bb23d27208138
diff --git a/selfdrive/test/process_replay/process_replay.py b/selfdrive/test/process_replay/process_replay.py
index c3c3670a74..19f1c127a6 100755
--- a/selfdrive/test/process_replay/process_replay.py
+++ b/selfdrive/test/process_replay/process_replay.py
@@ -749,6 +749,9 @@ def generate_params_config(lr=None, CP=None, fingerprint=None, custom_params=Non
if CP.openpilotLongitudinalControl:
params_dict["ExperimentalLongitudinalEnabled"] = True
+ if CP.notCar:
+ params_dict["JoystickDebugMode"] = True
+
return params_dict
diff --git a/selfdrive/test/process_replay/regen_all.py b/selfdrive/test/process_replay/regen_all.py
index 070cb5f783..656a5b89e1 100755
--- a/selfdrive/test/process_replay/regen_all.py
+++ b/selfdrive/test/process_replay/regen_all.py
@@ -8,8 +8,7 @@ from tqdm import tqdm
from openpilot.common.prefix import OpenpilotPrefix
from openpilot.selfdrive.test.process_replay.regen import regen_and_save
-from openpilot.selfdrive.test.process_replay.process_replay import FAKEDATA
-from openpilot.selfdrive.test.process_replay.test_processes import source_segments as segments
+from openpilot.selfdrive.test.process_replay.test_processes import FAKEDATA, source_segments as segments
from openpilot.tools.lib.route import SegmentName
diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py
index eb01e50e33..5429c9b63e 100755
--- a/selfdrive/test/process_replay/test_processes.py
+++ b/selfdrive/test/process_replay/test_processes.py
@@ -1,15 +1,20 @@
#!/usr/bin/env python3
-import unittest
-import pytest
+import argparse
+import concurrent.futures
+import os
import sys
-
-from parameterized import parameterized_class
-from typing import List, Optional
+from collections import defaultdict
+from tqdm import tqdm
+from typing import Any, DefaultDict, Dict
from openpilot.selfdrive.car.car_helpers import interface_names
-from openpilot.selfdrive.test.process_replay.process_replay import check_openpilot_enabled
-from openpilot.selfdrive.test.process_replay.helpers import TestProcessReplayDiffBase
-
+from openpilot.selfdrive.test.openpilotci import get_url, upload_file
+from openpilot.selfdrive.test.process_replay.compare_logs import compare_logs, format_diff
+from openpilot.selfdrive.test.process_replay.process_replay import CONFIGS, PROC_REPLAY_DIR, FAKEDATA, check_openpilot_enabled, replay_process
+from openpilot.system.version import get_commit
+from openpilot.tools.lib.filereader import FileReader
+from openpilot.tools.lib.logreader import LogReader
+from openpilot.tools.lib.helpers import save_log
source_segments = [
("BODY", "937ccb7243511b65|2022-05-24--16-03-09--1"), # COMMA.BODY
@@ -58,42 +63,166 @@ segments = [
# dashcamOnly makes don't need to be tested until a full port is done
excluded_interfaces = ["mock", "tesla"]
-ALL_CARS = sorted({car for car, _ in segments})
-
-
-@pytest.mark.slow
-@parameterized_class(('case_name', 'segment'), segments)
-@pytest.mark.xdist_group_class_property('case_name')
-class TestCarProcessReplay(TestProcessReplayDiffBase):
- """
- Runs a replay diff on a segment for each car.
- """
-
- case_name: Optional[str] = None
- tested_cars: List[str] = ALL_CARS
-
- @classmethod
- def setUpClass(cls):
- if cls.case_name not in cls.tested_cars:
- raise unittest.SkipTest(f"{cls.case_name} was not requested to be tested")
- super().setUpClass()
-
- def test_all_makes_are_tested(self):
- if set(self.tested_cars) != set(ALL_CARS):
- raise unittest.SkipTest("skipping check because some cars were skipped via command line")
-
- # check to make sure all car brands are tested
- untested = (set(interface_names) - set(excluded_interfaces)) - {c.lower() for c in self.tested_cars}
- self.assertEqual(len(untested), 0, f"Cars missing routes: {str(untested)}")
-
- def test_controlsd_engaged(self):
- if "controlsd" not in self.tested_procs:
- raise unittest.SkipTest("controlsd was not requested to be tested")
-
- # check to make sure openpilot is engaged in the route
- log_msgs = self.log_msgs["controlsd"]
- self.assertTrue(check_openpilot_enabled(log_msgs), f"Route did not enable at all or for long enough: {self.segment}")
-
-
-if __name__ == '__main__':
- pytest.main([*sys.argv[1:], __file__])
\ No newline at end of file
+BASE_URL = "https://commadataci.blob.core.windows.net/openpilotci/"
+REF_COMMIT_FN = os.path.join(PROC_REPLAY_DIR, "ref_commit")
+EXCLUDED_PROCS = {"modeld", "dmonitoringmodeld"}
+
+
+def run_test_process(data):
+ segment, cfg, args, cur_log_fn, ref_log_path, lr_dat = data
+ res = None
+ if not args.upload_only:
+ lr = LogReader.from_bytes(lr_dat)
+ res, log_msgs = test_process(cfg, lr, segment, ref_log_path, cur_log_fn, args.ignore_fields, args.ignore_msgs)
+ # save logs so we can upload when updating refs
+ save_log(cur_log_fn, log_msgs)
+
+ if args.update_refs or args.upload_only:
+ print(f'Uploading: {os.path.basename(cur_log_fn)}')
+ assert os.path.exists(cur_log_fn), f"Cannot find log to upload: {cur_log_fn}"
+ upload_file(cur_log_fn, os.path.basename(cur_log_fn))
+ os.remove(cur_log_fn)
+ return (segment, cfg.proc_name, res)
+
+
+def get_log_data(segment):
+ r, n = segment.rsplit("--", 1)
+ with FileReader(get_url(r, n)) as f:
+ return (segment, f.read())
+
+
+def test_process(cfg, lr, segment, ref_log_path, new_log_path, ignore_fields=None, ignore_msgs=None):
+ if ignore_fields is None:
+ ignore_fields = []
+ if ignore_msgs is None:
+ ignore_msgs = []
+
+ ref_log_msgs = list(LogReader(ref_log_path))
+
+ try:
+ log_msgs = replay_process(cfg, lr, disable_progress=True)
+ except Exception as e:
+ raise Exception("failed on segment: " + segment) from e
+
+ # check to make sure openpilot is engaged in the route
+ if cfg.proc_name == "controlsd":
+ if not check_openpilot_enabled(log_msgs):
+ return f"Route did not enable at all or for long enough: {new_log_path}", log_msgs
+
+ try:
+ return compare_logs(ref_log_msgs, log_msgs, ignore_fields + cfg.ignore, ignore_msgs, cfg.tolerance), log_msgs
+ except Exception as e:
+ return str(e), log_msgs
+
+
+if __name__ == "__main__":
+ all_cars = {car for car, _ in segments}
+ all_procs = {cfg.proc_name for cfg in CONFIGS if cfg.proc_name not in EXCLUDED_PROCS}
+
+ cpu_count = os.cpu_count() or 1
+
+ parser = argparse.ArgumentParser(description="Regression test to identify changes in a process's output")
+ parser.add_argument("--whitelist-procs", type=str, nargs="*", default=all_procs,
+ help="Whitelist given processes from the test (e.g. controlsd)")
+ parser.add_argument("--whitelist-cars", type=str, nargs="*", default=all_cars,
+ help="Whitelist given cars from the test (e.g. HONDA)")
+ parser.add_argument("--blacklist-procs", type=str, nargs="*", default=[],
+ help="Blacklist given processes from the test (e.g. controlsd)")
+ parser.add_argument("--blacklist-cars", type=str, nargs="*", default=[],
+ help="Blacklist given cars from the test (e.g. HONDA)")
+ parser.add_argument("--ignore-fields", type=str, nargs="*", default=[],
+ help="Extra fields or msgs to ignore (e.g. carState.events)")
+ parser.add_argument("--ignore-msgs", type=str, nargs="*", default=[],
+ help="Msgs to ignore (e.g. carEvents)")
+ parser.add_argument("--update-refs", action="store_true",
+ help="Updates reference logs using current commit")
+ parser.add_argument("--upload-only", action="store_true",
+ help="Skips testing processes and uploads logs from previous test run")
+ parser.add_argument("-j", "--jobs", type=int, default=max(cpu_count - 2, 1),
+ help="Max amount of parallel jobs")
+ args = parser.parse_args()
+
+ tested_procs = set(args.whitelist_procs) - set(args.blacklist_procs)
+ tested_cars = set(args.whitelist_cars) - set(args.blacklist_cars)
+ tested_cars = {c.upper() for c in tested_cars}
+
+ full_test = (tested_procs == all_procs) and (tested_cars == all_cars) and all(len(x) == 0 for x in (args.ignore_fields, args.ignore_msgs))
+ upload = args.update_refs or args.upload_only
+ os.makedirs(os.path.dirname(FAKEDATA), exist_ok=True)
+
+ if upload:
+ assert full_test, "Need to run full test when updating refs"
+
+ try:
+ ref_commit = open(REF_COMMIT_FN).read().strip()
+ except FileNotFoundError:
+ print("Couldn't find reference commit")
+ sys.exit(1)
+
+ cur_commit = get_commit()
+ if cur_commit is None:
+ raise Exception("Couldn't get current commit")
+
+ print(f"***** testing against commit {ref_commit} *****")
+
+ # check to make sure all car brands are tested
+ if full_test:
+ untested = (set(interface_names) - set(excluded_interfaces)) - {c.lower() for c in tested_cars}
+ assert len(untested) == 0, f"Cars missing routes: {str(untested)}"
+
+ log_paths: DefaultDict[str, Dict[str, Dict[str, str]]] = defaultdict(lambda: defaultdict(dict))
+ with concurrent.futures.ProcessPoolExecutor(max_workers=args.jobs) as pool:
+ if not args.upload_only:
+ download_segments = [seg for car, seg in segments if car in tested_cars]
+ log_data: Dict[str, LogReader] = {}
+ p1 = pool.map(get_log_data, download_segments)
+ for segment, lr in tqdm(p1, desc="Getting Logs", total=len(download_segments)):
+ log_data[segment] = lr
+
+ pool_args: Any = []
+ for car_brand, segment in segments:
+ if car_brand not in tested_cars:
+ continue
+
+ for cfg in CONFIGS:
+ if cfg.proc_name not in tested_procs:
+ continue
+
+ cur_log_fn = os.path.join(FAKEDATA, f"{segment}_{cfg.proc_name}_{cur_commit}.bz2")
+ if args.update_refs: # reference logs will not exist if routes were just regenerated
+ ref_log_path = get_url(*segment.rsplit("--", 1))
+ else:
+ ref_log_fn = os.path.join(FAKEDATA, f"{segment}_{cfg.proc_name}_{ref_commit}.bz2")
+ ref_log_path = ref_log_fn if os.path.exists(ref_log_fn) else BASE_URL + os.path.basename(ref_log_fn)
+
+ dat = None if args.upload_only else log_data[segment]
+ pool_args.append((segment, cfg, args, cur_log_fn, ref_log_path, dat))
+
+ log_paths[segment][cfg.proc_name]['ref'] = ref_log_path
+ log_paths[segment][cfg.proc_name]['new'] = cur_log_fn
+
+ results: Any = defaultdict(dict)
+ p2 = pool.map(run_test_process, pool_args)
+ for (segment, proc, result) in tqdm(p2, desc="Running Tests", total=len(pool_args)):
+ if not args.upload_only:
+ results[segment][proc] = result
+
+ diff_short, diff_long, failed = format_diff(results, log_paths, ref_commit)
+ if not upload:
+ with open(os.path.join(PROC_REPLAY_DIR, "diff.txt"), "w") as f:
+ f.write(diff_long)
+ print(diff_short)
+
+ if failed:
+ print("TEST FAILED")
+ print("\n\nTo push the new reference logs for this commit run:")
+ print("./test_processes.py --upload-only")
+ else:
+ print("TEST SUCCEEDED")
+
+ else:
+ with open(REF_COMMIT_FN, "w") as f:
+ f.write(cur_commit)
+ print(f"\n\nUpdated reference logs for commit: {cur_commit}")
+
+ sys.exit(int(failed))
diff --git a/selfdrive/test/test_onroad.py b/selfdrive/test/test_onroad.py
index b4121529d1..d7c5c58280 100755
--- a/selfdrive/test/test_onroad.py
+++ b/selfdrive/test/test_onroad.py
@@ -36,7 +36,7 @@ PROCS = {
"./locationd": 11.0,
"./mapsd": (1.0, 10.0),
"selfdrive.controls.plannerd": 11.0,
- "./_ui": 18.0,
+ "./ui": 18.0,
"selfdrive.locationd.paramsd": 9.0,
"./sensord": 7.0,
"selfdrive.controls.radard": 4.5,
@@ -46,13 +46,13 @@ PROCS = {
"selfdrive.thermald.thermald": 3.87,
"selfdrive.locationd.calibrationd": 2.0,
"selfdrive.locationd.torqued": 5.0,
- "selfdrive.ui.soundd": 5.8,
+ "selfdrive.ui.soundd": 3.5,
"selfdrive.monitoring.dmonitoringd": 4.0,
"./proclogd": 1.54,
"system.logmessaged": 0.2,
"selfdrive.tombstoned": 0,
"./logcatd": 0,
- "system.micd": 10.0,
+ "system.micd": 6.0,
"system.timezoned": 0,
"selfdrive.boardd.pandad": 0,
"selfdrive.statsd": 0.4,
@@ -303,7 +303,7 @@ class TestOnroad(unittest.TestCase):
self.assertLessEqual(max(mems) - min(mems), 3.0)
def test_gpu_usage(self):
- self.assertEqual(self.gpu_procs, {"weston", "_ui", "camerad", "selfdrive.modeld.modeld"})
+ self.assertEqual(self.gpu_procs, {"weston", "ui", "camerad", "selfdrive.modeld.modeld"})
def test_camera_processing_time(self):
result = "\n"
diff --git a/selfdrive/ui/.gitignore b/selfdrive/ui/.gitignore
index 8ad5d39493..99f9097905 100644
--- a/selfdrive/ui/.gitignore
+++ b/selfdrive/ui/.gitignore
@@ -3,6 +3,7 @@ moc_*
translations/main_test_en.*
+ui
watch3
installer/installers/*
qt/text
diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript
index f0db1f63a7..b0f5a4f4a6 100644
--- a/selfdrive/ui/SConscript
+++ b/selfdrive/ui/SConscript
@@ -77,7 +77,7 @@ qt_env.Program("qt/text", ["qt/text.cc"], LIBS=qt_libs)
qt_env.Program("qt/spinner", ["qt/spinner.cc"], LIBS=qt_libs)
# build main UI
-qt_env.Program("_ui", qt_src + [asset_obj], LIBS=qt_libs)
+qt_env.Program("ui", qt_src + [asset_obj], LIBS=qt_libs)
if GetOption('extras'):
qt_src.remove("main.cc") # replaced by test_runner
qt_env.Program('tests/test_translations', [asset_obj, 'tests/test_runner.cc', 'tests/test_translations.cc'] + qt_src, LIBS=qt_libs)
diff --git a/selfdrive/ui/qt/offroad/driverview.cc b/selfdrive/ui/qt/offroad/driverview.cc
index 693a0253b4..df9bb24651 100644
--- a/selfdrive/ui/qt/offroad/driverview.cc
+++ b/selfdrive/ui/qt/offroad/driverview.cc
@@ -3,62 +3,39 @@
#include
#include
-#include "selfdrive/ui/qt/qt_window.h"
#include "selfdrive/ui/qt/util.h"
const int FACE_IMG_SIZE = 130;
-DriverViewWindow::DriverViewWindow(QWidget* parent) : QWidget(parent) {
- setAttribute(Qt::WA_OpaquePaintEvent);
- layout = new QStackedLayout(this);
- layout->setStackingMode(QStackedLayout::StackAll);
-
- cameraView = new CameraWidget("camerad", VISION_STREAM_DRIVER, true, this);
- layout->addWidget(cameraView);
-
- scene = new DriverViewScene(this);
- connect(cameraView, &CameraWidget::vipcThreadFrameReceived, scene, &DriverViewScene::frameUpdated);
- layout->addWidget(scene);
- layout->setCurrentWidget(scene);
-
- QObject::connect(device(), &Device::interactiveTimeout, this, &DriverViewWindow::closeView);
-}
-
-void DriverViewWindow::closeView() {
- if (isVisible()) {
- cameraView->stopVipcThread();
- emit done();
- }
-}
-
-void DriverViewWindow::mouseReleaseEvent(QMouseEvent* e) {
- closeView();
-}
-
-DriverViewScene::DriverViewScene(QWidget* parent) : QWidget(parent) {
+DriverViewWindow::DriverViewWindow(QWidget* parent) : CameraWidget("camerad", VISION_STREAM_DRIVER, true, parent) {
face_img = loadPixmap("../assets/img_driver_face_static.png", {FACE_IMG_SIZE, FACE_IMG_SIZE});
+ QObject::connect(this, &CameraWidget::clicked, this, &DriverViewWindow::done);
+ QObject::connect(device(), &Device::interactiveTimeout, this, [this]() {
+ if (isVisible()) {
+ emit done();
+ }
+ });
}
-void DriverViewScene::showEvent(QShowEvent* event) {
- frame_updated = false;
+void DriverViewWindow::showEvent(QShowEvent* event) {
params.putBool("IsDriverViewEnabled", true);
device()->resetInteractiveTimeout(60);
+ CameraWidget::showEvent(event);
}
-void DriverViewScene::hideEvent(QHideEvent* event) {
+void DriverViewWindow::hideEvent(QHideEvent* event) {
params.putBool("IsDriverViewEnabled", false);
+ stopVipcThread();
+ CameraWidget::hideEvent(event);
}
-void DriverViewScene::frameUpdated() {
- frame_updated = true;
- update();
-}
+void DriverViewWindow::paintGL() {
+ CameraWidget::paintGL();
-void DriverViewScene::paintEvent(QPaintEvent* event) {
+ std::lock_guard lk(frame_lock);
QPainter p(this);
-
// startup msg
- if (!frame_updated) {
+ if (frames.empty()) {
p.setPen(Qt::white);
p.setRenderHint(QPainter::TextAntialiasing);
p.setFont(InterFont(100, QFont::Bold));
@@ -68,10 +45,8 @@ void DriverViewScene::paintEvent(QPaintEvent* event) {
const auto &sm = *(uiState()->sm);
cereal::DriverStateV2::Reader driver_state = sm["driverStateV2"].getDriverStateV2();
- cereal::DriverStateV2::DriverData::Reader driver_data;
-
- is_rhd = driver_state.getWheelOnRightProb() > 0.5;
- driver_data = is_rhd ? driver_state.getRightDriverData() : driver_state.getLeftDriverData();
+ bool is_rhd = driver_state.getWheelOnRightProb() > 0.5;
+ auto driver_data = is_rhd ? driver_state.getRightDriverData() : driver_state.getLeftDriverData();
bool face_detected = driver_data.getFaceProb() > 0.7;
if (face_detected) {
diff --git a/selfdrive/ui/qt/offroad/driverview.h b/selfdrive/ui/qt/offroad/driverview.h
index 8bfc7a4b7b..155e4ede32 100644
--- a/selfdrive/ui/qt/offroad/driverview.h
+++ b/selfdrive/ui/qt/offroad/driverview.h
@@ -1,44 +1,21 @@
#pragma once
-#include
-
#include "selfdrive/ui/qt/widgets/cameraview.h"
-class DriverViewScene : public QWidget {
+class DriverViewWindow : public CameraWidget {
Q_OBJECT
public:
- explicit DriverViewScene(QWidget *parent);
+ explicit DriverViewWindow(QWidget *parent);
-public slots:
- void frameUpdated();
+signals:
+ void done();
protected:
void showEvent(QShowEvent *event) override;
void hideEvent(QHideEvent *event) override;
- void paintEvent(QPaintEvent *event) override;
+ void paintGL() override;
-private:
Params params;
QPixmap face_img;
- bool is_rhd = false;
- bool frame_updated = false;
-};
-
-class DriverViewWindow : public QWidget {
- Q_OBJECT
-
-public:
- explicit DriverViewWindow(QWidget *parent);
-
-signals:
- void done();
-
-protected:
- void mouseReleaseEvent(QMouseEvent* e) override;
- void closeView();
-
- CameraWidget *cameraView;
- DriverViewScene *scene;
- QStackedLayout *layout;
};
diff --git a/selfdrive/ui/qt/util.cc b/selfdrive/ui/qt/util.cc
index 78da183503..c5222b865f 100644
--- a/selfdrive/ui/qt/util.cc
+++ b/selfdrive/ui/qt/util.cc
@@ -112,6 +112,8 @@ void initApp(int argc, char *argv[], bool disable_hidpi) {
#endif
}
+ qputenv("QT_DBL_CLICK_DIST", QByteArray::number(150));
+
setQtSurfaceFormat();
}
diff --git a/selfdrive/ui/soundd.py b/selfdrive/ui/soundd.py
index 9d6d24a594..01148ec199 100644
--- a/selfdrive/ui/soundd.py
+++ b/selfdrive/ui/soundd.py
@@ -8,14 +8,14 @@ from typing import Dict, Optional, Tuple
from cereal import car, messaging
from openpilot.common.basedir import BASEDIR
from openpilot.common.filter_simple import FirstOrderFilter
-
-from openpilot.system import micd
-from openpilot.system.hardware import TICI
-
from openpilot.common.realtime import Ratekeeper
+from openpilot.common.retry import retry
from openpilot.common.swaglog import cloudlog
+from openpilot.system import micd
+
SAMPLE_RATE = 48000
+SAMPLE_BUFFER = 4096 # (approx 100ms)
MAX_VOLUME = 1.0
MIN_VOLUME = 0.1
CONTROLS_TIMEOUT = 5 # 5 seconds
@@ -126,18 +126,23 @@ class Soundd:
volume = ((weighted_db - AMBIENT_DB) / DB_SCALE) * (MAX_VOLUME - MIN_VOLUME) + MIN_VOLUME
return math.pow(10, (np.clip(volume, MIN_VOLUME, MAX_VOLUME) - 1))
+ @retry(attempts=7, delay=3)
+ def get_stream(self, sd):
+ # reload sounddevice to reinitialize portaudio
+ sd._terminate()
+ sd._initialize()
+ return sd.OutputStream(channels=1, samplerate=SAMPLE_RATE, callback=self.callback, blocksize=SAMPLE_BUFFER)
+
def soundd_thread(self):
# sounddevice must be imported after forking processes
import sounddevice as sd
- if TICI:
- micd.wait_for_devices(sd) # wait for alsa to be initialized on device
+ sm = messaging.SubMaster(['controlsState', 'microphone'])
- with sd.OutputStream(channels=1, samplerate=SAMPLE_RATE, callback=self.callback) as stream:
+ with self.get_stream(sd) as stream:
rk = Ratekeeper(20)
- sm = messaging.SubMaster(['controlsState', 'microphone'])
- cloudlog.info(f"soundd stream started: {stream.samplerate=} {stream.channels=} {stream.dtype=} {stream.device=}")
+ cloudlog.info(f"soundd stream started: {stream.samplerate=} {stream.channels=} {stream.dtype=} {stream.device=}, {stream.blocksize=}")
while True:
sm.update(0)
@@ -158,4 +163,4 @@ def main():
if __name__ == "__main__":
- main()
\ No newline at end of file
+ main()
diff --git a/selfdrive/ui/translations/main_ar.ts b/selfdrive/ui/translations/main_ar.ts
index 4159f28c31..dc771b8c6e 100644
--- a/selfdrive/ui/translations/main_ar.ts
+++ b/selfdrive/ui/translations/main_ar.ts
@@ -275,7 +275,7 @@
- DriverViewScene
+ DriverViewWindow
camera starting
بدء تشغيل الكاميرا
diff --git a/selfdrive/ui/translations/main_de.ts b/selfdrive/ui/translations/main_de.ts
index e2e5771905..498d4c4438 100644
--- a/selfdrive/ui/translations/main_de.ts
+++ b/selfdrive/ui/translations/main_de.ts
@@ -275,7 +275,7 @@
- DriverViewScene
+ DriverViewWindow
camera starting
Kamera startet
diff --git a/selfdrive/ui/translations/main_fr.ts b/selfdrive/ui/translations/main_fr.ts
index 456efe6366..5ae3acdc1e 100644
--- a/selfdrive/ui/translations/main_fr.ts
+++ b/selfdrive/ui/translations/main_fr.ts
@@ -275,7 +275,7 @@
- DriverViewScene
+ DriverViewWindow
camera starting
démarrage de la caméra
diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts
index 63de8f0471..d01657f8e4 100644
--- a/selfdrive/ui/translations/main_ja.ts
+++ b/selfdrive/ui/translations/main_ja.ts
@@ -275,7 +275,7 @@
- DriverViewScene
+ DriverViewWindow
camera starting
カメラを起動しています
diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts
index bc0c5f2b0e..d2d6a4ddc1 100644
--- a/selfdrive/ui/translations/main_ko.ts
+++ b/selfdrive/ui/translations/main_ko.ts
@@ -275,7 +275,7 @@
- DriverViewScene
+ DriverViewWindow
camera starting
카메라 시작 중
diff --git a/selfdrive/ui/translations/main_pt-BR.ts b/selfdrive/ui/translations/main_pt-BR.ts
index 4cf37cc585..04458974cb 100644
--- a/selfdrive/ui/translations/main_pt-BR.ts
+++ b/selfdrive/ui/translations/main_pt-BR.ts
@@ -275,7 +275,7 @@
- DriverViewScene
+ DriverViewWindow
camera starting
câmera iniciando
diff --git a/selfdrive/ui/translations/main_th.ts b/selfdrive/ui/translations/main_th.ts
index a1748a6951..5f77f6c9de 100644
--- a/selfdrive/ui/translations/main_th.ts
+++ b/selfdrive/ui/translations/main_th.ts
@@ -275,7 +275,7 @@
- DriverViewScene
+ DriverViewWindow
camera starting
กำลังเปิดกล้อง
diff --git a/selfdrive/ui/translations/main_tr.ts b/selfdrive/ui/translations/main_tr.ts
index 51fdddd5ce..f8a76669a2 100644
--- a/selfdrive/ui/translations/main_tr.ts
+++ b/selfdrive/ui/translations/main_tr.ts
@@ -275,7 +275,7 @@
- DriverViewScene
+ DriverViewWindow
camera starting
kamera başlatılıyor
diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts
index 7b682535ce..371106d571 100644
--- a/selfdrive/ui/translations/main_zh-CHS.ts
+++ b/selfdrive/ui/translations/main_zh-CHS.ts
@@ -275,7 +275,7 @@
- DriverViewScene
+ DriverViewWindow
camera starting
正在启动相机
diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts
index 1794cc78ac..6aa6295ce2 100644
--- a/selfdrive/ui/translations/main_zh-CHT.ts
+++ b/selfdrive/ui/translations/main_zh-CHT.ts
@@ -275,7 +275,7 @@
- DriverViewScene
+ DriverViewWindow
camera starting
開啟相機中
diff --git a/selfdrive/ui/ui b/selfdrive/ui/ui
deleted file mode 100755
index acb2a705a8..0000000000
--- a/selfdrive/ui/ui
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-cd "$(dirname "$0")"
-export QT_DBL_CLICK_DIST=150
-exec ./_ui
diff --git a/system/camerad/cameras/camera_common.cc b/system/camerad/cameras/camera_common.cc
index e36766ca2d..645a6f305c 100644
--- a/system/camerad/cameras/camera_common.cc
+++ b/system/camerad/cameras/camera_common.cc
@@ -61,9 +61,9 @@ private:
cl_kernel krnl_;
};
-void CameraBuf::init(cl_device_id device_id, cl_context context, CameraState *s, VisionIpcServer * v, int frame_cnt, VisionStreamType init_yuv_type) {
+void CameraBuf::init(cl_device_id device_id, cl_context context, CameraState *s, VisionIpcServer * v, int frame_cnt, VisionStreamType type) {
vipc_server = v;
- this->yuv_type = init_yuv_type;
+ stream_type = type;
frame_buf_count = frame_cnt;
const SensorInfo *ci = s->ci.get();
@@ -87,7 +87,7 @@ void CameraBuf::init(cl_device_id device_id, cl_context context, CameraState *s,
assert(nv12_height/2 == VENUS_UV_SCANLINES(COLOR_FMT_NV12, rgb_height));
size_t nv12_size = 2346 * nv12_width; // comes from v4l2_format.fmt.pix_mp.plane_fmt[0].sizeimage
size_t nv12_uv_offset = nv12_width * nv12_height;
- vipc_server->create_buffers_with_sizes(yuv_type, YUV_BUFFER_COUNT, false, rgb_width, rgb_height, nv12_size, nv12_width, nv12_uv_offset);
+ vipc_server->create_buffers_with_sizes(stream_type, YUV_BUFFER_COUNT, false, rgb_width, rgb_height, nv12_size, nv12_width, nv12_uv_offset);
LOGD("created %d YUV vipc buffers with size %dx%d", YUV_BUFFER_COUNT, nv12_width, nv12_height);
debayer = new Debayer(device_id, context, this, s, nv12_width, nv12_uv_offset);
@@ -113,7 +113,7 @@ bool CameraBuf::acquire() {
}
cur_frame_data = camera_bufs_metadata[cur_buf_idx];
- cur_yuv_buf = vipc_server->get_buffer(yuv_type);
+ cur_yuv_buf = vipc_server->get_buffer(stream_type);
cur_camera_buf = &camera_bufs[cur_buf_idx];
double start_time = millis_since_boot();
diff --git a/system/camerad/cameras/camera_common.h b/system/camerad/cameras/camera_common.h
index e93d357b8d..9ebe018408 100644
--- a/system/camerad/cameras/camera_common.h
+++ b/system/camerad/cameras/camera_common.h
@@ -55,7 +55,7 @@ class CameraBuf {
private:
VisionIpcServer *vipc_server;
Debayer *debayer = nullptr;
- VisionStreamType yuv_type;
+ VisionStreamType stream_type;
int cur_buf_idx;
SafeQueue safe_queue;
int frame_buf_count;
@@ -71,7 +71,7 @@ public:
CameraBuf() = default;
~CameraBuf();
- void init(cl_device_id device_id, cl_context context, CameraState *s, VisionIpcServer * v, int frame_cnt, VisionStreamType yuv_type);
+ void init(cl_device_id device_id, cl_context context, CameraState *s, VisionIpcServer * v, int frame_cnt, VisionStreamType type);
bool acquire();
void queue(size_t buf_idx);
};
diff --git a/system/camerad/cameras/camera_qcom2.cc b/system/camerad/cameras/camera_qcom2.cc
index 194f11fe6d..7f2118e7e4 100644
--- a/system/camerad/cameras/camera_qcom2.cc
+++ b/system/camerad/cameras/camera_qcom2.cc
@@ -426,7 +426,7 @@ void CameraState::camera_map_bufs(MultiCameraState *s) {
enqueue_req_multi(1, FRAME_BUF_COUNT, 0);
}
-void CameraState::camera_init(MultiCameraState *s, VisionIpcServer * v, unsigned int fps, cl_device_id device_id, cl_context ctx, VisionStreamType yuv_type) {
+void CameraState::camera_init(MultiCameraState *s, VisionIpcServer * v, cl_device_id device_id, cl_context ctx, VisionStreamType yuv_type) {
if (!enabled) return;
LOGD("camera init %d", camera_num);
@@ -618,9 +618,9 @@ void CameraState::camera_open(MultiCameraState *multi_cam_state_, int camera_num
}
void cameras_init(VisionIpcServer *v, MultiCameraState *s, cl_device_id device_id, cl_context ctx) {
- s->driver_cam.camera_init(s, v, 20, device_id, ctx, VISION_STREAM_DRIVER);
- s->road_cam.camera_init(s, v, 20, device_id, ctx, VISION_STREAM_ROAD);
- s->wide_road_cam.camera_init(s, v, 20, device_id, ctx, VISION_STREAM_WIDE_ROAD);
+ s->driver_cam.camera_init(s, v, device_id, ctx, VISION_STREAM_DRIVER);
+ s->road_cam.camera_init(s, v, device_id, ctx, VISION_STREAM_ROAD);
+ s->wide_road_cam.camera_init(s, v, device_id, ctx, VISION_STREAM_WIDE_ROAD);
s->pm = new PubMaster({"roadCameraState", "driverCameraState", "wideRoadCameraState", "thumbnail"});
}
diff --git a/system/camerad/cameras/camera_qcom2.h b/system/camerad/cameras/camera_qcom2.h
index 3da5ec207d..d61c087f7c 100644
--- a/system/camerad/cameras/camera_qcom2.h
+++ b/system/camerad/cameras/camera_qcom2.h
@@ -50,7 +50,7 @@ public:
void camera_open(MultiCameraState *multi_cam_state, int camera_num, bool enabled);
void sensor_set_parameters();
void camera_map_bufs(MultiCameraState *s);
- void camera_init(MultiCameraState *s, VisionIpcServer *v, unsigned int fps, cl_device_id device_id, cl_context ctx, VisionStreamType yuv_type);
+ void camera_init(MultiCameraState *s, VisionIpcServer *v, cl_device_id device_id, cl_context ctx, VisionStreamType yuv_type);
void camera_close();
int32_t session_handle;
diff --git a/system/hardware/hw.py b/system/hardware/hw.py
index 6c3d90345c..a8967520e3 100644
--- a/system/hardware/hw.py
+++ b/system/hardware/hw.py
@@ -53,4 +53,4 @@ class Paths:
if PC:
return Paths.comma_home()
else:
- return "/tmp/.comma"
\ No newline at end of file
+ return "/tmp/.comma"
diff --git a/system/loggerd/encoder/encoder.cc b/system/loggerd/encoder/encoder.cc
index 869b4617b3..0aba4b8b49 100644
--- a/system/loggerd/encoder/encoder.cc
+++ b/system/loggerd/encoder/encoder.cc
@@ -27,8 +27,11 @@ void VideoEncoder::publisher_publish(VideoEncoder *e, int segment_num, uint32_t
edat.setData(dat);
if (flags & V4L2_BUF_FLAG_KEYFRAME) edat.setHeader(header);
- auto words = new kj::Array(capnp::messageToFlatArray(msg));
- auto bytes = words->asBytes();
- e->pm->send(e->encoder_info.publish_name, bytes.begin(), bytes.size());
- delete words;
+ uint32_t bytes_size = capnp::computeSerializedSizeInWords(msg) * sizeof(capnp::word);
+ if (e->msg_cache.size() < bytes_size) {
+ e->msg_cache.resize(bytes_size);
+ }
+ kj::ArrayOutputStream output_stream(kj::ArrayPtr(e->msg_cache.data(), bytes_size));
+ capnp::writeMessage(output_stream, msg);
+ e->pm->send(e->encoder_info.publish_name, e->msg_cache.data(), bytes_size);
}
diff --git a/system/loggerd/encoder/encoder.h b/system/loggerd/encoder/encoder.h
index a8bfd5c054..9c23928cc6 100644
--- a/system/loggerd/encoder/encoder.h
+++ b/system/loggerd/encoder/encoder.h
@@ -4,6 +4,7 @@
#include
#include
#include
+#include
#include "cereal/messaging/messaging.h"
#include "cereal/visionipc/visionipc.h"
@@ -23,7 +24,6 @@ public:
static void publisher_publish(VideoEncoder *e, int segment_num, uint32_t idx, VisionIpcBufExtra &extra, unsigned int flags, kj::ArrayPtr header, kj::ArrayPtr dat);
-
protected:
int in_width, in_height;
const EncoderInfo encoder_info;
@@ -32,4 +32,5 @@ private:
// total frames encoded
int cnt = 0;
std::unique_ptr pm;
+ std::vector msg_cache;
};
diff --git a/system/micd.py b/system/micd.py
index f4085becd4..8b738ebe93 100755
--- a/system/micd.py
+++ b/system/micd.py
@@ -5,24 +5,12 @@ from cereal import messaging
from openpilot.common.realtime import Ratekeeper
from openpilot.common.retry import retry
from openpilot.common.swaglog import cloudlog
-from openpilot.system.hardware import TICI
RATE = 10
FFT_SAMPLES = 4096
REFERENCE_SPL = 2e-5 # newtons/m^2
SAMPLE_RATE = 44100
-
-
-@retry(attempts=7, delay=3)
-def wait_for_devices(sd):
- # reload sounddevice to reinitialize portaudio
- sd._terminate()
- sd._initialize()
-
- devices = sd.query_devices()
- cloudlog.info(f"sounddevice available devices: {list(devices)}")
-
- assert len(devices) > 0
+SAMPLE_BUFFER = 4096 # (approx 100ms)
def calculate_spl(measurements):
@@ -91,15 +79,19 @@ class Mic:
self.measurements = self.measurements[FFT_SAMPLES:]
+ @retry(attempts=7, delay=3)
+ def get_stream(self, sd):
+ # reload sounddevice to reinitialize portaudio
+ sd._terminate()
+ sd._initialize()
+ return sd.InputStream(channels=1, samplerate=SAMPLE_RATE, callback=self.callback, blocksize=SAMPLE_BUFFER)
+
def micd_thread(self):
# sounddevice must be imported after forking processes
import sounddevice as sd
- if TICI:
- wait_for_devices(sd) # wait for alsa to be initialized on device
-
- with sd.InputStream(channels=1, samplerate=SAMPLE_RATE, callback=self.callback) as stream:
- cloudlog.info(f"micd stream started: {stream.samplerate=} {stream.channels=} {stream.dtype=} {stream.device=}")
+ with self.get_stream(sd) as stream:
+ cloudlog.info(f"micd stream started: {stream.samplerate=} {stream.channels=} {stream.dtype=} {stream.device=}, {stream.blocksize=}")
while True:
self.update()
diff --git a/tools/cabana/dbc/dbc.h b/tools/cabana/dbc/dbc.h
index e07903e680..0262a546f6 100644
--- a/tools/cabana/dbc/dbc.h
+++ b/tools/cabana/dbc/dbc.h
@@ -1,12 +1,10 @@
#pragma once
#include
-#include
#include
#include
#include
-#include
#include
#include
@@ -47,7 +45,7 @@ struct std::hash {
std::size_t operator()(const MessageId &k) const noexcept { return qHash(k); }
};
-typedef QList> ValueDescription;
+typedef std::vector> ValueDescription;
namespace cabana {
diff --git a/tools/cabana/dbc/dbcfile.cc b/tools/cabana/dbc/dbcfile.cc
index a22d979212..fbbb54fd58 100644
--- a/tools/cabana/dbc/dbcfile.cc
+++ b/tools/cabana/dbc/dbcfile.cc
@@ -52,8 +52,7 @@ void DBCFile::cleanupAutoSaveFile() {
bool DBCFile::writeContents(const QString &fn) {
QFile file(fn);
if (file.open(QIODevice::WriteOnly)) {
- file.write(generateDBC().toUtf8());
- return true;
+ return file.write(generateDBC().toUtf8()) >= 0;
}
return false;
}
@@ -77,10 +76,6 @@ cabana::Msg *DBCFile::msg(const QString &name) {
return it != msgs.end() ? &(it->second) : nullptr;
}
-int DBCFile::signalCount() {
- return std::accumulate(msgs.cbegin(), msgs.cend(), 0, [](int &n, const auto &m) { return n + m.second.sigs.size(); });
-}
-
void DBCFile::parse(const QString &content) {
static QRegularExpression bo_regexp(R"(^BO_ (\w+) (\w+) *: (\w+) (\w+))");
static QRegularExpression sg_regexp(R"(^SG_ (\w+) : (\d+)\|(\d+)@(\d+)([\+|\-]) \(([0-9.+\-eE]+),([0-9.+\-eE]+)\) \[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] \"(.*)\" (.*))");
@@ -226,7 +221,7 @@ QString DBCFile::generateDBC() {
if (!sig->comment.isEmpty()) {
signal_comment += QString("CM_ SG_ %1 %2 \"%3\";\n").arg(address).arg(sig->name).arg(sig->comment);
}
- if (!sig->val_desc.isEmpty()) {
+ if (!sig->val_desc.empty()) {
QStringList text;
for (auto &[val, desc] : sig->val_desc) {
text << QString("%1 \"%2\"").arg(val).arg(desc);
diff --git a/tools/cabana/dbc/dbcfile.h b/tools/cabana/dbc/dbcfile.h
index ade6b249e2..551bac4946 100644
--- a/tools/cabana/dbc/dbcfile.h
+++ b/tools/cabana/dbc/dbcfile.h
@@ -27,10 +27,8 @@ public:
cabana::Msg *msg(const QString &name);
inline cabana::Msg *msg(const MessageId &id) { return msg(id.address); }
- int signalCount();
- inline int msgCount() { return msgs.size(); }
- inline QString name() { return name_.isEmpty() ? "untitled" : name_; }
- inline bool isEmpty() { return (signalCount() == 0) && name_.isEmpty(); }
+ inline QString name() const { return name_.isEmpty() ? "untitled" : name_; }
+ inline bool isEmpty() const { return msgs.empty() && name_.isEmpty(); }
QString filename;
diff --git a/tools/cabana/dbc/dbcmanager.cc b/tools/cabana/dbc/dbcmanager.cc
index 87a7d962c5..250ec225b5 100644
--- a/tools/cabana/dbc/dbcmanager.cc
+++ b/tools/cabana/dbc/dbcmanager.cc
@@ -106,12 +106,6 @@ QString DBCManager::newSignalName(const MessageId &id) {
return m ? m->newSignalName() : "";
}
-const std::vector &DBCManager::mask(const MessageId &id) {
- static std::vector empty_mask;
- auto m = msg(id);
- return m ? m->mask : empty_mask;
-}
-
const std::map &DBCManager::getMessages(uint8_t source) {
static std::map empty_msgs;
auto dbc_file = findDBCFile(source);
@@ -143,25 +137,6 @@ QStringList DBCManager::signalNames() {
return ret;
}
-int DBCManager::signalCount(const MessageId &id) {
- auto m = msg(id);
- return m ? m->sigs.size() : 0;
-}
-
-int DBCManager::signalCount() {
- auto files = allDBCFiles();
- return std::accumulate(files.cbegin(), files.cend(), 0, [](int &n, auto &f) { return n + f->signalCount(); });
-}
-
-int DBCManager::msgCount() {
- auto files = allDBCFiles();
- return std::accumulate(files.cbegin(), files.cend(), 0, [](int &n, auto &f) { return n + f->msgCount(); });
-}
-
-int DBCManager::dbcCount() {
- return allDBCFiles().size();
-}
-
int DBCManager::nonEmptyDBCCount() {
auto files = allDBCFiles();
return std::count_if(files.cbegin(), files.cend(), [](auto &f) { return !f->isEmpty(); });
diff --git a/tools/cabana/dbc/dbcmanager.h b/tools/cabana/dbc/dbcmanager.h
index 53a77a2c13..5f183752d2 100644
--- a/tools/cabana/dbc/dbcmanager.h
+++ b/tools/cabana/dbc/dbcmanager.h
@@ -4,7 +4,6 @@
#include
#include