From 43210ca0e21b15c1fcaff5517c71827b9fc21dab Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 12 Sep 2023 01:01:07 +1000 Subject: [PATCH 01/59] replay: Include cstdarg from util (#29871) Fix compilation errors "use of undeclared identifier" for va_start & va_end. --- tools/replay/util.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/replay/util.cc b/tools/replay/util.cc index 172d545c75..2c2de69e78 100644 --- a/tools/replay/util.cc +++ b/tools/replay/util.cc @@ -4,6 +4,7 @@ #include #include +#include #include #include #include From 5e1b5b36e48f3b7c776b843993071e24a9d1466e Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Tue, 12 Sep 2023 04:18:40 +0800 Subject: [PATCH 02/59] cabana: use applicationPath for settings (#29875) --- tools/cabana/cabana.cc | 2 ++ tools/cabana/settings.cc | 8 ++------ tools/cabana/settings.h | 4 +++- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/cabana/cabana.cc b/tools/cabana/cabana.cc index 33403a2bff..0ccef7d3ab 100644 --- a/tools/cabana/cabana.cc +++ b/tools/cabana/cabana.cc @@ -18,6 +18,8 @@ int main(int argc, char *argv[]) { app.setWindowIcon(QIcon(":cabana-icon.png")); UnixSignalHandler signalHandler; + + settings.load(); utils::setTheme(settings.theme); QCommandLineParser cmd_parser; diff --git a/tools/cabana/settings.cc b/tools/cabana/settings.cc index d0cada680a..027dcb903f 100644 --- a/tools/cabana/settings.cc +++ b/tools/cabana/settings.cc @@ -13,12 +13,8 @@ Settings settings; -Settings::Settings() { - load(); -} - void Settings::save() { - QSettings s("settings", QSettings::IniFormat); + QSettings s(filePath(), QSettings::IniFormat); s.setValue("fps", fps); s.setValue("max_cached_minutes", max_cached_minutes); s.setValue("chart_height", chart_height); @@ -42,7 +38,7 @@ void Settings::save() { } void Settings::load() { - QSettings s("settings", QSettings::IniFormat); + QSettings s(filePath(), QSettings::IniFormat); fps = s.value("fps", 10).toInt(); max_cached_minutes = s.value("max_cached_minutes", 30).toInt(); chart_height = s.value("chart_height", 200).toInt(); diff --git a/tools/cabana/settings.h b/tools/cabana/settings.h index b8a3797f86..f9eaa8ffad 100644 --- a/tools/cabana/settings.h +++ b/tools/cabana/settings.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -22,9 +23,10 @@ public: AlwaysBE, }; - Settings(); + Settings() {} void save(); void load(); + inline static QString filePath() { return QApplication::applicationDirPath() + "/settings"; } int fps = 10; int max_cached_minutes = 30; From 2c1dfc2f341b09381af2cc7872c4092df28dc9d5 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 11 Sep 2023 14:01:50 -0700 Subject: [PATCH 03/59] use pytest for cpp tests (#29833) * add pytest-cpp package (#29828) * add pytest-cpp package * disable for now * use in ci * use pytest cpp * use my branch * add missing tests * that doesn't make sense * it was merged upstream * replace TEST_RLOG_URL with a publicly accessible url * PR Cleanup * assert instead * update poetry lock * add comment about pytest-cpp --------- Co-authored-by: Justin Newberry Co-authored-by: Justin Newberry Co-authored-by: deanlee --- .github/workflows/selfdrive_tests.yaml | 9 +- poetry.lock | 187 +++++++++++++------------ pyproject.toml | 7 +- system/loggerd/tests/test_logger.cc | 2 +- system/proclogd/tests/test_proclog.cc | 1 - tools/cabana/tests/test_cabana.cc | 3 +- 6 files changed, 105 insertions(+), 104 deletions(-) diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index bce0d553ea..a038570c15 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -263,18 +263,11 @@ jobs: timeout-minutes: 40 run: | ${{ env.RUN }} "export SKIP_LONG_TESTS=1 && \ - $PYTEST -n auto --dist=loadscope --timeout 30 && \ + $PYTEST -n auto --dist=loadscope --timeout 30 -o cpp_files=test_* && \ selfdrive/locationd/test/_test_locationd_lib.py && \ - ./system/ubloxd/tests/test_glonass_runner && \ ./selfdrive/ui/tests/create_test_translations.sh && \ QT_QPA_PLATFORM=offscreen ./selfdrive/ui/tests/test_translations && \ ./selfdrive/ui/tests/test_translations.py && \ - ./common/tests/test_common && \ - ./selfdrive/boardd/tests/test_boardd_usbprotocol && \ - ./system/loggerd/tests/test_logger &&\ - ./system/proclogd/tests/test_proclog && \ - ./tools/replay/tests/test_replay && \ - ./tools/cabana/tests/test_cabana && \ ./system/camerad/test/ae_gray_test && \ ./selfdrive/test/process_replay/test_fuzzy.py" - name: "Upload coverage to Codecov" diff --git a/poetry.lock b/poetry.lock index b1bd2df7c6..255f6b2acc 100644 --- a/poetry.lock +++ b/poetry.lock @@ -314,13 +314,13 @@ files = [ [[package]] name = "azure-core" -version = "1.29.3" +version = "1.29.4" description = "Microsoft Azure Core Library for Python" optional = false python-versions = ">=3.7" files = [ - {file = "azure-core-1.29.3.tar.gz", hash = "sha256:c92700af982e71c8c73de9f4c20da8b3f03ce2c22d13066e4d416b4629c87903"}, - {file = "azure_core-1.29.3-py3-none-any.whl", hash = "sha256:f8b2910f92b66293d93bd00564924ad20ad48f4a1e150577cf18d1e7d4f9263c"}, + {file = "azure-core-1.29.4.tar.gz", hash = "sha256:500b3aa9bf2e90c5ccc88bb105d056114ca0ce7d0ce73afb8bc4d714b2fc7568"}, + {file = "azure_core-1.29.4-py3-none-any.whl", hash = "sha256:b03261bcba22c0b9290faf9999cedd23e849ed2577feee90515694cea6bc74bf"}, ] [package.dependencies] @@ -813,63 +813,63 @@ test = ["pytest", "pytest-timeout"] [[package]] name = "coverage" -version = "7.3.0" +version = "7.3.1" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:db76a1bcb51f02b2007adacbed4c88b6dee75342c37b05d1822815eed19edee5"}, - {file = "coverage-7.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c02cfa6c36144ab334d556989406837336c1d05215a9bdf44c0bc1d1ac1cb637"}, - {file = "coverage-7.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:477c9430ad5d1b80b07f3c12f7120eef40bfbf849e9e7859e53b9c93b922d2af"}, - {file = "coverage-7.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce2ee86ca75f9f96072295c5ebb4ef2a43cecf2870b0ca5e7a1cbdd929cf67e1"}, - {file = "coverage-7.3.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68d8a0426b49c053013e631c0cdc09b952d857efa8f68121746b339912d27a12"}, - {file = "coverage-7.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b3eb0c93e2ea6445b2173da48cb548364f8f65bf68f3d090404080d338e3a689"}, - {file = "coverage-7.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:90b6e2f0f66750c5a1178ffa9370dec6c508a8ca5265c42fbad3ccac210a7977"}, - {file = "coverage-7.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:96d7d761aea65b291a98c84e1250cd57b5b51726821a6f2f8df65db89363be51"}, - {file = "coverage-7.3.0-cp310-cp310-win32.whl", hash = "sha256:63c5b8ecbc3b3d5eb3a9d873dec60afc0cd5ff9d9f1c75981d8c31cfe4df8527"}, - {file = "coverage-7.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:97c44f4ee13bce914272589b6b41165bbb650e48fdb7bd5493a38bde8de730a1"}, - {file = "coverage-7.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:74c160285f2dfe0acf0f72d425f3e970b21b6de04157fc65adc9fd07ee44177f"}, - {file = "coverage-7.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b543302a3707245d454fc49b8ecd2c2d5982b50eb63f3535244fd79a4be0c99d"}, - {file = "coverage-7.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad0f87826c4ebd3ef484502e79b39614e9c03a5d1510cfb623f4a4a051edc6fd"}, - {file = "coverage-7.3.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:13c6cbbd5f31211d8fdb477f0f7b03438591bdd077054076eec362cf2207b4a7"}, - {file = "coverage-7.3.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fac440c43e9b479d1241fe9d768645e7ccec3fb65dc3a5f6e90675e75c3f3e3a"}, - {file = "coverage-7.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3c9834d5e3df9d2aba0275c9f67989c590e05732439b3318fa37a725dff51e74"}, - {file = "coverage-7.3.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4c8e31cf29b60859876474034a83f59a14381af50cbe8a9dbaadbf70adc4b214"}, - {file = "coverage-7.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7a9baf8e230f9621f8e1d00c580394a0aa328fdac0df2b3f8384387c44083c0f"}, - {file = "coverage-7.3.0-cp311-cp311-win32.whl", hash = "sha256:ccc51713b5581e12f93ccb9c5e39e8b5d4b16776d584c0f5e9e4e63381356482"}, - {file = "coverage-7.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:887665f00ea4e488501ba755a0e3c2cfd6278e846ada3185f42d391ef95e7e70"}, - {file = "coverage-7.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d000a739f9feed900381605a12a61f7aaced6beae832719ae0d15058a1e81c1b"}, - {file = "coverage-7.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:59777652e245bb1e300e620ce2bef0d341945842e4eb888c23a7f1d9e143c446"}, - {file = "coverage-7.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9737bc49a9255d78da085fa04f628a310c2332b187cd49b958b0e494c125071"}, - {file = "coverage-7.3.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5247bab12f84a1d608213b96b8af0cbb30d090d705b6663ad794c2f2a5e5b9fe"}, - {file = "coverage-7.3.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2ac9a1de294773b9fa77447ab7e529cf4fe3910f6a0832816e5f3d538cfea9a"}, - {file = "coverage-7.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:85b7335c22455ec12444cec0d600533a238d6439d8d709d545158c1208483873"}, - {file = "coverage-7.3.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:36ce5d43a072a036f287029a55b5c6a0e9bd73db58961a273b6dc11a2c6eb9c2"}, - {file = "coverage-7.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:211a4576e984f96d9fce61766ffaed0115d5dab1419e4f63d6992b480c2bd60b"}, - {file = "coverage-7.3.0-cp312-cp312-win32.whl", hash = "sha256:56afbf41fa4a7b27f6635bc4289050ac3ab7951b8a821bca46f5b024500e6321"}, - {file = "coverage-7.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:7f297e0c1ae55300ff688568b04ff26b01c13dfbf4c9d2b7d0cb688ac60df479"}, - {file = "coverage-7.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ac0dec90e7de0087d3d95fa0533e1d2d722dcc008bc7b60e1143402a04c117c1"}, - {file = "coverage-7.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:438856d3f8f1e27f8e79b5410ae56650732a0dcfa94e756df88c7e2d24851fcd"}, - {file = "coverage-7.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1084393c6bda8875c05e04fce5cfe1301a425f758eb012f010eab586f1f3905e"}, - {file = "coverage-7.3.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49ab200acf891e3dde19e5aa4b0f35d12d8b4bd805dc0be8792270c71bd56c54"}, - {file = "coverage-7.3.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a67e6bbe756ed458646e1ef2b0778591ed4d1fcd4b146fc3ba2feb1a7afd4254"}, - {file = "coverage-7.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8f39c49faf5344af36042b293ce05c0d9004270d811c7080610b3e713251c9b0"}, - {file = "coverage-7.3.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7df91fb24c2edaabec4e0eee512ff3bc6ec20eb8dccac2e77001c1fe516c0c84"}, - {file = "coverage-7.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:34f9f0763d5fa3035a315b69b428fe9c34d4fc2f615262d6be3d3bf3882fb985"}, - {file = "coverage-7.3.0-cp38-cp38-win32.whl", hash = "sha256:bac329371d4c0d456e8d5f38a9b0816b446581b5f278474e416ea0c68c47dcd9"}, - {file = "coverage-7.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:b859128a093f135b556b4765658d5d2e758e1fae3e7cc2f8c10f26fe7005e543"}, - {file = "coverage-7.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fc0ed8d310afe013db1eedd37176d0839dc66c96bcfcce8f6607a73ffea2d6ba"}, - {file = "coverage-7.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61260ec93f99f2c2d93d264b564ba912bec502f679793c56f678ba5251f0393"}, - {file = "coverage-7.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97af9554a799bd7c58c0179cc8dbf14aa7ab50e1fd5fa73f90b9b7215874ba28"}, - {file = "coverage-7.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3558e5b574d62f9c46b76120a5c7c16c4612dc2644c3d48a9f4064a705eaee95"}, - {file = "coverage-7.3.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37d5576d35fcb765fca05654f66aa71e2808d4237d026e64ac8b397ffa66a56a"}, - {file = "coverage-7.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:07ea61bcb179f8f05ffd804d2732b09d23a1238642bf7e51dad62082b5019b34"}, - {file = "coverage-7.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:80501d1b2270d7e8daf1b64b895745c3e234289e00d5f0e30923e706f110334e"}, - {file = "coverage-7.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4eddd3153d02204f22aef0825409091a91bf2a20bce06fe0f638f5c19a85de54"}, - {file = "coverage-7.3.0-cp39-cp39-win32.whl", hash = "sha256:2d22172f938455c156e9af2612650f26cceea47dc86ca048fa4e0b2d21646ad3"}, - {file = "coverage-7.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:60f64e2007c9144375dd0f480a54d6070f00bb1a28f65c408370544091c9bc9e"}, - {file = "coverage-7.3.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:5492a6ce3bdb15c6ad66cb68a0244854d9917478877a25671d70378bdc8562d0"}, - {file = "coverage-7.3.0.tar.gz", hash = "sha256:49dbb19cdcafc130f597d9e04a29d0a032ceedf729e41b181f51cd170e6ee865"}, + {file = "coverage-7.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cd0f7429ecfd1ff597389907045ff209c8fdb5b013d38cfa7c60728cb484b6e3"}, + {file = "coverage-7.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:966f10df9b2b2115da87f50f6a248e313c72a668248be1b9060ce935c871f276"}, + {file = "coverage-7.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0575c37e207bb9b98b6cf72fdaaa18ac909fb3d153083400c2d48e2e6d28bd8e"}, + {file = "coverage-7.3.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:245c5a99254e83875c7fed8b8b2536f040997a9b76ac4c1da5bff398c06e860f"}, + {file = "coverage-7.3.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c96dd7798d83b960afc6c1feb9e5af537fc4908852ef025600374ff1a017392"}, + {file = "coverage-7.3.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:de30c1aa80f30af0f6b2058a91505ea6e36d6535d437520067f525f7df123887"}, + {file = "coverage-7.3.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:50dd1e2dd13dbbd856ffef69196781edff26c800a74f070d3b3e3389cab2600d"}, + {file = "coverage-7.3.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b9c0c19f70d30219113b18fe07e372b244fb2a773d4afde29d5a2f7930765136"}, + {file = "coverage-7.3.1-cp310-cp310-win32.whl", hash = "sha256:770f143980cc16eb601ccfd571846e89a5fe4c03b4193f2e485268f224ab602f"}, + {file = "coverage-7.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:cdd088c00c39a27cfa5329349cc763a48761fdc785879220d54eb785c8a38520"}, + {file = "coverage-7.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:74bb470399dc1989b535cb41f5ca7ab2af561e40def22d7e188e0a445e7639e3"}, + {file = "coverage-7.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:025ded371f1ca280c035d91b43252adbb04d2aea4c7105252d3cbc227f03b375"}, + {file = "coverage-7.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6191b3a6ad3e09b6cfd75b45c6aeeffe7e3b0ad46b268345d159b8df8d835f9"}, + {file = "coverage-7.3.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7eb0b188f30e41ddd659a529e385470aa6782f3b412f860ce22b2491c89b8593"}, + {file = "coverage-7.3.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75c8f0df9dfd8ff745bccff75867d63ef336e57cc22b2908ee725cc552689ec8"}, + {file = "coverage-7.3.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7eb3cd48d54b9bd0e73026dedce44773214064be93611deab0b6a43158c3d5a0"}, + {file = "coverage-7.3.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ac3c5b7e75acac31e490b7851595212ed951889918d398b7afa12736c85e13ce"}, + {file = "coverage-7.3.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5b4ee7080878077af0afa7238df1b967f00dc10763f6e1b66f5cced4abebb0a3"}, + {file = "coverage-7.3.1-cp311-cp311-win32.whl", hash = "sha256:229c0dd2ccf956bf5aeede7e3131ca48b65beacde2029f0361b54bf93d36f45a"}, + {file = "coverage-7.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:c6f55d38818ca9596dc9019eae19a47410d5322408140d9a0076001a3dcb938c"}, + {file = "coverage-7.3.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5289490dd1c3bb86de4730a92261ae66ea8d44b79ed3cc26464f4c2cde581fbc"}, + {file = "coverage-7.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ca833941ec701fda15414be400c3259479bfde7ae6d806b69e63b3dc423b1832"}, + {file = "coverage-7.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd694e19c031733e446c8024dedd12a00cda87e1c10bd7b8539a87963685e969"}, + {file = "coverage-7.3.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aab8e9464c00da5cb9c536150b7fbcd8850d376d1151741dd0d16dfe1ba4fd26"}, + {file = "coverage-7.3.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87d38444efffd5b056fcc026c1e8d862191881143c3aa80bb11fcf9dca9ae204"}, + {file = "coverage-7.3.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:8a07b692129b8a14ad7a37941a3029c291254feb7a4237f245cfae2de78de037"}, + {file = "coverage-7.3.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:2829c65c8faaf55b868ed7af3c7477b76b1c6ebeee99a28f59a2cb5907a45760"}, + {file = "coverage-7.3.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1f111a7d85658ea52ffad7084088277135ec5f368457275fc57f11cebb15607f"}, + {file = "coverage-7.3.1-cp312-cp312-win32.whl", hash = "sha256:c397c70cd20f6df7d2a52283857af622d5f23300c4ca8e5bd8c7a543825baa5a"}, + {file = "coverage-7.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:5ae4c6da8b3d123500f9525b50bf0168023313963e0e2e814badf9000dd6ef92"}, + {file = "coverage-7.3.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ca70466ca3a17460e8fc9cea7123c8cbef5ada4be3140a1ef8f7b63f2f37108f"}, + {file = "coverage-7.3.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f2781fd3cabc28278dc982a352f50c81c09a1a500cc2086dc4249853ea96b981"}, + {file = "coverage-7.3.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6407424621f40205bbe6325686417e5e552f6b2dba3535dd1f90afc88a61d465"}, + {file = "coverage-7.3.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:04312b036580ec505f2b77cbbdfb15137d5efdfade09156961f5277149f5e344"}, + {file = "coverage-7.3.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac9ad38204887349853d7c313f53a7b1c210ce138c73859e925bc4e5d8fc18e7"}, + {file = "coverage-7.3.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:53669b79f3d599da95a0afbef039ac0fadbb236532feb042c534fbb81b1a4e40"}, + {file = "coverage-7.3.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:614f1f98b84eb256e4f35e726bfe5ca82349f8dfa576faabf8a49ca09e630086"}, + {file = "coverage-7.3.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f1a317fdf5c122ad642db8a97964733ab7c3cf6009e1a8ae8821089993f175ff"}, + {file = "coverage-7.3.1-cp38-cp38-win32.whl", hash = "sha256:defbbb51121189722420a208957e26e49809feafca6afeef325df66c39c4fdb3"}, + {file = "coverage-7.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:f4f456590eefb6e1b3c9ea6328c1e9fa0f1006e7481179d749b3376fc793478e"}, + {file = "coverage-7.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f12d8b11a54f32688b165fd1a788c408f927b0960984b899be7e4c190ae758f1"}, + {file = "coverage-7.3.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f09195dda68d94a53123883de75bb97b0e35f5f6f9f3aa5bf6e496da718f0cb6"}, + {file = "coverage-7.3.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6601a60318f9c3945be6ea0f2a80571f4299b6801716f8a6e4846892737ebe4"}, + {file = "coverage-7.3.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07d156269718670d00a3b06db2288b48527fc5f36859425ff7cec07c6b367745"}, + {file = "coverage-7.3.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:636a8ac0b044cfeccae76a36f3b18264edcc810a76a49884b96dd744613ec0b7"}, + {file = "coverage-7.3.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5d991e13ad2ed3aced177f524e4d670f304c8233edad3210e02c465351f785a0"}, + {file = "coverage-7.3.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:586649ada7cf139445da386ab6f8ef00e6172f11a939fc3b2b7e7c9082052fa0"}, + {file = "coverage-7.3.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4aba512a15a3e1e4fdbfed2f5392ec221434a614cc68100ca99dcad7af29f3f8"}, + {file = "coverage-7.3.1-cp39-cp39-win32.whl", hash = "sha256:6bc6f3f4692d806831c136c5acad5ccedd0262aa44c087c46b7101c77e139140"}, + {file = "coverage-7.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:553d7094cb27db58ea91332e8b5681bac107e7242c23f7629ab1316ee73c4981"}, + {file = "coverage-7.3.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:220eb51f5fb38dfdb7e5d54284ca4d0cd70ddac047d750111a68ab1798945194"}, + {file = "coverage-7.3.1.tar.gz", hash = "sha256:6cb7fe1581deb67b782c153136541e20901aa312ceedaf1467dcb35255787952"}, ] [package.extras] @@ -3194,24 +3194,24 @@ files = [ [[package]] name = "protobuf" -version = "4.24.2" +version = "4.24.3" description = "" optional = false python-versions = ">=3.7" files = [ - {file = "protobuf-4.24.2-cp310-abi3-win32.whl", hash = "sha256:58e12d2c1aa428ece2281cef09bbaa6938b083bcda606db3da4e02e991a0d924"}, - {file = "protobuf-4.24.2-cp310-abi3-win_amd64.whl", hash = "sha256:77700b55ba41144fc64828e02afb41901b42497b8217b558e4a001f18a85f2e3"}, - {file = "protobuf-4.24.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:237b9a50bd3b7307d0d834c1b0eb1a6cd47d3f4c2da840802cd03ea288ae8880"}, - {file = "protobuf-4.24.2-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:25ae91d21e3ce8d874211110c2f7edd6384816fb44e06b2867afe35139e1fd1c"}, - {file = "protobuf-4.24.2-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:c00c3c7eb9ad3833806e21e86dca448f46035242a680f81c3fe068ff65e79c74"}, - {file = "protobuf-4.24.2-cp37-cp37m-win32.whl", hash = "sha256:4e69965e7e54de4db989289a9b971a099e626f6167a9351e9d112221fc691bc1"}, - {file = "protobuf-4.24.2-cp37-cp37m-win_amd64.whl", hash = "sha256:c5cdd486af081bf752225b26809d2d0a85e575b80a84cde5172a05bbb1990099"}, - {file = "protobuf-4.24.2-cp38-cp38-win32.whl", hash = "sha256:6bd26c1fa9038b26c5c044ee77e0ecb18463e957fefbaeb81a3feb419313a54e"}, - {file = "protobuf-4.24.2-cp38-cp38-win_amd64.whl", hash = "sha256:bb7aa97c252279da65584af0456f802bd4b2de429eb945bbc9b3d61a42a8cd16"}, - {file = "protobuf-4.24.2-cp39-cp39-win32.whl", hash = "sha256:2b23bd6e06445699b12f525f3e92a916f2dcf45ffba441026357dea7fa46f42b"}, - {file = "protobuf-4.24.2-cp39-cp39-win_amd64.whl", hash = "sha256:839952e759fc40b5d46be319a265cf94920174d88de31657d5622b5d8d6be5cd"}, - {file = "protobuf-4.24.2-py3-none-any.whl", hash = "sha256:3b7b170d3491ceed33f723bbf2d5a260f8a4e23843799a3906f16ef736ef251e"}, - {file = "protobuf-4.24.2.tar.gz", hash = "sha256:7fda70797ddec31ddfa3576cbdcc3ddbb6b3078b737a1a87ab9136af0570cd6e"}, + {file = "protobuf-4.24.3-cp310-abi3-win32.whl", hash = "sha256:20651f11b6adc70c0f29efbe8f4a94a74caf61b6200472a9aea6e19898f9fcf4"}, + {file = "protobuf-4.24.3-cp310-abi3-win_amd64.whl", hash = "sha256:3d42e9e4796a811478c783ef63dc85b5a104b44aaaca85d4864d5b886e4b05e3"}, + {file = "protobuf-4.24.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:6e514e8af0045be2b56e56ae1bb14f43ce7ffa0f68b1c793670ccbe2c4fc7d2b"}, + {file = "protobuf-4.24.3-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:ba53c2f04798a326774f0e53b9c759eaef4f6a568ea7072ec6629851c8435959"}, + {file = "protobuf-4.24.3-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:f6ccbcf027761a2978c1406070c3788f6de4a4b2cc20800cc03d52df716ad675"}, + {file = "protobuf-4.24.3-cp37-cp37m-win32.whl", hash = "sha256:1b182c7181a2891e8f7f3a1b5242e4ec54d1f42582485a896e4de81aa17540c2"}, + {file = "protobuf-4.24.3-cp37-cp37m-win_amd64.whl", hash = "sha256:b0271a701e6782880d65a308ba42bc43874dabd1a0a0f41f72d2dac3b57f8e76"}, + {file = "protobuf-4.24.3-cp38-cp38-win32.whl", hash = "sha256:e29d79c913f17a60cf17c626f1041e5288e9885c8579832580209de8b75f2a52"}, + {file = "protobuf-4.24.3-cp38-cp38-win_amd64.whl", hash = "sha256:067f750169bc644da2e1ef18c785e85071b7c296f14ac53e0900e605da588719"}, + {file = "protobuf-4.24.3-cp39-cp39-win32.whl", hash = "sha256:2da777d34b4f4f7613cdf85c70eb9a90b1fbef9d36ae4a0ccfe014b0b07906f1"}, + {file = "protobuf-4.24.3-cp39-cp39-win_amd64.whl", hash = "sha256:f631bb982c5478e0c1c70eab383af74a84be66945ebf5dd6b06fc90079668d0b"}, + {file = "protobuf-4.24.3-py3-none-any.whl", hash = "sha256:f6f8dc65625dadaad0c8545319c2e2f0424fede988368893ca3844261342c11a"}, + {file = "protobuf-4.24.3.tar.gz", hash = "sha256:12e9ad2ec079b833176d2921be2cb24281fa591f0b119b208b788adc48c2561d"}, ] [[package]] @@ -3759,13 +3759,13 @@ cp2110 = ["hidapi"] [[package]] name = "pytest" -version = "7.4.1" +version = "7.4.2" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.4.1-py3-none-any.whl", hash = "sha256:460c9a59b14e27c602eb5ece2e47bec99dc5fc5f6513cf924a7d03a578991b1f"}, - {file = "pytest-7.4.1.tar.gz", hash = "sha256:2f2301e797521b23e4d2585a0a3d7b5e50fdddaaf7e7d6773ea26ddb17c213ab"}, + {file = "pytest-7.4.2-py3-none-any.whl", hash = "sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002"}, + {file = "pytest-7.4.2.tar.gz", hash = "sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069"}, ] [package.dependencies] @@ -3795,6 +3795,21 @@ pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] +[[package]] +name = "pytest-cpp" +version = "2.4.0" +description = "Use pytest's runner to discover and execute C++ tests" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-cpp-2.4.0.tar.gz", hash = "sha256:dcb8b09d4c714fc7f778dc40a7c2c47e73cc50280d7f9bba3bdd3ca98abd4685"}, + {file = "pytest_cpp-2.4.0-py3-none-any.whl", hash = "sha256:e7c5f40b70b00cc09d672a1584e35beb9b9553512cdd4b1d1f99468747b3bc31"}, +] + +[package.dependencies] +colorama = "*" +pytest = ">=7.0" + [[package]] name = "pytest-subtests" version = "0.11.0" @@ -3934,7 +3949,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"}, @@ -3942,15 +3956,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"}, @@ -3967,7 +3974,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"}, @@ -3975,7 +3981,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"}, @@ -4166,9 +4171,9 @@ setuptools = "*" [[package]] name = "sconscontrib" version = "1.0" -description = "Contributed builders and other useful logic for the SCons build system.," +description = "" optional = false -python-versions = "<4,>=3.6" +python-versions = ">=3.6, <4" files = [] develop = false @@ -4333,19 +4338,19 @@ test = ["pytest"] [[package]] name = "setuptools" -version = "68.1.2" +version = "68.2.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-68.1.2-py3-none-any.whl", hash = "sha256:3d8083eed2d13afc9426f227b24fd1659489ec107c0e86cec2ffdde5c92e790b"}, - {file = "setuptools-68.1.2.tar.gz", hash = "sha256:3d4dfa6d95f1b101d695a6160a7626e15583af71a5f52176efa5d39a054d475d"}, + {file = "setuptools-68.2.0-py3-none-any.whl", hash = "sha256:af3d5949030c3f493f550876b2fd1dd5ec66689c4ee5d5344f009746f71fd5a8"}, + {file = "setuptools-68.2.0.tar.gz", hash = "sha256:00478ca80aeebeecb2f288d3206b0de568df5cd2b8fada1209843cc9a8d88a48"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5,<=7.1.2)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "shapely" @@ -5049,4 +5054,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "~3.11" -content-hash = "0e7f2a907e73eaa31137d70be3a56d350d6fc6dbc54811c80d6031409fddcac1" +content-hash = "7258a24274936ccdafb930a683f4ea197e82ab187698d0723bb4683ca41e6d26" diff --git a/pyproject.toml b/pyproject.toml index 5d4daadb15..5d4bcafa7a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,7 @@ [tool.pytest.ini_options] minversion = "6.0" addopts = "--ignore=openpilot/ --ignore=cereal/ --ignore=opendbc/ --ignore=panda/ --ignore=rednose_repo/ --ignore=tinygrad_repo/ --ignore=laika_repo/ -Werror --strict-config --strict-markers --durations=10" +#cpp_files = "test_*" # uncomment when agnos has pytest-cpp and remove from CI python_files = "test_*.py" #timeout = "30" # you get this long by default markers = [ @@ -18,9 +19,12 @@ testpaths = [ "selfdrive/test/longitudinal_maneuvers", "system/hardware/tici", "system/loggerd", + "system/proclogd", "system/tests", "system/ubloxd", - "tools/lib/tests" + "tools/lib/tests", + "tools/replay", + "tools/cabana" ] [tool.mypy] @@ -142,6 +146,7 @@ pygame = "*" pyprof2calltree = "*" pytest = "*" pytest-cov = "*" +pytest-cpp = "*" pytest-subtests = "*" pytest-xdist = "*" pytest-timeout = "*" diff --git a/system/loggerd/tests/test_logger.cc b/system/loggerd/tests/test_logger.cc index 9c82299091..9f815c2189 100644 --- a/system/loggerd/tests/test_logger.cc +++ b/system/loggerd/tests/test_logger.cc @@ -97,7 +97,7 @@ TEST_CASE("logger") { auto logging_thread = [&]() -> void { LoggerHandle *lh = logger_get_handle(&logger); - REQUIRE(lh != nullptr); + assert(lh != nullptr); int segment = main_segment; int delayed_cnt = 0; while (!do_exit) { diff --git a/system/proclogd/tests/test_proclog.cc b/system/proclogd/tests/test_proclog.cc index affde2f320..33fccd4f30 100644 --- a/system/proclogd/tests/test_proclog.cc +++ b/system/proclogd/tests/test_proclog.cc @@ -140,7 +140,6 @@ TEST_CASE("buildProcLogerMessage") { REQUIRE(p.getName() == "test_proclog"); REQUIRE(p.getState() == 'R'); REQUIRE_THAT(p.getExe().cStr(), Catch::Matchers::Contains("test_proclog")); - REQUIRE(p.getCmdline().size() == 1); REQUIRE_THAT(p.getCmdline()[0], Catch::Matchers::Contains("test_proclog")); } else { std::string cmd_path = "/proc/" + std::to_string(p.getPid()) + "/cmdline"; diff --git a/tools/cabana/tests/test_cabana.cc b/tools/cabana/tests/test_cabana.cc index a3d014dd2c..d114f72ea5 100644 --- a/tools/cabana/tests/test_cabana.cc +++ b/tools/cabana/tests/test_cabana.cc @@ -6,8 +6,7 @@ #include "tools/cabana/dbc/dbcmanager.h" #include "tools/cabana/streams/abstractstream.h" -// demo route, first segment -const std::string TEST_RLOG_URL = "https://commadata2.blob.core.windows.net/commadata2/a2a0ccea32023010/2023-07-27--13-01-19/0/rlog.bz2"; +const std::string TEST_RLOG_URL = "https://commadataci.blob.core.windows.net/openpilotci/0c94aa1e1296d7c6/2021-05-05--19-48-37/0/rlog.bz2"; TEST_CASE("DBCFile::generateDBC") { QString fn = QString("%1/%2.dbc").arg(OPENDBC_FILE_PATH, "tesla_can"); From 30084bb1beee0e8b62ee049016a482420389dfb5 Mon Sep 17 00:00:00 2001 From: freddiebd Date: Mon, 11 Sep 2023 22:11:32 +0100 Subject: [PATCH 04/59] VW MQB: Add FW for 2019 Golf R Estate (#29843) --- selfdrive/car/volkswagen/values.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index ebb873c8be..1cb7f1d29d 100644 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -461,6 +461,7 @@ FW_VERSIONS = { b'\xf1\x878V0906259K \xf1\x890003', b'\xf1\x878V0906259P \xf1\x890001', b'\xf1\x878V0906259Q \xf1\x890002', + b'\xf1\x878V0906259R \xf1\x890002', b'\xf1\x878V0906264F \xf1\x890003', b'\xf1\x878V0906264L \xf1\x890002', b'\xf1\x878V0906264M \xf1\x890001', @@ -502,6 +503,7 @@ FW_VERSIONS = { b'\xf1\x870GC300012A \xf1\x891401', b'\xf1\x870GC300012A \xf1\x891403', b'\xf1\x870GC300014B \xf1\x892401', + b'\xf1\x870GC300014B \xf1\x892403', b'\xf1\x870GC300014B \xf1\x892405', b'\xf1\x870GC300020G \xf1\x892401', b'\xf1\x870GC300020G \xf1\x892403', @@ -521,6 +523,7 @@ FW_VERSIONS = { b'\xf1\x875Q0959655BS\xf1\x890403\xf1\x82\x1314160011123300314240012250229333463100', b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\x13141600111233003142404A2251229333463100', b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\x13141600111233003142404A2252229333463100', + b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\x13141600111233003142405A2251229333463100', b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\x13141600111233003142405A2252229333463100', b'\xf1\x875Q0959655C \xf1\x890361\xf1\x82\x111413001112120004110415121610169112', b'\xf1\x875Q0959655D \xf1\x890388\xf1\x82\x111413001113120006110417121A101A9113', @@ -547,6 +550,7 @@ FW_VERSIONS = { b'\xf1\x873Q0909144K \xf1\x895072\xf1\x82\x0571A0J714A1', b'\xf1\x873Q0909144L \xf1\x895081\xf1\x82\x0571A0JA15A1', b'\xf1\x873Q0909144M \xf1\x895082\xf1\x82\x0571A01A18A1', + b'\xf1\x873Q0909144M \xf1\x895082\xf1\x82\x0571A02A16A1', b'\xf1\x873Q0909144M \xf1\x895082\xf1\x82\x0571A0JA16A1', b'\xf1\x873QM909144 \xf1\x895072\xf1\x82\x0571A01714A1', b'\xf1\x875Q0909143K \xf1\x892033\xf1\x820519A9040203', From 00d1c682b0a6e62652dbfe4686c674539fe82d8f Mon Sep 17 00:00:00 2001 From: Vivek Aithal Date: Mon, 11 Sep 2023 16:28:42 -0700 Subject: [PATCH 05/59] Alerts: More understandable locationd, paramsd alerts (#29831) * add locationd paramsd alerts * remove more additions, just renames * update refs * Update selfdrive/controls/lib/events.py Co-authored-by: Adeeb Shihadeh * Update selfdrive/controls/lib/events.py Co-authored-by: Adeeb Shihadeh * resolve comemnts * update cereal * update refs * remove nosensor in new alerts * bump cereal --------- Co-authored-by: Adeeb Shihadeh --- cereal | 2 +- selfdrive/controls/controlsd.py | 14 ++++---- selfdrive/controls/lib/events.py | 44 +++++++++++++++--------- selfdrive/test/process_replay/ref_commit | 2 +- 4 files changed, 37 insertions(+), 25 deletions(-) diff --git a/cereal b/cereal index 7de568b659..4b334f6f10 160000 --- a/cereal +++ b/cereal @@ -1 +1 @@ -Subproject commit 7de568b65922b1b7a5cb9a9a391e3e03394500f7 +Subproject commit 4b334f6f10877e4a666b23983de2d27934ebf3b1 diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 6cfeabefd4..1dc9dd39f7 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -374,19 +374,19 @@ class Controls: else: self.logged_comm_issue = None - if not self.sm['liveParameters'].valid and not TESTING_CLOSET and (not SIMULATION or REPLAY): - self.events.add(EventName.vehicleModelInvalid) if not self.sm['lateralPlan'].mpcSolutionValid: self.events.add(EventName.plannerError) - if not (self.sm['liveParameters'].sensorValid or self.sm['liveLocationKalman'].sensorsOK) and not NOSENSOR: - if self.sm.frame > 5 / DT_CTRL: # Give locationd some time to receive all the inputs - self.events.add(EventName.sensorDataInvalid) - if not self.sm['liveLocationKalman'].inputsOK and not NOSENSOR: - self.events.add(EventName.localizerMalfunction) if not self.sm['liveLocationKalman'].posenetOK: self.events.add(EventName.posenetInvalid) if not self.sm['liveLocationKalman'].deviceStable: self.events.add(EventName.deviceFalling) + if not (self.sm['liveParameters'].sensorValid or self.sm['liveLocationKalman'].sensorsOK): + if self.sm.frame > 5 / DT_CTRL: # Give locationd some time to receive sensor inputs + self.events.add(EventName.sensorDataInvalid) + if not self.sm['liveLocationKalman'].inputsOK: + self.events.add(EventName.locationdTemporaryError) + if not self.sm['liveParameters'].valid and not TESTING_CLOSET and (not SIMULATION or REPLAY): + self.events.add(EventName.paramsdTemporaryError) if not REPLAY: # Check for mismatch between openpilot and car's PCM diff --git a/selfdrive/controls/lib/events.py b/selfdrive/controls/lib/events.py index 6f41224475..81e55e6bbc 100755 --- a/selfdrive/controls/lib/events.py +++ b/selfdrive/controls/lib/events.py @@ -424,19 +424,6 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = { # ********** events only containing alerts that display while engaged ********** - # openpilot tries to learn certain parameters about your car by observing - # how the car behaves to steering inputs from both human and openpilot driving. - # This includes: - # - steer ratio: gear ratio of the steering rack. Steering angle divided by tire angle - # - tire stiffness: how much grip your tires have - # - angle offset: most steering angle sensors are offset and measure a non zero angle when driving straight - # This alert is thrown when any of these values exceed a sanity check. This can be caused by - # bad alignment or bad sensor data. If this happens consistently consider creating an issue on GitHub - EventName.vehicleModelInvalid: { - ET.NO_ENTRY: NoEntryAlert("Vehicle Parameter Identification Failed"), - ET.SOFT_DISABLE: soft_disable_alert("Vehicle Parameter Identification Failed"), - }, - EventName.steerTempUnavailableSilent: { ET.WARNING: Alert( "Steering Temporarily Unavailable", @@ -576,9 +563,34 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = { ET.PERMANENT: NormalPermanentAlert("GPS Malfunction", "Likely Hardware Issue"), }, - EventName.localizerMalfunction: { - ET.NO_ENTRY: NoEntryAlert("Localizer Malfunction"), - ET.SOFT_DISABLE: soft_disable_alert("Localizer Malfunction"), + EventName.locationdTemporaryError: { + ET.NO_ENTRY: NoEntryAlert("locationd Temporary Error"), + ET.SOFT_DISABLE: soft_disable_alert("locationd Temporary Error"), + }, + + EventName.locationdPermanentError: { + ET.NO_ENTRY: NoEntryAlert("locationd Permanent Error"), + ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("locationd Permanent Error"), + ET.PERMANENT: NormalPermanentAlert("locationd Permanent Error"), + }, + + # openpilot tries to learn certain parameters about your car by observing + # how the car behaves to steering inputs from both human and openpilot driving. + # This includes: + # - steer ratio: gear ratio of the steering rack. Steering angle divided by tire angle + # - tire stiffness: how much grip your tires have + # - angle offset: most steering angle sensors are offset and measure a non zero angle when driving straight + # This alert is thrown when any of these values exceed a sanity check. This can be caused by + # bad alignment or bad sensor data. If this happens consistently consider creating an issue on GitHub + EventName.paramsdTemporaryError: { + ET.NO_ENTRY: NoEntryAlert("paramsd Temporary Error"), + ET.SOFT_DISABLE: soft_disable_alert("paramsd Temporary Error"), + }, + + EventName.paramsdPermanentError: { + ET.NO_ENTRY: NoEntryAlert("paramsd Permanent Error"), + ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("paramsd Permanent Error"), + ET.PERMANENT: NormalPermanentAlert("paramsd Permanent Error"), }, # ********** events that affect controls state transitions ********** diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 19a8a56e55..c6a2d58fec 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -98c21236f831ca3cff63939cb760b213460e84de \ No newline at end of file +b421ff389ce720b70a36dd2b3510af54eb484b5f \ No newline at end of file From 57f0c3b8d592a28be1ad81ee884150650e722e31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20R=C4=85czy?= Date: Mon, 11 Sep 2023 17:00:08 -0700 Subject: [PATCH 06/59] macos: link qt5 during setup (#29879) * link qt5 or prompt user to unlink existing qt installation if needed * change condition * version detection fixes * fix wording --- tools/mac_setup.sh | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tools/mac_setup.sh b/tools/mac_setup.sh index 712923626b..0c9627ca4e 100755 --- a/tools/mac_setup.sh +++ b/tools/mac_setup.sh @@ -74,6 +74,27 @@ export PYCURL_SSL_LIBRARY=openssl $DIR/install_python_dependencies.sh echo "[ ] installed python dependencies t=$SECONDS" +# brew does not link qt5 by default +# check if qt5 can be linked, if not, prompt the user to link it +QT_BIN_LOCATION="$(command -v lupdate || :)" +if [ -n "$QT_BIN_LOCATION" ]; then + # if qt6 is linked, prompt the user to unlink it and link the right version + QT_BIN_VERSION="$(lupdate -version | awk '{print $NF}')" + if [[ ! "$QT_BIN_VERSION" =~ 5\.[0-9]+\.[0-9]+ ]]; then + echo + echo "lupdate/lrelease available at PATH is $QT_BIN_VERSION" + if [[ "$QT_BIN_LOCATION" == "$(brew --prefix)/"* ]]; then + echo "Run the following command to link qt5:" + echo "brew unlink qt@6 && brew link qt@5" + else + echo "Remove conflicting qt entries from PATH and run the following command to link qt5:" + echo "brew link qt@5" + fi + fi +else + brew link qt@5 +fi + echo echo "---- OPENPILOT SETUP DONE ----" echo "Open a new shell or configure your active shell env by running:" From d0c922ce77a358fdce4702ceaf31c2a70db50fe7 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 11 Sep 2023 20:58:30 -0700 Subject: [PATCH 07/59] bump opendbc (#29884) --- opendbc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opendbc b/opendbc index 5ebf73ebed..966e16c31e 160000 --- a/opendbc +++ b/opendbc @@ -1 +1 @@ -Subproject commit 5ebf73ebed8d1693aadffe97bd2dd012da3b3c1c +Subproject commit 966e16c31e5d7e2a08f8a365024424ee28efc240 From 11d157369b2144f2cb73b141c7cfbf9929f923f8 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Tue, 12 Sep 2023 13:56:40 +0800 Subject: [PATCH 08/59] cabana/chart: fix rubber band precision issue (#29887) fix rubber band precision issue --- tools/cabana/chart/chart.cc | 7 +++++-- tools/cabana/chart/chart.h | 1 + tools/cabana/chart/chartswidget.cc | 2 +- tools/cabana/chart/chartswidget.h | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/cabana/chart/chart.cc b/tools/cabana/chart/chart.cc index 709a052d72..3ee47ae0c6 100644 --- a/tools/cabana/chart/chart.cc +++ b/tools/cabana/chart/chart.cc @@ -474,7 +474,7 @@ void ChartView::mouseReleaseEvent(QMouseEvent *event) { auto rubber = findChild(); if (event->button() == Qt::LeftButton && rubber && rubber->isVisible()) { rubber->hide(); - QRectF rect = rubber->geometry().normalized(); + auto rect = rubber->geometry().normalized(); double min = chart()->mapToValue(rect.topLeft()).x(); double max = chart()->mapToValue(rect.bottomRight()).x(); @@ -698,7 +698,10 @@ void ChartView::drawForeground(QPainter *painter, const QRectF &rect) { } } - // paint zoom range + drawRubberBandTimeRange(painter); +} + +void ChartView::drawRubberBandTimeRange(QPainter *painter) { auto rubber = findChild(); if (rubber && rubber->isVisible() && rubber->width() > 1) { painter->setPen(Qt::white); diff --git a/tools/cabana/chart/chart.h b/tools/cabana/chart/chart.h index 2740d81b66..71cf7058ab 100644 --- a/tools/cabana/chart/chart.h +++ b/tools/cabana/chart/chart.h @@ -84,6 +84,7 @@ private: void drawBackground(QPainter *painter, const QRectF &rect) override; void drawDropIndicator(bool draw) { if (std::exchange(can_drop, draw) != can_drop) viewport()->update(); } void drawTimeline(QPainter *painter); + void drawRubberBandTimeRange(QPainter *painter); std::tuple getNiceAxisNumbers(qreal min, qreal max, int tick_count); qreal niceNumber(qreal x, bool ceiling); QXYSeries *createSeries(SeriesType type, QColor color); diff --git a/tools/cabana/chart/chartswidget.cc b/tools/cabana/chart/chartswidget.cc index e852e6d206..d4ad9d48ad 100644 --- a/tools/cabana/chart/chartswidget.cc +++ b/tools/cabana/chart/chartswidget.cc @@ -219,7 +219,7 @@ void ChartsWidget::updateToolBar() { undo_zoom_action->setVisible(is_zoomed); redo_zoom_action->setVisible(is_zoomed); reset_zoom_action->setVisible(is_zoomed); - reset_zoom_btn->setText(is_zoomed ? tr("%1-%2").arg(zoomed_range.first, 0, 'f', 1).arg(zoomed_range.second, 0, 'f', 1) : ""); + reset_zoom_btn->setText(is_zoomed ? tr("%1-%2").arg(zoomed_range.first, 0, 'f', 2).arg(zoomed_range.second, 0, 'f', 2) : ""); remove_all_btn->setEnabled(!charts.isEmpty()); dock_btn->setIcon(docking ? "arrow-up-right-square" : "arrow-down-left-square"); dock_btn->setToolTip(docking ? tr("Undock charts") : tr("Dock charts")); diff --git a/tools/cabana/chart/chartswidget.h b/tools/cabana/chart/chartswidget.h index 88ba4226c0..3541f8d96e 100644 --- a/tools/cabana/chart/chartswidget.h +++ b/tools/cabana/chart/chartswidget.h @@ -120,7 +120,7 @@ class ZoomCommand : public QUndoCommand { public: ZoomCommand(ChartsWidget *charts, std::pair range) : charts(charts), range(range), QUndoCommand() { prev_range = charts->is_zoomed ? charts->zoomed_range : charts->display_range; - setText(QObject::tr("Zoom to %1-%2").arg(range.first, 0, 'f', 1).arg(range.second, 0, 'f', 1)); + setText(QObject::tr("Zoom to %1-%2").arg(range.first, 0, 'f', 2).arg(range.second, 0, 'f', 2)); } void undo() override { charts->setZoom(prev_range.first, prev_range.second); } void redo() override { charts->setZoom(range.first, range.second); } From f9a60072f7b5c78723a48634807b2f7304c2d663 Mon Sep 17 00:00:00 2001 From: Justin Newberry Date: Mon, 11 Sep 2023 23:04:53 -0700 Subject: [PATCH 09/59] CI: never remove existing labels (#29885) --- .github/labeler.yaml | 57 ++++++++++++++++++++++------------ .github/workflows/labeler.yaml | 2 +- 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/.github/labeler.yaml b/.github/labeler.yaml index 94bc9074cd..4c4d371d43 100644 --- a/.github/labeler.yaml +++ b/.github/labeler.yaml @@ -1,42 +1,61 @@ CI / testing: - - all: ['.github/**'] - - all: ['**/test_*'] + - all: + - changed-files: ['.github/**'] + - all: + - changed-files: ['**/test_*'] car: - - all: ['selfdrive/car/**'] + - all: + - changed-files: ['selfdrive/car/**'] body: - - all: ['selfdrive/car/body/*'] + - all: + - changed-files: ['selfdrive/car/body/*'] chrysler: - - all: ['selfdrive/car/chrysler/*'] + - all: + - changed-files: ['selfdrive/car/chrysler/*'] ford: - - all: ['selfdrive/car/ford/*'] + - all: + - changed-files: ['selfdrive/car/ford/*'] gm: - - all: ['selfdrive/car/gm/*'] + - all: + - changed-files: ['selfdrive/car/gm/*'] honda: - - all: ['selfdrive/car/honda/*'] + - all: + - changed-files: ['selfdrive/car/honda/*'] hyundai: - - all: ['selfdrive/car/hyundai/*'] + - all: + - changed-files: ['selfdrive/car/hyundai/*'] mazda: - - all: ['selfdrive/car/mazda/*'] + - all: + - changed-files: ['selfdrive/car/mazda/*'] nissan: - - all: ['selfdrive/car/nissan/*'] + - all: + - changed-files: ['selfdrive/car/nissan/*'] subaru: - - all: ['selfdrive/car/subaru/*'] + - all: + - changed-files: ['selfdrive/car/subaru/*'] tesla: - - all: ['selfdrive/car/tesla/*'] + - all: + - changed-files: ['selfdrive/car/tesla/*'] toyota: - - all: ['selfdrive/car/toyota/*'] + - all: + - changed-files: ['selfdrive/car/toyota/*'] volkswagen: - - all: ['selfdrive/car/volkswagen/*'] + - all: + - changed-files: ['selfdrive/car/volkswagen/*'] simulation: - - all: ['tools/sim/**'] + - all: + - changed-files: ['tools/sim/**'] ui: - - all: ['selfdrive/ui/**'] + - all: + - changed-files: ['selfdrive/ui/**'] tools: - - all: ['tools/**'] + - all: + - changed-files: ['tools/**'] multilanguage: - - all: ['selfdrive/ui/translations/**'] + - all: + - changed-files: ['selfdrive/ui/translations/**'] diff --git a/.github/workflows/labeler.yaml b/.github/workflows/labeler.yaml index 7c91b1591c..20f7260ef7 100644 --- a/.github/workflows/labeler.yaml +++ b/.github/workflows/labeler.yaml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v3 with: submodules: false - - uses: actions/labeler@v4 + - uses: actions/labeler@v5.0.0-alpha.1 with: dot: true configuration-path: .github/labeler.yaml \ No newline at end of file From a87d62ffa64a88243e9111e20a740f9ce8b9c11c Mon Sep 17 00:00:00 2001 From: Justin Newberry Date: Mon, 11 Sep 2023 23:08:04 -0700 Subject: [PATCH 10/59] CI: fix setup retry sleep time (#29877) --- .github/workflows/setup-with-retry/action.yaml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/setup-with-retry/action.yaml b/.github/workflows/setup-with-retry/action.yaml index 846d8bbaf0..e4c97af3ce 100644 --- a/.github/workflows/setup-with-retry/action.yaml +++ b/.github/workflows/setup-with-retry/action.yaml @@ -9,9 +9,10 @@ inputs: description: 'Prefix for caching key' required: false default: 'scons_x86_64' - -env: - SLEEP_TIME: 30 # Time to sleep between retries + sleep_time: + description: 'Time to sleep between retries' + required: false + default: 30 runs: using: "composite" @@ -25,7 +26,7 @@ runs: is_retried: true - if: steps.setup1.outcome == 'failure' shell: bash - run: sleep ${{ env.SLEEP_TIME }} + run: sleep ${{ inputs.sleep_time }} - id: setup2 if: steps.setup1.outcome == 'failure' uses: ./.github/workflows/setup @@ -36,7 +37,7 @@ runs: is_retried: true - if: steps.setup2.outcome == 'failure' shell: bash - run: sleep ${{ env.SLEEP_TIME }} + run: sleep ${{ inputs.sleep_time }} - id: setup3 if: steps.setup2.outcome == 'failure' uses: ./.github/workflows/setup From 3d60e8a2a056fc798c23734377f1e3883b115a32 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 12 Sep 2023 00:09:09 -0700 Subject: [PATCH 11/59] Hyundai CAN: log nonAdaptive cruise state (#29880) * log nonAdaptive * bump opendbc * test labeler * test labeler 2 * revert --- opendbc | 2 +- selfdrive/car/hyundai/carstate.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/opendbc b/opendbc index 966e16c31e..8d2f614ce3 160000 --- a/opendbc +++ b/opendbc @@ -1 +1 @@ -Subproject commit 966e16c31e5d7e2a08f8a365024424ee28efc240 +Subproject commit 8d2f614ce3f323c65de802b2d5f29143de9c427b diff --git a/selfdrive/car/hyundai/carstate.py b/selfdrive/car/hyundai/carstate.py index b4ff0e9e6e..b0c53c7db3 100644 --- a/selfdrive/car/hyundai/carstate.py +++ b/selfdrive/car/hyundai/carstate.py @@ -105,10 +105,12 @@ class CarState(CarStateBase): ret.cruiseState.available = cp.vl["TCS13"]["ACCEnable"] == 0 ret.cruiseState.enabled = cp.vl["TCS13"]["ACC_REQ"] == 1 ret.cruiseState.standstill = False + ret.cruiseState.nonAdaptive = False else: ret.cruiseState.available = cp_cruise.vl["SCC11"]["MainMode_ACC"] == 1 ret.cruiseState.enabled = cp_cruise.vl["SCC12"]["ACCMode"] != 0 ret.cruiseState.standstill = cp_cruise.vl["SCC11"]["SCCInfoDisplay"] == 4. + ret.cruiseState.nonAdaptive = cp_cruise.vl["SCC11"]["SCCInfoDisplay"] == 2. # Shows 'Cruise Control' on dash ret.cruiseState.speed = cp_cruise.vl["SCC11"]["VSetDis"] * speed_conv # TODO: Find brake pressure From 279377ec0b8fcd6deae37143f6d333d2a49a2ee7 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 12 Sep 2023 01:34:33 -0700 Subject: [PATCH 12/59] Hyundai CAN FD: disallow Manual Speed Limit Assist for EVs (#29888) * bump opendbc * block MSLA * EV only * Update selfdrive/car/hyundai/carstate.py * Update selfdrive/car/hyundai/carstate.py * Update selfdrive/car/hyundai/carstate.py * Update selfdrive/car/hyundai/carstate.py --- selfdrive/car/hyundai/carstate.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/selfdrive/car/hyundai/carstate.py b/selfdrive/car/hyundai/carstate.py index b0c53c7db3..8090bbcd8f 100644 --- a/selfdrive/car/hyundai/carstate.py +++ b/selfdrive/car/hyundai/carstate.py @@ -228,6 +228,13 @@ class CarState(CarStateBase): ret.cruiseState.speed = cp_cruise_info.vl["SCC_CONTROL"]["VSetDis"] * speed_factor self.cruise_info = copy.copy(cp_cruise_info.vl["SCC_CONTROL"]) + # Manual Speed Limit Assist is a feature that replaces non-adaptive cruise control on EV CAN FD platforms. + # It limits the vehicle speed, overridable by pressing the accelerator past a certain point. + # The car will brake, but does not respect positive acceleration commands in this mode + # TODO: find this message on ICE & HYBRID cars + cruise control signals (if exists) + if self.CP.carFingerprint in EV_CAR: + ret.cruiseState.nonAdaptive = cp.vl["MANUAL_SPEED_LIMIT_ASSIST"]["MSLA_ENABLED"] == 1 + self.prev_cruise_buttons = self.cruise_buttons[-1] self.cruise_buttons.extend(cp.vl_all[self.cruise_btns_msg_canfd]["CRUISE_BUTTONS"]) self.main_buttons.extend(cp.vl_all[self.cruise_btns_msg_canfd]["ADAPTIVE_CRUISE_MAIN_BTN"]) @@ -322,6 +329,11 @@ class CarState(CarStateBase): ("DOORS_SEATBELTS", 4), ] + if CP.carFingerprint in EV_CAR: + messages += [ + ("MANUAL_SPEED_LIMIT_ASSIST", 10), + ] + if not (CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS): messages += [ ("CRUISE_BUTTONS", 50) From 9b959dc86e1fb9ba04bca1b3dc4139d9f643c325 Mon Sep 17 00:00:00 2001 From: Erich Moraga <33645296+ErichMoraga@users.noreply.github.com> Date: Tue, 12 Sep 2023 03:44:59 -0500 Subject: [PATCH 13/59] VW MQB: Add missing FW versions for 2018 Skoda Superb (#29792) VW MQB: Add SRS, transmission, & engine ECU versions for 2018 Skoda Superb `@Gottmoz#6511` 2018 Skoda Superb DongleID/route 54ada937747ef8ca|2023-09-06--06-40-46 --- selfdrive/car/volkswagen/values.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index 1cb7f1d29d..494d59bad2 100644 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -1327,6 +1327,7 @@ FW_VERSIONS = { b'\xf1\x8704E906027BT\xf1\x899042', b'\xf1\x8704L906026ET\xf1\x891343', b'\xf1\x8704L906026FP\xf1\x891196', + b'\xf1\x8704L906026KA\xf1\x896014', b'\xf1\x8704L906026KB\xf1\x894071', b'\xf1\x8704L906026KD\xf1\x894798', b'\xf1\x8704L906026MT\xf1\x893076', @@ -1344,6 +1345,7 @@ FW_VERSIONS = { b'\xf1\x870D9300014K \xf1\x895006', b'\xf1\x870D9300041H \xf1\x894905', b'\xf1\x870D9300043F \xf1\x895202', + b'\xf1\x870GC300013K \xf1\x892403', b'\xf1\x870GC300014M \xf1\x892801', b'\xf1\x870GC300019G \xf1\x892803', b'\xf1\x870GC300043 \xf1\x892301', @@ -1356,6 +1358,7 @@ FW_VERSIONS = { b'\xf1\x875Q0959655BH\xf1\x890336\xf1\x82\02331310031313100313131013141319331413100', b'\xf1\x875Q0959655BK\xf1\x890336\xf1\x82\x1331310031313100313131013141319331413100', b'\xf1\x875Q0959655CA\xf1\x890403\xf1\x82\x1331310031313100313151013141319331423100', + b'\xf1\x875Q0959655CA\xf1\x890403\xf1\x82\x1331310031313100313151823143319331423100', b'\xf1\x875Q0959655CH\xf1\x890421\xf1\x82\x1333310031313100313152025350539331463100', b'\xf1\x875Q0959655CH\xf1\x890421\xf1\x82\x1333310031313100313152855372539331463100', ], From 140a4ba5587b84fd234df04c23261f1e50dece08 Mon Sep 17 00:00:00 2001 From: Greg Hogan Date: Tue, 12 Sep 2023 11:00:18 -0700 Subject: [PATCH 14/59] importing auth_config.py should not have side effects (#29893) import should not create directory --- tools/lib/auth_config.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/lib/auth_config.py b/tools/lib/auth_config.py index 8863dd57a2..bd76761043 100644 --- a/tools/lib/auth_config.py +++ b/tools/lib/auth_config.py @@ -13,9 +13,6 @@ if PC: else: CONFIG_DIR = "/tmp/.comma" -mkdirs_exists_ok(CONFIG_DIR) - - def get_token(): try: with open(os.path.join(CONFIG_DIR, 'auth.json')) as f: @@ -26,9 +23,13 @@ def get_token(): def set_token(token): + mkdirs_exists_ok(CONFIG_DIR) with open(os.path.join(CONFIG_DIR, 'auth.json'), 'w') as f: json.dump({'access_token': token}, f) def clear_token(): - os.unlink(os.path.join(CONFIG_DIR, 'auth.json')) + try: + os.unlink(os.path.join(CONFIG_DIR, 'auth.json')) + except FileNotFoundError: + pass From 9596a3c9403f17ab0b8723701a4b001b0a1e576d Mon Sep 17 00:00:00 2001 From: Varun Nair <73822176+MufcVarun11@users.noreply.github.com> Date: Wed, 13 Sep 2023 00:08:29 +0530 Subject: [PATCH 15/59] Updating the readme.md to make it easier to follow (#29820) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * upadting the readme.md to make it easier to follow * addressing pr comments * addressing the pr * Update README.md * bold --------- Co-authored-by: Harald Schäfer --- README.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 5978a0e5dd..523f459f3b 100644 --- a/README.md +++ b/README.md @@ -39,13 +39,17 @@ Running on a dedicated device in a car ------ To use openpilot in a car, you need four things -* A supported device to run this software: a [comma 3X](https://comma.ai/shop/comma-3x) or comma three. -* This software. The setup procedure of the comma 3/3X allows the user to enter a URL for custom software. -The URL, openpilot.comma.ai will install the release version of openpilot. To install openpilot master, you can use installer.comma.ai/commaai/master, and replacing commaai with another GitHub username can install a fork. -* One of [the 250+ supported cars](docs/CARS.md). We support Honda, Toyota, Hyundai, Nissan, Kia, Chrysler, Lexus, Acura, Audi, VW, Ford and more. If your car is not supported but has adaptive cruise control and lane-keeping assist, it's likely able to run openpilot. -* A [car harness](https://comma.ai/shop/products/car-harness) to connect to your car. - -We have detailed instructions for [how to mount the device in a car](https://comma.ai/setup). +1. **Supported Device:** A comma 3/3X. You can purchase these devices from (https://comma.ai/shop/comma-3x) + +2. **Software:** The setup procedure for the comma 3/3X allows users to enter a URL for custom software. + To install the release version of openpilot, use the URL `openpilot.comma.ai`. + To install openpilot master (for more advanced users), use the URL `installer.comma.ai/commaai/master`. You can replace "commaai" with another GitHub username to install a fork. + +3. **Supported Car:** Ensure that you have one of [the 250+ supported cars](docs/CARS.md). openpilot supports a wide range of car makes including Honda, Toyota, Hyundai, Nissan, Kia, Chrysler, Lexus, Acura, Audi, VW, Ford, and many more. + If your car is not officially listed as supported but has adaptive cruise control and lane-keeping assist, it's likely capable of running openpilot. + +4. **Car Harness:** You will also need a [car harness](https://comma.ai/shop/car-harness) to connect your comma 3/3X to your car. + We have detailed instructions for [how to install the harness and device in a car](https://comma.ai/setup). Running on PC ------ From ac2d0525129d0bc6f8cddd1a510cf625ed78670b Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 12 Sep 2023 13:12:55 -0700 Subject: [PATCH 16/59] Update Python packages and pre-commit hooks (#29891) Co-authored-by: adeebshihadeh --- .pre-commit-config.yaml | 2 +- poetry.lock | 191 +++++++++++++++++++++++----------------- 2 files changed, 113 insertions(+), 80 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f74692c01e..a5da03b266 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -38,7 +38,7 @@ repos: args: ['--explicit-package-bases'] exclude: '^(third_party/)|(cereal/)|(opendbc/)|(panda/)|(laika/)|(laika_repo/)|(rednose/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)|(xx/)' - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.0.287 + rev: v0.0.288 hooks: - id: ruff exclude: '^(third_party/)|(cereal/)|(rednose/)|(panda/)|(laika/)|(laika_repo/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)' diff --git a/poetry.lock b/poetry.lock index 255f6b2acc..2c134ec32d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "aiohttp" @@ -1595,13 +1595,13 @@ zoneinfo = ["backports.zoneinfo (>=0.2.1)", "tzdata (>=2022.1)"] [[package]] name = "identify" -version = "2.5.27" +version = "2.5.28" description = "File identification library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "identify-2.5.27-py2.py3-none-any.whl", hash = "sha256:fdb527b2dfe24602809b2201e033c2a113d7bdf716db3ca8e3243f735dcecaba"}, - {file = "identify-2.5.27.tar.gz", hash = "sha256:287b75b04a0e22d727bc9a41f0d4f3c1bcada97490fa6eabb5b28f0e9097e733"}, + {file = "identify-2.5.28-py2.py3-none-any.whl", hash = "sha256:87816de144bf46d161bd5b3e8f5596b16cade3b80be537087334b26bc5c177f3"}, + {file = "identify-2.5.28.tar.gz", hash = "sha256:94bb59643083ebd60dc996d043497479ee554381fbc5307763915cda49b0e78f"}, ] [package.extras] @@ -2144,6 +2144,16 @@ 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"}, @@ -2178,52 +2188,58 @@ files = [ [[package]] name = "matplotlib" -version = "3.7.2" +version = "3.7.3" description = "Python plotting package" optional = false python-versions = ">=3.8" files = [ - {file = "matplotlib-3.7.2-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:2699f7e73a76d4c110f4f25be9d2496d6ab4f17345307738557d345f099e07de"}, - {file = "matplotlib-3.7.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a8035ba590658bae7562786c9cc6ea1a84aa49d3afab157e414c9e2ea74f496d"}, - {file = "matplotlib-3.7.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f8e4a49493add46ad4a8c92f63e19d548b2b6ebbed75c6b4c7f46f57d36cdd1"}, - {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71667eb2ccca4c3537d9414b1bc00554cb7f91527c17ee4ec38027201f8f1603"}, - {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:152ee0b569a37630d8628534c628456b28686e085d51394da6b71ef84c4da201"}, - {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:070f8dddd1f5939e60aacb8fa08f19551f4b0140fab16a3669d5cd6e9cb28fc8"}, - {file = "matplotlib-3.7.2-cp310-cp310-win32.whl", hash = "sha256:fdbb46fad4fb47443b5b8ac76904b2e7a66556844f33370861b4788db0f8816a"}, - {file = "matplotlib-3.7.2-cp310-cp310-win_amd64.whl", hash = "sha256:23fb1750934e5f0128f9423db27c474aa32534cec21f7b2153262b066a581fd1"}, - {file = "matplotlib-3.7.2-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:30e1409b857aa8a747c5d4f85f63a79e479835f8dffc52992ac1f3f25837b544"}, - {file = "matplotlib-3.7.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:50e0a55ec74bf2d7a0ebf50ac580a209582c2dd0f7ab51bc270f1b4a0027454e"}, - {file = "matplotlib-3.7.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ac60daa1dc83e8821eed155796b0f7888b6b916cf61d620a4ddd8200ac70cd64"}, - {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:305e3da477dc8607336ba10bac96986d6308d614706cae2efe7d3ffa60465b24"}, - {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c308b255efb9b06b23874236ec0f10f026673ad6515f602027cc8ac7805352d"}, - {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60c521e21031632aa0d87ca5ba0c1c05f3daacadb34c093585a0be6780f698e4"}, - {file = "matplotlib-3.7.2-cp311-cp311-win32.whl", hash = "sha256:26bede320d77e469fdf1bde212de0ec889169b04f7f1179b8930d66f82b30cbc"}, - {file = "matplotlib-3.7.2-cp311-cp311-win_amd64.whl", hash = "sha256:af4860132c8c05261a5f5f8467f1b269bf1c7c23902d75f2be57c4a7f2394b3e"}, - {file = "matplotlib-3.7.2-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:a1733b8e84e7e40a9853e505fe68cc54339f97273bdfe6f3ed980095f769ddc7"}, - {file = "matplotlib-3.7.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d9881356dc48e58910c53af82b57183879129fa30492be69058c5b0d9fddf391"}, - {file = "matplotlib-3.7.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f081c03f413f59390a80b3e351cc2b2ea0205839714dbc364519bcf51f4b56ca"}, - {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1cd120fca3407a225168238b790bd5c528f0fafde6172b140a2f3ab7a4ea63e9"}, - {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a2c1590b90aa7bd741b54c62b78de05d4186271e34e2377e0289d943b3522273"}, - {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d2ff3c984b8a569bc1383cd468fc06b70d7b59d5c2854ca39f1436ae8394117"}, - {file = "matplotlib-3.7.2-cp38-cp38-win32.whl", hash = "sha256:5dea00b62d28654b71ca92463656d80646675628d0828e08a5f3b57e12869e13"}, - {file = "matplotlib-3.7.2-cp38-cp38-win_amd64.whl", hash = "sha256:0f506a1776ee94f9e131af1ac6efa6e5bc7cb606a3e389b0ccb6e657f60bb676"}, - {file = "matplotlib-3.7.2-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:6515e878f91894c2e4340d81f0911857998ccaf04dbc1bba781e3d89cbf70608"}, - {file = "matplotlib-3.7.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:71f7a8c6b124e904db550f5b9fe483d28b896d4135e45c4ea381ad3b8a0e3256"}, - {file = "matplotlib-3.7.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:12f01b92ecd518e0697da4d97d163b2b3aa55eb3eb4e2c98235b3396d7dad55f"}, - {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7e28d6396563955f7af437894a36bf2b279462239a41028323e04b85179058b"}, - {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbcf59334ff645e6a67cd5f78b4b2cdb76384cdf587fa0d2dc85f634a72e1a3e"}, - {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:318c89edde72ff95d8df67d82aca03861240512994a597a435a1011ba18dbc7f"}, - {file = "matplotlib-3.7.2-cp39-cp39-win32.whl", hash = "sha256:ce55289d5659b5b12b3db4dc9b7075b70cef5631e56530f14b2945e8836f2d20"}, - {file = "matplotlib-3.7.2-cp39-cp39-win_amd64.whl", hash = "sha256:2ecb5be2b2815431c81dc115667e33da0f5a1bcf6143980d180d09a717c4a12e"}, - {file = "matplotlib-3.7.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:fdcd28360dbb6203fb5219b1a5658df226ac9bebc2542a9e8f457de959d713d0"}, - {file = "matplotlib-3.7.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c3cca3e842b11b55b52c6fb8bd6a4088693829acbfcdb3e815fa9b7d5c92c1b"}, - {file = "matplotlib-3.7.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebf577c7a6744e9e1bd3fee45fc74a02710b214f94e2bde344912d85e0c9af7c"}, - {file = "matplotlib-3.7.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:936bba394682049919dda062d33435b3be211dc3dcaa011e09634f060ec878b2"}, - {file = "matplotlib-3.7.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bc221ffbc2150458b1cd71cdd9ddd5bb37962b036e41b8be258280b5b01da1dd"}, - {file = "matplotlib-3.7.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35d74ebdb3f71f112b36c2629cf32323adfbf42679e2751252acd468f5001c07"}, - {file = "matplotlib-3.7.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:717157e61b3a71d3d26ad4e1770dc85156c9af435659a25ee6407dc866cb258d"}, - {file = "matplotlib-3.7.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:20f844d6be031948148ba49605c8b96dfe7d3711d1b63592830d650622458c11"}, - {file = "matplotlib-3.7.2.tar.gz", hash = "sha256:a8cdb91dddb04436bd2f098b8fdf4b81352e68cf4d2c6756fcc414791076569b"}, + {file = "matplotlib-3.7.3-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:085c33b27561d9c04386789d5aa5eb4a932ddef43cfcdd0e01735f9a6e85ce0c"}, + {file = "matplotlib-3.7.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:c568e80e1c17f68a727f30f591926751b97b98314d8e59804f54f86ae6fa6a22"}, + {file = "matplotlib-3.7.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7baf98c5ad59c5c4743ea884bb025cbffa52dacdfdac0da3e6021a285a90377e"}, + {file = "matplotlib-3.7.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:236024f582e40dac39bca592258888b38ae47a9fed7b8de652d68d3d02d47d2b"}, + {file = "matplotlib-3.7.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12b4f6795efea037ce2d41e7c417ad8bd02d5719c6ad4a8450a0708f4a1cfb89"}, + {file = "matplotlib-3.7.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b2136cc6c5415b78977e0e8c608647d597204b05b1d9089ccf513c7d913733"}, + {file = "matplotlib-3.7.3-cp310-cp310-win32.whl", hash = "sha256:122dcbf9be0086e2a95d9e5e0632dbf3bd5b65eaa68c369363310a6c87753059"}, + {file = "matplotlib-3.7.3-cp310-cp310-win_amd64.whl", hash = "sha256:4aab27d9e33293389e3c1d7c881d414a72bdfda0fedc3a6bf46c6fa88d9b8015"}, + {file = "matplotlib-3.7.3-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:d5adc743de91e8e0b13df60deb1b1c285b8effea3d66223afceb14b63c9b05de"}, + {file = "matplotlib-3.7.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:55de4cf7cd0071b8ebf203981b53ab64f988a0a1f897a2dff300a1124e8bcd8b"}, + {file = "matplotlib-3.7.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ac03377fd908aaee2312d0b11735753e907adb6f4d1d102de5e2425249693f6c"}, + {file = "matplotlib-3.7.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:755bafc10a46918ce9a39980009b54b02dd249594e5adf52f9c56acfddb5d0b7"}, + {file = "matplotlib-3.7.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a6094c6f8e8d18db631754df4fe9a34dec3caf074f6869a7db09f18f9b1d6b2"}, + {file = "matplotlib-3.7.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:272dba2f1b107790ed78ebf5385b8d14b27ad9e90419de340364b49fe549a993"}, + {file = "matplotlib-3.7.3-cp311-cp311-win32.whl", hash = "sha256:591c123bed1cb4b9996fb60b41a6d89c2ec4943244540776c5f1283fb6960a53"}, + {file = "matplotlib-3.7.3-cp311-cp311-win_amd64.whl", hash = "sha256:3bf3a178c6504694cee8b88b353df0051583f2f6f8faa146f67115c27c856881"}, + {file = "matplotlib-3.7.3-cp312-cp312-macosx_10_12_universal2.whl", hash = "sha256:edf54cac8ee3603f3093616b40a931e8c063969756a4d78a86e82c2fea9659f7"}, + {file = "matplotlib-3.7.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:91e36a85ea639a1ba9f91427041eac064b04829945fe331a92617b6cb21d27e5"}, + {file = "matplotlib-3.7.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:caf5eaaf7c68f8d7df269dfbcaf46f48a70ff482bfcebdcc97519671023f2a7d"}, + {file = "matplotlib-3.7.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74bf57f505efea376097e948b7cdd87191a7ce8180616390aef496639edf601f"}, + {file = "matplotlib-3.7.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee152a88a0da527840a426535514b6ed8ac4240eb856b1da92cf48124320e346"}, + {file = "matplotlib-3.7.3-cp312-cp312-win_amd64.whl", hash = "sha256:67a410a9c9e07cbc83581eeea144bbe298870bf0ac0ee2f2e10a015ab7efee19"}, + {file = "matplotlib-3.7.3-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:259999c05285cb993d7f2a419cea547863fa215379eda81f7254c9e932963729"}, + {file = "matplotlib-3.7.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:3f4e7fd5a6157e1d018ce2166ec8e531a481dd4a36f035b5c23edfe05a25419a"}, + {file = "matplotlib-3.7.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:faa3d12d8811d08d14080a8b7b9caea9a457dc495350166b56df0db4b9909ef5"}, + {file = "matplotlib-3.7.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:336e88900c11441e458da01c8414fc57e04e17f9d3bb94958a76faa2652bcf6b"}, + {file = "matplotlib-3.7.3-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:12f4c0dd8aa280d796c8772ea8265a14f11a04319baa3a16daa5556065e8baea"}, + {file = "matplotlib-3.7.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1990955b11e7918d256cf3b956b10997f405b7917a3f1c7d8e69c1d15c7b1930"}, + {file = "matplotlib-3.7.3-cp38-cp38-win32.whl", hash = "sha256:e78707b751260b42b721507ad7aa60fe4026d7f51c74cca6b9cd8b123ebb633a"}, + {file = "matplotlib-3.7.3-cp38-cp38-win_amd64.whl", hash = "sha256:e594ee43c59ea39ca5c6244667cac9d017a3527febc31f5532ad9135cf7469ec"}, + {file = "matplotlib-3.7.3-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:6eaa1cf0e94c936a26b78f6d756c5fbc12e0a58c8a68b7248a2a31456ce4e234"}, + {file = "matplotlib-3.7.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:0a97af9d22e8ebedc9f00b043d9bbd29a375e9e10b656982012dded44c10fd77"}, + {file = "matplotlib-3.7.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1f9c6c16597af660433ab330b59ee2934b832ee1fabcaf5cbde7b2add840f31e"}, + {file = "matplotlib-3.7.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7240259b4b9cbc62381f6378cff4d57af539162a18e832c1e48042fabc40b6b"}, + {file = "matplotlib-3.7.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:747c6191d2e88ae854809e69aa358dbf852ff1a5738401b85c1cc9012309897a"}, + {file = "matplotlib-3.7.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec726b08a5275d827aa91bb951e68234a4423adb91cf65bc0fcdc0f2777663f7"}, + {file = "matplotlib-3.7.3-cp39-cp39-win32.whl", hash = "sha256:40e3b9b450c6534f07278310c4e34caff41c2a42377e4b9d47b0f8d3ac1083a2"}, + {file = "matplotlib-3.7.3-cp39-cp39-win_amd64.whl", hash = "sha256:dfc118642903a23e309b1da32886bb39a4314147d013e820c86b5fb4cb2e36d0"}, + {file = "matplotlib-3.7.3-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:165c8082bf8fc0360c24aa4724a22eaadbfd8c28bf1ccf7e94d685cad48261e4"}, + {file = "matplotlib-3.7.3-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ebd8470cc2a3594746ff0513aecbfa2c55ff6f58e6cef2efb1a54eb87c88ffa2"}, + {file = "matplotlib-3.7.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7153453669c9672b52095119fd21dd032d19225d48413a2871519b17db4b0fde"}, + {file = "matplotlib-3.7.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:498a08267dc69dd8f24c4b5d7423fa584d7ce0027ba71f7881df05fc09b89bb7"}, + {file = "matplotlib-3.7.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d48999c4b19b5a0c058c9cd828ff6fc7748390679f6cf9a2ad653a3e802c87d3"}, + {file = "matplotlib-3.7.3-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22d65d18b4ee8070a5fea5761d59293f1f9e2fac37ec9ce090463b0e629432fd"}, + {file = "matplotlib-3.7.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c40cde976c36693cc0767e27cf5f443f91c23520060bd9496678364adfafe9c"}, + {file = "matplotlib-3.7.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:39018a2b17592448fbfdf4b8352955e6c3905359939791d4ff429296494d1a0c"}, + {file = "matplotlib-3.7.3.tar.gz", hash = "sha256:f09b3dd6bdeb588de91f853bbb2d6f0ff8ab693485b0c49035eaa510cb4f142e"}, ] [package.dependencies] @@ -2231,11 +2247,12 @@ contourpy = ">=1.0.1" cycler = ">=0.10" fonttools = ">=4.22.0" kiwisolver = ">=1.0.1" -numpy = ">=1.20" +numpy = ">=1.20,<2" packaging = ">=20.0" pillow = ">=6.2.0" -pyparsing = ">=2.3.1,<3.1" +pyparsing = ">=2.3.1" python-dateutil = ">=2.7" +setuptools_scm = ">=7" [[package]] name = "mdit-py-plugins" @@ -2766,14 +2783,7 @@ files = [ ] [package.dependencies] -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\""}, -] +numpy = {version = ">=1.23.5", markers = "python_version >= \"3.11\""} [[package]] name = "opencv-python-headless" @@ -2792,14 +2802,7 @@ files = [ ] [package.dependencies] -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\""}, -] +numpy = {version = ">=1.23.5", markers = "python_version >= \"3.11\""} [[package]] name = "packaging" @@ -3623,13 +3626,13 @@ test = ["flaky", "pretend", "pytest (>=3.0.1)"] [[package]] name = "pyparsing" -version = "3.0.9" +version = "3.1.1" description = "pyparsing module - Classes and methods to define and execute parsing grammars" optional = false python-versions = ">=3.6.8" files = [ - {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, - {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, + {file = "pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb"}, + {file = "pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"}, ] [package.extras] @@ -3949,6 +3952,7 @@ 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"}, @@ -3956,8 +3960,15 @@ 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"}, @@ -3974,6 +3985,7 @@ 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"}, @@ -3981,6 +3993,7 @@ 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"}, @@ -4171,9 +4184,9 @@ setuptools = "*" [[package]] name = "sconscontrib" version = "1.0" -description = "" +description = "Contributed builders and other useful logic for the SCons build system.," optional = false -python-versions = ">=3.6, <4" +python-versions = "<4,>=3.6" files = [] develop = false @@ -4338,19 +4351,39 @@ test = ["pytest"] [[package]] name = "setuptools" -version = "68.2.0" +version = "68.2.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-68.2.0-py3-none-any.whl", hash = "sha256:af3d5949030c3f493f550876b2fd1dd5ec66689c4ee5d5344f009746f71fd5a8"}, - {file = "setuptools-68.2.0.tar.gz", hash = "sha256:00478ca80aeebeecb2f288d3206b0de568df5cd2b8fada1209843cc9a8d88a48"}, + {file = "setuptools-68.2.1-py3-none-any.whl", hash = "sha256:eff96148eb336377ab11beee0c73ed84f1709a40c0b870298b0d058828761bae"}, + {file = "setuptools-68.2.1.tar.gz", hash = "sha256:56ee14884fd8d0cd015411f4a13f40b4356775a0aefd9ebc1d3bfb9a1acb32f1"}, ] [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + +[[package]] +name = "setuptools-scm" +version = "7.1.0" +description = "the blessed package to manage your versions by scm tags" +optional = false +python-versions = ">=3.7" +files = [ + {file = "setuptools_scm-7.1.0-py3-none-any.whl", hash = "sha256:73988b6d848709e2af142aa48c986ea29592bbcfca5375678064708205253d8e"}, + {file = "setuptools_scm-7.1.0.tar.gz", hash = "sha256:6c508345a771aad7d56ebff0e70628bf2b0ec7573762be9960214730de278f27"}, +] + +[package.dependencies] +packaging = ">=20.0" +setuptools = "*" +typing-extensions = "*" + +[package.extras] +test = ["pytest (>=6.2)", "virtualenv (>20)"] +toml = ["setuptools (>=42)"] [[package]] name = "shapely" @@ -4899,13 +4932,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.24.4" +version = "20.24.5" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.24.4-py3-none-any.whl", hash = "sha256:29c70bb9b88510f6414ac3e55c8b413a1f96239b6b789ca123437d5e892190cb"}, - {file = "virtualenv-20.24.4.tar.gz", hash = "sha256:772b05bfda7ed3b8ecd16021ca9716273ad9f4467c801f27e83ac73430246dca"}, + {file = "virtualenv-20.24.5-py3-none-any.whl", hash = "sha256:b80039f280f4919c77b30f1c23294ae357c4c8701042086e3fc005963e4e537b"}, + {file = "virtualenv-20.24.5.tar.gz", hash = "sha256:e8361967f6da6fbdf1426483bfe9fca8287c242ac0bc30429905721cefbff752"}, ] [package.dependencies] @@ -4919,13 +4952,13 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess [[package]] name = "websocket-client" -version = "1.6.2" +version = "1.6.3" description = "WebSocket client for Python with low level API options" optional = false python-versions = ">=3.8" files = [ - {file = "websocket-client-1.6.2.tar.gz", hash = "sha256:53e95c826bf800c4c465f50093a8c4ff091c7327023b10bfaff40cf1ef170eaa"}, - {file = "websocket_client-1.6.2-py3-none-any.whl", hash = "sha256:ce54f419dfae71f4bdba69ebe65bf7f0a93fe71bc009ad3a010aacc3eebad537"}, + {file = "websocket-client-1.6.3.tar.gz", hash = "sha256:3aad25d31284266bcfcfd1fd8a743f63282305a364b8d0948a43bd606acc652f"}, + {file = "websocket_client-1.6.3-py3-none-any.whl", hash = "sha256:6cfc30d051ebabb73a5fa246efdcc14c8fbebbd0330f8984ac3bb6d9edd2ad03"}, ] [package.extras] From f63dc5128411c6dc39c5bda9f05144c5f0af5b30 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Wed, 13 Sep 2023 04:13:59 +0800 Subject: [PATCH 17/59] cabana: display warning if failed to write settings (#29873) * display warning if failed to write_settings * use Settings::filePath() --- tools/cabana/mainwin.cc | 8 +++++++- tools/cabana/settings.cc | 5 +++-- tools/cabana/settings.h | 3 ++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/tools/cabana/mainwin.cc b/tools/cabana/mainwin.cc index d3caf492a6..c91fcf7100 100644 --- a/tools/cabana/mainwin.cc +++ b/tools/cabana/mainwin.cc @@ -606,7 +606,13 @@ void MainWindow::closeEvent(QCloseEvent *event) { settings.video_splitter_state = video_splitter->saveState(); } settings.message_header_state = messages_widget->saveHeaderState(); - settings.save(); + + auto status = settings.save(); + if (status == QSettings::AccessError) { + QString error = tr("Failed to write settings to [%1]: access denied").arg(Settings::filePath()); + qDebug() << error; + QMessageBox::warning(this, tr("Failed to write settings"), error); + } QWidget::closeEvent(event); } diff --git a/tools/cabana/settings.cc b/tools/cabana/settings.cc index 027dcb903f..ee345c490c 100644 --- a/tools/cabana/settings.cc +++ b/tools/cabana/settings.cc @@ -6,14 +6,13 @@ #include #include #include -#include #include #include "tools/cabana/util.h" Settings settings; -void Settings::save() { +QSettings::Status Settings::save() { QSettings s(filePath(), QSettings::IniFormat); s.setValue("fps", fps); s.setValue("max_cached_minutes", max_cached_minutes); @@ -35,6 +34,8 @@ void Settings::save() { s.setValue("log_path", log_path); s.setValue("drag_direction", drag_direction); s.setValue("suppress_defined_signals", suppress_defined_signals); + s.sync(); + return s.status(); } void Settings::load() { diff --git a/tools/cabana/settings.h b/tools/cabana/settings.h index f9eaa8ffad..42073a72de 100644 --- a/tools/cabana/settings.h +++ b/tools/cabana/settings.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #define LIGHT_THEME 1 @@ -24,7 +25,7 @@ public: }; Settings() {} - void save(); + QSettings::Status save(); void load(); inline static QString filePath() { return QApplication::applicationDirPath() + "/settings"; } From d9f107a2c980828657c709527568f2b121962e78 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Wed, 13 Sep 2023 10:49:59 +0800 Subject: [PATCH 18/59] cabana: improve precision of timeline (#29872) --- tools/cabana/chart/chart.cc | 13 ++++++++----- tools/cabana/chart/chart.h | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/tools/cabana/chart/chart.cc b/tools/cabana/chart/chart.cc index 3ee47ae0c6..68d1593d52 100644 --- a/tools/cabana/chart/chart.cc +++ b/tools/cabana/chart/chart.cc @@ -25,7 +25,8 @@ const int AXIS_X_TOP_MARGIN = 4; static inline bool xLessThan(const QPointF &p, float x) { return p.x() < x; } -ChartView::ChartView(const std::pair &x_range, ChartsWidget *parent) : charts_widget(parent), tip_label(this), QChartView(nullptr, parent) { +ChartView::ChartView(const std::pair &x_range, ChartsWidget *parent) + : charts_widget(parent), tip_label(this), QChartView(nullptr, parent) { series_type = (SeriesType)settings.chart_series_type; QChart *chart = new QChart(); chart->setBackgroundVisible(false); @@ -668,6 +669,7 @@ void ChartView::drawBackground(QPainter *painter, const QRectF &rect) { void ChartView::drawForeground(QPainter *painter, const QRectF &rect) { drawTimeline(painter); + drawSignalValue(painter); // draw track points painter->setPen(Qt::NoPen); qreal track_line_x = -1; @@ -718,23 +720,24 @@ void ChartView::drawRubberBandTimeRange(QPainter *painter) { void ChartView::drawTimeline(QPainter *painter) { const auto plot_area = chart()->plotArea(); - // draw line + // draw vertical time line qreal x = std::clamp(chart()->mapToPosition(QPointF{cur_sec, 0}).x(), plot_area.left(), plot_area.right()); painter->setPen(QPen(chart()->titleBrush().color(), 2)); painter->drawLine(QPointF{x, plot_area.top()}, QPointF{x, plot_area.bottom() + 1}); - // draw current time + // draw current time under the axis-x QString time_str = QString::number(cur_sec, 'f', 2); QSize time_str_size = QFontMetrics(axis_x->labelsFont()).size(Qt::TextSingleLine, time_str) + QSize(8, 2); - QRect time_str_rect(QPoint(x - time_str_size.width() / 2, plot_area.bottom() + AXIS_X_TOP_MARGIN), time_str_size); + QRectF time_str_rect(QPointF(x - time_str_size.width() / 2.0, plot_area.bottom() + AXIS_X_TOP_MARGIN), time_str_size); QPainterPath path; path.addRoundedRect(time_str_rect, 3, 3); painter->fillPath(path, settings.theme == DARK_THEME ? Qt::darkGray : Qt::gray); painter->setPen(palette().color(QPalette::BrightText)); painter->setFont(axis_x->labelsFont()); painter->drawText(time_str_rect, Qt::AlignCenter, time_str); +} - // draw signal value +void ChartView::drawSignalValue(QPainter *painter) { auto item_group = qgraphicsitem_cast(chart()->legend()->childItems()[0]); assert(item_group != nullptr); auto legend_markers = item_group->childItems(); diff --git a/tools/cabana/chart/chart.h b/tools/cabana/chart/chart.h index 71cf7058ab..4342bdfefc 100644 --- a/tools/cabana/chart/chart.h +++ b/tools/cabana/chart/chart.h @@ -83,6 +83,7 @@ private: void drawForeground(QPainter *painter, const QRectF &rect) override; void drawBackground(QPainter *painter, const QRectF &rect) override; void drawDropIndicator(bool draw) { if (std::exchange(can_drop, draw) != can_drop) viewport()->update(); } + void drawSignalValue(QPainter *painter); void drawTimeline(QPainter *painter); void drawRubberBandTimeRange(QPainter *painter); std::tuple getNiceAxisNumbers(qreal min, qreal max, int tick_count); From 587f6ce0dc4d33f050e4b922b7727b0c9b58230f Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Wed, 13 Sep 2023 16:14:12 +0800 Subject: [PATCH 19/59] cabana: mark the undo stack as clean after save as (#29898) Marks the undo stack as clean after save as --- tools/cabana/mainwin.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/cabana/mainwin.cc b/tools/cabana/mainwin.cc index c91fcf7100..5cd5e70267 100644 --- a/tools/cabana/mainwin.cc +++ b/tools/cabana/mainwin.cc @@ -439,11 +439,11 @@ void MainWindow::saveFile(DBCFile *dbc_file) { if (!dbc_file->filename.isEmpty()) { dbc_file->save(); updateLoadSaveMenus(); + UndoStack::instance()->setClean(); + statusBar()->showMessage(tr("File saved"), 2000); } else if (!dbc_file->isEmpty()) { saveFileAs(dbc_file); } - UndoStack::instance()->setClean(); - statusBar()->showMessage(tr("File saved"), 2000); } void MainWindow::saveFileAs(DBCFile *dbc_file) { @@ -451,6 +451,8 @@ void MainWindow::saveFileAs(DBCFile *dbc_file) { QString fn = QFileDialog::getSaveFileName(this, title, QDir::cleanPath(settings.last_dir + "/untitled.dbc"), tr("DBC (*.dbc)")); if (!fn.isEmpty()) { dbc_file->saveAs(fn); + UndoStack::instance()->setClean(); + statusBar()->showMessage(tr("File saved as %1").arg(fn), 2000); updateRecentFiles(fn); updateLoadSaveMenus(); } From 748eb4a7c7c8f3eae22659f450ba50ba0a8f3fb1 Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Wed, 13 Sep 2023 05:22:04 -0400 Subject: [PATCH 20/59] Hyundai: Car Port for Azera 6th Generation (#29876) * Hyundai: Car Port for Azera 2022 * harness k * not crc8 * use gen * add test route * Middle East only * Revert "Middle East only" This reverts commit 1abe795ad00d10344761e99f415a1cfc14f4c163. * rename to 6th gen * sorting * has a little less torque --------- Co-authored-by: Shane Smiskol --- RELEASES.md | 1 + docs/CARS.md | 3 ++- selfdrive/car/hyundai/hyundaican.py | 3 ++- selfdrive/car/hyundai/interface.py | 6 +++++- selfdrive/car/hyundai/values.py | 20 ++++++++++++++++++++ selfdrive/car/tests/routes.py | 1 + selfdrive/car/torque_data/override.yaml | 1 + 7 files changed, 32 insertions(+), 3 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 0a7925200e..88c3eb7041 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,5 +1,6 @@ Version 0.9.5 (202X-XX-XX) ======================== +* Hyundai Azera 2022 support thanks to sunnyhaibin! * Hyundai Ioniq 6 2023 support thanks to sunnyhaibin, alamo3, and sshane! * Hyundai Kona Electric 2023 (Korean version) support thanks to sunnyhaibin and haram-KONA! * Kia Sorento Hybrid 2023 support thanks to sunnyhaibin! diff --git a/docs/CARS.md b/docs/CARS.md index 775418427d..ed5683919f 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. -# 260 Supported Cars +# 261 Supported Cars |Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|Hardware Needed
 |Video| |---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:| @@ -71,6 +71,7 @@ A supported vehicle is one that just works when you install a comma device. All |Honda|Passport 2019-23|All|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 Honda Nidec connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Honda|Pilot 2016-22|Honda Sensing|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 Honda Nidec connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Honda|Ridgeline 2017-23|Honda Sensing|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 Honda Nidec connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Hyundai|Azera 2022|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai K connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Hyundai|Elantra 2017-19|Smart Cruise Control (SCC)|Stock|19 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai B connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Hyundai|Elantra 2021-23|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai K connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Hyundai|Elantra GT 2017-19|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai E connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| diff --git a/selfdrive/car/hyundai/hyundaican.py b/selfdrive/car/hyundai/hyundaican.py index 0083974020..3b98432615 100644 --- a/selfdrive/car/hyundai/hyundaican.py +++ b/selfdrive/car/hyundai/hyundaican.py @@ -37,7 +37,8 @@ def create_lkas11(packer, frame, car_fingerprint, apply_steer, steer_req, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KIA_SELTOS, CAR.ELANTRA_2021, CAR.GENESIS_G70_2020, CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_EV, CAR.KONA_HEV, CAR.KONA_EV_2022, CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, - CAR.SANTA_FE_PHEV_2022, CAR.KIA_STINGER_2022, CAR.KIA_K5_HEV_2020, CAR.KIA_CEED): + CAR.SANTA_FE_PHEV_2022, CAR.KIA_STINGER_2022, CAR.KIA_K5_HEV_2020, CAR.KIA_CEED, + CAR.AZERA_6TH_GEN): values["CF_Lkas_LdwsActivemode"] = int(left_lane) + (int(right_lane) << 1) values["CF_Lkas_LdwsOpt_USM"] = 2 diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index 9b4ae508e5..e55f8bec3b 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -64,7 +64,11 @@ class CarInterface(CarInterfaceBase): ret.steerLimitTimer = 0.4 CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) - if candidate in (CAR.SANTA_FE, CAR.SANTA_FE_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022): + if candidate == CAR.AZERA_6TH_GEN: + ret.mass = 1540. # average + ret.wheelbase = 2.885 + ret.steerRatio = 14.5 + elif candidate in (CAR.SANTA_FE, CAR.SANTA_FE_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022): ret.mass = 3982. * CV.LB_TO_KG ret.wheelbase = 2.766 # Values from optimizer diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 2b8bb763a2..3029c2ee65 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -69,6 +69,7 @@ class HyundaiFlags(IntFlag): class CAR: # Hyundai + AZERA_6TH_GEN = "HYUNDAI AZERA 6TH GEN" ELANTRA = "HYUNDAI ELANTRA 2017" ELANTRA_2021 = "HYUNDAI ELANTRA 2021" ELANTRA_HEV_2021 = "HYUNDAI ELANTRA HYBRID 2021" @@ -152,6 +153,7 @@ class HyundaiCarInfo(CarInfo): CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = { + CAR.AZERA_6TH_GEN: HyundaiCarInfo("Hyundai Azera 2022", "All", car_parts=CarParts.common([CarHarness.hyundai_k])), CAR.ELANTRA: [ HyundaiCarInfo("Hyundai Elantra 2017-19", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_b])), HyundaiCarInfo("Hyundai Elantra GT 2017-19", car_parts=CarParts.common([CarHarness.hyundai_e])), @@ -523,6 +525,23 @@ FW_QUERY_CONFIG = FwQueryConfig( ) FW_VERSIONS = { + CAR.AZERA_6TH_GEN: { + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00IG__ SCC F-CU- 1.00 1.00 99110-G8100 ', + ], + (Ecu.eps, 0x7d4, None): [ + b'\xf1\x00IG MDPS C 1.00 1.02 56310G8510\x00 4IGSC103', + ], + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00IG MFC AT MES LHD 1.00 1.04 99211-G8100 200511', + ], + (Ecu.transmission, 0x7e1, None): [ + b'\xf1\x00bcsh8p54 U912\x00\x00\x00\x00\x00\x00SIG0M35MH0\xa4 |.', + ], + (Ecu.engine, 0x7e0, None): [ + b'\xf1\x81641KA051\x00\x00\x00\x00\x00\x00\x00\x00', + ], + }, CAR.HYUNDAI_GENESIS: { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00DH LKAS 1.1 -150210', @@ -1990,6 +2009,7 @@ UNSUPPORTED_LONGITUDINAL_CAR = LEGACY_SAFETY_MODE_CAR | {CAR.KIA_NIRO_PHEV, CAR. # If 0x500 is present on bus 1 it probably has a Mando radar outputting radar points. # If no points are outputted by default it might be possible to turn it on using selfdrive/debug/hyundai_enable_radar_points.py DBC = { + CAR.AZERA_6TH_GEN: dbc_dict('hyundai_kia_generic', None), CAR.ELANTRA: dbc_dict('hyundai_kia_generic', None), CAR.ELANTRA_2021: dbc_dict('hyundai_kia_generic', None), CAR.ELANTRA_HEV_2021: dbc_dict('hyundai_kia_generic', None), diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index 4d99f594db..aaac4e2180 100755 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -94,6 +94,7 @@ routes = [ CarTestRoute("2d5808fae0b38ac6|2021-09-01--17-14-11", HONDA.HONDA_E), CarTestRoute("f44aa96ace22f34a|2021-12-22--06-22-31", HONDA.CIVIC_2022), + CarTestRoute("87d7f06ade479c2e|2023-09-11--23-30-11", HYUNDAI.AZERA_6TH_GEN), CarTestRoute("6fe86b4e410e4c37|2020-07-22--16-27-13", HYUNDAI.HYUNDAI_GENESIS), CarTestRoute("b5d6dc830ad63071|2022-12-12--21-28-25", HYUNDAI.GENESIS_GV60_EV_1ST_GEN, segment=12), CarTestRoute("70c5bec28ec8e345|2020-08-08--12-22-23", HYUNDAI.GENESIS_G70), diff --git a/selfdrive/car/torque_data/override.yaml b/selfdrive/car/torque_data/override.yaml index d332f7fc3d..e3da0b0e4e 100644 --- a/selfdrive/car/torque_data/override.yaml +++ b/selfdrive/car/torque_data/override.yaml @@ -59,6 +59,7 @@ LEXUS IS 2023: [2.0, 2.0, 0.1] KIA SORENTO HYBRID 4TH GEN: [2.5, 2.5, 0.1] HYUNDAI KONA ELECTRIC 2ND GEN: [2.5, 2.5, 0.1] HYUNDAI IONIQ 6 2023: [2.5, 2.5, 0.1] +HYUNDAI AZERA 6TH GEN: [1.8, 1.8, 0.1] # Dashcam or fallback configured as ideal car mock: [10.0, 10, 0.0] From 34f5cad4e7a115826167d44ee48446e7e157b79f Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Wed, 13 Sep 2023 18:03:16 +0800 Subject: [PATCH 21/59] cabana/chart: use different colors to distinguish similar signals (#29890) * Use different colors to distinguish similar signals * check hueF value * lighter --- tools/cabana/chart/chart.cc | 23 ++++++++++++++++++++++- tools/cabana/chart/chart.h | 1 + tools/cabana/chart/chartswidget.cc | 4 ++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/tools/cabana/chart/chart.cc b/tools/cabana/chart/chart.cc index 68d1593d52..93fbbaeae3 100644 --- a/tools/cabana/chart/chart.cc +++ b/tools/cabana/chart/chart.cc @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -151,6 +152,11 @@ void ChartView::removeIf(std::function predicate) { void ChartView::signalUpdated(const cabana::Signal *sig) { if (std::any_of(sigs.cbegin(), sigs.cend(), [=](auto &s) { return s.sig == sig; })) { + for (const auto &s : sigs) { + if (s.sig == sig && s.series->color() != sig->color) { + setSeriesColor(s.series, sig->color); + } + } updateTitle(); updateSeries(sig); } @@ -281,7 +287,6 @@ void ChartView::updateSeries(const cabana::Signal *sig, bool clear) { s.step_vals.clear(); s.last_value_mono_time = 0; } - s.series->setColor(s.sig->color); const auto &msgs = can->events(s.msg_id); s.vals.reserve(msgs.capacity()); @@ -789,6 +794,7 @@ QXYSeries *ChartView::createSeries(SeriesType type, QColor color) { } void ChartView::addSeries(QXYSeries *series) { + setSeriesColor(series, series->color()); chart()->addSeries(series); series->attachAxis(axis_x); series->attachAxis(axis_y); @@ -801,6 +807,21 @@ void ChartView::addSeries(QXYSeries *series) { } } +void ChartView::setSeriesColor(QXYSeries *series, QColor color) { + auto existing_series = chart()->series(); + for (auto s : existing_series) { + if (s != series && std::abs(color.hueF() - qobject_cast(s)->color().hueF()) < 0.1) { + // use different color to distinguish it from others. + auto last_color = qobject_cast(existing_series.back())->color(); + color.setHsvF(std::fmod(last_color.hueF() + 60 / 360.0, 1.0), + QRandomGenerator::global()->bounded(35, 100) / 100.0, + QRandomGenerator::global()->bounded(85, 100) / 100.0); + break; + } + } + series->setColor(color); +} + void ChartView::setSeriesType(SeriesType type) { if (type != series_type) { series_type = type; diff --git a/tools/cabana/chart/chart.h b/tools/cabana/chart/chart.h index 4342bdfefc..de2a1b4510 100644 --- a/tools/cabana/chart/chart.h +++ b/tools/cabana/chart/chart.h @@ -89,6 +89,7 @@ private: std::tuple getNiceAxisNumbers(qreal min, qreal max, int tick_count); qreal niceNumber(qreal x, bool ceiling); QXYSeries *createSeries(SeriesType type, QColor color); + void setSeriesColor(QXYSeries *, QColor color); void updateSeriesPoints(); void removeIf(std::function predicate); inline void clearTrackPoints() { for (auto &s : sigs) s.track_pt = {}; } diff --git a/tools/cabana/chart/chartswidget.cc b/tools/cabana/chart/chartswidget.cc index d4ad9d48ad..2495096b1a 100644 --- a/tools/cabana/chart/chartswidget.cc +++ b/tools/cabana/chart/chartswidget.cc @@ -277,6 +277,10 @@ void ChartsWidget::splitChart(ChartView *src_chart) { for (auto it = src_chart->sigs.begin() + 1; it != src_chart->sigs.end(); /**/) { auto c = createChart(); src_chart->chart()->removeSeries(it->series); + + // Restore to the original color + it->series->setColor(it->sig->color); + c->addSeries(it->series); c->sigs.push_back(*it); c->updateAxisY(); From 0bd9df31930abb4f72cdef9908a6b3240426b659 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Thu, 14 Sep 2023 03:52:56 +0800 Subject: [PATCH 22/59] cabana: bug fixes (#29902) * fix freq * fix chart legend alignment issue --- tools/cabana/chart/chartswidget.cc | 1 + tools/cabana/streams/abstractstream.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/cabana/chart/chartswidget.cc b/tools/cabana/chart/chartswidget.cc index 2495096b1a..83991d914f 100644 --- a/tools/cabana/chart/chartswidget.cc +++ b/tools/cabana/chart/chartswidget.cc @@ -289,6 +289,7 @@ void ChartsWidget::splitChart(ChartView *src_chart) { } src_chart->updateAxisY(); src_chart->updateTitle(); + QTimer::singleShot(0, src_chart, &ChartView::resetChartCache); } } diff --git a/tools/cabana/streams/abstractstream.h b/tools/cabana/streams/abstractstream.h index eae34e2cc4..3a89d4e57d 100644 --- a/tools/cabana/streams/abstractstream.h +++ b/tools/cabana/streams/abstractstream.h @@ -30,7 +30,7 @@ struct CanData { std::vector> bit_change_counts; std::vector last_delta; std::vector same_delta_counter; - double last_freq_update_ts = seconds_since_boot(); + double last_freq_update_ts = 0; }; struct CanEvent { From fb804c9529dd8f1b0c48fb4b7c3d796cdd226878 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20R=C4=85czy?= Date: Wed, 13 Sep 2023 14:39:06 -0700 Subject: [PATCH 23/59] scons: delete SHARED flag (#29906) Delete SHARED --- SConstruct | 52 +++++++++++++++-------------------------------- common/SConscript | 11 +++------- 2 files changed, 19 insertions(+), 44 deletions(-) diff --git a/SConstruct b/SConstruct index f213a5e0bd..a086f8448a 100644 --- a/SConstruct +++ b/SConstruct @@ -244,18 +244,6 @@ def progress_function(node): if os.environ.get('SCONS_PROGRESS'): Progress(progress_function, interval=node_interval) -SHARED = False - -# TODO: this can probably be removed -def abspath(x): - if arch == 'aarch64': - pth = os.path.join("/data/pythonpath", x[0].path) - env.Depends(pth, x) - return File(pth) - else: - # rpath works elsewhere - return x[0].path.rsplit("/", 1)[1][:-3] - # Cython build environment py_include = sysconfig.get_paths()['include'] envCython = env.Clone() @@ -337,34 +325,35 @@ if GetOption("clazy"): qt_env['ENV']['CLAZY_IGNORE_DIRS'] = qt_dirs[0] qt_env['ENV']['CLAZY_CHECKS'] = ','.join(checks) -Export('env', 'qt_env', 'arch', 'real_arch', 'SHARED') +Export('env', 'qt_env', 'arch', 'real_arch') +# Build common module SConscript(['common/SConscript']) Import('_common', '_gpucommon') -if SHARED: - common, gpucommon = abspath(common), abspath(gpucommon) -else: - common = [_common, 'json11'] - gpucommon = [_gpucommon] +common = [_common, 'json11'] +gpucommon = [_gpucommon] Export('common', 'gpucommon') -# cereal and messaging are shared with the system +# Build cereal and messaging SConscript(['cereal/SConscript']) -if SHARED: - cereal = abspath([File('cereal/libcereal_shared.so')]) - messaging = abspath([File('cereal/libmessaging_shared.so')]) -else: - cereal = [File('#cereal/libcereal.a')] - messaging = [File('#cereal/libmessaging.a')] - visionipc = [File('#cereal/libvisionipc.a')] + +cereal = [File('#cereal/libcereal.a')] +messaging = [File('#cereal/libmessaging.a')] +visionipc = [File('#cereal/libvisionipc.a')] messaging_python = [File('#cereal/messaging/messaging_pyx.so')] Export('cereal', 'messaging', 'messaging_python', 'visionipc') -# Build rednose library and ekf models +# Build other submodules +SConscript([ + 'body/board/SConscript', + 'opendbc/can/SConscript', + 'panda/SConscript', +]) +# Build rednose library and ekf models rednose_deps = [ "#selfdrive/locationd/models/constants.py", "#selfdrive/locationd/models/gnss_helpers.py", @@ -406,15 +395,6 @@ if arch != "Darwin": ]) # Build openpilot - -# build submodules -SConscript([ - 'body/board/SConscript', - 'cereal/SConscript', - 'opendbc/can/SConscript', - 'panda/SConscript', -]) - SConscript(['third_party/SConscript']) SConscript(['selfdrive/boardd/SConscript']) diff --git a/common/SConscript b/common/SConscript index d22aca128b..97322b248d 100644 --- a/common/SConscript +++ b/common/SConscript @@ -1,9 +1,4 @@ -Import('env', 'envCython', 'arch', 'SHARED') - -if SHARED: - fxn = env.SharedLibrary -else: - fxn = env.Library +Import('env', 'envCython', 'arch') common_libs = [ 'params.cc', @@ -18,13 +13,13 @@ common_libs = [ if arch != "Darwin": common_libs.append('gpio.cc') -_common = fxn('common', common_libs, LIBS="json11") +_common = env.Library('common', common_libs, LIBS="json11") files = [ 'clutil.cc', ] -_gpucommon = fxn('gpucommon', files) +_gpucommon = env.Library('gpucommon', files) Export('_common', '_gpucommon') if GetOption('extras'): From 0d3cc2ae04e5578da45dd5632791cc08977cfb59 Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Wed, 13 Sep 2023 18:20:03 -0400 Subject: [PATCH 24/59] HKG: Car Port for Kia K8 Hybrid 2023 (HDA2) (#29899) * HKG: Car Port for Kia K8 2023 (HDA2) * Fix release docs * add test route * engaged segment --------- Co-authored-by: Shane Smiskol --- RELEASES.md | 1 + docs/CARS.md | 3 ++- selfdrive/car/hyundai/interface.py | 4 ++++ selfdrive/car/hyundai/values.py | 15 +++++++++++++-- selfdrive/car/tests/routes.py | 1 + selfdrive/car/torque_data/override.yaml | 1 + 6 files changed, 22 insertions(+), 3 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 88c3eb7041..c4572dba19 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -3,6 +3,7 @@ Version 0.9.5 (202X-XX-XX) * Hyundai Azera 2022 support thanks to sunnyhaibin! * Hyundai Ioniq 6 2023 support thanks to sunnyhaibin, alamo3, and sshane! * Hyundai Kona Electric 2023 (Korean version) support thanks to sunnyhaibin and haram-KONA! +* Kia K8 Hybrid (with HDA II) 2023 support thanks to sunnyhaibin! * Kia Sorento Hybrid 2023 support thanks to sunnyhaibin! * Lexus IS 2023 support thanks to L3R5! diff --git a/docs/CARS.md b/docs/CARS.md index ed5683919f..8bb318c13e 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. -# 261 Supported Cars +# 262 Supported Cars |Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|Hardware Needed
 |Video| |---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:| @@ -120,6 +120,7 @@ A supported vehicle is one that just works when you install a comma device. All |Kia|Forte 2023|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai E connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Kia|K5 2021-22|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai A connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Kia|K5 Hybrid 2020|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai A connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Kia|K8 Hybrid (with HDA II) 2023[6](#footnotes)|Highway Driving Assist II|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai Q connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Kia|Niro EV 2019|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai H connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Kia|Niro EV 2020|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai F connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Kia|Niro EV 2021|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai C connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index e55f8bec3b..c5537993df 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -215,6 +215,10 @@ class CarInterface(CarInterfaceBase): ret.mass = 2087. ret.wheelbase = 3.09 ret.steerRatio = 14.23 + elif candidate == CAR.KIA_K8_HEV_1ST_GEN: + ret.mass = 1630. # https://carprices.ae/brands/kia/2023/k8/1.6-turbo-hybrid + ret.wheelbase = 2.895 + ret.steerRatio = 13.27 # guesstimate from K5 platform # Genesis elif candidate == CAR.GENESIS_GV60_EV_1ST_GEN: diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 3029c2ee65..8827c7bb0c 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -105,6 +105,7 @@ class CAR: KIA_FORTE = "KIA FORTE E 2018 & GT 2021" KIA_K5_2021 = "KIA K5 2021" KIA_K5_HEV_2020 = "KIA K5 HYBRID 2020" + KIA_K8_HEV_1ST_GEN = "KIA K8 HYBRID 1ST GEN" KIA_NIRO_EV = "KIA NIRO EV 2020" KIA_NIRO_EV_2ND_GEN = "KIA NIRO EV 2ND GEN" KIA_NIRO_PHEV = "KIA NIRO HYBRID 2019" @@ -219,6 +220,7 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = { ], CAR.KIA_K5_2021: HyundaiCarInfo("Kia K5 2021-22", car_parts=CarParts.common([CarHarness.hyundai_a])), CAR.KIA_K5_HEV_2020: HyundaiCarInfo("Kia K5 Hybrid 2020", car_parts=CarParts.common([CarHarness.hyundai_a])), + CAR.KIA_K8_HEV_1ST_GEN: HyundaiCarInfo("Kia K8 Hybrid (with HDA II) 2023", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_q])), CAR.KIA_NIRO_EV: [ HyundaiCarInfo("Kia Niro EV 2019", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", car_parts=CarParts.common([CarHarness.hyundai_h])), HyundaiCarInfo("Kia Niro EV 2020", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", car_parts=CarParts.common([CarHarness.hyundai_f])), @@ -1959,6 +1961,14 @@ FW_VERSIONS = { b'\xf1\x00MQhe SCC FHCUP 1.00 1.07 99110-P4000 ', ], }, + CAR.KIA_K8_HEV_1ST_GEN: { + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00GL3HMFC AT KOR LHD 1.00 1.03 99211-L8000 210907', + ], + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00GL3_ RDR ----- 1.00 1.02 99110-L8000 ', + ], + }, } CHECKSUM = { @@ -1980,7 +1990,7 @@ CAN_GEARS = { CANFD_CAR = {CAR.KIA_EV6, CAR.IONIQ_5, CAR.IONIQ_6, CAR.TUCSON_4TH_GEN, CAR.TUCSON_HYBRID_4TH_GEN, CAR.KIA_SPORTAGE_HYBRID_5TH_GEN, CAR.SANTA_CRUZ_1ST_GEN, CAR.KIA_SPORTAGE_5TH_GEN, CAR.GENESIS_GV70_1ST_GEN, CAR.KIA_SORENTO_PHEV_4TH_GEN, CAR.GENESIS_GV60_EV_1ST_GEN, CAR.KIA_SORENTO_4TH_GEN, CAR.KIA_NIRO_HEV_2ND_GEN, CAR.KIA_NIRO_EV_2ND_GEN, - CAR.GENESIS_GV80, CAR.KIA_CARNIVAL_4TH_GEN, CAR.KIA_SORENTO_HEV_4TH_GEN, CAR.KONA_EV_2ND_GEN} + CAR.GENESIS_GV80, CAR.KIA_CARNIVAL_4TH_GEN, CAR.KIA_SORENTO_HEV_4TH_GEN, CAR.KONA_EV_2ND_GEN, CAR.KIA_K8_HEV_1ST_GEN} # The radar does SCC on these cars when HDA I, rather than the camera CANFD_RADAR_SCC_CAR = {CAR.GENESIS_GV70_1ST_GEN, CAR.KIA_SORENTO_PHEV_4TH_GEN, CAR.KIA_SORENTO_4TH_GEN, CAR.GENESIS_GV80, @@ -1993,7 +2003,7 @@ CAMERA_SCC_CAR = {CAR.KONA_EV_2022, } HYBRID_CAR = {CAR.IONIQ_PHEV, CAR.ELANTRA_HEV_2021, CAR.KIA_NIRO_PHEV, CAR.KIA_NIRO_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.IONIQ, 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_SORENTO_HEV_4TH_GEN, CAR.KIA_OPTIMA_H, CAR.KIA_K8_HEV_1ST_GEN} 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} @@ -2070,4 +2080,5 @@ DBC = { CAR.KIA_CARNIVAL_4TH_GEN: dbc_dict('hyundai_canfd', None), CAR.KIA_SORENTO_HEV_4TH_GEN: dbc_dict('hyundai_canfd', None), CAR.KONA_EV_2ND_GEN: dbc_dict('hyundai_canfd', None), + CAR.KIA_K8_HEV_1ST_GEN: dbc_dict('hyundai_canfd', None), } diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index aaac4e2180..c8701e8f0a 100755 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -147,6 +147,7 @@ routes = [ CarTestRoute("9b25e8c1484a1b67|2023-04-13--10-41-45", HYUNDAI.KIA_EV6), CarTestRoute("007d5e4ad9f86d13|2021-09-30--15-09-23", HYUNDAI.KIA_K5_2021), CarTestRoute("c58dfc9fc16590e0|2023-01-14--13-51-48", HYUNDAI.KIA_K5_HEV_2020), + CarTestRoute("78ad5150de133637|2023-09-13--16-15-57", HYUNDAI.KIA_K8_HEV_1ST_GEN, segment=3), 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), diff --git a/selfdrive/car/torque_data/override.yaml b/selfdrive/car/torque_data/override.yaml index e3da0b0e4e..fc39cd76cb 100644 --- a/selfdrive/car/torque_data/override.yaml +++ b/selfdrive/car/torque_data/override.yaml @@ -60,6 +60,7 @@ KIA SORENTO HYBRID 4TH GEN: [2.5, 2.5, 0.1] HYUNDAI KONA ELECTRIC 2ND GEN: [2.5, 2.5, 0.1] HYUNDAI IONIQ 6 2023: [2.5, 2.5, 0.1] HYUNDAI AZERA 6TH GEN: [1.8, 1.8, 0.1] +KIA K8 HYBRID 1ST GEN: [2.5, 2.5, 0.1] # Dashcam or fallback configured as ideal car mock: [10.0, 10, 0.0] From a95c896b5f04dcd59e38bf2e38ba8fc7033df58f Mon Sep 17 00:00:00 2001 From: Justin Newberry Date: Wed, 13 Sep 2023 18:47:39 -0700 Subject: [PATCH 25/59] Simulator: launch simulator from any directory (#29910) launch sim from any directory --- tools/sim/launch_openpilot.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/sim/launch_openpilot.sh b/tools/sim/launch_openpilot.sh index d5922a4819..361f7b18ea 100755 --- a/tools/sim/launch_openpilot.sh +++ b/tools/sim/launch_openpilot.sh @@ -12,5 +12,8 @@ if [[ "$CI" ]]; then export BLOCK="${BLOCK},ui" fi +SCRIPT_DIR=$(dirname "$0") +OPENPILOT_DIR=$SCRIPT_DIR/../../ + DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -cd ../../selfdrive/manager && exec ./manager.py +cd $OPENPILOT_DIR/selfdrive/manager && exec ./manager.py From 01011c6c1d8a211092d8f90658497f50ebd06bf1 Mon Sep 17 00:00:00 2001 From: Vivek Aithal Date: Wed, 13 Sep 2023 18:59:32 -0700 Subject: [PATCH 26/59] liblocationd: No longer used (#29909) remove liblocationd --- .github/workflows/selfdrive_tests.yaml | 1 - selfdrive/locationd/SConscript | 6 +- selfdrive/locationd/liblocationd.cc | 41 ------- .../locationd/test/_test_locationd_lib.py | 109 ------------------ 4 files changed, 1 insertion(+), 156 deletions(-) delete mode 100644 selfdrive/locationd/liblocationd.cc delete mode 100755 selfdrive/locationd/test/_test_locationd_lib.py diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index a038570c15..6503b164df 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -264,7 +264,6 @@ jobs: run: | ${{ env.RUN }} "export SKIP_LONG_TESTS=1 && \ $PYTEST -n auto --dist=loadscope --timeout 30 -o cpp_files=test_* && \ - selfdrive/locationd/test/_test_locationd_lib.py && \ ./selfdrive/ui/tests/create_test_translations.sh && \ QT_QPA_PLATFORM=offscreen ./selfdrive/ui/tests/test_translations && \ ./selfdrive/ui/tests/test_translations.py && \ diff --git a/selfdrive/locationd/SConscript b/selfdrive/locationd/SConscript index 740f827a49..a6febe0170 100644 --- a/selfdrive/locationd/SConscript +++ b/selfdrive/locationd/SConscript @@ -7,8 +7,4 @@ locationd_sources = ["locationd.cc", "models/live_kf.cc", ekf_sym_cc] lenv = env.Clone() lenv["_LIBFLAGS"] += f' {libkf[0].get_labspath()}' locationd = lenv.Program("locationd", locationd_sources, LIBS=loc_libs + transformations) -lenv.Depends(locationd, libkf) - -if File("liblocationd.cc").exists(): - liblocationd = lenv.SharedLibrary("liblocationd", ["liblocationd.cc"] + locationd_sources, LIBS=loc_libs + transformations) - lenv.Depends(liblocationd, libkf) \ No newline at end of file +lenv.Depends(locationd, libkf) \ No newline at end of file diff --git a/selfdrive/locationd/liblocationd.cc b/selfdrive/locationd/liblocationd.cc deleted file mode 100644 index e2b85d93a1..0000000000 --- a/selfdrive/locationd/liblocationd.cc +++ /dev/null @@ -1,41 +0,0 @@ -#include "selfdrive/locationd/locationd.h" - -extern "C" { - typedef Localizer* Localizer_t; - - Localizer *localizer_init(bool has_ublox) { - return new Localizer(has_ublox ? LocalizerGnssSource::UBLOX : LocalizerGnssSource::QCOM); - } - - void localizer_get_message_bytes(Localizer *localizer, bool inputsOK, bool sensorsOK, bool gpsOK, bool msgValid, - char *buff, size_t buff_size) { - MessageBuilder msg_builder; - kj::ArrayPtr arr = localizer->get_message_bytes(msg_builder, inputsOK, sensorsOK, gpsOK, msgValid).asChars(); - assert(buff_size >= arr.size()); - memcpy(buff, arr.begin(), arr.size()); - } - - void localizer_handle_msg_bytes(Localizer *localizer, const char *data, size_t size) { - localizer->handle_msg_bytes(data, size); - } - - void get_filter_internals(Localizer *localizer, double *state_buff, double *std_buff){ - Eigen::VectorXd state = localizer->get_state(); - memcpy(state_buff, state.data(), sizeof(double) * state.size()); - Eigen::VectorXd stdev = localizer->get_stdev(); - memcpy(std_buff, stdev.data(), sizeof(double) * stdev.size()); - } - - bool is_gps_ok(Localizer *localizer){ - return localizer->is_gps_ok(); - } - - bool are_inputs_ok(Localizer *localizer){ - return localizer->are_inputs_ok(); - } - - void observation_timings_invalid_reset(Localizer *localizer){ - localizer->observation_timings_invalid_reset(); - } - -} diff --git a/selfdrive/locationd/test/_test_locationd_lib.py b/selfdrive/locationd/test/_test_locationd_lib.py deleted file mode 100755 index bf4fcbdbe9..0000000000 --- a/selfdrive/locationd/test/_test_locationd_lib.py +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env python3 -"""This test can't be run together with other locationd tests. -cffi.dlopen breaks the list of registered filters.""" -import os -import random -import unittest - -from cffi import FFI - -import cereal.messaging as messaging -from cereal import log - -from openpilot.common.ffi_wrapper import suffix - -SENSOR_DECIMATION = 1 -VISION_DECIMATION = 1 - -LIBLOCATIOND_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '../liblocationd' + suffix())) - - -class TestLocationdLib(unittest.TestCase): - def setUp(self): - header = '''typedef ...* Localizer_t; -Localizer_t localizer_init(bool has_ublox); -void localizer_get_message_bytes(Localizer_t localizer, bool inputsOK, bool sensorsOK, bool gpsOK, bool msgValid, char *buff, size_t buff_size); -void localizer_handle_msg_bytes(Localizer_t localizer, const char *data, size_t size);''' - - self.ffi = FFI() - self.ffi.cdef(header) - self.lib = self.ffi.dlopen(LIBLOCATIOND_PATH) - - self.localizer = self.lib.localizer_init(True) # default to ublox - - self.buff_size = 2048 - self.msg_buff = self.ffi.new(f'char[{self.buff_size}]') - - def localizer_handle_msg(self, msg_builder): - bytstr = msg_builder.to_bytes() - self.lib.localizer_handle_msg_bytes(self.localizer, self.ffi.from_buffer(bytstr), len(bytstr)) - - def localizer_get_msg(self, t=0, inputsOK=True, sensorsOK=True, gpsOK=True, msgValid=True): - self.lib.localizer_get_message_bytes(self.localizer, inputsOK, sensorsOK, gpsOK, msgValid, self.ffi.addressof(self.msg_buff, 0), self.buff_size) - with log.Event.from_bytes(self.ffi.buffer(self.msg_buff), nesting_limit=self.buff_size // 8) as log_evt: - return log_evt - - def test_liblocalizer(self): - msg = messaging.new_message('liveCalibration') - msg.liveCalibration.validBlocks = random.randint(1, 10) - msg.liveCalibration.rpyCalib = [random.random() / 10 for _ in range(3)] - - self.localizer_handle_msg(msg) - liveloc = self.localizer_get_msg() - self.assertTrue(liveloc is not None) - - @unittest.skip("temporarily disabled due to false positives") - def test_device_fell(self): - msg = messaging.new_message('accelerometer') - msg.accelerometer.sensor = 1 - msg.accelerometer.timestamp = msg.logMonoTime - msg.accelerometer.type = 1 - msg.accelerometer.init('acceleration') - msg.accelerometer.acceleration.v = [10.0, 0.0, 0.0] # zero with gravity - self.localizer_handle_msg(msg) - - ret = self.localizer_get_msg() - self.assertTrue(ret.liveLocationKalman.deviceStable) - - msg = messaging.new_message('accelerometer') - msg.accelerometer.sensor = 1 - msg.accelerometer.timestamp = msg.logMonoTime - msg.accelerometer.type = 1 - msg.accelerometer.init('acceleration') - msg.accelerometer.acceleration.v = [50.1, 0.0, 0.0] # more than 40 m/s**2 - self.localizer_handle_msg(msg) - - ret = self.localizer_get_msg() - self.assertFalse(ret.liveLocationKalman.deviceStable) - - def test_posenet_spike(self): - for _ in range(SENSOR_DECIMATION): - msg = messaging.new_message('carState') - msg.carState.vEgo = 6.0 # more than 5 m/s - self.localizer_handle_msg(msg) - - ret = self.localizer_get_msg() - self.assertTrue(ret.liveLocationKalman.posenetOK) - - for _ in range(20 * VISION_DECIMATION): # size of hist_old - msg = messaging.new_message('cameraOdometry') - msg.cameraOdometry.rot = [0.0, 0.0, 0.0] - msg.cameraOdometry.rotStd = [0.1, 0.1, 0.1] - msg.cameraOdometry.trans = [0.0, 0.0, 0.0] - msg.cameraOdometry.transStd = [2.0, 0.1, 0.1] - self.localizer_handle_msg(msg) - - for _ in range(20 * VISION_DECIMATION): # size of hist_new - msg = messaging.new_message('cameraOdometry') - msg.cameraOdometry.rot = [0.0, 0.0, 0.0] - msg.cameraOdometry.rotStd = [1.0, 1.0, 1.0] - msg.cameraOdometry.trans = [0.0, 0.0, 0.0] - msg.cameraOdometry.transStd = [10.1, 0.1, 0.1] # more than 4 times larger - self.localizer_handle_msg(msg) - - ret = self.localizer_get_msg() - self.assertFalse(ret.liveLocationKalman.posenetOK) - -if __name__ == "__main__": - unittest.main() - From 82452ec66b0dd4e48365e794ac70ce22003edaec Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Thu, 14 Sep 2023 10:00:00 +0800 Subject: [PATCH 27/59] cabana: use QStaticText to boost rending performance (#29900) use QStaticText to boost rending performance --- tools/cabana/binaryview.cc | 17 +++++++++++++---- tools/cabana/binaryview.h | 6 ++++-- tools/cabana/util.cc | 7 +++++-- tools/cabana/util.h | 8 ++++++++ 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/tools/cabana/binaryview.cc b/tools/cabana/binaryview.cc index bd43c337bd..e7edc0ecb9 100644 --- a/tools/cabana/binaryview.cc +++ b/tools/cabana/binaryview.cc @@ -280,7 +280,7 @@ void BinaryViewModel::refresh() { updateState(); } -void BinaryViewModel::updateItem(int row, int col, const QString &val, const QColor &color) { +void BinaryViewModel::updateItem(int row, int col, uint8_t val, const QColor &color) { auto &item = items[row * column_count + col]; if (item.val != val || item.bg_color != color) { item.val = val; @@ -307,7 +307,7 @@ void BinaryViewModel::updateState() { for (int i = 0; i < binary.size(); ++i) { for (int j = 0; j < 8; ++j) { auto &item = items[i * column_count + j]; - QString val = ((binary[i] >> (7 - j)) & 1) != 0 ? "1" : "0"; + int val = ((binary[i] >> (7 - j)) & 1) != 0 ? 1 : 0; // Bit update frequency based highlighting double offset = !item.sigs.empty() ? 50 : 0; auto n = last_msg.bit_change_counts[i][7 - j]; @@ -317,7 +317,7 @@ void BinaryViewModel::updateState() { color.setAlpha(alpha); updateItem(i, j, val, color); } - updateItem(i, 8, toHex(binary[i]), last_msg.colors[i]); + updateItem(i, 8, binary[i], last_msg.colors[i]); } } @@ -348,6 +348,13 @@ BinaryItemDelegate::BinaryItemDelegate(QObject *parent) : QStyledItemDelegate(pa small_font.setPixelSize(8); hex_font = QFontDatabase::systemFont(QFontDatabase::FixedFont); hex_font.setBold(true); + + bin_text_table[0].setText("0"); + bin_text_table[1].setText("1"); + for (int i = 0; i < 256; ++i) { + hex_text_table[i].setText(QStringLiteral("%1").arg(i, 2, 16, QLatin1Char('0')).toUpper()); + hex_text_table[i].prepare({}, hex_font); + } } bool BinaryItemDelegate::hasSignal(const QModelIndex &index, int dx, int dy, const cabana::Signal *sig) const { @@ -392,7 +399,9 @@ void BinaryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op } else if (!item->valid) { painter->fillRect(option.rect, QBrush(Qt::darkGray, Qt::BDiagPattern)); } - painter->drawText(option.rect, Qt::AlignCenter, item->val); + if (item->valid) { + utils::drawStaticText(painter, option.rect, index.column() == 8 ? hex_text_table[item->val] : bin_text_table[item->val]); + } if (item->is_msb || item->is_lsb) { painter->setFont(small_font); painter->drawText(option.rect.adjusted(8, 0, -8, -3), Qt::AlignRight | Qt::AlignBottom, item->is_msb ? "M" : "L"); diff --git a/tools/cabana/binaryview.h b/tools/cabana/binaryview.h index 04e1d5b2af..584910dc83 100644 --- a/tools/cabana/binaryview.h +++ b/tools/cabana/binaryview.h @@ -19,6 +19,8 @@ public: void drawSignalCell(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index, const cabana::Signal *sig) const; QFont small_font, hex_font; + std::array hex_text_table; + std::array bin_text_table; }; class BinaryViewModel : public QAbstractTableModel { @@ -26,7 +28,7 @@ public: BinaryViewModel(QObject *parent) : QAbstractTableModel(parent) {} void refresh(); void updateState(); - void updateItem(int row, int col, const QString &val, const QColor &color); + void updateItem(int row, int col, uint8_t val, const QColor &color); QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override { return row_count; } @@ -42,7 +44,7 @@ public: QColor bg_color = QColor(102, 86, 169, 255); bool is_msb = false; bool is_lsb = false; - QString val; + uint8_t val; QList sigs; bool valid = false; }; diff --git a/tools/cabana/util.cc b/tools/cabana/util.cc index 951856e32d..4c21530774 100644 --- a/tools/cabana/util.cc +++ b/tools/cabana/util.cc @@ -1,7 +1,6 @@ #include "tools/cabana/util.h" #include -#include #include #include #include @@ -56,6 +55,10 @@ std::pair SegmentTree::get_minmax(int n, int left, int right, in MessageBytesDelegate::MessageBytesDelegate(QObject *parent, bool multiple_lines) : multiple_lines(multiple_lines), QStyledItemDelegate(parent) { fixed_font = QFontDatabase::systemFont(QFontDatabase::FixedFont); byte_size = QFontMetrics(fixed_font).size(Qt::TextSingleLine, "00 ") + QSize(0, 2); + for (int i = 0; i < 256; ++i) { + hex_text_table[i].setText(QStringLiteral("%1").arg(i, 2, 16, QLatin1Char('0')).toUpper()); + hex_text_table[i].prepare({}, fixed_font); + } } int MessageBytesDelegate::widthForBytes(int n) const { @@ -107,7 +110,7 @@ void MessageBytesDelegate::paint(QPainter *painter, const QStyleOptionViewItem & } else if (option.state & QStyle::State_Selected) { painter->setPen(option.palette.color(QPalette::HighlightedText)); } - painter->drawText(r, Qt::AlignCenter, toHex(byte_list[i])); + utils::drawStaticText(painter, r, hex_text_table[(uint8_t)(byte_list[i])]); } painter->setFont(old_font); painter->setPen(old_pen); diff --git a/tools/cabana/util.h b/tools/cabana/util.h index 9e93e74833..2c1bc5cf7b 100644 --- a/tools/cabana/util.h +++ b/tools/cabana/util.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -10,8 +11,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -75,6 +78,7 @@ public: int widthForBytes(int n) const; private: + std::array hex_text_table; QFont fixed_font; QSize byte_size = {}; bool multiple_lines = false; @@ -102,6 +106,10 @@ void setTheme(int theme); inline QString formatSeconds(int seconds) { return QDateTime::fromSecsSinceEpoch(seconds, Qt::UTC).toString(seconds > 60 * 60 ? "hh:mm:ss" : "mm:ss"); } +inline void drawStaticText(QPainter *p, const QRect &r, const QStaticText &text) { + auto size = (r.size() - text.size()) / 2; + p->drawStaticText(r.left() + size.width(), r.top() + size.height(), text); +} } class ToolButton : public QToolButton { From 6666413626d72b51759ce0330b9c02dc3ebf8fc9 Mon Sep 17 00:00:00 2001 From: Justin Newberry Date: Wed, 13 Sep 2023 19:19:06 -0700 Subject: [PATCH 28/59] test_replay: speedup by preventing multiple downloads (#29901) * Demo route fixture * fix tests * demo route download * remove iostream --- tools/replay/tests/test_replay.cc | 47 ++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/tools/replay/tests/test_replay.cc b/tools/replay/tests/test_replay.cc index 393a561c0f..05c0ca8ac4 100644 --- a/tools/replay/tests/test_replay.cc +++ b/tools/replay/tests/test_replay.cc @@ -12,7 +12,7 @@ const std::string TEST_RLOG_URL = "https://commadataci.blob.core.windows.net/openpilotci/0c94aa1e1296d7c6/2021-05-05--19-48-37/0/rlog.bz2"; const std::string TEST_RLOG_CHECKSUM = "5b966d4bb21a100a8c4e59195faeb741b975ccbe268211765efd1763d892bfb3"; -bool donload_to_file(const std::string &url, const std::string &local_file, int chunk_size = 5 * 1024 * 1024, int retries = 3) { +bool download_to_file(const std::string &url, const std::string &local_file, int chunk_size = 5 * 1024 * 1024, int retries = 3) { do { if (httpDownload(url, local_file, chunk_size)) { return true; @@ -29,7 +29,7 @@ TEST_CASE("httpMultiPartDownload") { const size_t chunk_size = 5 * 1024 * 1024; std::string content; SECTION("download to file") { - REQUIRE(donload_to_file(TEST_RLOG_URL, filename, chunk_size)); + REQUIRE(download_to_file(TEST_RLOG_URL, filename, chunk_size)); content = util::read_file(filename); } SECTION("download to buffer") { @@ -110,23 +110,36 @@ void read_segment(int n, const SegmentFile &segment_file, uint32_t flags) { loop.exec(); } -TEST_CASE("Route") { - // Create a local route from remote for testing - Route remote_route(DEMO_ROUTE); - REQUIRE(remote_route.load()); - char tmp_path[] = "/tmp/root_XXXXXX"; - const std::string data_dir = mkdtemp(tmp_path); - const std::string route_name = DEMO_ROUTE.mid(17).toStdString(); - for (int i = 0; i < 2; ++i) { - std::string log_path = util::string_format("%s/%s--%d/", data_dir.c_str(), route_name.c_str(), i); - util::create_directories(log_path, 0755); - REQUIRE(donload_to_file(remote_route.at(i).rlog.toStdString(), log_path + "rlog.bz2")); - REQUIRE(donload_to_file(remote_route.at(i).road_cam.toStdString(), log_path + "fcamera.hevc")); - REQUIRE(donload_to_file(remote_route.at(i).driver_cam.toStdString(), log_path + "dcamera.hevc")); - REQUIRE(donload_to_file(remote_route.at(i).wide_road_cam.toStdString(), log_path + "ecamera.hevc")); - REQUIRE(donload_to_file(remote_route.at(i).qcamera.toStdString(), log_path + "qcamera.ts")); +std::string download_demo_route() { + static std::string data_dir; + + if (data_dir == "") { + char tmp_path[] = "/tmp/root_XXXXXX"; + data_dir = mkdtemp(tmp_path); + + Route remote_route(DEMO_ROUTE); + assert(remote_route.load()); + + // Create a local route from remote for testing + const std::string route_name = DEMO_ROUTE.mid(17).toStdString(); + for (int i = 0; i < 2; ++i) { + std::string log_path = util::string_format("%s/%s--%d/", data_dir.c_str(), route_name.c_str(), i); + util::create_directories(log_path, 0755); + REQUIRE(download_to_file(remote_route.at(i).rlog.toStdString(), log_path + "rlog.bz2")); + REQUIRE(download_to_file(remote_route.at(i).road_cam.toStdString(), log_path + "fcamera.hevc")); + REQUIRE(download_to_file(remote_route.at(i).driver_cam.toStdString(), log_path + "dcamera.hevc")); + REQUIRE(download_to_file(remote_route.at(i).wide_road_cam.toStdString(), log_path + "ecamera.hevc")); + REQUIRE(download_to_file(remote_route.at(i).qcamera.toStdString(), log_path + "qcamera.ts")); + } } + return data_dir; +} + + +TEST_CASE("Route") { + std::string data_dir = download_demo_route(); + SECTION("Local route") { auto flags = GENERATE(REPLAY_FLAG_DCAM | REPLAY_FLAG_ECAM, REPLAY_FLAG_QCAMERA); Route route(DEMO_ROUTE, QString::fromStdString(data_dir)); From e9edf1300ac486e1e1f79035b14a648d41f0d16d Mon Sep 17 00:00:00 2001 From: Vivek Aithal Date: Thu, 14 Sep 2023 13:59:21 -0700 Subject: [PATCH 29/59] locationd: Unit tests for different scenarios (#29908) * add different scenarios for locationd * add locationd scenario tests to unit tests --- .github/workflows/selfdrive_tests.yaml | 1 + .../test/test_locationd_scenarios.py | 223 ++++++++++++++++++ 2 files changed, 224 insertions(+) create mode 100755 selfdrive/locationd/test/test_locationd_scenarios.py diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index 6503b164df..f82da4195f 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -264,6 +264,7 @@ jobs: run: | ${{ env.RUN }} "export SKIP_LONG_TESTS=1 && \ $PYTEST -n auto --dist=loadscope --timeout 30 -o cpp_files=test_* && \ + ./selfdrive/locationd/test/test_locationd_scenarios.py && \ ./selfdrive/ui/tests/create_test_translations.sh && \ QT_QPA_PLATFORM=offscreen ./selfdrive/ui/tests/test_translations && \ ./selfdrive/ui/tests/test_translations.py && \ diff --git a/selfdrive/locationd/test/test_locationd_scenarios.py b/selfdrive/locationd/test/test_locationd_scenarios.py new file mode 100755 index 0000000000..f08fe72ff1 --- /dev/null +++ b/selfdrive/locationd/test/test_locationd_scenarios.py @@ -0,0 +1,223 @@ +#!/usr/bin/env python3 +import unittest +import numpy as np +from collections import defaultdict +from enum import Enum + + +from openpilot.selfdrive.test.openpilotci import get_url +from openpilot.tools.lib.logreader import LogReader +from openpilot.selfdrive.test.process_replay.process_replay import replay_process_with_name + +TEST_ROUTE, TEST_SEG_NUM = "ff2bd20623fcaeaa|2023-09-05--10-14-54", 4 +GPS_MESSAGES = ['gpsLocationExternal', 'gpsLocation'] +SELECT_COMPARE_FIELDS = { + 'yaw_rate': ['angularVelocityCalibrated', 'value', 2], + 'roll': ['orientationNED', 'value', 0], + 'gps_flag': ['gpsOK'], + 'inputs_flag': ['inputsOK'], + 'sensors_flag': ['sensorsOK'], +} +JUNK_IDX = 100 + + +class Scenario(Enum): + BASE = 'base' + GPS_OFF = 'gps_off' + GPS_OFF_MIDWAY = 'gps_off_midway' + GPS_ON_MIDWAY = 'gps_on_midway' + GPS_TUNNEL = 'gps_tunnel' + GYRO_OFF = 'gyro_off' + GYRO_SPIKE_MIDWAY = 'gyro_spike_midway' + ACCEL_OFF = 'accel_off' + ACCEL_SPIKE_MIDWAY = 'accel_spike_midway' + + +def get_select_fields_data(logs): + def get_nested_keys(msg, keys): + val = None + for key in keys: + val = getattr(msg if val is None else val, key) if isinstance(key, str) else val[key] + return val + llk = [x.liveLocationKalman for x in logs if x.which() == 'liveLocationKalman'] + data = defaultdict(list) + for msg in llk: + for key, fields in SELECT_COMPARE_FIELDS.items(): + data[key].append(get_nested_keys(msg, fields)) + for key in data: + data[key] = np.array(data[key][JUNK_IDX:], dtype=float) + return data + + +def run_scenarios(scenario): + logs = list(LogReader(get_url(TEST_ROUTE, TEST_SEG_NUM))) + if scenario == Scenario.BASE: + pass + + elif scenario == Scenario.GPS_OFF: + logs = sorted([x for x in logs if x.which() not in GPS_MESSAGES], key=lambda x: x.logMonoTime) + + elif scenario == Scenario.GPS_OFF_MIDWAY: + non_gps = [x for x in logs if x.which() not in GPS_MESSAGES] + gps = [x for x in logs if x.which() in GPS_MESSAGES] + logs = sorted(non_gps + gps[: len(gps) // 2], key=lambda x: x.logMonoTime) + + elif scenario == Scenario.GPS_ON_MIDWAY: + non_gps = [x for x in logs if x.which() not in GPS_MESSAGES] + gps = [x for x in logs if x.which() in GPS_MESSAGES] + logs = sorted(non_gps + gps[len(gps) // 2:], key=lambda x: x.logMonoTime) + + elif scenario == Scenario.GPS_TUNNEL: + non_gps = [x for x in logs if x.which() not in GPS_MESSAGES] + gps = [x for x in logs if x.which() in GPS_MESSAGES] + logs = sorted(non_gps + gps[:len(gps) // 4] + gps[-len(gps) // 4:], key=lambda x: x.logMonoTime) + + elif scenario == Scenario.GYRO_OFF: + logs = sorted([x for x in logs if x.which() != 'gyroscope'], key=lambda x: x.logMonoTime) + + elif scenario == Scenario.GYRO_SPIKE_MIDWAY: + non_gyro = [x for x in logs if x.which() not in 'gyroscope'] + gyro = [x for x in logs if x.which() in 'gyroscope'] + temp = gyro[len(gyro) // 2].as_builder() + temp.gyroscope.gyroUncalibrated.v[0] += 3.0 + gyro[len(gyro) // 2] = temp.as_reader() + logs = sorted(non_gyro + gyro, key=lambda x: x.logMonoTime) + + elif scenario == Scenario.ACCEL_OFF: + logs = sorted([x for x in logs if x.which() != 'accelerometer'], key=lambda x: x.logMonoTime) + + elif scenario == Scenario.ACCEL_SPIKE_MIDWAY: + non_accel = [x for x in logs if x.which() not in 'accelerometer'] + accel = [x for x in logs if x.which() in 'accelerometer'] + temp = accel[len(accel) // 2].as_builder() + temp.accelerometer.acceleration.v[0] += 10.0 + accel[len(accel) // 2] = temp.as_reader() + logs = sorted(non_accel + accel, key=lambda x: x.logMonoTime) + + replayed_logs = replay_process_with_name(name='locationd', lr=logs) + return get_select_fields_data(logs), get_select_fields_data(replayed_logs) + + +class TestLocationdScenarios(unittest.TestCase): + """ + Test locationd with different scenarios. In all these scenarios, we expect the following: + - locationd kalman filter should never go unstable (we care mostly about yaw_rate, roll, gpsOK, inputsOK, sensorsOK) + - faulty values should be ignored, with appropriate flags set + """ + def test_base(self): + """ + Test: unchanged log + Expected Result: + - yaw_rate: unchanged + - roll: unchanged + """ + orig_data, replayed_data = run_scenarios(Scenario.BASE) + self.assertTrue(np.allclose(orig_data['yaw_rate'], replayed_data['yaw_rate'], atol=np.radians(0.2))) + self.assertTrue(np.allclose(orig_data['roll'], replayed_data['roll'], atol=np.radians(0.5))) + + def test_gps_off(self): + """ + Test: no GPS message for the entire segment + Expected Result: + - yaw_rate: unchanged + - roll: + - gpsOK: False + """ + orig_data, replayed_data = run_scenarios(Scenario.GPS_OFF) + self.assertTrue(np.allclose(orig_data['yaw_rate'], replayed_data['yaw_rate'], atol=np.radians(0.2))) + self.assertTrue(np.allclose(orig_data['roll'], replayed_data['roll'], atol=np.radians(0.5))) + self.assertTrue(np.all(replayed_data['gps_flag'] == 0.0)) + + def test_gps_off_midway(self): + """ + Test: no GPS message for the second half of the segment + Expected Result: + - yaw_rate: unchanged + - roll: + - gpsOK: True for the first half, False for the second half + """ + orig_data, replayed_data = run_scenarios(Scenario.GPS_OFF_MIDWAY) + self.assertTrue(np.allclose(orig_data['yaw_rate'], replayed_data['yaw_rate'], atol=np.radians(0.2))) + self.assertTrue(np.allclose(orig_data['roll'], replayed_data['roll'], atol=np.radians(0.5))) + self.assertTrue(np.diff(replayed_data['gps_flag'])[512] == -1.0) + + def test_gps_on_midway(self): + """ + Test: no GPS message for the first half of the segment + Expected Result: + - yaw_rate: unchanged + - roll: + - gpsOK: False for the first half, True for the second half + """ + orig_data, replayed_data = run_scenarios(Scenario.GPS_ON_MIDWAY) + self.assertTrue(np.allclose(orig_data['yaw_rate'], replayed_data['yaw_rate'], atol=np.radians(0.2))) + self.assertTrue(np.allclose(orig_data['roll'], replayed_data['roll'], atol=np.radians(1.5))) + self.assertTrue(np.diff(replayed_data['gps_flag'])[505] == 1.0) + + def test_gps_tunnel(self): + """ + Test: no GPS message for the middle section of the segment + Expected Result: + - yaw_rate: unchanged + - roll: + - gpsOK: False for the middle section, True for the rest + """ + orig_data, replayed_data = run_scenarios(Scenario.GPS_TUNNEL) + self.assertTrue(np.allclose(orig_data['yaw_rate'], replayed_data['yaw_rate'], atol=np.radians(0.2))) + self.assertTrue(np.allclose(orig_data['roll'], replayed_data['roll'], atol=np.radians(0.5))) + self.assertTrue(np.diff(replayed_data['gps_flag'])[213] == -1.0) + self.assertTrue(np.diff(replayed_data['gps_flag'])[805] == 1.0) + + def test_gyro_off(self): + """ + Test: no gyroscope message for the entire segment + Expected Result: + - yaw_rate: 0 + - roll: 0 + - sensorsOK: False + """ + _, replayed_data = run_scenarios(Scenario.GYRO_OFF) + self.assertTrue(np.allclose(replayed_data['yaw_rate'], 0.0)) + self.assertTrue(np.allclose(replayed_data['roll'], 0.0)) + self.assertTrue(np.all(replayed_data['sensors_flag'] == 0.0)) + + def test_gyro_spikes(self): + """ + Test: a gyroscope spike in the middle of the segment + Expected Result: + - yaw_rate: unchanged + - roll: unchanged + - inputsOK: False for some time after the spike, True for the rest + """ + orig_data, replayed_data = run_scenarios(Scenario.GYRO_SPIKE_MIDWAY) + self.assertTrue(np.allclose(orig_data['yaw_rate'], replayed_data['yaw_rate'], atol=np.radians(0.2))) + self.assertTrue(np.allclose(orig_data['roll'], replayed_data['roll'], atol=np.radians(0.5))) + self.assertTrue(np.diff(replayed_data['inputs_flag'])[500] == -1.0) + self.assertTrue(np.diff(replayed_data['inputs_flag'])[694] == 1.0) + + def test_accel_off(self): + """ + Test: no accelerometer message for the entire segment + Expected Result: + - yaw_rate: 0 + - roll: 0 + - sensorsOK: False + """ + _, replayed_data = run_scenarios(Scenario.ACCEL_OFF) + self.assertTrue(np.allclose(replayed_data['yaw_rate'], 0.0)) + self.assertTrue(np.allclose(replayed_data['roll'], 0.0)) + self.assertTrue(np.all(replayed_data['sensors_flag'] == 0.0)) + + def test_accel_spikes(self): + """ + ToDo: + Test: an accelerometer spike in the middle of the segment + Expected Result: Right now, the kalman filter is not robust to small spikes like it is to gyroscope spikes. + """ + orig_data, replayed_data = run_scenarios(Scenario.ACCEL_SPIKE_MIDWAY) + self.assertTrue(np.allclose(orig_data['yaw_rate'], replayed_data['yaw_rate'], atol=np.radians(0.2))) + self.assertTrue(np.allclose(orig_data['roll'], replayed_data['roll'], atol=np.radians(0.5))) + + +if __name__ == "__main__": + unittest.main() From 7ef8898624cddb0f2afb3322e2691dd5212239f2 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 14 Sep 2023 14:08:24 -0700 Subject: [PATCH 30/59] don't run test twice --- .github/workflows/selfdrive_tests.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index f82da4195f..6503b164df 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -264,7 +264,6 @@ jobs: run: | ${{ env.RUN }} "export SKIP_LONG_TESTS=1 && \ $PYTEST -n auto --dist=loadscope --timeout 30 -o cpp_files=test_* && \ - ./selfdrive/locationd/test/test_locationd_scenarios.py && \ ./selfdrive/ui/tests/create_test_translations.sh && \ QT_QPA_PLATFORM=offscreen ./selfdrive/ui/tests/test_translations && \ ./selfdrive/ui/tests/test_translations.py && \ From 880157f5a614a4a524273a9833e0a066fdec371e Mon Sep 17 00:00:00 2001 From: YassineYousfi Date: Thu, 14 Sep 2023 14:36:32 -0700 Subject: [PATCH 31/59] framereader: add cache_dir argument (#29904) * framereader: add cache_dir argument * make it an env var --- tools/lib/cache.py | 6 +++--- tools/lib/framereader.py | 26 +++++++++++++------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tools/lib/cache.py b/tools/lib/cache.py index d142955e59..fd214f6bb5 100644 --- a/tools/lib/cache.py +++ b/tools/lib/cache.py @@ -2,10 +2,10 @@ import os import urllib.parse from openpilot.common.file_helpers import mkdirs_exists_ok -DEFAULT_CACHE_DIR = os.path.expanduser("~/.commacache") +DEFAULT_CACHE_DIR = os.getenv("CACHE_ROOT", os.path.expanduser("~/.commacache")) -def cache_path_for_file_path(fn, cache_prefix=None): - dir_ = os.path.join(DEFAULT_CACHE_DIR, "local") +def cache_path_for_file_path(fn, cache_dir=DEFAULT_CACHE_DIR): + dir_ = os.path.join(cache_dir, "local") mkdirs_exists_ok(dir_) fn_parsed = urllib.parse.urlparse(fn) if fn_parsed.scheme == '': diff --git a/tools/lib/framereader.py b/tools/lib/framereader.py index cbc9310790..06fee6857d 100644 --- a/tools/lib/framereader.py +++ b/tools/lib/framereader.py @@ -12,7 +12,7 @@ import numpy as np from lru import LRU import _io -from openpilot.tools.lib.cache import cache_path_for_file_path +from openpilot.tools.lib.cache import cache_path_for_file_path, DEFAULT_CACHE_DIR from openpilot.tools.lib.exceptions import DataUnreadableError from openpilot.common.file_helpers import atomic_write_in_dir @@ -106,8 +106,8 @@ def cache_fn(func): if kwargs.pop('no_cache', None): cache_path = None else: - cache_prefix = kwargs.pop('cache_prefix', None) - cache_path = cache_path_for_file_path(fn, cache_prefix) + cache_dir = kwargs.pop('cache_dir', DEFAULT_CACHE_DIR) + cache_path = cache_path_for_file_path(fn, cache_dir) if cache_path and os.path.exists(cache_path): with open(cache_path, "rb") as cache_file: @@ -140,18 +140,18 @@ def index_stream(fn, typ): } -def index_videos(camera_paths, cache_prefix=None): +def index_videos(camera_paths, cache_dir=DEFAULT_CACHE_DIR): """Requires that paths in camera_paths are contiguous and of the same type.""" if len(camera_paths) < 1: raise ValueError("must provide at least one video to index") frame_type = fingerprint_video(camera_paths[0]) for fn in camera_paths: - index_video(fn, frame_type, cache_prefix) + index_video(fn, frame_type, cache_dir) -def index_video(fn, frame_type=None, cache_prefix=None): - cache_path = cache_path_for_file_path(fn, cache_prefix) +def index_video(fn, frame_type=None, cache_dir=DEFAULT_CACHE_DIR): + cache_path = cache_path_for_file_path(fn, cache_dir) if os.path.exists(cache_path): return @@ -160,16 +160,16 @@ def index_video(fn, frame_type=None, cache_prefix=None): frame_type = fingerprint_video(fn[0]) if frame_type == FrameType.h265_stream: - index_stream(fn, "hevc", cache_prefix=cache_prefix) + index_stream(fn, "hevc", cache_dir=cache_dir) else: raise NotImplementedError("Only h265 supported") -def get_video_index(fn, frame_type, cache_prefix=None): - cache_path = cache_path_for_file_path(fn, cache_prefix) +def get_video_index(fn, frame_type, cache_dir=DEFAULT_CACHE_DIR): + cache_path = cache_path_for_file_path(fn, cache_dir) if not os.path.exists(cache_path): - index_video(fn, frame_type, cache_prefix) + index_video(fn, frame_type, cache_dir) if not os.path.exists(cache_path): return None @@ -284,13 +284,13 @@ class BaseFrameReader: raise NotImplementedError -def FrameReader(fn, cache_prefix=None, readahead=False, readbehind=False, index_data=None): +def FrameReader(fn, cache_dir=DEFAULT_CACHE_DIR, readahead=False, readbehind=False, index_data=None): frame_type = fingerprint_video(fn) if frame_type == FrameType.raw: return RawFrameReader(fn) elif frame_type in (FrameType.h265_stream,): if not index_data: - index_data = get_video_index(fn, frame_type, cache_prefix) + index_data = get_video_index(fn, frame_type, cache_dir) return StreamFrameReader(fn, frame_type, index_data, readahead=readahead, readbehind=readbehind) else: raise NotImplementedError(frame_type) From 9dfd0579d4bcf4065ee289a2486bb77f0700655a Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Thu, 14 Sep 2023 14:48:12 -0700 Subject: [PATCH 32/59] Toyota: use torque control for Japanese-made 2023 RAV4 (#29896) * use torque for 2023 RAV4s that allow it * FW * better cmt * better * better values comment * switch * add torque params * simpler * better to use steerControlType * ??? * fix condition * adjust params * pid is only for old cars * add comment * move comment up * one if fix * invert * better comment * better here * for * add torque hybrid test route * fix condition * this might be simpler * back to one if fix * better name * other way * this reads so much better * last change * better * did i break ci? --- selfdrive/car/tests/routes.py | 2 +- selfdrive/car/torque_data/override.yaml | 6 +-- selfdrive/car/toyota/interface.py | 49 ++++++++++++++----------- selfdrive/car/toyota/values.py | 3 +- 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index c8701e8f0a..69a935fece 100755 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -25,7 +25,6 @@ non_tested_cars = [ HONDA.ODYSSEY_CHN, VOLKSWAGEN.CRAFTER_MK2, # need a route from an ACC-equipped Crafter TOYOTA.RAV4_TSS2_2023, - TOYOTA.RAV4H_TSS2_2023, SUBARU.FORESTER_HYBRID, ] @@ -184,6 +183,7 @@ routes = [ CarTestRoute("a5c341bb250ca2f0|2022-05-18--16-05-17", TOYOTA.RAV4_TSS2_2022), CarTestRoute("7e34a988419b5307|2019-12-18--19-13-30", TOYOTA.RAV4H_TSS2), CarTestRoute("2475fb3eb2ffcc2e|2022-04-29--12-46-23", TOYOTA.RAV4H_TSS2_2022), + CarTestRoute("49e041422a032273|2023-09-14--09-21-32", TOYOTA.RAV4H_TSS2_2023), CarTestRoute("7a31f030957b9c85|2023-04-01--14-12-51", TOYOTA.LEXUS_ES), CarTestRoute("e6a24be49a6cd46e|2019-10-29--10-52-42", TOYOTA.LEXUS_ES_TSS2), CarTestRoute("da23c367491f53e2|2021-05-21--09-09-11", TOYOTA.LEXUS_CTH, segment=3), diff --git a/selfdrive/car/torque_data/override.yaml b/selfdrive/car/torque_data/override.yaml index fc39cd76cb..61ed8a5a77 100644 --- a/selfdrive/car/torque_data/override.yaml +++ b/selfdrive/car/torque_data/override.yaml @@ -12,10 +12,6 @@ SUBARU FORESTER 2022: [.nan, 3.0, .nan] SUBARU OUTBACK 7TH GEN: [.nan, 3.0, .nan] SUBARU ASCENT 2023: [.nan, 3.0, .nan] -# Toyota LTA also has torque -TOYOTA RAV4 2023: [.nan, 3.0, .nan] -TOYOTA RAV4 HYBRID 2023: [.nan, 3.0, .nan] - # Tesla has high torque TESLA AP1 MODEL S: [.nan, 2.5, .nan] TESLA AP2 MODEL S: [.nan, 2.5, .nan] @@ -61,6 +57,8 @@ HYUNDAI KONA ELECTRIC 2ND GEN: [2.5, 2.5, 0.1] HYUNDAI IONIQ 6 2023: [2.5, 2.5, 0.1] HYUNDAI AZERA 6TH GEN: [1.8, 1.8, 0.1] KIA K8 HYBRID 1ST GEN: [2.5, 2.5, 0.1] +TOYOTA RAV4 2023: [2.5, 2.5, 0.1] +TOYOTA RAV4 HYBRID 2023: [2.5, 2.5, 0.1] # Dashcam or fallback configured as ideal car mock: [10.0, 10, 0.0] diff --git a/selfdrive/car/toyota/interface.py b/selfdrive/car/toyota/interface.py index d6f428ab1d..d51026b547 100644 --- a/selfdrive/car/toyota/interface.py +++ b/selfdrive/car/toyota/interface.py @@ -27,7 +27,15 @@ class CarInterface(CarInterfaceBase): if DBC[candidate]["pt"] == "toyota_new_mc_pt_generated": ret.safetyConfigs[0].safetyParam |= Panda.FLAG_TOYOTA_ALT_BRAKE - if candidate in ANGLE_CONTROL_CAR: + # Allow angle control cars with whitelisted EPSs to use torque control (made in Japan) + # So far only hybrid RAV4 2023 has been seen with this FW version + angle_car_torque_fw = any(fw.ecu == "eps" and fw.fwVersion == b'8965B42371\x00\x00\x00\x00\x00\x00' for fw in car_fw) + if candidate not in ANGLE_CONTROL_CAR or (angle_car_torque_fw and candidate == CAR.RAV4H_TSS2_2023): + CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) + + ret.steerActuatorDelay = 0.12 # Default delay, Prius has larger delay + ret.steerLimitTimer = 0.4 + else: ret.dashcamOnly = True ret.steerControlType = SteerControlType.angle ret.safetyConfigs[0].safetyParam |= Panda.FLAG_TOYOTA_LTA @@ -35,11 +43,6 @@ class CarInterface(CarInterfaceBase): # LTA control can be more delayed and winds up more often ret.steerActuatorDelay = 0.25 ret.steerLimitTimer = 0.8 - else: - CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) - - ret.steerActuatorDelay = 0.12 # Default delay, Prius has larger delay - ret.steerLimitTimer = 0.4 ret.stoppingControl = False # Toyota starts braking more when it thinks you want to stop @@ -121,21 +124,25 @@ class CarInterface(CarInterfaceBase): ret.steerRatio = 14.3 ret.tireStiffnessFactor = 0.7933 ret.mass = 3585. * CV.LB_TO_KG # Average between ICE and Hybrid - ret.lateralTuning.init('pid') - ret.lateralTuning.pid.kiBP = [0.0] - ret.lateralTuning.pid.kpBP = [0.0] - ret.lateralTuning.pid.kpV = [0.6] - ret.lateralTuning.pid.kiV = [0.1] - ret.lateralTuning.pid.kf = 0.00007818594 - - # 2019+ RAV4 TSS2 uses two different steering racks and specific tuning seems to be necessary. - # See https://github.com/commaai/openpilot/pull/21429#issuecomment-873652891 - for fw in car_fw: - if fw.ecu == "eps" and (fw.fwVersion.startswith(b'\x02') or fw.fwVersion in [b'8965B42181\x00\x00\x00\x00\x00\x00']): - ret.lateralTuning.pid.kpV = [0.15] - ret.lateralTuning.pid.kiV = [0.05] - ret.lateralTuning.pid.kf = 0.00004 - break + + # Only specific EPS FW accept torque on 2023 RAV4, so they likely are all the same + # TODO: revisit this disparity if there is a divide for 2023 + if candidate not in (CAR.RAV4_TSS2_2023, CAR.RAV4H_TSS2_2023): + ret.lateralTuning.init('pid') + ret.lateralTuning.pid.kiBP = [0.0] + ret.lateralTuning.pid.kpBP = [0.0] + ret.lateralTuning.pid.kpV = [0.6] + ret.lateralTuning.pid.kiV = [0.1] + ret.lateralTuning.pid.kf = 0.00007818594 + + # 2019+ RAV4 TSS2 uses two different steering racks and specific tuning seems to be necessary. + # See https://github.com/commaai/openpilot/pull/21429#issuecomment-873652891 + for fw in car_fw: + if fw.ecu == "eps" and (fw.fwVersion.startswith(b'\x02') or fw.fwVersion in [b'8965B42181\x00\x00\x00\x00\x00\x00']): + ret.lateralTuning.pid.kpV = [0.15] + ret.lateralTuning.pid.kiV = [0.05] + ret.lateralTuning.pid.kf = 0.00004 + break elif candidate in (CAR.COROLLA_TSS2, CAR.COROLLAH_TSS2): ret.wheelbase = 2.67 # Average between 2.70 for sedan and 2.64 for hatchback diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index bb9672fb0e..fd0a54b349 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -2389,7 +2389,8 @@ UNSUPPORTED_DSU_CAR = {CAR.LEXUS_IS, CAR.LEXUS_RC} # these cars have a radar which sends ACC messages instead of the camera RADAR_ACC_CAR = {CAR.RAV4H_TSS2_2022, CAR.RAV4_TSS2_2022, CAR.RAV4H_TSS2_2023, CAR.RAV4_TSS2_2023, CAR.CHR_TSS2, CAR.CHRH_TSS2} -# these cars use the Lane Tracing Assist (LTA) message for lateral control +# these cars manufactured in U.S., Canada have EPSs that reject Lane Keep Assist (LKA, torque) messages and require +# Lane Tracing Assist (LTA, angle) to steer properly. cars manufactured in Japan still work with the older LKA messages which is detected ANGLE_CONTROL_CAR = {CAR.RAV4H_TSS2_2023, CAR.RAV4_TSS2_2023} EV_HYBRID_CAR = {CAR.AVALONH_2019, CAR.AVALONH_TSS2, CAR.CAMRYH, CAR.CAMRYH_TSS2, CAR.CHRH, CAR.CHRH_TSS2, CAR.COROLLAH_TSS2, From c9ec7bc2a3de1bd889d9034bd9336a4f65d36e23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20R=C4=85czy?= Date: Thu, 14 Sep 2023 17:08:49 -0700 Subject: [PATCH 33/59] CI: login to dockerhub on aarch64 runners (#29915) * DOCKER_HUB_LOGIN command * Add docker creds * checkout runner name * test again * Use runner.name to distinguish between buildjet and GH runners --- .github/workflows/prebuilt.yaml | 4 ++-- .github/workflows/selfdrive_tests.yaml | 17 ++++++++++++++--- .github/workflows/tools_tests.yaml | 6 +++--- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/.github/workflows/prebuilt.yaml b/.github/workflows/prebuilt.yaml index 8b16ea90b9..3558d7eb7e 100644 --- a/.github/workflows/prebuilt.yaml +++ b/.github/workflows/prebuilt.yaml @@ -5,7 +5,7 @@ on: workflow_dispatch: env: - DOCKER_LOGIN: docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} + DOCKER_GHCR_LOGIN: docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} BUILD: selfdrive/test/docker_build.sh prebuilt jobs: @@ -29,5 +29,5 @@ jobs: submodules: true - name: Build and Push docker image run: | - $DOCKER_LOGIN + $DOCKER_GHCR_LOGIN eval "$BUILD" diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index 6503b164df..f7aba648a4 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -16,7 +16,8 @@ env: CL_BASE_IMAGE: openpilot-base-cl AZURE_TOKEN: ${{ secrets.AZURE_COMMADATACI_OPENPILOTCI_TOKEN }} - DOCKER_LOGIN: docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} + DOCKER_GHCR_LOGIN: docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} + DOCKER_HUB_LOGIN: docker login -u adeebshihadeh -p ${{ secrets.DOCKER_HUB_PAT }} BUILD: selfdrive/test/docker_build.sh base RUN: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONWARNINGS=error -e FILEREADER_CACHE=1 -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v $GITHUB_WORKSPACE/.ci_cache/scons_cache:/tmp/scons_cache -v $GITHUB_WORKSPACE/.ci_cache/comma_download_cache:/tmp/comma_download_cache -v $GITHUB_WORKSPACE/.ci_cache/openpilot_cache:/tmp/openpilot_cache $BASE_IMAGE /bin/sh -c @@ -76,6 +77,11 @@ jobs: - uses: actions/checkout@v3 with: submodules: true + # login only on arm machines, due to buildjet rate limits + - name: Setup docker + if: contains(runner.name, 'buildjet') + run: | + $DOCKER_HUB_LOGIN - uses: ./.github/workflows/setup-with-retry with: cache_key_prefix: scons_${{ matrix.arch }} @@ -190,7 +196,12 @@ jobs: run: | echo "PUSH_IMAGE=true" >> "$GITHUB_ENV" echo "TARGET_ARCHITECTURE=${{ matrix.arch }}" >> "$GITHUB_ENV" - $DOCKER_LOGIN + $DOCKER_GHCR_LOGIN + # login only on arm machines, due to buildjet rate limits + - name: Additional setup for buildjet + if: contains(runner.name, 'buildjet') + run: | + $DOCKER_HUB_LOGIN - uses: ./.github/workflows/setup-with-retry with: git-lfs: false @@ -211,7 +222,7 @@ jobs: submodules: false - name: Setup docker run: | - $DOCKER_LOGIN + $DOCKER_GHCR_LOGIN - name: Merge x64 and arm64 tags run: | export PUSH_IMAGE=true diff --git a/.github/workflows/tools_tests.yaml b/.github/workflows/tools_tests.yaml index c7a5f80c3b..27c362fcd6 100644 --- a/.github/workflows/tools_tests.yaml +++ b/.github/workflows/tools_tests.yaml @@ -13,7 +13,7 @@ concurrency: env: BASE_IMAGE: openpilot-base CL_BASE_IMAGE: openpilot-base-cl - DOCKER_LOGIN: docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} + DOCKER_GHCR_LOGIN: docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} BUILD: selfdrive/test/docker_build.sh base @@ -58,7 +58,7 @@ jobs: if: github.ref == 'refs/heads/master' && github.repository == 'commaai/openpilot' run: | echo "PUSH_IMAGE=true" >> "$GITHUB_ENV" - $DOCKER_LOGIN + $DOCKER_GHCR_LOGIN - name: Build and push sim image run: | selfdrive/test/docker_build.sh sim @@ -78,7 +78,7 @@ jobs: if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'commaai/openpilot' run: | echo "PUSH_IMAGE=true" >> "$GITHUB_ENV" - $DOCKER_LOGIN + $DOCKER_GHCR_LOGIN - name: Build and push docs image run: | selfdrive/test/docker_build.sh docs From 59c7a1d5d45e6353b2929bc632c7ce1adb7c4bb4 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 14 Sep 2023 19:05:17 -0700 Subject: [PATCH 34/59] bump panda (#29917) --- panda | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda b/panda index 8e8aa5acf6..f660323969 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 8e8aa5acf6ab0e45d91e72beaab74e69810448cd +Subproject commit f6603239690ccee80f19e8bc5cf3ba03123f3498 From 1410a1150c9909bc643df4e2cacbefa721d3b6cb Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Thu, 14 Sep 2023 20:20:49 -0700 Subject: [PATCH 35/59] test_models: check controlsd events (#29907) * test_moedls: check controlsd events * clean up * sort * controlsd modifies CP * fix * can use any segment now * final fix * use constant --- selfdrive/car/tests/routes.py | 2 +- selfdrive/car/tests/test_models.py | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index 69a935fece..f7ad219f63 100755 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -146,7 +146,7 @@ routes = [ CarTestRoute("9b25e8c1484a1b67|2023-04-13--10-41-45", HYUNDAI.KIA_EV6), CarTestRoute("007d5e4ad9f86d13|2021-09-30--15-09-23", HYUNDAI.KIA_K5_2021), CarTestRoute("c58dfc9fc16590e0|2023-01-14--13-51-48", HYUNDAI.KIA_K5_HEV_2020), - CarTestRoute("78ad5150de133637|2023-09-13--16-15-57", HYUNDAI.KIA_K8_HEV_1ST_GEN, segment=3), + CarTestRoute("78ad5150de133637|2023-09-13--16-15-57", HYUNDAI.KIA_K8_HEV_1ST_GEN), 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), diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py index 1b9e39f2f1..e6460d491e 100755 --- a/selfdrive/car/tests/test_models.py +++ b/selfdrive/car/tests/test_models.py @@ -9,6 +9,7 @@ from parameterized import parameterized_class from cereal import log, car from openpilot.common.basedir import BASEDIR +from openpilot.common.params import Params from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.car.fingerprints import all_known_cars from openpilot.selfdrive.car.car_helpers import FRAME_FINGERPRINT, interfaces @@ -16,6 +17,7 @@ from openpilot.selfdrive.car.gm.values import CAR as GM from openpilot.selfdrive.car.honda.values import CAR as HONDA, HONDA_BOSCH from openpilot.selfdrive.car.hyundai.values import CAR as HYUNDAI from openpilot.selfdrive.car.tests.routes import non_tested_cars, routes, CarTestRoute +from openpilot.selfdrive.controls.controlsd import Controls from openpilot.selfdrive.test.openpilotci import get_url from openpilot.tools.lib.logreader import LogReader from openpilot.tools.lib.route import Route, SegmentName, RouteName @@ -23,6 +25,7 @@ from openpilot.tools.lib.route import Route, SegmentName, RouteName from panda.tests.libpanda import libpanda_py from openpilot.selfdrive.test.helpers import SKIP_ENV_VAR +EventName = car.CarEvent.EventName PandaType = log.PandaState.PandaType SafetyModel = car.CarParams.SafetyModel @@ -163,9 +166,11 @@ class TestCarModelBase(unittest.TestCase): del cls.can_msgs def setUp(self): - self.CI = self.CarInterface(self.CP, self.CarController, self.CarState) + self.CI = self.CarInterface(self.CP.copy(), self.CarController, self.CarState) assert self.CI + Params().put_bool("OpenpilotEnabledToggle", self.openpilot_enabled) + # TODO: check safetyModel is in release panda build self.safety = libpanda_py.libpanda @@ -315,6 +320,8 @@ class TestCarModelBase(unittest.TestCase): controls_allowed_prev = False CS_prev = car.CarState.new_message() checks = defaultdict(lambda: 0) + controlsd = Controls(CI=self.CI) + controlsd.initialized = True for idx, can in enumerate(self.can_msgs): CS = self.CI.update(CC, (can.as_builder().to_bytes(), )) for msg in filter(lambda m: m.src in range(64), can.can): @@ -359,7 +366,10 @@ class TestCarModelBase(unittest.TestCase): checks['cruiseState'] += CS.cruiseState.enabled != self.safety.get_cruise_engaged_prev() else: # Check for enable events on rising edge of controls allowed - button_enable = any(evt.enable for evt in CS.events) + controlsd.update_events(CS) + controlsd.CS_prev = CS + button_enable = (any(evt.enable for evt in CS.events) and + not any(evt == EventName.pedalPressed for evt in controlsd.events.names)) mismatch = button_enable != (self.safety.get_controls_allowed() and not controls_allowed_prev) checks['controlsAllowed'] += mismatch controls_allowed_prev = self.safety.get_controls_allowed() From c4df40a04a57478883609748c08d1abed539b017 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Fri, 15 Sep 2023 15:27:44 +0800 Subject: [PATCH 36/59] cabana: support ECU node names (#29897) * support display&edit node name * cleanup * set validator for Node name * modify validator to support multiple receivers * set default to XXX in updateMsg * add DEFAULT_NODE_NAME * Update tools/cabana/commands.h --------- Co-authored-by: Shane Smiskol --- tools/cabana/commands.cc | 14 ++++++++------ tools/cabana/commands.h | 5 +++-- tools/cabana/dbc/dbc.cc | 6 ++++++ tools/cabana/dbc/dbc.h | 1 + tools/cabana/dbc/dbcfile.cc | 8 +++++--- tools/cabana/dbc/dbcfile.h | 2 +- tools/cabana/dbc/dbcmanager.cc | 4 ++-- tools/cabana/dbc/dbcmanager.h | 2 +- tools/cabana/detailwidget.cc | 23 +++++++++++------------ tools/cabana/detailwidget.h | 1 + tools/cabana/signalview.cc | 16 ++++++++++------ tools/cabana/signalview.h | 4 ++-- 12 files changed, 51 insertions(+), 35 deletions(-) diff --git a/tools/cabana/commands.cc b/tools/cabana/commands.cc index cf48abb4c9..52861723f4 100644 --- a/tools/cabana/commands.cc +++ b/tools/cabana/commands.cc @@ -4,11 +4,13 @@ // EditMsgCommand -EditMsgCommand::EditMsgCommand(const MessageId &id, const QString &name, int size, const QString &comment, QUndoCommand *parent) - : id(id), new_name(name), new_size(size), new_comment(comment), QUndoCommand(parent) { +EditMsgCommand::EditMsgCommand(const MessageId &id, const QString &name, int size, + const QString &node, const QString &comment, QUndoCommand *parent) + : id(id), new_name(name), new_size(size), new_node(node), new_comment(comment), QUndoCommand(parent) { if (auto msg = dbc()->msg(id)) { old_name = msg->name; old_size = msg->size; + old_node = msg->transmitter; old_comment = msg->comment; setText(QObject::tr("edit message %1:%2").arg(name).arg(id.address)); } else { @@ -20,11 +22,11 @@ void EditMsgCommand::undo() { if (old_name.isEmpty()) dbc()->removeMsg(id); else - dbc()->updateMsg(id, old_name, old_size, old_comment); + dbc()->updateMsg(id, old_name, old_size, old_node, old_comment); } void EditMsgCommand::redo() { - dbc()->updateMsg(id, new_name, new_size, new_comment); + dbc()->updateMsg(id, new_name, new_size, new_node, new_comment); } // RemoveMsgCommand @@ -38,7 +40,7 @@ RemoveMsgCommand::RemoveMsgCommand(const MessageId &id, QUndoCommand *parent) : void RemoveMsgCommand::undo() { if (!message.name.isEmpty()) { - dbc()->updateMsg(id, message.name, message.size, message.comment); + dbc()->updateMsg(id, message.name, message.size, message.transmitter, message.comment); for (auto s : message.getSignals()) dbc()->addSignal(id, *s); } @@ -64,7 +66,7 @@ void AddSigCommand::undo() { void AddSigCommand::redo() { if (auto msg = dbc()->msg(id); !msg) { msg_created = true; - dbc()->updateMsg(id, dbc()->newMsgName(id), can->lastMessage(id).dat.size(), ""); + dbc()->updateMsg(id, dbc()->newMsgName(id), can->lastMessage(id).dat.size(), "", ""); } signal.name = dbc()->newSignalName(id); signal.max = std::pow(2, signal.size) - 1; diff --git a/tools/cabana/commands.h b/tools/cabana/commands.h index c7f59c4c7f..0736d9b83f 100644 --- a/tools/cabana/commands.h +++ b/tools/cabana/commands.h @@ -10,13 +10,14 @@ class EditMsgCommand : public QUndoCommand { public: - EditMsgCommand(const MessageId &id, const QString &name, int size, const QString &comment, QUndoCommand *parent = nullptr); + EditMsgCommand(const MessageId &id, const QString &name, int size, const QString &node, + const QString &comment, QUndoCommand *parent = nullptr); void undo() override; void redo() override; private: const MessageId id; - QString old_name, new_name, old_comment, new_comment; + QString old_name, new_name, old_comment, new_comment, old_node, new_node; int old_size = 0, new_size = 0; }; diff --git a/tools/cabana/dbc/dbc.cc b/tools/cabana/dbc/dbc.cc index 537749e48d..a0e523d666 100644 --- a/tools/cabana/dbc/dbc.cc +++ b/tools/cabana/dbc/dbc.cc @@ -78,6 +78,9 @@ QString cabana::Msg::newSignalName() { } void cabana::Msg::update() { + if (transmitter.isEmpty()) { + transmitter = DEFAULT_NODE_NAME; + } mask.assign(size, 0x00); multiplexor = nullptr; @@ -125,6 +128,9 @@ void cabana::Msg::update() { void cabana::Signal::update() { updateMsbLsb(*this); + if (receiver_name.isEmpty()) { + receiver_name = DEFAULT_NODE_NAME; + } float h = 19 * (float)lsb / 64.0; h = fmod(h, 1.0); diff --git a/tools/cabana/dbc/dbc.h b/tools/cabana/dbc/dbc.h index e44bc41abf..bfb26c2842 100644 --- a/tools/cabana/dbc/dbc.h +++ b/tools/cabana/dbc/dbc.h @@ -13,6 +13,7 @@ #include "opendbc/can/common_dbc.h" const QString UNTITLED = "untitled"; +const QString DEFAULT_NODE_NAME = "XXX"; struct MessageId { uint8_t source = 0; diff --git a/tools/cabana/dbc/dbcfile.cc b/tools/cabana/dbc/dbcfile.cc index 2f93c1543e..063f516ead 100644 --- a/tools/cabana/dbc/dbcfile.cc +++ b/tools/cabana/dbc/dbcfile.cc @@ -60,11 +60,12 @@ bool DBCFile::writeContents(const QString &fn) { return false; } -void DBCFile::updateMsg(const MessageId &id, const QString &name, uint32_t size, const QString &comment) { +void DBCFile::updateMsg(const MessageId &id, const QString &name, uint32_t size, const QString &node, const QString &comment) { auto &m = msgs[id.address]; m.address = id.address; m.name = name; m.size = size; + m.transmitter = node.isEmpty() ? DEFAULT_NODE_NAME : node; m.comment = comment; } @@ -198,7 +199,8 @@ void DBCFile::parse(const QString &content) { QString DBCFile::generateDBC() { QString dbc_string, signal_comment, message_comment, val_desc; for (const auto &[address, m] : msgs) { - dbc_string += QString("BO_ %1 %2: %3 %4\n").arg(address).arg(m.name).arg(m.size).arg(m.transmitter.isEmpty() ? "XXX" : m.transmitter); + const QString transmitter = m.transmitter.isEmpty() ? DEFAULT_NODE_NAME : m.transmitter; + dbc_string += QString("BO_ %1 %2: %3 %4\n").arg(address).arg(m.name).arg(m.size).arg(transmitter); if (!m.comment.isEmpty()) { message_comment += QString("CM_ BO_ %1 \"%2\";\n").arg(address).arg(m.comment); } @@ -221,7 +223,7 @@ QString DBCFile::generateDBC() { .arg(doubleToString(sig->min)) .arg(doubleToString(sig->max)) .arg(sig->unit) - .arg(sig->receiver_name.isEmpty() ? "XXX" : sig->receiver_name); + .arg(sig->receiver_name.isEmpty() ? DEFAULT_NODE_NAME : sig->receiver_name); if (!sig->comment.isEmpty()) { signal_comment += QString("CM_ SG_ %1 %2 \"%3\";\n").arg(address).arg(sig->name).arg(sig->comment); } diff --git a/tools/cabana/dbc/dbcfile.h b/tools/cabana/dbc/dbcfile.h index 78a73d58e4..a3ab1cebe4 100644 --- a/tools/cabana/dbc/dbcfile.h +++ b/tools/cabana/dbc/dbcfile.h @@ -22,7 +22,7 @@ public: void cleanupAutoSaveFile(); QString generateDBC(); - void updateMsg(const MessageId &id, const QString &name, uint32_t size, const QString &comment); + void updateMsg(const MessageId &id, const QString &name, uint32_t size, const QString &node, const QString &comment); inline void removeMsg(const MessageId &id) { msgs.erase(id.address); } inline const std::map &getMessages() const { return msgs; } diff --git a/tools/cabana/dbc/dbcmanager.cc b/tools/cabana/dbc/dbcmanager.cc index 5736ac1e89..459ca0111d 100644 --- a/tools/cabana/dbc/dbcmanager.cc +++ b/tools/cabana/dbc/dbcmanager.cc @@ -82,10 +82,10 @@ void DBCManager::removeSignal(const MessageId &id, const QString &sig_name) { } } -void DBCManager::updateMsg(const MessageId &id, const QString &name, uint32_t size, const QString &comment) { +void DBCManager::updateMsg(const MessageId &id, const QString &name, uint32_t size, const QString &node, const QString &comment) { auto dbc_file = findDBCFile(id); assert(dbc_file); // This should be impossible - dbc_file->updateMsg(id, name, size, comment); + dbc_file->updateMsg(id, name, size, node, comment); emit msgUpdated(id); } diff --git a/tools/cabana/dbc/dbcmanager.h b/tools/cabana/dbc/dbcmanager.h index 3ac0829487..5f782fc930 100644 --- a/tools/cabana/dbc/dbcmanager.h +++ b/tools/cabana/dbc/dbcmanager.h @@ -28,7 +28,7 @@ public: void updateSignal(const MessageId &id, const QString &sig_name, const cabana::Signal &sig); void removeSignal(const MessageId &id, const QString &sig_name); - void updateMsg(const MessageId &id, const QString &name, uint32_t size, const QString &comment); + void updateMsg(const MessageId &id, const QString &name, uint32_t size, const QString &node, const QString &comment); void removeMsg(const MessageId &id); QString newMsgName(const MessageId &id); diff --git a/tools/cabana/detailwidget.cc b/tools/cabana/detailwidget.cc index 2f6e9cbfe8..d70aeff0c8 100644 --- a/tools/cabana/detailwidget.cc +++ b/tools/cabana/detailwidget.cc @@ -2,7 +2,6 @@ #include #include -#include #include "tools/cabana/commands.h" #include "tools/cabana/mainwin.h" @@ -135,11 +134,12 @@ void DetailWidget::refresh() { for (auto s : binary_view->getOverlappingSignals()) { warnings.push_back(tr("%1 has overlapping bits.").arg(s->name)); } + name_label->setText(QString("%1 (%2)").arg(msgName(msg_id), msg->transmitter)); } else { warnings.push_back(tr("Drag-Select in binary view to create new signal.")); + name_label->setText(msgName(msg_id)); } remove_btn->setEnabled(msg != nullptr); - name_label->setText(msgName(msg_id)); if (!warnings.isEmpty()) { warning_label->setText(warnings.join('\n')); @@ -164,8 +164,8 @@ void DetailWidget::editMsg() { int size = msg ? msg->size : can->lastMessage(msg_id).dat.size(); EditMessageDialog dlg(msg_id, msgName(msg_id), size, this); if (dlg.exec()) { - UndoStack::push(new EditMsgCommand(msg_id, dlg.name_edit->text().trimmed(), - dlg.size_spin->value(), dlg.comment_edit->toPlainText().trimmed())); + UndoStack::push(new EditMsgCommand(msg_id, dlg.name_edit->text().trimmed(), dlg.size_spin->value(), + dlg.node->text().trimmed(), dlg.comment_edit->toPlainText().trimmed())); } } @@ -182,25 +182,24 @@ EditMessageDialog::EditMessageDialog(const MessageId &msg_id, const QString &tit form_layout->addRow("", error_label = new QLabel); error_label->setVisible(false); - name_edit = new QLineEdit(title, this); + form_layout->addRow(tr("Name"), name_edit = new QLineEdit(title, this)); name_edit->setValidator(new NameValidator(name_edit)); - form_layout->addRow(tr("Name"), name_edit); - size_spin = new QSpinBox(this); + form_layout->addRow(tr("Size"), size_spin = new QSpinBox(this)); // TODO: limit the maximum? size_spin->setMinimum(1); size_spin->setValue(size); - form_layout->addRow(tr("Size"), size_spin); + form_layout->addRow(tr("Node"), node = new QLineEdit(this)); + node->setValidator(new NameValidator(name_edit)); form_layout->addRow(tr("Comment"), comment_edit = new QTextEdit(this)); + form_layout->addRow(btn_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel)); + if (auto msg = dbc()->msg(msg_id)) { + node->setText(msg->transmitter); comment_edit->setText(msg->comment); } - - btn_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); validateName(name_edit->text()); - form_layout->addRow(btn_box); - setFixedWidth(parent->width() * 0.9); connect(name_edit, &QLineEdit::textEdited, this, &EditMessageDialog::validateName); connect(btn_box, &QDialogButtonBox::accepted, this, &QDialog::accept); diff --git a/tools/cabana/detailwidget.h b/tools/cabana/detailwidget.h index 10c6a6c46e..ed6a865f53 100644 --- a/tools/cabana/detailwidget.h +++ b/tools/cabana/detailwidget.h @@ -21,6 +21,7 @@ public: QString original_name; QDialogButtonBox *btn_box; QLineEdit *name_edit; + QLineEdit *node; QTextEdit *comment_edit; QLabel *error_label; QSpinBox *size_spin; diff --git a/tools/cabana/signalview.cc b/tools/cabana/signalview.cc index 1b1c8dac22..b2798e9f3b 100644 --- a/tools/cabana/signalview.cc +++ b/tools/cabana/signalview.cc @@ -36,7 +36,7 @@ SignalModel::SignalModel(QObject *parent) : root(new Item), QAbstractItemModel(p void SignalModel::insertItem(SignalModel::Item *parent_item, int pos, const cabana::Signal *sig) { Item *item = new Item{.sig = sig, .parent = parent_item, .title = sig->name, .type = Item::Sig}; parent_item->children.insert(pos, item); - QString titles[]{"Name", "Size", "Little Endian", "Signed", "Offset", "Factor", "Type", "Multiplex Value", "Extra Info", + QString titles[]{"Name", "Size", "Node", "Little Endian", "Signed", "Offset", "Factor", "Type", "Multiplex Value", "Extra Info", "Unit", "Comment", "Minimum Value", "Maximum Value", "Value Descriptions"}; for (int i = 0; i < std::size(titles); ++i) { item->children.push_back(new Item{.sig = sig, .parent = item, .title = titles[i], .type = (Item::Type)(i + Item::Name)}); @@ -134,6 +134,7 @@ QVariant SignalModel::data(const QModelIndex &index, int role) const { case Item::Sig: return item->sig_val; case Item::Name: return item->sig->name; case Item::Size: return item->sig->size; + case Item::Node: return item->sig->receiver_name; case Item::SignalType: return signalTypeToString(item->sig->type); case Item::MultiplexValue: return item->sig->multiplex_value; case Item::Offset: return doubleToString(item->sig->offset); @@ -172,6 +173,7 @@ bool SignalModel::setData(const QModelIndex &index, const QVariant &value, int r switch (item->type) { case Item::Name: s.name = value.toString(); break; case Item::Size: s.size = value.toInt(); break; + case Item::Node: s.receiver_name = value.toString().trimmed(); break; case Item::SignalType: s.type = (cabana::Signal::Type)value.toInt(); break; case Item::MultiplexValue: s.multiplex_value = value.toInt(); break; case Item::Endian: s.is_little_endian = value.toBool(); break; @@ -195,11 +197,11 @@ void SignalModel::showExtraInfo(const QModelIndex &index) { if (item->type == Item::ExtraInfo) { if (!item->parent->extra_expanded) { item->parent->extra_expanded = true; - beginInsertRows(index.parent(), 7, 13); + beginInsertRows(index.parent(), Item::ExtraInfo - 2, Item::Desc - 2); endInsertRows(); } else { item->parent->extra_expanded = false; - beginRemoveRows(index.parent(), 7, 13); + beginRemoveRows(index.parent(), Item::ExtraInfo - 2, Item::Desc - 2); endRemoveRows(); } } @@ -267,6 +269,7 @@ void SignalModel::handleSignalRemoved(const cabana::Signal *sig) { SignalItemDelegate::SignalItemDelegate(QObject *parent) : QStyledItemDelegate(parent) { name_validator = new NameValidator(this); + node_validator = new QRegExpValidator(QRegExp("^\\w+(,\\w+)*$"), this); double_validator = new DoubleValidator(this); label_font.setPointSize(8); @@ -382,12 +385,14 @@ void SignalItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op QWidget *SignalItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { auto item = (SignalModel::Item *)index.internalPointer(); - if (item->type == SignalModel::Item::Name || item->type == SignalModel::Item::Offset || + if (item->type == SignalModel::Item::Name || item->type == SignalModel::Item::Node || item->type == SignalModel::Item::Offset || item->type == SignalModel::Item::Factor || item->type == SignalModel::Item::MultiplexValue || item->type == SignalModel::Item::Min || item->type == SignalModel::Item::Max) { QLineEdit *e = new QLineEdit(parent); e->setFrame(false); - e->setValidator(item->type == SignalModel::Item::Name ? name_validator : double_validator); + if (item->type == SignalModel::Item::Name) e->setValidator(name_validator); + else if (item->type == SignalModel::Item::Node) e->setValidator(node_validator); + else e->setValidator(double_validator); if (item->type == SignalModel::Item::Name) { QCompleter *completer = new QCompleter(dbc()->signalNames()); @@ -395,7 +400,6 @@ QWidget *SignalItemDelegate::createEditor(QWidget *parent, const QStyleOptionVie completer->setFilterMode(Qt::MatchContains); e->setCompleter(completer); } - return e; } else if (item->type == SignalModel::Item::Size) { QSpinBox *spin = new QSpinBox(parent); diff --git a/tools/cabana/signalview.h b/tools/cabana/signalview.h index 9d8571d0b8..bcf0019bc4 100644 --- a/tools/cabana/signalview.h +++ b/tools/cabana/signalview.h @@ -17,7 +17,7 @@ class SignalModel : public QAbstractItemModel { Q_OBJECT public: struct Item { - enum Type {Root, Sig, Name, Size, Endian, Signed, Offset, Factor, SignalType, MultiplexValue, ExtraInfo, Unit, Comment, Min, Max, Desc }; + enum Type {Root, Sig, Name, Size, Node, Endian, Signed, Offset, Factor, SignalType, MultiplexValue, ExtraInfo, Unit, Comment, Min, Max, Desc }; ~Item() { qDeleteAll(children); } inline int row() { return parent->children.indexOf(this); } @@ -87,7 +87,7 @@ public: void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override; void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; - QValidator *name_validator, *double_validator; + QValidator *name_validator, *double_validator, *node_validator; QFont label_font, minmax_font; const int color_label_width = 18; mutable QSize button_size; From 7ceccaf6c31a194bacb9eaa96cad74bb8a148567 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 15 Sep 2023 00:30:49 -0700 Subject: [PATCH 37/59] bump opendbc (#29922) * change signals * bump opendbc * bump * bump --- opendbc | 2 +- selfdrive/car/gm/carstate.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/opendbc b/opendbc index 8d2f614ce3..4ab347baef 160000 --- a/opendbc +++ b/opendbc @@ -1 +1 @@ -Subproject commit 8d2f614ce3f323c65de802b2d5f29143de9c427b +Subproject commit 4ab347baefb7473771ada0723c969c50d0c28d01 diff --git a/selfdrive/car/gm/carstate.py b/selfdrive/car/gm/carstate.py index 8585e9f205..89c1a3596a 100644 --- a/selfdrive/car/gm/carstate.py +++ b/selfdrive/car/gm/carstate.py @@ -98,7 +98,7 @@ class CarState(CarStateBase): ret.leftBlinker = pt_cp.vl["BCMTurnSignals"]["TurnSignals"] == 1 ret.rightBlinker = pt_cp.vl["BCMTurnSignals"]["TurnSignals"] == 2 - ret.parkingBrake = pt_cp.vl["VehicleIgnitionAlt"]["ParkBrake"] == 1 + ret.parkingBrake = pt_cp.vl["BCMGeneralPlatformStatus"]["ParkBrakeSwActive"] == 1 ret.cruiseState.available = pt_cp.vl["ECMEngineStatus"]["CruiseMainOn"] != 0 ret.espDisabled = pt_cp.vl["ESPStatus"]["TractionControlOn"] != 1 ret.accFaulted = (pt_cp.vl["AcceleratorPedal2"]["CruiseState"] == AccState.FAULTED or @@ -135,7 +135,7 @@ class CarState(CarStateBase): ("PSCMStatus", 10), ("ESPStatus", 10), ("BCMDoorBeltStatus", 10), - ("VehicleIgnitionAlt", 10), + ("BCMGeneralPlatformStatus", 10), ("EBCMWheelSpdFront", 20), ("EBCMWheelSpdRear", 20), ("EBCMFrictionBrakeStatus", 20), From 05db624884aa701b8ad78cae75bc17c8298984db Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 15 Sep 2023 02:55:30 -0700 Subject: [PATCH 38/59] GM: use new ignition signal (#29923) bump panda --- panda | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda b/panda index f660323969..546087125f 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit f6603239690ccee80f19e8bc5cf3ba03123f3498 +Subproject commit 546087125ff72877e4273eef78aa03dae5244a22 From 6a72d532963498d7de601fa79aaccc1f3d4e6b31 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Fri, 15 Sep 2023 18:20:27 +0800 Subject: [PATCH 39/59] cabana/chart: fix value overflow (#29924) fix value overflow --- tools/cabana/chart/chart.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tools/cabana/chart/chart.cc b/tools/cabana/chart/chart.cc index 93fbbaeae3..537aac1f28 100644 --- a/tools/cabana/chart/chart.cc +++ b/tools/cabana/chart/chart.cc @@ -17,7 +17,6 @@ #include #include #include -#include #include #include "tools/cabana/chart/chartswidget.h" @@ -365,7 +364,7 @@ void ChartView::updateAxisY() { axis_y->setRange(min_y, max_y); axis_y->setTickCount(tick_count); - int n = qMax(int(-qFloor(std::log10((max_y - min_y) / (tick_count - 1)))), 0) + 1; + int n = std::max(int(-std::floor(std::log10((max_y - min_y) / (tick_count - 1)))), 0) + 1; int max_label_width = 0; QFontMetrics fm(axis_y->labelsFont()); for (int i = 0; i < tick_count; i++) { @@ -383,15 +382,15 @@ void ChartView::updateAxisY() { std::tuple ChartView::getNiceAxisNumbers(qreal min, qreal max, int tick_count) { qreal range = niceNumber((max - min), true); // range with ceiling qreal step = niceNumber(range / (tick_count - 1), false); - min = qFloor(min / step); - max = qCeil(max / step); + min = std::floor(min / step); + max = std::ceil(max / step); tick_count = int(max - min) + 1; return {min * step, max * step, tick_count}; } // nice numbers can be expressed as form of 1*10^n, 2* 10^n or 5*10^n qreal ChartView::niceNumber(qreal x, bool ceiling) { - qreal z = qPow(10, qFloor(std::log10(x))); //find corresponding number of the form of 10^n than is smaller than x + qreal z = std::pow(10, std::floor(std::log10(x))); //find corresponding number of the form of 10^n than is smaller than x qreal q = x / z; //q<10 && q>=1; if (ceiling) { if (q <= 1.0) q = 1; From 33c51c122b5ae5f345bcd310400b05d864bce502 Mon Sep 17 00:00:00 2001 From: mitchellgoffpc Date: Fri, 15 Sep 2023 10:26:38 -0700 Subject: [PATCH 40/59] Added release notes for new driving model --- RELEASES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index c4572dba19..addec88222 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,5 +1,7 @@ Version 0.9.5 (202X-XX-XX) ======================== +* New driving model + * Improved navigate on openpilot performance using navigation instructions as an additional model input * Hyundai Azera 2022 support thanks to sunnyhaibin! * Hyundai Ioniq 6 2023 support thanks to sunnyhaibin, alamo3, and sshane! * Hyundai Kona Electric 2023 (Korean version) support thanks to sunnyhaibin and haram-KONA! From e0edff65d53d0e1d35c7600e72219934fc51b8a0 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 15 Sep 2023 12:57:45 -0700 Subject: [PATCH 41/59] Update RELEASES.md --- RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index addec88222..89f864dd71 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,4 +1,4 @@ -Version 0.9.5 (202X-XX-XX) +Version 0.9.5 (2023-09-27) ======================== * New driving model * Improved navigate on openpilot performance using navigation instructions as an additional model input From 7e54882458c0e9e6111f4523ef93983650cc816b Mon Sep 17 00:00:00 2001 From: Justin Newberry Date: Fri, 15 Sep 2023 13:11:39 -0700 Subject: [PATCH 42/59] test_locationd: don't redownload logs (#29929) don't redownload logs --- .../test/test_locationd_scenarios.py | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/selfdrive/locationd/test/test_locationd_scenarios.py b/selfdrive/locationd/test/test_locationd_scenarios.py index f08fe72ff1..d2455ef9e0 100755 --- a/selfdrive/locationd/test/test_locationd_scenarios.py +++ b/selfdrive/locationd/test/test_locationd_scenarios.py @@ -49,8 +49,7 @@ def get_select_fields_data(logs): return data -def run_scenarios(scenario): - logs = list(LogReader(get_url(TEST_ROUTE, TEST_SEG_NUM))) +def run_scenarios(scenario, logs): if scenario == Scenario.BASE: pass @@ -104,6 +103,11 @@ class TestLocationdScenarios(unittest.TestCase): - locationd kalman filter should never go unstable (we care mostly about yaw_rate, roll, gpsOK, inputsOK, sensorsOK) - faulty values should be ignored, with appropriate flags set """ + + @classmethod + def setUpClass(cls): + cls.logs = list(LogReader(get_url(TEST_ROUTE, TEST_SEG_NUM))) + def test_base(self): """ Test: unchanged log @@ -111,7 +115,7 @@ class TestLocationdScenarios(unittest.TestCase): - yaw_rate: unchanged - roll: unchanged """ - orig_data, replayed_data = run_scenarios(Scenario.BASE) + orig_data, replayed_data = run_scenarios(Scenario.BASE, self.logs) self.assertTrue(np.allclose(orig_data['yaw_rate'], replayed_data['yaw_rate'], atol=np.radians(0.2))) self.assertTrue(np.allclose(orig_data['roll'], replayed_data['roll'], atol=np.radians(0.5))) @@ -123,7 +127,7 @@ class TestLocationdScenarios(unittest.TestCase): - roll: - gpsOK: False """ - orig_data, replayed_data = run_scenarios(Scenario.GPS_OFF) + orig_data, replayed_data = run_scenarios(Scenario.GPS_OFF, self.logs) self.assertTrue(np.allclose(orig_data['yaw_rate'], replayed_data['yaw_rate'], atol=np.radians(0.2))) self.assertTrue(np.allclose(orig_data['roll'], replayed_data['roll'], atol=np.radians(0.5))) self.assertTrue(np.all(replayed_data['gps_flag'] == 0.0)) @@ -136,7 +140,7 @@ class TestLocationdScenarios(unittest.TestCase): - roll: - gpsOK: True for the first half, False for the second half """ - orig_data, replayed_data = run_scenarios(Scenario.GPS_OFF_MIDWAY) + orig_data, replayed_data = run_scenarios(Scenario.GPS_OFF_MIDWAY, self.logs) self.assertTrue(np.allclose(orig_data['yaw_rate'], replayed_data['yaw_rate'], atol=np.radians(0.2))) self.assertTrue(np.allclose(orig_data['roll'], replayed_data['roll'], atol=np.radians(0.5))) self.assertTrue(np.diff(replayed_data['gps_flag'])[512] == -1.0) @@ -149,7 +153,7 @@ class TestLocationdScenarios(unittest.TestCase): - roll: - gpsOK: False for the first half, True for the second half """ - orig_data, replayed_data = run_scenarios(Scenario.GPS_ON_MIDWAY) + orig_data, replayed_data = run_scenarios(Scenario.GPS_ON_MIDWAY, self.logs) self.assertTrue(np.allclose(orig_data['yaw_rate'], replayed_data['yaw_rate'], atol=np.radians(0.2))) self.assertTrue(np.allclose(orig_data['roll'], replayed_data['roll'], atol=np.radians(1.5))) self.assertTrue(np.diff(replayed_data['gps_flag'])[505] == 1.0) @@ -162,7 +166,7 @@ class TestLocationdScenarios(unittest.TestCase): - roll: - gpsOK: False for the middle section, True for the rest """ - orig_data, replayed_data = run_scenarios(Scenario.GPS_TUNNEL) + orig_data, replayed_data = run_scenarios(Scenario.GPS_TUNNEL, self.logs) self.assertTrue(np.allclose(orig_data['yaw_rate'], replayed_data['yaw_rate'], atol=np.radians(0.2))) self.assertTrue(np.allclose(orig_data['roll'], replayed_data['roll'], atol=np.radians(0.5))) self.assertTrue(np.diff(replayed_data['gps_flag'])[213] == -1.0) @@ -176,7 +180,7 @@ class TestLocationdScenarios(unittest.TestCase): - roll: 0 - sensorsOK: False """ - _, replayed_data = run_scenarios(Scenario.GYRO_OFF) + _, replayed_data = run_scenarios(Scenario.GYRO_OFF, self.logs) self.assertTrue(np.allclose(replayed_data['yaw_rate'], 0.0)) self.assertTrue(np.allclose(replayed_data['roll'], 0.0)) self.assertTrue(np.all(replayed_data['sensors_flag'] == 0.0)) @@ -189,7 +193,7 @@ class TestLocationdScenarios(unittest.TestCase): - roll: unchanged - inputsOK: False for some time after the spike, True for the rest """ - orig_data, replayed_data = run_scenarios(Scenario.GYRO_SPIKE_MIDWAY) + orig_data, replayed_data = run_scenarios(Scenario.GYRO_SPIKE_MIDWAY, self.logs) self.assertTrue(np.allclose(orig_data['yaw_rate'], replayed_data['yaw_rate'], atol=np.radians(0.2))) self.assertTrue(np.allclose(orig_data['roll'], replayed_data['roll'], atol=np.radians(0.5))) self.assertTrue(np.diff(replayed_data['inputs_flag'])[500] == -1.0) @@ -203,7 +207,7 @@ class TestLocationdScenarios(unittest.TestCase): - roll: 0 - sensorsOK: False """ - _, replayed_data = run_scenarios(Scenario.ACCEL_OFF) + _, replayed_data = run_scenarios(Scenario.ACCEL_OFF, self.logs) self.assertTrue(np.allclose(replayed_data['yaw_rate'], 0.0)) self.assertTrue(np.allclose(replayed_data['roll'], 0.0)) self.assertTrue(np.all(replayed_data['sensors_flag'] == 0.0)) @@ -214,7 +218,7 @@ class TestLocationdScenarios(unittest.TestCase): Test: an accelerometer spike in the middle of the segment Expected Result: Right now, the kalman filter is not robust to small spikes like it is to gyroscope spikes. """ - orig_data, replayed_data = run_scenarios(Scenario.ACCEL_SPIKE_MIDWAY) + orig_data, replayed_data = run_scenarios(Scenario.ACCEL_SPIKE_MIDWAY, self.logs) self.assertTrue(np.allclose(orig_data['yaw_rate'], replayed_data['yaw_rate'], atol=np.radians(0.2))) self.assertTrue(np.allclose(orig_data['roll'], replayed_data['roll'], atol=np.radians(0.5))) From 09bef0a165a8e4199abf6d2ff329d477cbc0e82b Mon Sep 17 00:00:00 2001 From: Justin Newberry Date: Fri, 15 Sep 2023 13:33:05 -0700 Subject: [PATCH 43/59] ignore temp translations (#29931) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a0c8df3142..afb3d5b1c3 100644 --- a/.gitignore +++ b/.gitignore @@ -48,6 +48,7 @@ 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 selfdrive/car/tests/cars_dump system/camerad/camerad From dd26a1faadb4cb6a468b77d5be7803cf1dad4beb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20R=C4=85czy?= Date: Fri, 15 Sep 2023 14:00:24 -0700 Subject: [PATCH 44/59] devcontainer: expose host config, fix mac screen issues (#29932) * export host config via .host/.env file. fix mac display issues * append instead of replace for bashrc * Log when mac display override happens * Update xauthority path in json --- .devcontainer/.gitignore | 4 +++- .devcontainer/container_post_create.sh | 14 ++++++++++++++ .devcontainer/container_post_start.sh | 7 +++++++ .devcontainer/devcontainer.json | 8 ++++---- .devcontainer/host_setup.sh | 24 ++++++++++++++++++++++++ .devcontainer/setup_host.sh | 16 ---------------- 6 files changed, 52 insertions(+), 21 deletions(-) create mode 100755 .devcontainer/container_post_create.sh create mode 100755 .devcontainer/container_post_start.sh create mode 100755 .devcontainer/host_setup.sh delete mode 100755 .devcontainer/setup_host.sh diff --git a/.devcontainer/.gitignore b/.devcontainer/.gitignore index 1f8ec242b8..5682fe1190 100644 --- a/.devcontainer/.gitignore +++ b/.devcontainer/.gitignore @@ -1 +1,3 @@ -.Xauthority \ No newline at end of file +.Xauthority +.env +.host/ \ No newline at end of file diff --git a/.devcontainer/container_post_create.sh b/.devcontainer/container_post_create.sh new file mode 100755 index 0000000000..52a4b5f858 --- /dev/null +++ b/.devcontainer/container_post_create.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +source .devcontainer/.host/.env + +# override display flag for mac +if [[ $HOST_OS == darwin ]]; then + echo "Setting up DISPLAY override for macOS..." + cat <> /root/.bashrc +if [ -n "\$DISPLAY" ]; then + DISPLAY_NUM=\$(echo "\$DISPLAY" | awk -F: '{print \$NF}') + export DISPLAY=host.docker.internal:\$DISPLAY_NUM +fi +EOF +fi diff --git a/.devcontainer/container_post_start.sh b/.devcontainer/container_post_start.sh new file mode 100755 index 0000000000..4404f6a9a9 --- /dev/null +++ b/.devcontainer/container_post_start.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +# setup safe directories for submodules +SUBMODULE_DIRS=$(git config --file .gitmodules --get-regexp path | awk '{ print $2 }') +for DIR in $SUBMODULE_DIRS; do + git config --global --add safe.directory "$PWD/$DIR" +done diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 2dfe46b4f0..7224f251a7 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -3,9 +3,9 @@ "build": { "dockerfile": "Dockerfile" }, - "postCreateCommand": "bash -c 'if [[ $DISPLAY == *xquartz* ]]; then echo \"export DISPLAY=host.docker.internal:0\" >> /root/.bashrc; fi'", - "postStartCommand": "git config --file .gitmodules --get-regexp path | awk '{ print $2 }' | xargs -I{} git config --global --add safe.directory \"$PWD/{}\"", - "initializeCommand": ".devcontainer/setup_host.sh", + "postCreateCommand": ".devcontainer/container_post_create.sh", + "postStartCommand": ".devcontainer/container_post_start.sh", + "initializeCommand": ".devcontainer/host_setup.sh", "privileged": true, "containerEnv": { "DISPLAY": "${localEnv:DISPLAY}", @@ -14,7 +14,7 @@ }, "runArgs": [ "--volume=/tmp/.X11-unix:/tmp/.X11-unix", - "--volume=${localWorkspaceFolder}/.devcontainer/.Xauthority:/root/.Xauthority", + "--volume=${localWorkspaceFolder}/.devcontainer/.host/.Xauthority:/root/.Xauthority", "--volume=${localEnv:HOME}/.comma:/root/.comma", "--volume=/tmp/comma_download_cache:/tmp/comma_download_cache", "--volume=/tmp/devcontainer_scons_cache:/tmp/scons_cache", diff --git a/.devcontainer/host_setup.sh b/.devcontainer/host_setup.sh new file mode 100755 index 0000000000..597d0a1112 --- /dev/null +++ b/.devcontainer/host_setup.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +# setup .host dir +mkdir -p .devcontainer/.host + +# setup links to Xauthority +XAUTHORITY_LINK=".devcontainer/.host/.Xauthority" +rm -f $XAUTHORITY_LINK +if [[ -z $XAUTHORITY ]]; then + echo "XAUTHORITY not set. Fallback to ~/.Xauthority ..." + if ! [[ -f $HOME/.Xauthority ]]; then + echo "~/.XAuthority file does not exist. GUI tools may not work properly." + touch $XAUTHORITY_LINK # dummy file to satisfy container volume mount + else + ln -sf $HOME/.Xauthority $XAUTHORITY_LINK + fi +else + ln -sf $XAUTHORITY $XAUTHORITY_LINK +fi + +# setup host env file +HOST_INFO_FILE=".devcontainer/.host/.env" +SYSTEM=$(uname -s | tr '[:upper:]' '[:lower:]') +echo "HOST_OS=\"$SYSTEM\"" > $HOST_INFO_FILE diff --git a/.devcontainer/setup_host.sh b/.devcontainer/setup_host.sh deleted file mode 100755 index 5c3c5e900c..0000000000 --- a/.devcontainer/setup_host.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash - -# setup links to Xauthority -XAUTHORITY_LINK=".devcontainer/.Xauthority" -rm -f $XAUTHORITY_LINK -if [[ -z $XAUTHORITY ]]; then - echo "XAUTHORITY not set. Fallback to ~/.Xauthority ..." - if ! [[ -f $HOME/.Xauthority ]]; then - echo "~/.XAuthority file does not exist. GUI tools may not work properly." - touch $XAUTHORITY_LINK # dummy file to satisfy container volume mount - else - ln -sf $HOME/.Xauthority $XAUTHORITY_LINK - fi -else - ln -sf $XAUTHORITY $XAUTHORITY_LINK -fi From 7f6718a7cb87909305fd6f23a614db926d225915 Mon Sep 17 00:00:00 2001 From: Justin Newberry Date: Fri, 15 Sep 2023 14:02:09 -0700 Subject: [PATCH 45/59] Simulator: cleanup in preparation for metadrive (#29903) * sim bridge cleanup * fix carla * remove that exception * pr cleanup * update car in a thread * more cleanup * import sorting * handle exits better --- tools/sim/bridge.py | 561 ---------------------- tools/sim/bridge/__init__.py | 0 tools/sim/bridge/carla.py | 163 +++++++ tools/sim/bridge/common.py | 163 +++++++ tools/sim/lib/camerad.py | 70 +++ tools/sim/lib/can.py | 94 ---- tools/sim/lib/common.py | 86 ++++ tools/sim/lib/keyboard_ctrl.py | 2 +- tools/sim/lib/simulated_car.py | 110 +++++ tools/sim/lib/simulated_sensors.py | 127 +++++ tools/sim/run_bridge.py | 50 ++ tools/sim/tests/test_carla_integration.py | 6 +- 12 files changed, 773 insertions(+), 659 deletions(-) delete mode 100755 tools/sim/bridge.py create mode 100644 tools/sim/bridge/__init__.py create mode 100644 tools/sim/bridge/carla.py create mode 100644 tools/sim/bridge/common.py create mode 100644 tools/sim/lib/camerad.py delete mode 100755 tools/sim/lib/can.py create mode 100644 tools/sim/lib/common.py create mode 100644 tools/sim/lib/simulated_car.py create mode 100644 tools/sim/lib/simulated_sensors.py create mode 100755 tools/sim/run_bridge.py diff --git a/tools/sim/bridge.py b/tools/sim/bridge.py deleted file mode 100755 index 33fb2c020e..0000000000 --- a/tools/sim/bridge.py +++ /dev/null @@ -1,561 +0,0 @@ -#!/usr/bin/env python3 -import argparse -import math -import os -import signal -import threading -import time -from multiprocessing import Process, Queue -from typing import Any - -import carla -import numpy as np -import pyopencl as cl -import pyopencl.array as cl_array - -import cereal.messaging as messaging -from cereal import log -from cereal.visionipc import VisionIpcServer, VisionStreamType -from openpilot.common.basedir import BASEDIR -from openpilot.common.numpy_fast import clip -from openpilot.common.params import Params -from openpilot.common.realtime import DT_DMON, Ratekeeper -from openpilot.selfdrive.car.honda.values import CruiseButtons -from openpilot.selfdrive.test.helpers import set_params_enabled -from openpilot.tools.sim.lib.can import can_function - -W, H = 1928, 1208 -REPEAT_COUNTER = 5 -PRINT_DECIMATION = 100 -STEER_RATIO = 15. - -pm = messaging.PubMaster(['roadCameraState', 'wideRoadCameraState', 'accelerometer', 'gyroscope', 'can', "gpsLocationExternal"]) -sm = messaging.SubMaster(['carControl', 'controlsState']) - -def parse_args(add_args=None): - parser = argparse.ArgumentParser(description='Bridge between CARLA and openpilot.') - parser.add_argument('--joystick', action='store_true') - parser.add_argument('--high_quality', action='store_true') - parser.add_argument('--dual_camera', action='store_true') - parser.add_argument('--town', type=str, default='Town04_Opt') - parser.add_argument('--spawn_point', dest='num_selected_spawn_point', type=int, default=16) - parser.add_argument('--host', dest='host', type=str, default='127.0.0.1') - parser.add_argument('--port', dest='port', type=int, default=2000) - - return parser.parse_args(add_args) - - -class VehicleState: - def __init__(self): - self.speed = 0.0 - self.angle = 0.0 - self.bearing_deg = 0.0 - self.vel = carla.Vector3D() - self.cruise_button = 0 - self.is_engaged = False - self.ignition = True - - -def steer_rate_limit(old, new): - # Rate limiting to 0.5 degrees per step - limit = 0.5 - if new > old + limit: - return old + limit - elif new < old - limit: - return old - limit - else: - return new - - -class Camerad: - def __init__(self, dual_camera): - self.frame_road_id = 0 - self.frame_wide_id = 0 - self.vipc_server = VisionIpcServer("camerad") - - self.vipc_server.create_buffers(VisionStreamType.VISION_STREAM_ROAD, 5, False, W, H) - if dual_camera: - self.vipc_server.create_buffers(VisionStreamType.VISION_STREAM_WIDE_ROAD, 5, False, W, H) - self.vipc_server.start_listener() - - # set up for pyopencl rgb to yuv conversion - self.ctx = cl.create_some_context() - self.queue = cl.CommandQueue(self.ctx) - cl_arg = f" -DHEIGHT={H} -DWIDTH={W} -DRGB_STRIDE={W * 3} -DUV_WIDTH={W // 2} -DUV_HEIGHT={H // 2} -DRGB_SIZE={W * H} -DCL_DEBUG " - - kernel_fn = os.path.join(BASEDIR, "tools/sim/rgb_to_nv12.cl") - with open(kernel_fn) as f: - prg = cl.Program(self.ctx, f.read()).build(cl_arg) - self.krnl = prg.rgb_to_nv12 - self.Wdiv4 = W // 4 if (W % 4 == 0) else (W + (4 - W % 4)) // 4 - self.Hdiv4 = H // 4 if (H % 4 == 0) else (H + (4 - H % 4)) // 4 - - def cam_callback_road(self, image): - self._cam_callback(image, self.frame_road_id, 'roadCameraState', VisionStreamType.VISION_STREAM_ROAD) - self.frame_road_id += 1 - - def cam_callback_wide_road(self, image): - self._cam_callback(image, self.frame_wide_id, 'wideRoadCameraState', VisionStreamType.VISION_STREAM_WIDE_ROAD) - self.frame_wide_id += 1 - - def _cam_callback(self, image, frame_id, pub_type, yuv_type): - img = np.frombuffer(image.raw_data, dtype=np.dtype("uint8")) - img = np.reshape(img, (H, W, 4)) - img = img[:, :, [0, 1, 2]].copy() - - # convert RGB frame to YUV - rgb = np.reshape(img, (H, W * 3)) - rgb_cl = cl_array.to_device(self.queue, rgb) - yuv_cl = cl_array.empty_like(rgb_cl) - self.krnl(self.queue, (np.int32(self.Wdiv4), np.int32(self.Hdiv4)), None, rgb_cl.data, yuv_cl.data).wait() - yuv = np.resize(yuv_cl.get(), rgb.size // 2) - eof = int(frame_id * 0.05 * 1e9) - - self.vipc_server.send(yuv_type, yuv.data.tobytes(), frame_id, eof, eof) - - dat = messaging.new_message(pub_type) - msg = { - "frameId": frame_id, - "transform": [1.0, 0.0, 0.0, - 0.0, 1.0, 0.0, - 0.0, 0.0, 1.0] - } - setattr(dat, pub_type, msg) - pm.send(pub_type, dat) - -def imu_callback(imu, vehicle_state): - # send 5x since 'sensor_tick' doesn't seem to work. limited by the world tick? - for _ in range(5): - vehicle_state.bearing_deg = math.degrees(imu.compass) - dat = messaging.new_message('accelerometer') - dat.accelerometer.sensor = 4 - dat.accelerometer.type = 0x10 - dat.accelerometer.timestamp = dat.logMonoTime # TODO: use the IMU timestamp - dat.accelerometer.init('acceleration') - dat.accelerometer.acceleration.v = [imu.accelerometer.x, imu.accelerometer.y, imu.accelerometer.z] - pm.send('accelerometer', dat) - - # copied these numbers from locationd - dat = messaging.new_message('gyroscope') - dat.gyroscope.sensor = 5 - dat.gyroscope.type = 0x10 - dat.gyroscope.timestamp = dat.logMonoTime # TODO: use the IMU timestamp - dat.gyroscope.init('gyroUncalibrated') - dat.gyroscope.gyroUncalibrated.v = [imu.gyroscope.x, imu.gyroscope.y, imu.gyroscope.z] - pm.send('gyroscope', dat) - time.sleep(0.01) - - -def panda_state_function(vs: VehicleState, exit_event: threading.Event): - pm = messaging.PubMaster(['pandaStates']) - while not exit_event.is_set(): - dat = messaging.new_message('pandaStates', 1) - dat.valid = True - dat.pandaStates[0] = { - 'ignitionLine': vs.ignition, - 'pandaType': "blackPanda", - 'controlsAllowed': True, - 'safetyModel': 'hondaNidec' - } - pm.send('pandaStates', dat) - time.sleep(0.5) - - -def peripheral_state_function(exit_event: threading.Event): - pm = messaging.PubMaster(['peripheralState']) - while not exit_event.is_set(): - dat = messaging.new_message('peripheralState') - dat.valid = True - # fake peripheral state data - dat.peripheralState = { - 'pandaType': log.PandaState.PandaType.blackPanda, - 'voltage': 12000, - 'current': 5678, - 'fanSpeedRpm': 1000 - } - pm.send('peripheralState', dat) - time.sleep(0.5) - - -def gps_callback(gps, vehicle_state): - dat = messaging.new_message('gpsLocationExternal') - - # transform vel from carla to NED - # north is -Y in CARLA - velNED = [ - -vehicle_state.vel.y, # north/south component of NED is negative when moving south - vehicle_state.vel.x, # positive when moving east, which is x in carla - vehicle_state.vel.z, - ] - - dat.gpsLocationExternal = { - "unixTimestampMillis": int(time.time() * 1000), - "flags": 1, # valid fix - "accuracy": 1.0, - "verticalAccuracy": 1.0, - "speedAccuracy": 0.1, - "bearingAccuracyDeg": 0.1, - "vNED": velNED, - "bearingDeg": vehicle_state.bearing_deg, - "latitude": gps.latitude, - "longitude": gps.longitude, - "altitude": gps.altitude, - "speed": vehicle_state.speed, - "source": log.GpsLocationData.SensorSource.ublox, - } - - pm.send('gpsLocationExternal', dat) - - -def fake_driver_monitoring(exit_event: threading.Event): - pm = messaging.PubMaster(['driverStateV2', 'driverMonitoringState']) - while not exit_event.is_set(): - # dmonitoringmodeld output - dat = messaging.new_message('driverStateV2') - dat.driverStateV2.leftDriverData.faceOrientation = [0., 0., 0.] - dat.driverStateV2.leftDriverData.faceProb = 1.0 - dat.driverStateV2.rightDriverData.faceOrientation = [0., 0., 0.] - dat.driverStateV2.rightDriverData.faceProb = 1.0 - pm.send('driverStateV2', dat) - - # dmonitoringd output - dat = messaging.new_message('driverMonitoringState') - dat.driverMonitoringState = { - "faceDetected": True, - "isDistracted": False, - "awarenessStatus": 1., - } - pm.send('driverMonitoringState', dat) - - time.sleep(DT_DMON) - - -def can_function_runner(vs: VehicleState, exit_event: threading.Event): - i = 0 - while not exit_event.is_set(): - can_function(pm, vs.speed, vs.angle, i, vs.cruise_button, vs.is_engaged) - time.sleep(0.01) - i += 1 - - -def connect_carla_client(host: str, port: int): - client = carla.Client(host, port) - client.set_timeout(5) - return client - - -class CarlaBridge: - - def __init__(self, arguments): - set_params_enabled() - - self.params = Params() - - msg = messaging.new_message('liveCalibration') - msg.liveCalibration.validBlocks = 20 - msg.liveCalibration.rpyCalib = [0.0, 0.0, 0.0] - self.params.put("CalibrationParams", msg.to_bytes()) - self.params.put_bool("DisengageOnAccelerator", True) - - self._args = arguments - self._carla_objects = [] - self._camerad = None - self._exit_event = threading.Event() - self._threads = [] - self._keep_alive = True - self.started = False - signal.signal(signal.SIGTERM, self._on_shutdown) - self._exit = threading.Event() - - def _on_shutdown(self, signal, frame): - self._keep_alive = False - - def bridge_keep_alive(self, q: Queue, retries: int): - try: - while self._keep_alive: - try: - self._run(q) - break - except RuntimeError as e: - self.close() - if retries == 0: - raise - - # Reset for another try - self._carla_objects = [] - self._threads = [] - self._exit_event = threading.Event() - - retries -= 1 - if retries <= -1: - print(f"Restarting bridge. Error: {e} ") - else: - print(f"Restarting bridge. Retries left {retries}. Error: {e} ") - finally: - # Clean up resources in the opposite order they were created. - self.close() - - def _run(self, q: Queue): - client = connect_carla_client(self._args.host, self._args.port) - world = client.load_world(self._args.town) - - settings = world.get_settings() - settings.synchronous_mode = True # Enables synchronous mode - settings.fixed_delta_seconds = 0.05 - world.apply_settings(settings) - - world.set_weather(carla.WeatherParameters.ClearSunset) - - if not self._args.high_quality: - world.unload_map_layer(carla.MapLayer.Foliage) - world.unload_map_layer(carla.MapLayer.Buildings) - world.unload_map_layer(carla.MapLayer.ParkedVehicles) - world.unload_map_layer(carla.MapLayer.Props) - world.unload_map_layer(carla.MapLayer.StreetLights) - world.unload_map_layer(carla.MapLayer.Particles) - - blueprint_library = world.get_blueprint_library() - - world_map = world.get_map() - - vehicle_bp = blueprint_library.filter('vehicle.tesla.*')[1] - vehicle_bp.set_attribute('role_name', 'hero') - spawn_points = world_map.get_spawn_points() - assert len(spawn_points) > self._args.num_selected_spawn_point, f'''No spawn point {self._args.num_selected_spawn_point}, try a value between 0 and - {len(spawn_points)} for this town.''' - spawn_point = spawn_points[self._args.num_selected_spawn_point] - vehicle = world.spawn_actor(vehicle_bp, spawn_point) - self._carla_objects.append(vehicle) - max_steer_angle = vehicle.get_physics_control().wheels[0].max_steer_angle - - # make tires less slippery - # wheel_control = carla.WheelPhysicsControl(tire_friction=5) - physics_control = vehicle.get_physics_control() - physics_control.mass = 2326 - # physics_control.wheels = [wheel_control]*4 - physics_control.torque_curve = [[20.0, 500.0], [5000.0, 500.0]] - physics_control.gear_switch_time = 0.0 - vehicle.apply_physics_control(physics_control) - - transform = carla.Transform(carla.Location(x=0.8, z=1.13)) - - def create_camera(fov, callback): - blueprint = blueprint_library.find('sensor.camera.rgb') - blueprint.set_attribute('image_size_x', str(W)) - blueprint.set_attribute('image_size_y', str(H)) - blueprint.set_attribute('fov', str(fov)) - if not self._args.high_quality: - blueprint.set_attribute('enable_postprocess_effects', 'False') - camera = world.spawn_actor(blueprint, transform, attach_to=vehicle) - camera.listen(callback) - return camera - - self._camerad = Camerad(self._args.dual_camera) - - if self._args.dual_camera: - road_wide_camera = create_camera(fov=120, callback=self._camerad.cam_callback_wide_road) # fov bigger than 120 shows unwanted artifacts - self._carla_objects.append(road_wide_camera) - road_camera = create_camera(fov=40, callback=self._camerad.cam_callback_road) - self._carla_objects.append(road_camera) - - vehicle_state = VehicleState() - - # re-enable IMU - imu_bp = blueprint_library.find('sensor.other.imu') - imu_bp.set_attribute('sensor_tick', '0.01') - imu = world.spawn_actor(imu_bp, transform, attach_to=vehicle) - imu.listen(lambda imu: imu_callback(imu, vehicle_state)) - - gps_bp = blueprint_library.find('sensor.other.gnss') - gps = world.spawn_actor(gps_bp, transform, attach_to=vehicle) - gps.listen(lambda gps: gps_callback(gps, vehicle_state)) - self.params.put_bool("UbloxAvailable", True) - - self._carla_objects.extend([imu, gps]) - # launch fake car threads - self._threads.append(threading.Thread(target=panda_state_function, args=(vehicle_state, self._exit_event,))) - self._threads.append(threading.Thread(target=peripheral_state_function, args=(self._exit_event,))) - self._threads.append(threading.Thread(target=fake_driver_monitoring, args=(self._exit_event,))) - self._threads.append(threading.Thread(target=can_function_runner, args=(vehicle_state, self._exit_event,))) - for t in self._threads: - t.start() - - # init - throttle_ease_out_counter = REPEAT_COUNTER - brake_ease_out_counter = REPEAT_COUNTER - steer_ease_out_counter = REPEAT_COUNTER - - vc = carla.VehicleControl(throttle=0, steer=0, brake=0, reverse=False) - - is_openpilot_engaged = False - throttle_out = steer_out = brake_out = 0. - throttle_op = steer_op = brake_op = 0. - throttle_manual = steer_manual = brake_manual = 0. - - old_steer = old_brake = old_throttle = 0. - throttle_manual_multiplier = 0.7 # keyboard signal is always 1 - brake_manual_multiplier = 0.7 # keyboard signal is always 1 - steer_manual_multiplier = 45 * STEER_RATIO # keyboard signal is always 1 - - # Simulation tends to be slow in the initial steps. This prevents lagging later - for _ in range(20): - world.tick() - - # loop - rk = Ratekeeper(100, print_delay_threshold=0.05) - - while self._keep_alive: - # 1. Read the throttle, steer and brake from op or manual controls - # 2. Set instructions in Carla - # 3. Send current carstate to op via can - - cruise_button = 0 - throttle_out = steer_out = brake_out = 0.0 - throttle_op = steer_op = brake_op = 0.0 - throttle_manual = steer_manual = brake_manual = 0.0 - - # --------------Step 1------------------------------- - if not q.empty(): - message = q.get() - m = message.split('_') - if m[0] == "steer": - steer_manual = float(m[1]) - is_openpilot_engaged = False - elif m[0] == "throttle": - throttle_manual = float(m[1]) - is_openpilot_engaged = False - elif m[0] == "brake": - brake_manual = float(m[1]) - is_openpilot_engaged = False - elif m[0] == "reverse": - cruise_button = CruiseButtons.CANCEL - is_openpilot_engaged = False - elif m[0] == "cruise": - if m[1] == "down": - cruise_button = CruiseButtons.DECEL_SET - is_openpilot_engaged = True - elif m[1] == "up": - cruise_button = CruiseButtons.RES_ACCEL - is_openpilot_engaged = True - elif m[1] == "cancel": - cruise_button = CruiseButtons.CANCEL - is_openpilot_engaged = False - elif m[0] == "ignition": - vehicle_state.ignition = not vehicle_state.ignition - elif m[0] == "quit": - break - - throttle_out = throttle_manual * throttle_manual_multiplier - steer_out = steer_manual * steer_manual_multiplier - brake_out = brake_manual * brake_manual_multiplier - - old_steer = steer_out - old_throttle = throttle_out - old_brake = brake_out - - if is_openpilot_engaged: - sm.update(0) - - # TODO gas and brake is deprecated - throttle_op = clip(sm['carControl'].actuators.accel / 1.6, 0.0, 1.0) - brake_op = clip(-sm['carControl'].actuators.accel / 4.0, 0.0, 1.0) - steer_op = sm['carControl'].actuators.steeringAngleDeg - - throttle_out = throttle_op - steer_out = steer_op - brake_out = brake_op - - steer_out = steer_rate_limit(old_steer, steer_out) - old_steer = steer_out - - else: - if throttle_out == 0 and old_throttle > 0: - if throttle_ease_out_counter > 0: - throttle_out = old_throttle - throttle_ease_out_counter += -1 - else: - throttle_ease_out_counter = REPEAT_COUNTER - old_throttle = 0 - - if brake_out == 0 and old_brake > 0: - if brake_ease_out_counter > 0: - brake_out = old_brake - brake_ease_out_counter += -1 - else: - brake_ease_out_counter = REPEAT_COUNTER - old_brake = 0 - - if steer_out == 0 and old_steer != 0: - if steer_ease_out_counter > 0: - steer_out = old_steer - steer_ease_out_counter += -1 - else: - steer_ease_out_counter = REPEAT_COUNTER - old_steer = 0 - - # --------------Step 2------------------------------- - steer_carla = steer_out / (max_steer_angle * STEER_RATIO * -1) - - steer_carla = np.clip(steer_carla, -1, 1) - steer_out = steer_carla * (max_steer_angle * STEER_RATIO * -1) - old_steer = steer_carla * (max_steer_angle * STEER_RATIO * -1) - - vc.throttle = throttle_out / 0.6 - vc.steer = steer_carla - vc.brake = brake_out - vehicle.apply_control(vc) - - # --------------Step 3------------------------------- - vel = vehicle.get_velocity() - speed = math.sqrt(vel.x ** 2 + vel.y ** 2 + vel.z ** 2) # in m/s - vehicle_state.speed = speed - vehicle_state.vel = vel - vehicle_state.angle = steer_out - vehicle_state.cruise_button = cruise_button - vehicle_state.is_engaged = is_openpilot_engaged - - if rk.frame % PRINT_DECIMATION == 0: - print("frame: ", "engaged:", is_openpilot_engaged, "; throttle: ", round(vc.throttle, 3), "; steer(c/deg): ", - round(vc.steer, 3), round(steer_out, 3), "; brake: ", round(vc.brake, 3)) - - if rk.frame % 5 == 0: - world.tick() - rk.keep_time() - self.started = True - - def close(self): - self.started = False - self._exit_event.set() - - for s in self._carla_objects: - try: - s.destroy() - except Exception as e: - print("Failed to destroy carla object", e) - for t in reversed(self._threads): - t.join() - - def run(self, queue, retries=-1): - bridge_p = Process(target=self.bridge_keep_alive, args=(queue, retries), daemon=True) - bridge_p.start() - return bridge_p - - -if __name__ == "__main__": - q: Any = Queue() - args = parse_args() - - carla_bridge = CarlaBridge(args) - p = carla_bridge.run(q) - - if args.joystick: - # start input poll for joystick - from openpilot.tools.sim.lib.manual_ctrl import wheel_poll_thread - - wheel_poll_thread(q) - else: - # start input poll for keyboard - from openpilot.tools.sim.lib.keyboard_ctrl import keyboard_poll_thread - - keyboard_poll_thread(q) - p.join() diff --git a/tools/sim/bridge/__init__.py b/tools/sim/bridge/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/sim/bridge/carla.py b/tools/sim/bridge/carla.py new file mode 100644 index 0000000000..df25734e19 --- /dev/null +++ b/tools/sim/bridge/carla.py @@ -0,0 +1,163 @@ +import numpy as np + +from openpilot.common.params import Params +from openpilot.tools.sim.lib.common import SimulatorState, vec3 +from openpilot.tools.sim.bridge.common import World, SimulatorBridge +from openpilot.tools.sim.lib.camerad import W, H + + +class CarlaWorld(World): + def __init__(self, world, vehicle, high_quality=False, dual_camera=False): + super().__init__(dual_camera) + import carla + self.world = world + self.vc: carla.VehicleControl = carla.VehicleControl(throttle=0, steer=0, brake=0, reverse=False) + self.vehicle = vehicle + self.max_steer_angle: float = vehicle.get_physics_control().wheels[0].max_steer_angle + self.params = Params() + + self.steer_ratio = 15 + + self.carla_objects = [] + + blueprint_library = self.world.get_blueprint_library() + transform = carla.Transform(carla.Location(x=0.8, z=1.13)) + + def create_camera(fov, callback): + blueprint = blueprint_library.find('sensor.camera.rgb') + blueprint.set_attribute('image_size_x', str(W)) + blueprint.set_attribute('image_size_y', str(H)) + blueprint.set_attribute('fov', str(fov)) + blueprint.set_attribute('sensor_tick', str(1/20)) + if not high_quality: + blueprint.set_attribute('enable_postprocess_effects', 'False') + camera = world.spawn_actor(blueprint, transform, attach_to=vehicle) + camera.listen(callback) + return camera + + self.road_camera = create_camera(fov=40, callback=self.cam_callback_road) + if dual_camera: + self.road_wide_camera = create_camera(fov=120, callback=self.cam_callback_wide_road) # fov bigger than 120 shows unwanted artifacts + else: + self.road_wide_camera = None + + # re-enable IMU + imu_bp = blueprint_library.find('sensor.other.imu') + imu_bp.set_attribute('sensor_tick', '0.01') + self.imu = world.spawn_actor(imu_bp, transform, attach_to=vehicle) + + gps_bp = blueprint_library.find('sensor.other.gnss') + self.gps = world.spawn_actor(gps_bp, transform, attach_to=vehicle) + self.params.put_bool("UbloxAvailable", True) + + self.carla_objects = [self.imu, self.gps, self.road_camera, self.road_wide_camera] + + def close(self): + for s in self.carla_objects: + if s is not None: + try: + s.destroy() + except Exception as e: + print("Failed to destroy carla object", e) + + def carla_image_to_rgb(self, image): + rgb = np.frombuffer(image.raw_data, dtype=np.dtype("uint8")) + rgb = np.reshape(rgb, (H, W, 4)) + return np.ascontiguousarray(rgb[:, :, [0, 1, 2]]) + + def cam_callback_road(self, image): + with self.image_lock: + self.road_image = self.carla_image_to_rgb(image) + + def cam_callback_wide_road(self, image): + with self.image_lock: + self.wide_road_image = self.carla_image_to_rgb(image) + + def apply_controls(self, steer_angle, throttle_out, brake_out): + self.vc.throttle = throttle_out + + steer_carla = steer_angle * -1 / (self.max_steer_angle * self.steer_ratio) + steer_carla = np.clip(steer_carla, -1, 1) + + self.vc.steer = steer_carla + self.vc.brake = brake_out + self.vehicle.apply_control(self.vc) + + def read_sensors(self, simulator_state: SimulatorState): + simulator_state.imu.bearing = self.imu.get_transform().rotation.yaw + + simulator_state.imu.accelerometer = vec3( + self.imu.get_acceleration().x, + self.imu.get_acceleration().y, + self.imu.get_acceleration().z + ) + + simulator_state.imu.gyroscope = vec3( + self.imu.get_angular_velocity().x, + self.imu.get_angular_velocity().y, + self.imu.get_angular_velocity().z + ) + + simulator_state.gps.from_xy([self.vehicle.get_location().x, self.vehicle.get_location().y]) + + simulator_state.velocity = self.vehicle.get_velocity() + simulator_state.valid = True + simulator_state.steering_angle = self.vc.steer * self.max_steer_angle + + def read_cameras(self): + pass # cameras are read within a callback for carla + + def tick(self): + self.world.tick() + + +class CarlaBridge(SimulatorBridge): + TICKS_PER_FRAME = 5 + + def __init__(self, arguments): + super().__init__(arguments) + self.host = arguments.host + self.port = arguments.port + self.town = arguments.town + self.num_selected_spawn_point = arguments.num_selected_spawn_point + + def spawn_world(self): + import carla + client = carla.Client(self.host, self.port) + client.set_timeout(5) + + world = client.load_world(self.town) + + settings = world.get_settings() + settings.fixed_delta_seconds = 0.01 + world.apply_settings(settings) + + world.set_weather(carla.WeatherParameters.ClearSunset) + + if not self.high_quality: + world.unload_map_layer(carla.MapLayer.Foliage) + world.unload_map_layer(carla.MapLayer.Buildings) + world.unload_map_layer(carla.MapLayer.ParkedVehicles) + world.unload_map_layer(carla.MapLayer.Props) + world.unload_map_layer(carla.MapLayer.StreetLights) + world.unload_map_layer(carla.MapLayer.Particles) + + blueprint_library = world.get_blueprint_library() + + world_map = world.get_map() + + vehicle_bp = blueprint_library.filter('vehicle.tesla.*')[1] + vehicle_bp.set_attribute('role_name', 'hero') + spawn_points = world_map.get_spawn_points() + assert len(spawn_points) > self.num_selected_spawn_point, \ + f'''No spawn point {self.num_selected_spawn_point}, try a value between 0 and {len(spawn_points)} for this town.''' + spawn_point = spawn_points[self.num_selected_spawn_point] + vehicle = world.spawn_actor(vehicle_bp, spawn_point) + + physics_control = vehicle.get_physics_control() + physics_control.mass = 2326 + physics_control.torque_curve = [[20.0, 500.0], [5000.0, 500.0]] + physics_control.gear_switch_time = 0.0 + vehicle.apply_physics_control(physics_control) + + return CarlaWorld(world, vehicle, dual_camera=self.dual_camera) \ No newline at end of file diff --git a/tools/sim/bridge/common.py b/tools/sim/bridge/common.py new file mode 100644 index 0000000000..464ea08823 --- /dev/null +++ b/tools/sim/bridge/common.py @@ -0,0 +1,163 @@ +import signal +import threading +import functools + +from multiprocessing import Process, Queue +from abc import ABC, abstractmethod +from typing import Optional + +import cereal.messaging as messaging + +from openpilot.common.params import Params +from openpilot.common.numpy_fast import clip +from openpilot.common.realtime import Ratekeeper +from openpilot.selfdrive.test.helpers import set_params_enabled +from openpilot.selfdrive.car.honda.values import CruiseButtons +from openpilot.tools.sim.lib.common import SimulatorState, World +from openpilot.tools.sim.lib.simulated_car import SimulatedCar +from openpilot.tools.sim.lib.simulated_sensors import SimulatedSensors + + +def rk_loop(function, hz, exit_event: threading.Event): + rk = Ratekeeper(hz) + while not exit_event.is_set(): + function() + rk.keep_time() + + +class SimulatorBridge(ABC): + TICKS_PER_FRAME = 5 + + def __init__(self, arguments): + set_params_enabled() + self.params = Params() + + self.rk = Ratekeeper(100) + + msg = messaging.new_message('liveCalibration') + msg.liveCalibration.validBlocks = 20 + msg.liveCalibration.rpyCalib = [0.0, 0.0, 0.0] + self.params.put("CalibrationParams", msg.to_bytes()) + + self.dual_camera = arguments.dual_camera + self.high_quality = arguments.high_quality + + self._exit_event = threading.Event() + self._threads = [] + self._keep_alive = True + self.started = False + signal.signal(signal.SIGTERM, self._on_shutdown) + self._exit = threading.Event() + self.simulator_state = SimulatorState() + + self.world: Optional[World] = None + + def _on_shutdown(self, signal, frame): + self.shutdown() + + def shutdown(self): + self._keep_alive = False + + def bridge_keep_alive(self, q: Queue, retries: int): + try: + self._run(q) + finally: + self.close() + + def close(self): + self.started = False + self._exit_event.set() + + if self.world is not None: + self.world.close() + + def run(self, queue, retries=-1): + bridge_p = Process(target=self.bridge_keep_alive, args=(queue, retries), daemon=True) + bridge_p.start() + return bridge_p + + @abstractmethod + def spawn_world(self) -> World: + pass + + def _run(self, q: Queue): + self.world = self.spawn_world() + + self.simulated_car = SimulatedCar() + self.simulated_sensors = SimulatedSensors(self.dual_camera) + + self.simulated_car_thread = threading.Thread(target=rk_loop, args=(functools.partial(self.simulated_car.update, self.simulator_state), + 100, self._exit_event)) + self.simulated_car_thread.start() + + rk = Ratekeeper(100, print_delay_threshold=None) + + # Simulation tends to be slow in the initial steps. This prevents lagging later + for _ in range(20): + self.world.tick() + + throttle_manual = steer_manual = brake_manual = 0. + + while self._keep_alive: + throttle_out = steer_out = brake_out = 0.0 + throttle_op = steer_op = brake_op = 0.0 + + self.simulator_state.cruise_button = 0 + + throttle_manual = steer_manual = brake_manual = 0. + + # Read manual controls + if not q.empty(): + message = q.get() + m = message.split('_') + if m[0] == "steer": + steer_manual = float(m[1]) + elif m[0] == "throttle": + throttle_manual = float(m[1]) + elif m[0] == "brake": + brake_manual = float(m[1]) + elif m[0] == "cruise": + if m[1] == "down": + self.simulator_state.cruise_button = CruiseButtons.DECEL_SET + elif m[1] == "up": + self.simulator_state.cruise_button = CruiseButtons.RES_ACCEL + elif m[1] == "cancel": + self.simulator_state.cruise_button = CruiseButtons.CANCEL + elif m[1] == "main": + self.simulator_state.cruise_button = CruiseButtons.MAIN + elif m[0] == "ignition": + self.simulator_state.ignition = not self.simulator_state.ignition + elif m[0] == "quit": + break + + self.simulator_state.user_brake = brake_manual + self.simulator_state.user_gas = throttle_manual + + steer_manual = steer_manual * -40 + + # Update openpilot on current sensor state + self.simulated_sensors.update(self.simulator_state, self.world) + + is_openpilot_engaged = self.simulated_car.sm['controlsState'].active + + self.simulated_car.sm.update(0) + + if is_openpilot_engaged: + throttle_op = clip(self.simulated_car.sm['carControl'].actuators.accel / 1.6, 0.0, 1.0) + brake_op = clip(-self.simulated_car.sm['carControl'].actuators.accel / 4.0, 0.0, 1.0) + steer_op = self.simulated_car.sm['carControl'].actuators.steeringAngleDeg + + throttle_out = throttle_op if is_openpilot_engaged else throttle_manual + brake_out = brake_op if is_openpilot_engaged else brake_manual + steer_out = steer_op if is_openpilot_engaged else steer_manual + + self.world.apply_controls(steer_out, throttle_out, brake_out) + self.world.read_sensors(self.simulator_state) + + if self.rk.frame % self.TICKS_PER_FRAME == 0: + self.world.tick() + self.world.read_cameras() + + self.started = True + + rk.keep_time() diff --git a/tools/sim/lib/camerad.py b/tools/sim/lib/camerad.py new file mode 100644 index 0000000000..4621347787 --- /dev/null +++ b/tools/sim/lib/camerad.py @@ -0,0 +1,70 @@ +import numpy as np +import os +import pyopencl as cl +import pyopencl.array as cl_array + +from cereal.visionipc import VisionIpcServer, VisionStreamType +from cereal import messaging + +from openpilot.common.basedir import BASEDIR +from openpilot.tools.sim.lib.common import W, H + +class Camerad: + """Simulates the camerad daemon""" + def __init__(self, dual_camera): + self.pm = messaging.PubMaster(['roadCameraState', 'wideRoadCameraState']) + + self.frame_road_id = 0 + self.frame_wide_id = 0 + self.vipc_server = VisionIpcServer("camerad") + + self.vipc_server.create_buffers(VisionStreamType.VISION_STREAM_ROAD, 5, False, W, H) + if dual_camera: + self.vipc_server.create_buffers(VisionStreamType.VISION_STREAM_WIDE_ROAD, 5, False, W, H) + + self.vipc_server.start_listener() + + # set up for pyopencl rgb to yuv conversion + self.ctx = cl.create_some_context() + self.queue = cl.CommandQueue(self.ctx) + cl_arg = f" -DHEIGHT={H} -DWIDTH={W} -DRGB_STRIDE={W * 3} -DUV_WIDTH={W // 2} -DUV_HEIGHT={H // 2} -DRGB_SIZE={W * H} -DCL_DEBUG " + + kernel_fn = os.path.join(BASEDIR, "tools/sim/rgb_to_nv12.cl") + with open(kernel_fn) as f: + prg = cl.Program(self.ctx, f.read()).build(cl_arg) + self.krnl = prg.rgb_to_nv12 + self.Wdiv4 = W // 4 if (W % 4 == 0) else (W + (4 - W % 4)) // 4 + self.Hdiv4 = H // 4 if (H % 4 == 0) else (H + (4 - H % 4)) // 4 + + def cam_send_yuv_road(self, yuv): + self._send_yuv(yuv, self.frame_road_id, 'roadCameraState', VisionStreamType.VISION_STREAM_ROAD) + self.frame_road_id += 1 + + def cam_send_yuv_wide_road(self, yuv): + self._send_yuv(yuv, self.frame_wide_id, 'wideRoadCameraState', VisionStreamType.VISION_STREAM_WIDE_ROAD) + self.frame_wide_id += 1 + + # Returns: yuv bytes + def rgb_to_yuv(self, rgb): + assert rgb.shape == (H, W, 3), f"{rgb.shape}" + assert rgb.dtype == np.uint8 + + rgb_cl = cl_array.to_device(self.queue, rgb) + yuv_cl = cl_array.empty_like(rgb_cl) + self.krnl(self.queue, (self.Wdiv4, self.Hdiv4), None, rgb_cl.data, yuv_cl.data).wait() + yuv = np.resize(yuv_cl.get(), rgb.size // 2) + return yuv.data.tobytes() + + def _send_yuv(self, yuv, frame_id, pub_type, yuv_type): + eof = int(frame_id * 0.05 * 1e9) + self.vipc_server.send(yuv_type, yuv, frame_id, eof, eof) + + dat = messaging.new_message(pub_type) + msg = { + "frameId": frame_id, + "transform": [1.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0] + } + setattr(dat, pub_type, msg) + self.pm.send(pub_type, dat) \ No newline at end of file diff --git a/tools/sim/lib/can.py b/tools/sim/lib/can.py deleted file mode 100755 index db321d3193..0000000000 --- a/tools/sim/lib/can.py +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env python3 -import cereal.messaging as messaging -from opendbc.can.packer import CANPacker -from opendbc.can.parser import CANParser -from openpilot.selfdrive.boardd.boardd_api_impl import can_list_to_can_capnp -from openpilot.selfdrive.car import crc8_pedal - -packer = CANPacker("honda_civic_touring_2016_can_generated") -rpacker = CANPacker("acura_ilx_2016_nidec") - - -def get_car_can_parser(): - dbc_f = 'honda_civic_touring_2016_can_generated' - checks = [ - (0xe4, 100), - (0x1fa, 50), - (0x200, 50), - ] - return CANParser(dbc_f, checks, 0) -cp = get_car_can_parser() - -def can_function(pm, speed, angle, idx, cruise_button, is_engaged): - - msg = [] - - # *** powertrain bus *** - - speed = speed * 3.6 # convert m/s to kph - msg.append(packer.make_can_msg("ENGINE_DATA", 0, {"XMISSION_SPEED": speed})) - msg.append(packer.make_can_msg("WHEEL_SPEEDS", 0, { - "WHEEL_SPEED_FL": speed, - "WHEEL_SPEED_FR": speed, - "WHEEL_SPEED_RL": speed, - "WHEEL_SPEED_RR": speed - })) - - msg.append(packer.make_can_msg("SCM_BUTTONS", 0, {"CRUISE_BUTTONS": cruise_button})) - - values = {"COUNTER_PEDAL": idx & 0xF} - checksum = crc8_pedal(packer.make_can_msg("GAS_SENSOR", 0, {"COUNTER_PEDAL": idx & 0xF})[2][:-1]) - values["CHECKSUM_PEDAL"] = checksum - msg.append(packer.make_can_msg("GAS_SENSOR", 0, values)) - - msg.append(packer.make_can_msg("GEARBOX", 0, {"GEAR": 4, "GEAR_SHIFTER": 8})) - msg.append(packer.make_can_msg("GAS_PEDAL_2", 0, {})) - msg.append(packer.make_can_msg("SEATBELT_STATUS", 0, {"SEATBELT_DRIVER_LATCHED": 1})) - msg.append(packer.make_can_msg("STEER_STATUS", 0, {})) - msg.append(packer.make_can_msg("STEERING_SENSORS", 0, {"STEER_ANGLE": angle})) - msg.append(packer.make_can_msg("VSA_STATUS", 0, {})) - msg.append(packer.make_can_msg("STANDSTILL", 0, {"WHEELS_MOVING": 1 if speed >= 1.0 else 0})) - msg.append(packer.make_can_msg("STEER_MOTOR_TORQUE", 0, {})) - msg.append(packer.make_can_msg("EPB_STATUS", 0, {})) - msg.append(packer.make_can_msg("DOORS_STATUS", 0, {})) - msg.append(packer.make_can_msg("CRUISE_PARAMS", 0, {})) - msg.append(packer.make_can_msg("CRUISE", 0, {})) - msg.append(packer.make_can_msg("SCM_FEEDBACK", 0, {"MAIN_ON": 1})) - msg.append(packer.make_can_msg("POWERTRAIN_DATA", 0, {"ACC_STATUS": int(is_engaged)})) - msg.append(packer.make_can_msg("HUD_SETTING", 0, {})) - msg.append(packer.make_can_msg("CAR_SPEED", 0, {})) - - # *** cam bus *** - msg.append(packer.make_can_msg("STEERING_CONTROL", 2, {})) - msg.append(packer.make_can_msg("ACC_HUD", 2, {})) - msg.append(packer.make_can_msg("LKAS_HUD", 2, {})) - msg.append(packer.make_can_msg("BRAKE_COMMAND", 2, {})) - - # *** radar bus *** - if idx % 5 == 0: - msg.append(rpacker.make_can_msg("RADAR_DIAGNOSTIC", 1, {"RADAR_STATE": 0x79})) - for i in range(16): - msg.append(rpacker.make_can_msg("TRACK_%d" % i, 1, {"LONG_DIST": 255.5})) - - pm.send('can', can_list_to_can_capnp(msg)) - -def sendcan_function(sendcan): - sc = messaging.drain_sock_raw(sendcan) - cp.update_strings(sc, sendcan=True) - - if cp.vl[0x1fa]['COMPUTER_BRAKE_REQUEST']: - brake = cp.vl[0x1fa]['COMPUTER_BRAKE'] / 1024. - else: - brake = 0.0 - - if cp.vl[0x200]['GAS_COMMAND'] > 0: - gas = ( cp.vl[0x200]['GAS_COMMAND'] + 83.3 ) / (0.253984064 * 2**16) - else: - gas = 0.0 - - if cp.vl[0xe4]['STEER_TORQUE_REQUEST']: - steer_torque = cp.vl[0xe4]['STEER_TORQUE']/3840 - else: - steer_torque = 0.0 - - return gas, brake, steer_torque diff --git a/tools/sim/lib/common.py b/tools/sim/lib/common.py new file mode 100644 index 0000000000..3de89f39fc --- /dev/null +++ b/tools/sim/lib/common.py @@ -0,0 +1,86 @@ +import math +import threading +import numpy as np + +from abc import ABC, abstractmethod +from collections import namedtuple + +W, H = 1928, 1208 + + +vec3 = namedtuple("vec3", ["x", "y", "z"]) + +class GPSState: + def __init__(self): + self.latitude = 0 + self.longitude = 0 + self.altitude = 0 + + def from_xy(self, xy): + """Simulates a lat/lon from an xy coordinate on a plane, for simple simlation. TODO: proper global projection?""" + BASE_LAT = 32.75308505188913 + BASE_LON = -117.2095393365393 + DEG_TO_METERS = 100000 + + self.latitude = float(BASE_LAT + xy[0] / DEG_TO_METERS) + self.longitude = float(BASE_LON + xy[1] / DEG_TO_METERS) + self.altitude = 0 + + +class IMUState: + def __init__(self): + self.accelerometer: vec3 = vec3(0,0,0) + self.gyroscope: vec3 = vec3(0,0,0) + self.bearing: float = 0 + + +class SimulatorState: + def __init__(self): + self.valid = False + self.is_engaged = False + self.ignition = True + + self.velocity: vec3 = None + self.bearing: float = 0 + self.gps = GPSState() + self.imu = IMUState() + + self.steering_angle: float = 0 + + self.user_gas: float = 0 + self.user_brake: float = 0 + + self.cruise_button = 0 + + @property + def speed(self): + return math.sqrt(self.velocity.x ** 2 + self.velocity.y ** 2 + self.velocity.z ** 2) + + +class World(ABC): + def __init__(self, dual_camera): + self.dual_camera = dual_camera + + self.image_lock = threading.Lock() + self.road_image = np.zeros((H, W, 3), dtype=np.uint8) + self.wide_road_image = np.zeros((H, W, 3), dtype=np.uint8) + + @abstractmethod + def apply_controls(self, steer_sim, throttle_out, brake_out): + pass + + @abstractmethod + def tick(self): + pass + + @abstractmethod + def read_sensors(self, simulator_state: SimulatorState): + pass + + @abstractmethod + def read_cameras(self): + pass + + @abstractmethod + def close(self): + pass \ No newline at end of file diff --git a/tools/sim/lib/keyboard_ctrl.py b/tools/sim/lib/keyboard_ctrl.py index 803aa091a3..57d5834026 100644 --- a/tools/sim/lib/keyboard_ctrl.py +++ b/tools/sim/lib/keyboard_ctrl.py @@ -1,6 +1,7 @@ import sys import termios import time + from termios import (BRKINT, CS8, CSIZE, ECHO, ICANON, ICRNL, IEXTEN, INPCK, ISTRIP, IXON, PARENB, VMIN, VTIME) from typing import NoReturn @@ -38,7 +39,6 @@ def getch() -> str: def keyboard_poll_thread(q: 'Queue[str]'): while True: c = getch() - print("got %s" % c) if c == '1': q.put("cruise_up") elif c == '2': diff --git a/tools/sim/lib/simulated_car.py b/tools/sim/lib/simulated_car.py new file mode 100644 index 0000000000..bbdbb9fcc4 --- /dev/null +++ b/tools/sim/lib/simulated_car.py @@ -0,0 +1,110 @@ +import cereal.messaging as messaging + +from opendbc.can.packer import CANPacker +from opendbc.can.parser import CANParser +from openpilot.selfdrive.boardd.boardd_api_impl import can_list_to_can_capnp +from openpilot.selfdrive.car import crc8_pedal +from openpilot.tools.sim.lib.common import SimulatorState + + +class SimulatedCar: + """Simulates a honda civic 2016 (panda state + can messages) to OpenPilot""" + packer = CANPacker("honda_civic_touring_2016_can_generated") + rpacker = CANPacker("acura_ilx_2016_nidec") + + def __init__(self): + self.pm = messaging.PubMaster(['can', 'pandaStates']) + self.sm = messaging.SubMaster(['carControl', 'controlsState']) + self.cp = self.get_car_can_parser() + self.idx = 0 + + @staticmethod + def get_car_can_parser(): + dbc_f = 'honda_civic_touring_2016_can_generated' + checks = [ + (0xe4, 100), + (0x1fa, 50), + (0x200, 50), + ] + return CANParser(dbc_f, checks, 0) + + def send_can_messages(self, simulator_state: SimulatorState): + if not simulator_state.valid: + return + + msg = [] + + # *** powertrain bus *** + + speed = simulator_state.speed * 3.6 # convert m/s to kph + msg.append(self.packer.make_can_msg("ENGINE_DATA", 0, {"XMISSION_SPEED": speed})) + msg.append(self.packer.make_can_msg("WHEEL_SPEEDS", 0, { + "WHEEL_SPEED_FL": speed, + "WHEEL_SPEED_FR": speed, + "WHEEL_SPEED_RL": speed, + "WHEEL_SPEED_RR": speed + })) + + msg.append(self.packer.make_can_msg("SCM_BUTTONS", 0, {"CRUISE_BUTTONS": simulator_state.cruise_button})) + + values = { + "COUNTER_PEDAL": self.idx & 0xF, + "INTERCEPTOR_GAS": simulator_state.user_gas * 2**12, + "INTERCEPTOR_GAS2": simulator_state.user_gas * 2**12, + } + checksum = crc8_pedal(self.packer.make_can_msg("GAS_SENSOR", 0, values)[2][:-1]) + values["CHECKSUM_PEDAL"] = checksum + msg.append(self.packer.make_can_msg("GAS_SENSOR", 0, values)) + + msg.append(self.packer.make_can_msg("GEARBOX", 0, {"GEAR": 4, "GEAR_SHIFTER": 8})) + msg.append(self.packer.make_can_msg("GAS_PEDAL_2", 0, {})) + msg.append(self.packer.make_can_msg("SEATBELT_STATUS", 0, {"SEATBELT_DRIVER_LATCHED": 1})) + msg.append(self.packer.make_can_msg("STEER_STATUS", 0, {})) + msg.append(self.packer.make_can_msg("STEERING_SENSORS", 0, {"STEER_ANGLE": simulator_state.steering_angle})) + msg.append(self.packer.make_can_msg("VSA_STATUS", 0, {})) + msg.append(self.packer.make_can_msg("STANDSTILL", 0, {"WHEELS_MOVING": 1 if simulator_state.speed >= 1.0 else 0})) + msg.append(self.packer.make_can_msg("STEER_MOTOR_TORQUE", 0, {})) + msg.append(self.packer.make_can_msg("EPB_STATUS", 0, {})) + msg.append(self.packer.make_can_msg("DOORS_STATUS", 0, {})) + msg.append(self.packer.make_can_msg("CRUISE_PARAMS", 0, {})) + msg.append(self.packer.make_can_msg("CRUISE", 0, {})) + msg.append(self.packer.make_can_msg("SCM_FEEDBACK", 0, {"MAIN_ON": 1})) + msg.append(self.packer.make_can_msg("POWERTRAIN_DATA", 0, + { + "ACC_STATUS": int(simulator_state.is_engaged), + "PEDAL_GAS": simulator_state.user_gas, + "BRAKE_PRESSED": simulator_state.user_brake > 0 + })) + msg.append(self.packer.make_can_msg("HUD_SETTING", 0, {})) + msg.append(self.packer.make_can_msg("CAR_SPEED", 0, {})) + + # *** cam bus *** + msg.append(self.packer.make_can_msg("STEERING_CONTROL", 2, {})) + msg.append(self.packer.make_can_msg("ACC_HUD", 2, {})) + msg.append(self.packer.make_can_msg("LKAS_HUD", 2, {})) + msg.append(self.packer.make_can_msg("BRAKE_COMMAND", 2, {})) + + # *** radar bus *** + if self.idx % 5 == 0: + msg.append(self.rpacker.make_can_msg("RADAR_DIAGNOSTIC", 1, {"RADAR_STATE": 0x79})) + for i in range(16): + msg.append(self.rpacker.make_can_msg("TRACK_%d" % i, 1, {"LONG_DIST": 255.5})) + + self.pm.send('can', can_list_to_can_capnp(msg)) + + def send_panda_state(self, simulator_state): + dat = messaging.new_message('pandaStates', 1) + dat.valid = True + dat.pandaStates[0] = { + 'ignitionLine': simulator_state.ignition, + 'pandaType': "blackPanda", + 'controlsAllowed': True, + 'safetyModel': 'hondaNidec', + } + self.pm.send('pandaStates', dat) + + def update(self, simulator_state: SimulatorState): + self.send_can_messages(simulator_state) + self.send_panda_state(simulator_state) + + self.idx += 1 \ No newline at end of file diff --git a/tools/sim/lib/simulated_sensors.py b/tools/sim/lib/simulated_sensors.py new file mode 100644 index 0000000000..dd55c02f02 --- /dev/null +++ b/tools/sim/lib/simulated_sensors.py @@ -0,0 +1,127 @@ +import time + +from cereal import log +import cereal.messaging as messaging + +from openpilot.common.params import Params +from openpilot.common.realtime import DT_DMON +from openpilot.tools.sim.lib.camerad import Camerad + +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from openpilot.tools.sim.lib.common import World, SimulatorState + + +class SimulatedSensors: + """Simulates the C3 sensors (acc, gyro, gps, peripherals, dm state, cameras) to OpenPilot""" + + def __init__(self, dual_camera=False): + self.pm = messaging.PubMaster(['accelerometer', 'gyroscope', 'gpsLocationExternal', 'driverStateV2', 'driverMonitoringState', 'peripheralState']) + self.camerad = Camerad(dual_camera=dual_camera) + self.last_perp_update = 0 + self.last_dmon_update = 0 + + def send_imu_message(self, simulator_state: 'SimulatorState'): + for _ in range(5): + dat = messaging.new_message('accelerometer') + dat.accelerometer.sensor = 4 + dat.accelerometer.type = 0x10 + dat.accelerometer.timestamp = dat.logMonoTime # TODO: use the IMU timestamp + dat.accelerometer.init('acceleration') + dat.accelerometer.acceleration.v = [simulator_state.imu.accelerometer.x, simulator_state.imu.accelerometer.y, simulator_state.imu.accelerometer.z] + self.pm.send('accelerometer', dat) + + # copied these numbers from locationd + dat = messaging.new_message('gyroscope') + dat.gyroscope.sensor = 5 + dat.gyroscope.type = 0x10 + dat.gyroscope.timestamp = dat.logMonoTime # TODO: use the IMU timestamp + dat.gyroscope.init('gyroUncalibrated') + dat.gyroscope.gyroUncalibrated.v = [simulator_state.imu.gyroscope.x, simulator_state.imu.gyroscope.y, simulator_state.imu.gyroscope.z] + self.pm.send('gyroscope', dat) + + def send_gps_message(self, simulator_state: 'SimulatorState'): + if not simulator_state.valid: + return + + # transform vel from carla to NED + # north is -Y in CARLA + velNED = [ + -simulator_state.velocity.y, # north/south component of NED is negative when moving south + simulator_state.velocity.x, # positive when moving east, which is x in carla + simulator_state.velocity.z, + ] + + for _ in range(10): + dat = messaging.new_message('gpsLocationExternal') + dat.gpsLocationExternal = { + "unixTimestampMillis": int(time.time() * 1000), + "flags": 1, # valid fix + "accuracy": 1.0, + "verticalAccuracy": 1.0, + "speedAccuracy": 0.1, + "bearingAccuracyDeg": 0.1, + "vNED": velNED, + "bearingDeg": simulator_state.imu.bearing, + "latitude": simulator_state.gps.latitude, + "longitude": simulator_state.gps.longitude, + "altitude": simulator_state.gps.altitude, + "speed": simulator_state.speed, + "source": log.GpsLocationData.SensorSource.ublox, + } + + self.pm.send('gpsLocationExternal', dat) + + def send_peripheral_state(self): + dat = messaging.new_message('peripheralState') + dat.valid = True + dat.peripheralState = { + 'pandaType': log.PandaState.PandaType.blackPanda, + 'voltage': 12000, + 'current': 5678, + 'fanSpeedRpm': 1000 + } + Params().put_bool("ObdMultiplexingEnabled", False) + self.pm.send('peripheralState', dat) + + def send_fake_driver_monitoring(self): + # dmonitoringmodeld output + dat = messaging.new_message('driverStateV2') + dat.driverStateV2.leftDriverData.faceOrientation = [0., 0., 0.] + dat.driverStateV2.leftDriverData.faceProb = 1.0 + dat.driverStateV2.rightDriverData.faceOrientation = [0., 0., 0.] + dat.driverStateV2.rightDriverData.faceProb = 1.0 + self.pm.send('driverStateV2', dat) + + # dmonitoringd output + dat = messaging.new_message('driverMonitoringState') + dat.driverMonitoringState = { + "faceDetected": True, + "isDistracted": False, + "awarenessStatus": 1., + } + self.pm.send('driverMonitoringState', dat) + + def send_camera_images(self, world: 'World'): + with world.image_lock: + yuv = self.camerad.rgb_to_yuv(world.road_image) + self.camerad.cam_send_yuv_road(yuv) + + if world.dual_camera: + yuv = self.camerad.rgb_to_yuv(world.wide_road_image) + self.camerad.cam_send_yuv_wide_road(yuv) + + def update(self, simulator_state: 'SimulatorState', world: 'World'): + now = time.time() + self.send_imu_message(simulator_state) + self.send_gps_message(simulator_state) + + if (now - self.last_dmon_update) > DT_DMON/2: + self.send_fake_driver_monitoring() + self.last_dmon_update = now + + if (now - self.last_perp_update) > 0.25: + self.send_peripheral_state() + self.last_perp_update = now + + self.send_camera_images(world) \ No newline at end of file diff --git a/tools/sim/run_bridge.py b/tools/sim/run_bridge.py new file mode 100755 index 0000000000..8e6dc8f2ef --- /dev/null +++ b/tools/sim/run_bridge.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +import argparse + +from typing import Any +from multiprocessing import Queue + +from openpilot.tools.sim.bridge.common import SimulatorBridge +from openpilot.tools.sim.bridge.carla import CarlaBridge + + +def parse_args(add_args=None): + parser = argparse.ArgumentParser(description='Bridge between CARLA and openpilot.') + parser.add_argument('--joystick', action='store_true') + parser.add_argument('--high_quality', action='store_true') + parser.add_argument('--dual_camera', action='store_true') + parser.add_argument('--simulator', dest='simulator', type=str, default='carla') + + # Carla specific + parser.add_argument('--town', type=str, default='Town04_Opt') + parser.add_argument('--spawn_point', dest='num_selected_spawn_point', type=int, default=16) + parser.add_argument('--host', dest='host', type=str, default='127.0.0.1') + parser.add_argument('--port', dest='port', type=int, default=2000) + + return parser.parse_args(add_args) + +if __name__ == "__main__": + q: Any = Queue() + args = parse_args() + + simulator_bridge: SimulatorBridge + if args.simulator == "carla": + simulator_bridge = CarlaBridge(args) + else: + raise AssertionError("simulator type not supported") + p = simulator_bridge.run(q) + + if args.joystick: + # start input poll for joystick + from openpilot.tools.sim.lib.manual_ctrl import wheel_poll_thread + + wheel_poll_thread(q) + else: + # start input poll for keyboard + from openpilot.tools.sim.lib.keyboard_ctrl import keyboard_poll_thread + + keyboard_poll_thread(q) + + simulator_bridge.shutdown() + + p.join() diff --git a/tools/sim/tests/test_carla_integration.py b/tools/sim/tests/test_carla_integration.py index 65f5f4a30f..b5a60ee0e3 100755 --- a/tools/sim/tests/test_carla_integration.py +++ b/tools/sim/tests/test_carla_integration.py @@ -8,8 +8,8 @@ from multiprocessing import Queue from cereal import messaging from openpilot.common.basedir import BASEDIR from openpilot.selfdrive.manager.helpers import unblock_stdout -from openpilot.tools.sim import bridge -from openpilot.tools.sim.bridge import CarlaBridge +from openpilot.tools.sim.run_bridge import parse_args +from openpilot.tools.sim.bridge.carla import CarlaBridge CI = "CI" in os.environ @@ -42,7 +42,7 @@ class TestCarlaIntegration(unittest.TestCase): sm = messaging.SubMaster(['controlsState', 'carEvents', 'managerState']) q = Queue() - carla_bridge = CarlaBridge(bridge.parse_args([])) + carla_bridge = CarlaBridge(parse_args([])) p_bridge = carla_bridge.run(q, retries=10) self.processes.append(p_bridge) From 22e7aa3d985d273d0a66198d9549f1778d79ed83 Mon Sep 17 00:00:00 2001 From: next176 <145059169+next176@users.noreply.github.com> Date: Fri, 15 Sep 2023 23:05:44 +0200 Subject: [PATCH 46/59] Hyundai Ioniq 6 "EUR" fwdCamera fingerprint (#29930) * Update values.py Hyundai Ioniq 6 Premium AWD 2023 / EUR fingerprint * Update routes.py Ioniq6 EUR model * Update selfdrive/car/tests/routes.py --------- Co-authored-by: Shane Smiskol --- selfdrive/car/hyundai/values.py | 1 + 1 file changed, 1 insertion(+) diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 8827c7bb0c..b84cb80843 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -1833,6 +1833,7 @@ FW_VERSIONS = { b'\xf1\x00CE__ RDR ----- 1.00 1.01 99110-KL000 ', ], (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00CE MFC AT EUR LHD 1.00 1.03 99211-KL000 221011', b'\xf1\x00CE MFC AT USA LHD 1.00 1.04 99211-KL000 221213', ], }, From c6f1f36789427e115c533a5d5c319d4e58ff644a Mon Sep 17 00:00:00 2001 From: Justin Newberry Date: Fri, 15 Sep 2023 14:38:51 -0700 Subject: [PATCH 47/59] CI: reduce unittest timeout (#29937) reduce timeout --- .github/workflows/selfdrive_tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index f7aba648a4..575ee21835 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -271,7 +271,7 @@ jobs: timeout-minutes: ${{ ((steps.restore-scons-cache.outputs.cache-hit == 'true') && 10 || 30) }} # allow more time when we missed the scons cache run: ${{ env.RUN }} "scons -j$(nproc)" - name: Run unit tests - timeout-minutes: 40 + timeout-minutes: 15 run: | ${{ env.RUN }} "export SKIP_LONG_TESTS=1 && \ $PYTEST -n auto --dist=loadscope --timeout 30 -o cpp_files=test_* && \ From ad7432b45d00cf05fb9635a850bae878d3b686b9 Mon Sep 17 00:00:00 2001 From: Justin Newberry Date: Fri, 15 Sep 2023 14:55:08 -0700 Subject: [PATCH 48/59] update metadrive (#29938) --- poetry.lock | 46 ++++++++++++++++++++-------------------------- pyproject.toml | 2 +- 2 files changed, 21 insertions(+), 27 deletions(-) diff --git a/poetry.lock b/poetry.lock index 2c134ec32d..0f0f587fd1 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" @@ -2144,16 +2144,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"}, @@ -2326,8 +2316,8 @@ waymo = ["waymo-open-dataset-tf-2.11.0 (==1.5.0)"] [package.source] type = "git" url = "https://github.com/metadriverse/metadrive.git" -reference = "51d4393f3b3574fd0e79ed04eae0081f8447ca72" -resolved_reference = "51d4393f3b3574fd0e79ed04eae0081f8447ca72" +reference = "7d6f8ef707bfff67c6b88f3b4a98f8b1d58bf8e6" +resolved_reference = "7d6f8ef707bfff67c6b88f3b4a98f8b1d58bf8e6" [[package]] name = "mpld3" @@ -2783,7 +2773,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" @@ -2802,7 +2799,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" @@ -3952,7 +3956,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"}, @@ -3960,15 +3963,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"}, @@ -3985,7 +3981,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"}, @@ -3993,7 +3988,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"}, @@ -5087,4 +5081,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "~3.11" -content-hash = "7258a24274936ccdafb930a683f4ea197e82ab187698d0723bb4683ca41e6d26" +content-hash = "6c93bf910082c9de645e00f036ebbce8cb1e658fb0b74f435ec3120e17acacca" diff --git a/pyproject.toml b/pyproject.toml index 5d4bcafa7a..a314c9e647 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -132,7 +132,7 @@ inputs = "*" lru-dict = "*" markdown-it-py = "*" matplotlib = "*" -metadrive-simulator = { git = "https://github.com/metadriverse/metadrive.git", rev ="51d4393f3b3574fd0e79ed04eae0081f8447ca72", markers = "platform_machine != 'aarch64'" } # no linux/aarch64 wheels for certain dependencies +metadrive-simulator = { git = "https://github.com/metadriverse/metadrive.git", rev ="7d6f8ef707bfff67c6b88f3b4a98f8b1d58bf8e6", markers = "platform_machine != 'aarch64'" } # no linux/aarch64 wheels for certain dependencies mpld3 = "*" mypy = "*" myst-parser = "*" From ef50b4fdacd64d748bd80db26645c8dc88843b37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20Sch=C3=A4fer?= Date: Fri, 15 Sep 2023 14:59:46 -0700 Subject: [PATCH 49/59] Test modeld: 3s enough for modeld startup (#29936) * Test modeld: 3s enough for modeld startup * Always fails when you send frames before modeld is ready * Wait for modeld to read --- selfdrive/modeld/tests/test_modeld.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/selfdrive/modeld/tests/test_modeld.py b/selfdrive/modeld/tests/test_modeld.py index c3d3b3daa1..7ae6d5308f 100755 --- a/selfdrive/modeld/tests/test_modeld.py +++ b/selfdrive/modeld/tests/test_modeld.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -import time import unittest import numpy as np import random @@ -27,8 +26,7 @@ class TestModeld(unittest.TestCase): self.pm = messaging.PubMaster(['roadCameraState', 'wideRoadCameraState', 'liveCalibration', 'lateralPlan']) managed_processes['modeld'].start() - time.sleep(0.2) - self.sm.update(1000) + self.pm.wait_for_readers_to_update("roadCameraState", 10) def tearDown(self): managed_processes['modeld'].stop() From ccc8e099b6e3457cc3a4e263491d1bfc92e8c897 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 15 Sep 2023 18:50:43 -0700 Subject: [PATCH 50/59] sensord: test update for provisioning (#29942) sensord: update for provisioning --- system/sensord/tests/test_sensord.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/sensord/tests/test_sensord.py b/system/sensord/tests/test_sensord.py index ccdce3b4e5..dbe28ab9db 100755 --- a/system/sensord/tests/test_sensord.py +++ b/system/sensord/tests/test_sensord.py @@ -81,7 +81,7 @@ def read_sensor_events(duration_sec): socks[stype] = messaging.sub_sock(stype, poller=poller, timeout=100) # wait for sensors to come up - with Timeout(60, "sensors didn't come up"): + with Timeout(int(os.environ.get("SENSOR_WAIT", "5")), "sensors didn't come up"): while len(poller.poll(250)) == 0: pass time.sleep(1) From f0b8ecd14f7aed3d3ad46c770881e3028ed9781f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20R=C4=85czy?= Date: Fri, 15 Sep 2023 19:05:32 -0700 Subject: [PATCH 51/59] macOS: add prompt about support in setup script (#29939) * Add prompt about the state of macos support in mac_setup * Change words Co-authored-by: Adeeb Shihadeh --------- Co-authored-by: Adeeb Shihadeh --- .github/workflows/selfdrive_tests.yaml | 2 +- tools/mac_setup.sh | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index 575ee21835..6fd2ca8556 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -142,7 +142,7 @@ jobs: fi - name: Install dependencies if: steps.dependency-cache.outputs.cache-hit != 'true' - run: ./tools/mac_setup.sh + run: SKIP_PROMPT=1 ./tools/mac_setup.sh env: # package install has DeprecationWarnings PYTHONWARNINGS: default diff --git a/tools/mac_setup.sh b/tools/mac_setup.sh index 0c9627ca4e..9ec2097ea4 100755 --- a/tools/mac_setup.sh +++ b/tools/mac_setup.sh @@ -2,6 +2,20 @@ set -e +if [ -z "$SKIP_PROMPT" ]; then + echo "--------------- macOS support ---------------" + echo "Running openpilot natively on macOS is not officially supported." + echo "It might build, some parts of it might work, but it's not fully tested, so there might be some issues." + echo + echo "Check out devcontainers for a seamless experience (see tools/README.md)." + echo "-------------------------------------------------" + echo -n "Are you sure you want to continue? [y/N] " + read -r response + if [[ ! "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then + exit 1 + fi +fi + DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" ROOT="$(cd $DIR/../ && pwd)" ARCH=$(uname -m) From f7d49ecca1fff0f680080919f87af790da2cd455 Mon Sep 17 00:00:00 2001 From: Quake4net <144956803+Quake4net@users.noreply.github.com> Date: Sat, 16 Sep 2023 08:11:20 +0200 Subject: [PATCH 52/59] VW: fingerprint for Crafter MK2 (#29926) * Update values.py Added Crafter_MK2 fwVersions: Problem there where two engine ecu's with the same address, I added both into the fwVersion list. * Update values.py deleted the hyundai engine ecu fwVersion - Discord told me to ignore Hyundai parts so I deleted that one line again. --- selfdrive/car/volkswagen/values.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index 494d59bad2..b98de73080 100644 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -396,6 +396,7 @@ FW_VERSIONS = { }, CAR.CRAFTER_MK2: { (Ecu.engine, 0x7e0, None): [ + b'\xf1\x8704L906056BP\xf1\x894729', b'\xf1\x8704L906056EK\xf1\x896391', b'\xf1\x8705L906023BC\xf1\x892688', ], @@ -403,15 +404,18 @@ FW_VERSIONS = { #(Ecu.transmission, 0x7e1, None): [ #], (Ecu.srs, 0x715, None): [ + b'\xf1\x873Q0959655AL\xf1\x890505\xf1\x82\x0e1411001413001203151311031100', b'\xf1\x873Q0959655BG\xf1\x890703\xf1\x82\x0e16120016130012051G1313052900', b'\xf1\x875QF959655AS\xf1\x890755\xf1\x82\x1315140015150011111100050200--1311120749', ], (Ecu.eps, 0x712, None): [ + b'\xf1\x872N0909143D\x00\xf1\x897010\xf1\x82\x05183AZ306A2', b'\xf1\x872N0909143E \xf1\x897021\xf1\x82\x05163AZ306A2', b'\xf1\x872N0909144K \xf1\x897045\xf1\x82\x05233AZ810A2', ], (Ecu.fwdRadar, 0x757, None): [ b'\xf1\x872Q0907572AA\xf1\x890396', + b'\xf1\x872Q0907572J \xf1\x890156', b'\xf1\x872Q0907572M \xf1\x890233', ], }, From ce608d03b7b258fee6248911a0aa4718d8123043 Mon Sep 17 00:00:00 2001 From: venmer2 <145170480+venmer2@users.noreply.github.com> Date: Fri, 15 Sep 2023 23:24:30 -0700 Subject: [PATCH 53/59] VW: missing FW for Tiguan 2019 (#29943) * Update values.py for VW Tiguan 2019 SEL Added all ECU Firmware Versions for VW Tiguan 2019 SEL model * rm duplicates --------- Co-authored-by: Shane Smiskol --- selfdrive/car/volkswagen/values.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index b98de73080..4ea9e1ddf8 100644 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -827,6 +827,7 @@ FW_VERSIONS = { b'\xf1\x8783A907115G \xf1\x890001', b'\xf1\x8783A907115K \xf1\x890001', b'\xf1\x8704E906024AP\xf1\x891461', + b'\xf1\x8783A907115 \xf1\x890007', ], (Ecu.transmission, 0x7e1, None): [ b'\xf1\x8709G927158DT\xf1\x893698', @@ -857,6 +858,7 @@ FW_VERSIONS = { b'\xf1\x875Q0959655CB\xf1\x890421\xf1\x82\x1316143231313500314647021750179333613100', b'\xf1\x875Q0959655CG\xf1\x890421\xf1\x82\x1331310031333300314240024050409333613100', b'\xf1\x875Q0959655CD\xf1\x890421\xf1\x82\x13123112313333003145406F6154619333613100', + b'\xf1\x875Q0959655AG\xf1\x890338\xf1\x82\x1316143231313500314617011730179333423100', ], (Ecu.eps, 0x712, None): [ b'\xf1\x875Q0909143M \xf1\x892041\xf1\x820529A6060603', @@ -871,6 +873,7 @@ FW_VERSIONS = { b'\xf1\x875QM909144C \xf1\x891082\xf1\x82\00521A60804A1', b'\xf1\x875QM907144D \xf1\x891063\xf1\x82\x002SA6092SOM', b'\xf1\x875Q0910143C \xf1\x892211\xf1\x82\x0567A6017A00', + b'\xf1\x875QM909144B \xf1\x891081\xf1\x82\x0521A60804A1', ], (Ecu.fwdRadar, 0x757, None): [ b'\xf1\x872Q0907572AA\xf1\x890396', From 5831c05a11fbbab79cbd0c9d842b8931929b6268 Mon Sep 17 00:00:00 2001 From: Narayan Babu Date: Sat, 16 Sep 2023 12:49:20 +0530 Subject: [PATCH 54/59] Add Tiguan 2019 fingerprint (#29892) * Added new ECU fingerprints * Update values.py formatting, syntax --- selfdrive/car/volkswagen/values.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index 4ea9e1ddf8..a5ed3744a5 100644 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -822,6 +822,7 @@ FW_VERSIONS = { b'\xf1\x875NA906259H \xf1\x890002', b'\xf1\x875NA907115E \xf1\x890003', b'\xf1\x875NA907115E \xf1\x890005', + b'\xf1\x875NA907115J \xf1\x890002', b'\xf1\x8783A907115B \xf1\x890005', b'\xf1\x8783A907115F \xf1\x890002', b'\xf1\x8783A907115G \xf1\x890001', @@ -845,12 +846,14 @@ FW_VERSIONS = { b'\xf1\x870DL300013G \xf1\x892120', b'\xf1\x870DL300014C \xf1\x893703', b'\xf1\x870DD300046K \xf1\x892302', + b'\xf1\x870GC300013P \xf1\x892401', ], (Ecu.srs, 0x715, None): [ b'\xf1\x875Q0959655AR\xf1\x890317\xf1\x82\02331310031333334313132573732379333313100', b'\xf1\x875Q0959655BJ\xf1\x890336\xf1\x82\x1312110031333300314232583732379333423100', b'\xf1\x875Q0959655BJ\xf1\x890339\xf1\x82\x1331310031333334313132013730379333423100', b'\xf1\x875Q0959655BM\xf1\x890403\xf1\x82\02316143231313500314641011750179333423100', + b'\xf1\x875Q0959655BS\xf1\x890403\xf1\x82\x1312110031333300314240013750379333423100', b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\02312110031333300314240583752379333423100', b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\02331310031333336313140013950399333423100', b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\x1331310031333334313140013750379333423100', From 5cb4e8352885aec86b800f3e981571a175f3b931 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Sat, 16 Sep 2023 15:11:09 -0700 Subject: [PATCH 55/59] ruff: check mutable default values for data class attributes (#29945) * Update pyproject.toml * Update pyproject.toml --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a314c9e647..a69cd28e4d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -172,7 +172,7 @@ build-backend = "poetry.core.masonry.api" # https://beta.ruff.rs/docs/configuration/#using-pyprojecttoml [tool.ruff] -select = ["E", "F", "W", "PIE", "C4", "ISC", "RUF100", "A", "B", "TID251"] +select = ["E", "F", "W", "PIE", "C4", "ISC", "RUF008", "RUF100", "A", "B", "TID251"] ignore = ["W292", "E741", "E402", "C408", "ISC003", "B027", "B024"] line-length = 160 target-version="py311" @@ -190,4 +190,4 @@ flake8-implicit-str-concat.allow-multiline=false "common".msg = "Use openpilot.common" "system".msg = "Use openpilot.system" "third_party".msg = "Use openpilot.third_party" -"tools".msg = "Use openpilot.tools" \ No newline at end of file +"tools".msg = "Use openpilot.tools" From 079a51cfdff8e79aa4e85d8e3c70285c0a7ab2e0 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 17 Sep 2023 15:16:07 -0700 Subject: [PATCH 56/59] Revert "CI: login to dockerhub on aarch64 runners (#29915)" This reverts commit c9ec7bc2a3de1bd889d9034bd9336a4f65d36e23. --- .github/workflows/prebuilt.yaml | 4 ++-- .github/workflows/selfdrive_tests.yaml | 17 +++-------------- .github/workflows/tools_tests.yaml | 6 +++--- 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/.github/workflows/prebuilt.yaml b/.github/workflows/prebuilt.yaml index 3558d7eb7e..8b16ea90b9 100644 --- a/.github/workflows/prebuilt.yaml +++ b/.github/workflows/prebuilt.yaml @@ -5,7 +5,7 @@ on: workflow_dispatch: env: - DOCKER_GHCR_LOGIN: docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} + DOCKER_LOGIN: docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} BUILD: selfdrive/test/docker_build.sh prebuilt jobs: @@ -29,5 +29,5 @@ jobs: submodules: true - name: Build and Push docker image run: | - $DOCKER_GHCR_LOGIN + $DOCKER_LOGIN eval "$BUILD" diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index 6fd2ca8556..9b2b565547 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -16,8 +16,7 @@ env: CL_BASE_IMAGE: openpilot-base-cl AZURE_TOKEN: ${{ secrets.AZURE_COMMADATACI_OPENPILOTCI_TOKEN }} - DOCKER_GHCR_LOGIN: docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} - DOCKER_HUB_LOGIN: docker login -u adeebshihadeh -p ${{ secrets.DOCKER_HUB_PAT }} + DOCKER_LOGIN: docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} BUILD: selfdrive/test/docker_build.sh base RUN: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONWARNINGS=error -e FILEREADER_CACHE=1 -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v $GITHUB_WORKSPACE/.ci_cache/scons_cache:/tmp/scons_cache -v $GITHUB_WORKSPACE/.ci_cache/comma_download_cache:/tmp/comma_download_cache -v $GITHUB_WORKSPACE/.ci_cache/openpilot_cache:/tmp/openpilot_cache $BASE_IMAGE /bin/sh -c @@ -77,11 +76,6 @@ jobs: - uses: actions/checkout@v3 with: submodules: true - # login only on arm machines, due to buildjet rate limits - - name: Setup docker - if: contains(runner.name, 'buildjet') - run: | - $DOCKER_HUB_LOGIN - uses: ./.github/workflows/setup-with-retry with: cache_key_prefix: scons_${{ matrix.arch }} @@ -196,12 +190,7 @@ jobs: run: | echo "PUSH_IMAGE=true" >> "$GITHUB_ENV" echo "TARGET_ARCHITECTURE=${{ matrix.arch }}" >> "$GITHUB_ENV" - $DOCKER_GHCR_LOGIN - # login only on arm machines, due to buildjet rate limits - - name: Additional setup for buildjet - if: contains(runner.name, 'buildjet') - run: | - $DOCKER_HUB_LOGIN + $DOCKER_LOGIN - uses: ./.github/workflows/setup-with-retry with: git-lfs: false @@ -222,7 +211,7 @@ jobs: submodules: false - name: Setup docker run: | - $DOCKER_GHCR_LOGIN + $DOCKER_LOGIN - name: Merge x64 and arm64 tags run: | export PUSH_IMAGE=true diff --git a/.github/workflows/tools_tests.yaml b/.github/workflows/tools_tests.yaml index 27c362fcd6..c7a5f80c3b 100644 --- a/.github/workflows/tools_tests.yaml +++ b/.github/workflows/tools_tests.yaml @@ -13,7 +13,7 @@ concurrency: env: BASE_IMAGE: openpilot-base CL_BASE_IMAGE: openpilot-base-cl - DOCKER_GHCR_LOGIN: docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} + DOCKER_LOGIN: docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} BUILD: selfdrive/test/docker_build.sh base @@ -58,7 +58,7 @@ jobs: if: github.ref == 'refs/heads/master' && github.repository == 'commaai/openpilot' run: | echo "PUSH_IMAGE=true" >> "$GITHUB_ENV" - $DOCKER_GHCR_LOGIN + $DOCKER_LOGIN - name: Build and push sim image run: | selfdrive/test/docker_build.sh sim @@ -78,7 +78,7 @@ jobs: if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'commaai/openpilot' run: | echo "PUSH_IMAGE=true" >> "$GITHUB_ENV" - $DOCKER_GHCR_LOGIN + $DOCKER_LOGIN - name: Build and push docs image run: | selfdrive/test/docker_build.sh docs From 8a0711a67d8bc00913db841f65f443e7472fd699 Mon Sep 17 00:00:00 2001 From: Alexandre Nobuharu Sato <66435071+AlexandreSato@users.noreply.github.com> Date: Sun, 17 Sep 2023 19:19:43 -0300 Subject: [PATCH 57/59] Duplicated #include in settings.cc (#29951) --- selfdrive/ui/qt/offroad/settings.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index 0af027ca90..f74e671d29 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -22,7 +22,6 @@ #include "selfdrive/ui/ui.h" #include "selfdrive/ui/qt/util.h" #include "selfdrive/ui/qt/qt_window.h" -#include "selfdrive/ui/qt/widgets/input.h" TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) { // param, title, desc, icon From 6f9798745c73e82fa4ed396e697d44947b527e68 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Mon, 18 Sep 2023 06:20:21 +0800 Subject: [PATCH 58/59] cabana: add button to skip to the end of stream (#29953) --- tools/cabana/videowidget.cc | 20 +++++++++++++++++--- tools/cabana/videowidget.h | 1 + 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/tools/cabana/videowidget.cc b/tools/cabana/videowidget.cc index 098f26841c..e7845bca47 100644 --- a/tools/cabana/videowidget.cc +++ b/tools/cabana/videowidget.cc @@ -35,13 +35,24 @@ VideoWidget::VideoWidget(QWidget *parent) : QFrame(parent) { } // btn controls + QButtonGroup *group = new QButtonGroup(this); + group->setExclusive(true); + QHBoxLayout *control_layout = new QHBoxLayout(); play_btn = new QPushButton(); play_btn->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); control_layout->addWidget(play_btn); + if (can->liveStreaming()) { + control_layout->addWidget(skip_to_end_btn = new QPushButton(utils::icon("skip-end-fill"), {})); + skip_to_end_btn->setToolTip(tr("Skip to the end")); + QObject::connect(skip_to_end_btn, &QPushButton::clicked, [group]() { + // set speed to 1.0 + group->buttons()[2]->click(); + can->pause(false); + can->seekTo(can->totalSeconds() + 1); + }); + } - QButtonGroup *group = new QButtonGroup(this); - group->setExclusive(true); for (float speed : {0.1, 0.5, 1., 2.}) { QPushButton *btn = new QPushButton(QString("%1x").arg(speed), this); btn->setCheckable(true); @@ -121,7 +132,10 @@ void VideoWidget::setMaximumTime(double sec) { } void VideoWidget::updateTimeRange(double min, double max, bool is_zoomed) { - if (can->liveStreaming()) return; + if (can->liveStreaming()) { + skip_to_end_btn->setEnabled(!is_zoomed); + return; + } if (!is_zoomed) { min = 0; diff --git a/tools/cabana/videowidget.h b/tools/cabana/videowidget.h index c17dd67e2a..bece039a21 100644 --- a/tools/cabana/videowidget.h +++ b/tools/cabana/videowidget.h @@ -81,6 +81,7 @@ protected: QLabel *end_time_label; QLabel *time_label; QPushButton *play_btn; + QPushButton *skip_to_end_btn = nullptr; InfoLabel *alert_label; Slider *slider; }; From 844b2815d535b444534c33e841a1f0fab2470b53 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 17 Sep 2023 15:44:03 -0700 Subject: [PATCH 59/59] add ruff package --- poetry.lock | 28 +++++++++++++++++++++++++++- pyproject.toml | 1 + 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index 0f0f587fd1..fe2beb4b35 100644 --- a/poetry.lock +++ b/poetry.lock @@ -4119,6 +4119,32 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "ruff" +version = "0.0.290" +description = "An extremely fast Python linter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.0.290-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:0e2b09ac4213b11a3520221083866a5816616f3ae9da123037b8ab275066fbac"}, + {file = "ruff-0.0.290-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:4ca6285aa77b3d966be32c9a3cd531655b3d4a0171e1f9bf26d66d0372186767"}, + {file = "ruff-0.0.290-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35e3550d1d9f2157b0fcc77670f7bb59154f223bff281766e61bdd1dd854e0c5"}, + {file = "ruff-0.0.290-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d748c8bd97874f5751aed73e8dde379ce32d16338123d07c18b25c9a2796574a"}, + {file = "ruff-0.0.290-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:982af5ec67cecd099e2ef5e238650407fb40d56304910102d054c109f390bf3c"}, + {file = "ruff-0.0.290-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:bbd37352cea4ee007c48a44c9bc45a21f7ba70a57edfe46842e346651e2b995a"}, + {file = "ruff-0.0.290-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d9be6351b7889462912e0b8185a260c0219c35dfd920fb490c7f256f1d8313e"}, + {file = "ruff-0.0.290-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75cdc7fe32dcf33b7cec306707552dda54632ac29402775b9e212a3c16aad5e6"}, + {file = "ruff-0.0.290-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb07f37f7aecdbbc91d759c0c09870ce0fb3eed4025eebedf9c4b98c69abd527"}, + {file = "ruff-0.0.290-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:2ab41bc0ba359d3f715fc7b705bdeef19c0461351306b70a4e247f836b9350ed"}, + {file = "ruff-0.0.290-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:150bf8050214cea5b990945b66433bf9a5e0cef395c9bc0f50569e7de7540c86"}, + {file = "ruff-0.0.290-py3-none-musllinux_1_2_i686.whl", hash = "sha256:75386ebc15fe5467248c039f5bf6a0cfe7bfc619ffbb8cd62406cd8811815fca"}, + {file = "ruff-0.0.290-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:ac93eadf07bc4ab4c48d8bb4e427bf0f58f3a9c578862eb85d99d704669f5da0"}, + {file = "ruff-0.0.290-py3-none-win32.whl", hash = "sha256:461fbd1fb9ca806d4e3d5c745a30e185f7cf3ca77293cdc17abb2f2a990ad3f7"}, + {file = "ruff-0.0.290-py3-none-win_amd64.whl", hash = "sha256:f1f49f5ec967fd5778813780b12a5650ab0ebcb9ddcca28d642c689b36920796"}, + {file = "ruff-0.0.290-py3-none-win_arm64.whl", hash = "sha256:ae5a92dfbdf1f0c689433c223f8dac0782c2b2584bd502dfdbc76475669f1ba1"}, + {file = "ruff-0.0.290.tar.gz", hash = "sha256:949fecbc5467bb11b8db810a7fa53c7e02633856ee6bd1302b2f43adcd71b88d"}, +] + [[package]] name = "scipy" version = "1.11.2" @@ -5081,4 +5107,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "~3.11" -content-hash = "6c93bf910082c9de645e00f036ebbce8cb1e658fb0b74f435ec3120e17acacca" +content-hash = "80bd9226bb8fc61c75fe8047c55ba2da3919bc8d9b32a8154ec0a40f9fe2a18e" diff --git a/pyproject.toml b/pyproject.toml index a69cd28e4d..bc28ed1da1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -151,6 +151,7 @@ pytest-subtests = "*" pytest-xdist = "*" pytest-timeout = "*" pytest-timeouts = "*" +ruff = "*" scipy = "*" sphinx = "*" sphinx-rtd-theme = "*"