From cace242433519399eb9c1e19f10d32ed8657ab48 Mon Sep 17 00:00:00 2001 From: commaci-public <60409688+commaci-public@users.noreply.github.com> Date: Sat, 1 Mar 2025 00:50:08 -0800 Subject: [PATCH 01/78] [bot] Update Python packages (#34739) Update Python packages Co-authored-by: Vehicle Researcher --- opendbc_repo | 2 +- panda | 2 +- uv.lock | 72 ++++++++++++++++++++++++++-------------------------- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/opendbc_repo b/opendbc_repo index b5f6d5c498..f8d9760e7e 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit b5f6d5c4982131c3a28acd7f9db7548ef1fb1414 +Subproject commit f8d9760e7e3ac2ef00da0c0261b0c6c24e94659f diff --git a/panda b/panda index a744fa7780..2c802449fd 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit a744fa778010b4689cc01f3bcf803b4becb80c22 +Subproject commit 2c802449fd51d9904ca265d06b7a5f9969057ae3 diff --git a/uv.lock b/uv.lock index 3923154ec6..fa933d5491 100644 --- a/uv.lock +++ b/uv.lock @@ -902,7 +902,7 @@ wheels = [ [[package]] name = "matplotlib" -version = "3.10.0" +version = "3.10.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "contourpy" }, @@ -915,20 +915,20 @@ dependencies = [ { name = "pyparsing" }, { name = "python-dateutil" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/68/dd/fa2e1a45fce2d09f4aea3cee169760e672c8262325aa5796c49d543dc7e6/matplotlib-3.10.0.tar.gz", hash = "sha256:b886d02a581b96704c9d1ffe55709e49b4d2d52709ccebc4be42db856e511278", size = 36686418 } +sdist = { url = "https://files.pythonhosted.org/packages/2f/08/b89867ecea2e305f408fbb417139a8dd941ecf7b23a2e02157c36da546f0/matplotlib-3.10.1.tar.gz", hash = "sha256:e8d2d0e3881b129268585bf4765ad3ee73a4591d77b9a18c214ac7e3a79fb2ba", size = 36743335 } wheels = [ - { url = "https://files.pythonhosted.org/packages/0c/f1/e37f6c84d252867d7ddc418fff70fc661cfd363179263b08e52e8b748e30/matplotlib-3.10.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:fd44fc75522f58612ec4a33958a7e5552562b7705b42ef1b4f8c0818e304a363", size = 8171677 }, - { url = "https://files.pythonhosted.org/packages/c7/8b/92e9da1f28310a1f6572b5c55097b0c0ceb5e27486d85fb73b54f5a9b939/matplotlib-3.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c58a9622d5dbeb668f407f35f4e6bfac34bb9ecdcc81680c04d0258169747997", size = 8044945 }, - { url = "https://files.pythonhosted.org/packages/c5/cb/49e83f0fd066937a5bd3bc5c5d63093703f3637b2824df8d856e0558beef/matplotlib-3.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:845d96568ec873be63f25fa80e9e7fae4be854a66a7e2f0c8ccc99e94a8bd4ef", size = 8458269 }, - { url = "https://files.pythonhosted.org/packages/b2/7d/2d873209536b9ee17340754118a2a17988bc18981b5b56e6715ee07373ac/matplotlib-3.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5439f4c5a3e2e8eab18e2f8c3ef929772fd5641876db71f08127eed95ab64683", size = 8599369 }, - { url = "https://files.pythonhosted.org/packages/b8/03/57d6cbbe85c61fe4cbb7c94b54dce443d68c21961830833a1f34d056e5ea/matplotlib-3.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4673ff67a36152c48ddeaf1135e74ce0d4bce1bbf836ae40ed39c29edf7e2765", size = 9405992 }, - { url = "https://files.pythonhosted.org/packages/14/cf/e382598f98be11bf51dd0bc60eca44a517f6793e3dc8b9d53634a144620c/matplotlib-3.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:7e8632baebb058555ac0cde75db885c61f1212e47723d63921879806b40bec6a", size = 8034580 }, - { url = "https://files.pythonhosted.org/packages/44/c7/6b2d8cb7cc251d53c976799cacd3200add56351c175ba89ab9cbd7c1e68a/matplotlib-3.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4659665bc7c9b58f8c00317c3c2a299f7f258eeae5a5d56b4c64226fca2f7c59", size = 8172465 }, - { url = "https://files.pythonhosted.org/packages/42/2a/6d66d0fba41e13e9ca6512a0a51170f43e7e7ed3a8dfa036324100775612/matplotlib-3.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d44cb942af1693cced2604c33a9abcef6205601c445f6d0dc531d813af8a2f5a", size = 8043300 }, - { url = "https://files.pythonhosted.org/packages/90/60/2a60342b27b90a16bada939a85e29589902b41073f59668b904b15ea666c/matplotlib-3.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a994f29e968ca002b50982b27168addfd65f0105610b6be7fa515ca4b5307c95", size = 8448936 }, - { url = "https://files.pythonhosted.org/packages/a7/b2/d872fc3d753516870d520595ddd8ce4dd44fa797a240999f125f58521ad7/matplotlib-3.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b0558bae37f154fffda54d779a592bc97ca8b4701f1c710055b609a3bac44c8", size = 8594151 }, - { url = "https://files.pythonhosted.org/packages/f4/bd/b2f60cf7f57d014ab33e4f74602a2b5bdc657976db8196bbc022185f6f9c/matplotlib-3.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:503feb23bd8c8acc75541548a1d709c059b7184cde26314896e10a9f14df5f12", size = 9400347 }, - { url = "https://files.pythonhosted.org/packages/9f/6e/264673e64001b99d747aff5a288eca82826c024437a3694e19aed1decf46/matplotlib-3.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:c40ba2eb08b3f5de88152c2333c58cee7edcead0a2a0d60fcafa116b17117adc", size = 8039144 }, + { url = "https://files.pythonhosted.org/packages/a5/14/a1b840075be247bb1834b22c1e1d558740b0f618fe3a823740181ca557a1/matplotlib-3.10.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:057206ff2d6ab82ff3e94ebd94463d084760ca682ed5f150817b859372ec4401", size = 8174669 }, + { url = "https://files.pythonhosted.org/packages/0a/e4/300b08e3e08f9c98b0d5635f42edabf2f7a1d634e64cb0318a71a44ff720/matplotlib-3.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a144867dd6bf8ba8cb5fc81a158b645037e11b3e5cf8a50bd5f9917cb863adfe", size = 8047996 }, + { url = "https://files.pythonhosted.org/packages/75/f9/8d99ff5a2498a5f1ccf919fb46fb945109623c6108216f10f96428f388bc/matplotlib-3.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56c5d9fcd9879aa8040f196a235e2dcbdf7dd03ab5b07c0696f80bc6cf04bedd", size = 8461612 }, + { url = "https://files.pythonhosted.org/packages/40/b8/53fa08a5eaf78d3a7213fd6da1feec4bae14a81d9805e567013811ff0e85/matplotlib-3.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f69dc9713e4ad2fb21a1c30e37bd445d496524257dfda40ff4a8efb3604ab5c", size = 8602258 }, + { url = "https://files.pythonhosted.org/packages/40/87/4397d2ce808467af86684a622dd112664553e81752ea8bf61bdd89d24a41/matplotlib-3.10.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4c59af3e8aca75d7744b68e8e78a669e91ccbcf1ac35d0102a7b1b46883f1dd7", size = 9408896 }, + { url = "https://files.pythonhosted.org/packages/d7/68/0d03098b3feb786cbd494df0aac15b571effda7f7cbdec267e8a8d398c16/matplotlib-3.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:11b65088c6f3dae784bc72e8d039a2580186285f87448babb9ddb2ad0082993a", size = 8061281 }, + { url = "https://files.pythonhosted.org/packages/7c/1d/5e0dc3b59c034e43de16f94deb68f4ad8a96b3ea00f4b37c160b7474928e/matplotlib-3.10.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:66e907a06e68cb6cfd652c193311d61a12b54f56809cafbed9736ce5ad92f107", size = 8175488 }, + { url = "https://files.pythonhosted.org/packages/7a/81/dae7e14042e74da658c3336ab9799128e09a1ee03964f2d89630b5d12106/matplotlib-3.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b4bb156abb8fa5e5b2b460196f7db7264fc6d62678c03457979e7d5254b7be", size = 8046264 }, + { url = "https://files.pythonhosted.org/packages/21/c4/22516775dcde10fc9c9571d155f90710761b028fc44f660508106c363c97/matplotlib-3.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1985ad3d97f51307a2cbfc801a930f120def19ba22864182dacef55277102ba6", size = 8452048 }, + { url = "https://files.pythonhosted.org/packages/63/23/c0615001f67ce7c96b3051d856baedc0c818a2ed84570b9bf9bde200f85d/matplotlib-3.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c96f2c2f825d1257e437a1482c5a2cf4fee15db4261bd6fc0750f81ba2b4ba3d", size = 8597111 }, + { url = "https://files.pythonhosted.org/packages/ca/c0/a07939a82aed77770514348f4568177d7dadab9787ebc618a616fe3d665e/matplotlib-3.10.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:35e87384ee9e488d8dd5a2dd7baf471178d38b90618d8ea147aced4ab59c9bea", size = 9402771 }, + { url = "https://files.pythonhosted.org/packages/a6/b6/a9405484fb40746fdc6ae4502b16a9d6e53282ba5baaf9ebe2da579f68c4/matplotlib-3.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:cfd414bce89cc78a7e1d25202e979b3f1af799e416010a20ab2b5ebb3a02425c", size = 8063742 }, ] [[package]] @@ -4678,27 +4678,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.9.7" +version = "0.9.9" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/39/8b/a86c300359861b186f18359adf4437ac8e4c52e42daa9eedc731ef9d5b53/ruff-0.9.7.tar.gz", hash = "sha256:643757633417907510157b206e490c3aa11cab0c087c912f60e07fbafa87a4c6", size = 3669813 } +sdist = { url = "https://files.pythonhosted.org/packages/6f/c3/418441a8170e8d53d05c0b9dad69760dbc7b8a12c10dbe6db1e1205d2377/ruff-0.9.9.tar.gz", hash = "sha256:0062ed13f22173e85f8f7056f9a24016e692efeea8704d1a5e8011b8aa850933", size = 3717448 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/f3/3a1d22973291226df4b4e2ff70196b926b6f910c488479adb0eeb42a0d7f/ruff-0.9.7-py3-none-linux_armv6l.whl", hash = "sha256:99d50def47305fe6f233eb8dabfd60047578ca87c9dcb235c9723ab1175180f4", size = 11774588 }, - { url = "https://files.pythonhosted.org/packages/8e/c9/b881f4157b9b884f2994fd08ee92ae3663fb24e34b0372ac3af999aa7fc6/ruff-0.9.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:d59105ae9c44152c3d40a9c40d6331a7acd1cdf5ef404fbe31178a77b174ea66", size = 11746848 }, - { url = "https://files.pythonhosted.org/packages/14/89/2f546c133f73886ed50a3d449e6bf4af27d92d2f960a43a93d89353f0945/ruff-0.9.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f313b5800483770bd540cddac7c90fc46f895f427b7820f18fe1822697f1fec9", size = 11177525 }, - { url = "https://files.pythonhosted.org/packages/d7/93/6b98f2c12bf28ab9def59c50c9c49508519c5b5cfecca6de871cf01237f6/ruff-0.9.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:042ae32b41343888f59c0a4148f103208bf6b21c90118d51dc93a68366f4e903", size = 11996580 }, - { url = "https://files.pythonhosted.org/packages/8e/3f/b3fcaf4f6d875e679ac2b71a72f6691a8128ea3cb7be07cbb249f477c061/ruff-0.9.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:87862589373b33cc484b10831004e5e5ec47dc10d2b41ba770e837d4f429d721", size = 11525674 }, - { url = "https://files.pythonhosted.org/packages/f0/48/33fbf18defb74d624535d5d22adcb09a64c9bbabfa755bc666189a6b2210/ruff-0.9.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a17e1e01bee0926d351a1ee9bc15c445beae888f90069a6192a07a84af544b6b", size = 12739151 }, - { url = "https://files.pythonhosted.org/packages/63/b5/7e161080c5e19fa69495cbab7c00975ef8a90f3679caa6164921d7f52f4a/ruff-0.9.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7c1f880ac5b2cbebd58b8ebde57069a374865c73f3bf41f05fe7a179c1c8ef22", size = 13416128 }, - { url = "https://files.pythonhosted.org/packages/4e/c8/b5e7d61fb1c1b26f271ac301ff6d9de5e4d9a9a63f67d732fa8f200f0c88/ruff-0.9.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e63fc20143c291cab2841dbb8260e96bafbe1ba13fd3d60d28be2c71e312da49", size = 12870858 }, - { url = "https://files.pythonhosted.org/packages/da/cb/2a1a8e4e291a54d28259f8fc6a674cd5b8833e93852c7ef5de436d6ed729/ruff-0.9.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91ff963baed3e9a6a4eba2a02f4ca8eaa6eba1cc0521aec0987da8d62f53cbef", size = 14786046 }, - { url = "https://files.pythonhosted.org/packages/ca/6c/c8f8a313be1943f333f376d79724260da5701426c0905762e3ddb389e3f4/ruff-0.9.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88362e3227c82f63eaebf0b2eff5b88990280fb1ecf7105523883ba8c3aaf6fb", size = 12550834 }, - { url = "https://files.pythonhosted.org/packages/9d/ad/f70cf5e8e7c52a25e166bdc84c082163c9c6f82a073f654c321b4dff9660/ruff-0.9.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0372c5a90349f00212270421fe91874b866fd3626eb3b397ede06cd385f6f7e0", size = 11961307 }, - { url = "https://files.pythonhosted.org/packages/52/d5/4f303ea94a5f4f454daf4d02671b1fbfe2a318b5fcd009f957466f936c50/ruff-0.9.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d76b8ab60e99e6424cd9d3d923274a1324aefce04f8ea537136b8398bbae0a62", size = 11612039 }, - { url = "https://files.pythonhosted.org/packages/eb/c8/bd12a23a75603c704ce86723be0648ba3d4ecc2af07eecd2e9fa112f7e19/ruff-0.9.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0c439bdfc8983e1336577f00e09a4e7a78944fe01e4ea7fe616d00c3ec69a3d0", size = 12168177 }, - { url = "https://files.pythonhosted.org/packages/cc/57/d648d4f73400fef047d62d464d1a14591f2e6b3d4a15e93e23a53c20705d/ruff-0.9.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:115d1f15e8fdd445a7b4dc9a30abae22de3f6bcabeb503964904471691ef7606", size = 12610122 }, - { url = "https://files.pythonhosted.org/packages/49/79/acbc1edd03ac0e2a04ae2593555dbc9990b34090a9729a0c4c0cf20fb595/ruff-0.9.7-py3-none-win32.whl", hash = "sha256:e9ece95b7de5923cbf38893f066ed2872be2f2f477ba94f826c8defdd6ec6b7d", size = 9988751 }, - { url = "https://files.pythonhosted.org/packages/6d/95/67153a838c6b6ba7a2401241fd8a00cd8c627a8e4a0491b8d853dedeffe0/ruff-0.9.7-py3-none-win_amd64.whl", hash = "sha256:3770fe52b9d691a15f0b87ada29c45324b2ace8f01200fb0c14845e499eb0c2c", size = 11002987 }, - { url = "https://files.pythonhosted.org/packages/63/6a/aca01554949f3a401991dc32fe22837baeaccb8a0d868256cbb26a029778/ruff-0.9.7-py3-none-win_arm64.whl", hash = "sha256:b075a700b2533feb7a01130ff656a4ec0d5f340bb540ad98759b8401c32c2037", size = 10177763 }, + { url = "https://files.pythonhosted.org/packages/bc/c3/2c4afa9ba467555d074b146d9aed0633a56ccdb900839fb008295d037b89/ruff-0.9.9-py3-none-linux_armv6l.whl", hash = "sha256:628abb5ea10345e53dff55b167595a159d3e174d6720bf19761f5e467e68d367", size = 10027252 }, + { url = "https://files.pythonhosted.org/packages/33/d1/439e58487cf9eac26378332e25e7d5ade4b800ce1eec7dc2cfc9b0d7ca96/ruff-0.9.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b6cd1428e834b35d7493354723543b28cc11dc14d1ce19b685f6e68e07c05ec7", size = 10840721 }, + { url = "https://files.pythonhosted.org/packages/50/44/fead822c38281ba0122f1b76b460488a175a9bd48b130650a6fb6dbcbcf9/ruff-0.9.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5ee162652869120ad260670706f3cd36cd3f32b0c651f02b6da142652c54941d", size = 10161439 }, + { url = "https://files.pythonhosted.org/packages/11/ae/d404a2ab8e61ddf6342e09cc6b7f7846cce6b243e45c2007dbe0ca928a5d/ruff-0.9.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3aa0f6b75082c9be1ec5a1db78c6d4b02e2375c3068438241dc19c7c306cc61a", size = 10336264 }, + { url = "https://files.pythonhosted.org/packages/6a/4e/7c268aa7d84cd709fb6f046b8972313142cffb40dfff1d2515c5e6288d54/ruff-0.9.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:584cc66e89fb5f80f84b05133dd677a17cdd86901d6479712c96597a3f28e7fe", size = 9908774 }, + { url = "https://files.pythonhosted.org/packages/cc/26/c618a878367ef1b76270fd027ca93692657d3f6122b84ba48911ef5f2edc/ruff-0.9.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abf3369325761a35aba75cd5c55ba1b5eb17d772f12ab168fbfac54be85cf18c", size = 11428127 }, + { url = "https://files.pythonhosted.org/packages/d7/9a/c5588a93d9bfed29f565baf193fe802fa676a0c837938137ea6cf0576d8c/ruff-0.9.9-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3403a53a32a90ce929aa2f758542aca9234befa133e29f4933dcef28a24317be", size = 12133187 }, + { url = "https://files.pythonhosted.org/packages/3e/ff/e7980a7704a60905ed7e156a8d73f604c846d9bd87deda9cabfa6cba073a/ruff-0.9.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:18454e7fa4e4d72cffe28a37cf6a73cb2594f81ec9f4eca31a0aaa9ccdfb1590", size = 11602937 }, + { url = "https://files.pythonhosted.org/packages/24/78/3690444ad9e3cab5c11abe56554c35f005b51d1d118b429765249095269f/ruff-0.9.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fadfe2c88724c9617339f62319ed40dcdadadf2888d5afb88bf3adee7b35bfb", size = 13771698 }, + { url = "https://files.pythonhosted.org/packages/6e/bf/e477c2faf86abe3988e0b5fd22a7f3520e820b2ee335131aca2e16120038/ruff-0.9.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6df104d08c442a1aabcfd254279b8cc1e2cbf41a605aa3e26610ba1ec4acf0b0", size = 11249026 }, + { url = "https://files.pythonhosted.org/packages/f7/82/cdaffd59e5a8cb5b14c408c73d7a555a577cf6645faaf83e52fe99521715/ruff-0.9.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:d7c62939daf5b2a15af48abbd23bea1efdd38c312d6e7c4cedf5a24e03207e17", size = 10220432 }, + { url = "https://files.pythonhosted.org/packages/fe/a4/2507d0026225efa5d4412b6e294dfe54725a78652a5c7e29e6bd0fc492f3/ruff-0.9.9-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:9494ba82a37a4b81b6a798076e4a3251c13243fc37967e998efe4cce58c8a8d1", size = 9874602 }, + { url = "https://files.pythonhosted.org/packages/d5/be/f3aab1813846b476c4bcffe052d232244979c3cd99d751c17afb530ca8e4/ruff-0.9.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:4efd7a96ed6d36ef011ae798bf794c5501a514be369296c672dab7921087fa57", size = 10851212 }, + { url = "https://files.pythonhosted.org/packages/8b/45/8e5fd559bea0d2f57c4e12bf197a2fade2fac465aa518284f157dfbca92b/ruff-0.9.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:ab90a7944c5a1296f3ecb08d1cbf8c2da34c7e68114b1271a431a3ad30cb660e", size = 11327490 }, + { url = "https://files.pythonhosted.org/packages/42/55/e6c90f13880aeef327746052907e7e930681f26a164fe130ddac28b08269/ruff-0.9.9-py3-none-win32.whl", hash = "sha256:6b4c376d929c25ecd6d87e182a230fa4377b8e5125a4ff52d506ee8c087153c1", size = 10227912 }, + { url = "https://files.pythonhosted.org/packages/35/b2/da925693cb82a1208aa34966c0f36cb222baca94e729dd22a587bc22d0f3/ruff-0.9.9-py3-none-win_amd64.whl", hash = "sha256:837982ea24091d4c1700ddb2f63b7070e5baec508e43b01de013dc7eff974ff1", size = 11355632 }, + { url = "https://files.pythonhosted.org/packages/31/d8/de873d1c1b020d668d8ec9855d390764cb90cf8f6486c0983da52be8b7b7/ruff-0.9.9-py3-none-win_arm64.whl", hash = "sha256:3ac78f127517209fe6d96ab00f3ba97cafe38718b23b1db3e96d8b2d39e37ddf", size = 10435860 }, ] [[package]] @@ -4919,14 +4919,14 @@ wheels = [ [[package]] name = "types-requests" -version = "2.32.0.20241016" +version = "2.32.0.20250301" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fa/3c/4f2a430c01a22abd49a583b6b944173e39e7d01b688190a5618bd59a2e22/types-requests-2.32.0.20241016.tar.gz", hash = "sha256:0d9cad2f27515d0e3e3da7134a1b6f28fb97129d86b867f24d9c726452634d95", size = 18065 } +sdist = { url = "https://files.pythonhosted.org/packages/87/88/365d6b46f1088ddeccbc89c26190c3180088ef6e7c8d162fc619496aab96/types_requests-2.32.0.20250301.tar.gz", hash = "sha256:3d909dc4eaab159c0d964ebe8bfa326a7afb4578d8706408d417e17d61b0c500", size = 22977 } wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/01/485b3026ff90e5190b5e24f1711522e06c79f4a56c8f4b95848ac072e20f/types_requests-2.32.0.20241016-py3-none-any.whl", hash = "sha256:4195d62d6d3e043a4eaaf08ff8a62184584d2e8684e9d2aa178c7915a7da3747", size = 15836 }, + { url = "https://files.pythonhosted.org/packages/b9/c2/e44564e8995dbc1738c2acacb8009d59c8cb19327da95a1b5c5d9cb68364/types_requests-2.32.0.20250301-py3-none-any.whl", hash = "sha256:0003e0124e2cbefefb88222ff822b48616af40c74df83350f599a650c8de483b", size = 20671 }, ] [[package]] From 2d882b716add9b2316760d7e5425cf5e35391b21 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Sun, 2 Mar 2025 02:33:49 +0800 Subject: [PATCH 02/78] replay: update help text with route and service list details (#34743) improve help --- tools/replay/README.md | 4 ++-- tools/replay/main.cc | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/replay/README.md b/tools/replay/README.md index 5e91aae943..f02090c58e 100644 --- a/tools/replay/README.md +++ b/tools/replay/README.md @@ -58,8 +58,8 @@ Mock openpilot components by publishing logged messages. Options: -h, --help Displays this help. - -a, --allow whitelist of services to send - -b, --block blacklist of services to send + -a, --allow whitelist of services to send (comma-separated) + -b, --block blacklist of services to send (comma-separated) -c, --cache cache segments in memory. default is 5 -s, --start start from -x playback . between 0.2 - 3 diff --git a/tools/replay/main.cc b/tools/replay/main.cc index 31493d1486..b33b7fa263 100644 --- a/tools/replay/main.cc +++ b/tools/replay/main.cc @@ -11,10 +11,10 @@ #include "tools/replay/util.h" const std::string helpText = -R"(Usage: replay [options] +R"(Usage: replay [options] [route] Options: - -a, --allow Whitelist of services to send - -b, --block Blacklist of services to send + -a, --allow Whitelist of services to send (comma-separated) + -b, --block Blacklist of services to send (comma-separated) -c, --cache Cache segments in memory. Default is 5 -s, --start Start from -x, --playback Playback From 095088ea9181624d02cd7ff0087ba64eeec5966a Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 1 Mar 2025 13:16:44 -0800 Subject: [PATCH 03/78] Deprecate master-ci (#34744) --- .github/workflows/release.yaml | 2 +- docs/CARS.md | 2 +- docs/contributing/roadmap.md | 2 +- opendbc_repo | 2 +- release/build_devel.sh | 12 ++++++------ selfdrive/ui/qt/offroad/software_settings.cc | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index c86c044772..1dd06f77e9 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -51,4 +51,4 @@ jobs: - name: Push master-ci run: | unset TARGET_DIR - BRANCH=master-ci release/build_devel.sh + BRANCH=__nightly release/build_devel.sh diff --git a/docs/CARS.md b/docs/CARS.md index fa32aec550..a3b1fe6351 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -312,7 +312,7 @@ A supported vehicle is one that just works when you install a comma device. All |Volkswagen|Touran 2016-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,13](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| ### Footnotes -1openpilot Longitudinal Control (Alpha) is available behind a toggle; the toggle is only available in non-release branches such as `devel` or `master-ci`.
+1openpilot Longitudinal Control (Alpha) is available behind a toggle; the toggle is only available in non-release branches such as `devel` or `nightly-dev`.
2By default, this car will use the stock Adaptive Cruise Control (ACC) for longitudinal control. If the Driver Support Unit (DSU) is disconnected, openpilot ACC will replace stock ACC. NOTE: disconnecting the DSU disables Automatic Emergency Braking (AEB).
3Refers only to the Focus Mk4 (C519) available in Europe/China/Taiwan/Australasia, not the Focus Mk3 (C346) in North and South America/Southeast Asia.
42019 Honda Civic 1.6L Diesel Sedan does not have ALC below 12mph.
diff --git a/docs/contributing/roadmap.md b/docs/contributing/roadmap.md index ce50ad5577..7086d85b85 100644 --- a/docs/contributing/roadmap.md +++ b/docs/contributing/roadmap.md @@ -16,7 +16,7 @@ a [learned simulator](https://youtu.be/EqQNZXqzFSI). * Always-on driver monitoring (behind a toggle) * GPS removed from the driving stack * 100KB qlogs -* `master-ci` pushed after 1000 hours of hardware-in-the-loop testing +* `nightly` pushed after 1000 hours of hardware-in-the-loop testing * Car interface code moved into [opendbc](https://github.com/commaai/opendbc) * openpilot on PC for Linux x86, Linux arm64, and Mac (Apple Silicon) diff --git a/opendbc_repo b/opendbc_repo index f8d9760e7e..966df198f0 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit f8d9760e7e3ac2ef00da0c0261b0c6c24e94659f +Subproject commit 966df198f063f0cd9d8f4afa0e68622966457f9a diff --git a/release/build_devel.sh b/release/build_devel.sh index c6d04396fe..666e9f1276 100755 --- a/release/build_devel.sh +++ b/release/build_devel.sh @@ -19,15 +19,15 @@ cd $TARGET_DIR cp -r $SOURCE_DIR/.git $TARGET_DIR pre-commit uninstall || true -echo "[-] bringing master-ci and devel in sync T=$SECONDS" +echo "[-] bringing __nightly and devel in sync T=$SECONDS" cd $TARGET_DIR -git fetch --depth 1 origin master-ci +git fetch --depth 1 origin __nightly git fetch --depth 1 origin devel -git checkout -f --track origin/master-ci -git reset --hard master-ci -git checkout master-ci +git checkout -f --track origin/__nightly +git reset --hard __nightly +git checkout __nightly git reset --hard origin/devel git clean -xdff git lfs uninstall @@ -81,7 +81,7 @@ fi if [ ! -z "$BRANCH" ]; then echo "[-] Pushing to $BRANCH T=$SECONDS" - git push -f origin master-ci:$BRANCH + git push -f origin __nightly:$BRANCH fi echo "[-] done T=$SECONDS, ready at $TARGET_DIR" diff --git a/selfdrive/ui/qt/offroad/software_settings.cc b/selfdrive/ui/qt/offroad/software_settings.cc index 194b723fc9..9bc3fad3c9 100644 --- a/selfdrive/ui/qt/offroad/software_settings.cc +++ b/selfdrive/ui/qt/offroad/software_settings.cc @@ -54,7 +54,7 @@ SoftwarePanel::SoftwarePanel(QWidget* parent) : ListWidget(parent) { connect(targetBranchBtn, &ButtonControl::clicked, [=]() { auto current = params.get("GitBranch"); QStringList branches = QString::fromStdString(params.get("UpdaterAvailableBranches")).split(","); - for (QString b : {current.c_str(), "devel-staging", "devel", "nightly", "nightly-dev", "master-ci", "master"}) { + for (QString b : {current.c_str(), "devel-staging", "devel", "nightly", "nightly-dev", "master"}) { auto i = branches.indexOf(b); if (i >= 0) { branches.removeAt(i); From f50e1baa894b978ea680a04a2aedbb33b2fb6de1 Mon Sep 17 00:00:00 2001 From: Lee Jong Mun <43285072+crwusiz@users.noreply.github.com> Date: Sun, 2 Mar 2025 10:34:38 +0900 Subject: [PATCH 04/78] kor translation update (#34741) --- selfdrive/ui/translations/main_ko.ts | 32 +++++++++++++++------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index cc648a5e39..b497e39f21 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -121,27 +121,27 @@ Longitudinal Maneuver Mode - 롱컨 기동 모드 + 롱컨 제어 모드 openpilot Longitudinal Control (Alpha) - openpilot 가감속 제어 (알파) + openpilot 가감속 제어 (알파) WARNING: openpilot longitudinal control is in alpha for this car and will disable Automatic Emergency Braking (AEB). - 경고: openpilot 가감속 제어 알파 기능으로 차량의 자동긴급제동(AEB)을 비활성화합니다. + 경고: openpilot 가감속 제어 알파 기능으로 차량의 자동긴급제동(AEB)을 비활성화합니다. On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when enabling openpilot longitudinal control alpha. - 이 차량은 openpilot 가감속 제어 대신 기본적으로 차량의 ACC로 가감속을 제어합니다. openpilot의 가감속 제어로 전환하려면 이 기능을 활성화하세요. openpilot 가감속 제어 알파를 활성화하는 경우 실험 모드 활성화를 권장합니다. + 이 차량은 openpilot 가감속 제어 대신 기본적으로 차량의 ACC로 가감속을 제어합니다. openpilot의 가감속 제어로 전환하려면 이 기능을 활성화하세요. openpilot 가감속 제어 알파를 활성화하는 경우 실험 모드 활성화를 권장합니다. Enable ADB - + ADB 사용 ADB (Android Debug Bridge) allows connecting to your device over USB or over the network. See https://docs.comma.ai/how-to/connect-to-comma for more info. - + ADB (안드로이드 디버그 브릿지) USB 또는 네트워크를 통해 장치에 연결할 수 있습니다. 자세한 내용은 https://docs.comma.ai/how-to/connect-to-comma를 참조하세요. @@ -309,25 +309,27 @@ FirehosePanel 🔥 Firehose Mode 🔥 - + 🔥 파이어호스 모드 🔥 Enable Firehose Mode - + 파이어호스 모드 활성화 openpilot learns to drive by watching humans, like you, drive. Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models with better Experimental Mode. - + 오픈파일럿은 여러분과 같은 사람이 운전하는 모습을 보면서 운전하는 법을 배웁니다. + +파이어호스 모드를 사용하면 훈련 데이터 업로드를 최대화하여 오픈파일럿의 주행 모델을 개선할 수 있습니다. 더 많은 데이터는 더 나은 실험 모드를 갖춘 더 큰 모델을 의미합니다. 0% - 5G {0%?} + 0% Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable the toggle<br> 4. Leave it connected for at least 30 minutes<br><br>The toggle turns off once you restart your device. Repeat at least once a week for maximum effectiveness.<br><br><b>FAQ</b><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><i>Do I need to be on Wi-Fi?</i> Yes.<br><i>Do I need to bring the device inside?</i> No, you can enable once you're parked, however your uploads will be limited by your car's battery.<br> - + 다음 단계에 따라 장치를 준비하세요.:<br> 1. 장치를 내부로 가져와 올바른 USB-C 어댑터에 연결하세요.<br> 2. Wi-Fi에 연결하세요.<br> 3. 토글을 활성화하세요.<br> 4. 최소 30분 동안 연결 상태로 두세요.<br><br> 장치를 다시 시작하면 토글이 꺼집니다. 효과를 극대화하려면 적어도 일주일에 한 번씩 반복하세요.<br><br><b>자주 묻는 질문</b><br><i>운전 방법이나 장소가 중요한가요?</i> 아니요, 평소처럼 운전하세요.<br><i>올바른 USB-C 어댑터란 무엇인가요?</i> 휴대폰이나 노트북 고속 충전기라면 어떤 것이든 괜찮습니다.<br><i>Wi-Fi에 연결되어 있어야 하나요?</i> 예.<br><i>장치를 차 안으로 가져와야 하나요?</i> 아니요, 주차한 후에는 활성화할 수 있지만 차량의 배터리에 따라 업로드가 제한됩니다.<br> @@ -664,7 +666,7 @@ This may take up to a minute. Firehose - + 파이어호스 @@ -1142,15 +1144,15 @@ This may take up to a minute. WiFiPromptWidget Open - + 열기 Maximize your training data uploads to improve openpilot's driving models. - + 훈련 데이터 업로드를 최대화하여 오픈파일럿의 주행 모델을 개선하세요. <span style='font-family: "Noto Color Emoji";'>🔥</span> Firehose Mode <span style='font-family: Noto Color Emoji;'>🔥</span> - + <span style='font-family: "Noto Color Emoji";'>🔥</span> 파이어호스 모드 <span style='font-family: Noto Color Emoji;'>🔥</span> From 5067ee1e94d64b16025ef746cb88e82db02f65b8 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 2 Mar 2025 09:45:05 -0800 Subject: [PATCH 05/78] plotjuggler: fix for fork routes --- tools/plotjuggler/juggle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/plotjuggler/juggle.py b/tools/plotjuggler/juggle.py index 66bb9fa404..5b6bd0a418 100755 --- a/tools/plotjuggler/juggle.py +++ b/tools/plotjuggler/juggle.py @@ -75,7 +75,7 @@ def start_juggler(fn=None, dbc=None, layout=None, route_or_segment_name=None, pl def process(can, lr): - return [d for d in lr if can or d.which() not in ['can', 'sendcan']] + return [d for d in lr if can or d.which() not in ['can', 'sendcan'] and not d.which().startswith('customReserved')] def juggle_route(route_or_segment_name, can, layout, dbc, should_migrate): From 38100805bf0d42877d6e321047595a87e859f18b Mon Sep 17 00:00:00 2001 From: Mauricio Alvarez Leon <65101411+BBBmau@users.noreply.github.com> Date: Sun, 2 Mar 2025 10:20:03 -0800 Subject: [PATCH 06/78] move update_translations from scons to GHA (#34481) * remove update_translations from scons * update_translations GHA * working GHA * fix scons fails * job name * remove test_update_translations * cleanup * move to repo-maintenance * Update .github/workflows/repo-maintenance.yaml * bring that back --------- Co-authored-by: Shane Smiskol Co-authored-by: Adeeb Shihadeh --- .github/workflows/repo-maintenance.yaml | 26 +++++++++++++++++++++++++ selfdrive/ui/SConscript | 3 --- selfdrive/ui/tests/test_translations.py | 14 +------------ 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/.github/workflows/repo-maintenance.yaml b/.github/workflows/repo-maintenance.yaml index ab0f3c1bee..3bcb143825 100644 --- a/.github/workflows/repo-maintenance.yaml +++ b/.github/workflows/repo-maintenance.yaml @@ -5,7 +5,33 @@ on: - cron: "0 14 * * 1" # every Monday at 2am UTC (6am PST) workflow_dispatch: +env: + BASE_IMAGE: openpilot-base + BUILD: selfdrive/test/docker_build.sh base + RUN: docker run --shm-size 2G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e CI=1 -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/bash -c + jobs: + update_translations: + runs-on: ubuntu-latest + if: github.repository == 'commaai/openpilot' + steps: + - uses: actions/checkout@v4 + - uses: ./.github/workflows/setup-with-retry + - name: Update translations + run: | + ${{ env.RUN }} "python3 selfdrive/ui/update_translations.py --vanish" + - name: Create Pull Request + uses: peter-evans/create-pull-request@9153d834b60caba6d51c9b9510b087acf9f33f83 + with: + author: Vehicle Researcher + commit-message: "Update translations" + title: "[bot] Update translations" + body: "Automatic PR from repo-maintenance -> update_translations" + branch: "update-translations" + base: "master" + delete-branch: true + labels: bot + package_updates: name: package_updates runs-on: ubuntu-latest diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript index 60c82fa645..8fa4b55ea7 100644 --- a/selfdrive/ui/SConscript +++ b/selfdrive/ui/SConscript @@ -40,12 +40,9 @@ translation_sources = [f"#selfdrive/ui/translations/{l}.ts" for l in languages.v translation_targets = [src.replace(".ts", ".qm") for src in translation_sources] lrelease_bin = 'third_party/qt5/larch64/bin/lrelease' if arch == 'larch64' else 'lrelease' -lupdate = qt_env.Command(translation_sources + ["translations/alerts_generated.h"], qt_src + widgets_src, "selfdrive/ui/update_translations.py") lrelease = qt_env.Command(translation_targets, translation_sources, f"{lrelease_bin} $SOURCES") -qt_env.Depends(lrelease, lupdate) qt_env.NoClean(translation_sources) qt_env.Precious(translation_sources) -qt_env.NoCache(lupdate) # create qrc file for compiled translations to include with assets translations_assets_src = "#selfdrive/assets/translations_assets.qrc" diff --git a/selfdrive/ui/tests/test_translations.py b/selfdrive/ui/tests/test_translations.py index 0967152fa4..09dd7c5d8b 100644 --- a/selfdrive/ui/tests/test_translations.py +++ b/selfdrive/ui/tests/test_translations.py @@ -2,14 +2,12 @@ import pytest import json import os import re -import shutil -import tempfile import xml.etree.ElementTree as ET import string import requests from parameterized import parameterized_class -from openpilot.selfdrive.ui.update_translations import TRANSLATIONS_DIR, LANGUAGES_FILE, update_translations +from openpilot.selfdrive.ui.update_translations import TRANSLATIONS_DIR, LANGUAGES_FILE with open(LANGUAGES_FILE) as f: translation_files = json.load(f) @@ -34,16 +32,6 @@ class TestTranslations: assert os.path.exists(os.path.join(TRANSLATIONS_DIR, f"{self.file}.ts")), \ f"{self.name} has no XML translation file, run selfdrive/ui/update_translations.py" - def test_translations_updated(self): - with tempfile.TemporaryDirectory() as tmpdir: - shutil.copytree(TRANSLATIONS_DIR, tmpdir, dirs_exist_ok=True) - update_translations(translation_files=[self.file], translations_dir=tmpdir) - - cur_translations = self._read_translation_file(TRANSLATIONS_DIR, self.file) - new_translations = self._read_translation_file(tmpdir, self.file) - assert cur_translations == new_translations, \ - f"{self.file} ({self.name}) XML translation file out of date. Run selfdrive/ui/update_translations.py to update the translation files" - @pytest.mark.skip("Only test unfinished translations before going to release") def test_unfinished_translations(self): cur_translations = self._read_translation_file(TRANSLATIONS_DIR, self.file) From 2d9f33cbe2f8e4b5238712850962a9e6e674f6f3 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 2 Mar 2025 12:46:00 -0800 Subject: [PATCH 07/78] detect BASEDIR --- launch_chffrplus.sh | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/launch_chffrplus.sh b/launch_chffrplus.sh index 442a811b16..66f57c2cd1 100755 --- a/launch_chffrplus.sh +++ b/launch_chffrplus.sh @@ -1,13 +1,9 @@ #!/usr/bin/env bash -if [ -z "$BASEDIR" ]; then - BASEDIR="/data/openpilot" -fi - -source "$BASEDIR/launch_env.sh" - DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source "$DIR/launch_env.sh" + function agnos_init { # TODO: move this to agnos sudo rm -f /data/etc/NetworkManager/system-connections/*.nmmeta From 54f1b00447af389f4388b39fa3d3ab28b43bcbd6 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 2 Mar 2025 13:11:38 -0800 Subject: [PATCH 08/78] Log git source commit (#34749) * Log git source commit * strip * fix trim * no trim --- cereal/log.capnp | 4 ++++ common/util.cc | 1 - release/build_devel.sh | 4 ++++ system/loggerd/logger.cc | 4 ++++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/cereal/log.capnp b/cereal/log.capnp index 8aa95ad6e6..78b511ca64 100644 --- a/cereal/log.capnp +++ b/cereal/log.capnp @@ -151,6 +151,10 @@ struct InitData { gitBranch @11 :Text; gitRemote @13 :Text; + # this is source commit for prebuilt branches + gitSrcCommit @23 :Text; + gitSrcCommitDate @24 :Text; + androidProperties @16 :Map(Text, Text); pandaInfo @8 :PandaInfo; diff --git a/common/util.cc b/common/util.cc index 096df85634..a853faed04 100644 --- a/common/util.cc +++ b/common/util.cc @@ -257,7 +257,6 @@ bool ends_with(const std::string& s, const std::string& suffix) { std::string strip(const std::string &str) { auto should_trim = [](unsigned char ch) { - // trim whitespace or a null character return std::isspace(ch) || ch == '\0'; }; diff --git a/release/build_devel.sh b/release/build_devel.sh index 666e9f1276..05dcaafcaa 100755 --- a/release/build_devel.sh +++ b/release/build_devel.sh @@ -51,9 +51,13 @@ rm -f panda/board/obj/panda.bin.signed # include source commit hash and build date in commit GIT_HASH=$(git --git-dir=$SOURCE_DIR/.git rev-parse HEAD) +GIT_COMMIT_DATE=$(git --git-dir=$SOURCE_DIR/.git show --no-patch --format='%ct %ci' HEAD) DATETIME=$(date '+%Y-%m-%dT%H:%M:%S') VERSION=$(cat $SOURCE_DIR/common/version.h | awk -F\" '{print $2}') +echo -n "$GIT_HASH" > git_src_commit +echo -n "$GIT_COMMIT_DATE" > git_src_commit_date + echo "[-] committing version $VERSION T=$SECONDS" git add -f . git status diff --git a/system/loggerd/logger.cc b/system/loggerd/logger.cc index 1461ceaca6..f07aee1596 100644 --- a/system/loggerd/logger.cc +++ b/system/loggerd/logger.cc @@ -50,6 +50,10 @@ kj::Array logger_build_init_data() { init.setPassive(false); init.setDongleId(params_map["DongleId"]); + // for prebuilt branches + init.setGitSrcCommit(util::read_file("../../git_src_commit")); + init.setGitSrcCommitDate(util::read_file("../../git_src_commit_date")); + auto lparams = init.initParams().initEntries(params_map.size()); int j = 0; for (auto& [key, value] : params_map) { From 0abe348283d56271112e368c35ce80bfee431559 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 2 Mar 2025 13:23:33 -0800 Subject: [PATCH 09/78] gc old stuff in modeld --- selfdrive/modeld/tests/dmon_lag/repro.cc | 101 -------------------- selfdrive/modeld/tests/tf_test/build.sh | 2 - selfdrive/modeld/tests/tf_test/main.cc | 69 ------------- selfdrive/modeld/tests/tf_test/pb_loader.py | 8 -- selfdrive/modeld/tests/timing/benchmark.py | 39 -------- 5 files changed, 219 deletions(-) delete mode 100644 selfdrive/modeld/tests/dmon_lag/repro.cc delete mode 100755 selfdrive/modeld/tests/tf_test/build.sh delete mode 100644 selfdrive/modeld/tests/tf_test/main.cc delete mode 100755 selfdrive/modeld/tests/tf_test/pb_loader.py delete mode 100755 selfdrive/modeld/tests/timing/benchmark.py diff --git a/selfdrive/modeld/tests/dmon_lag/repro.cc b/selfdrive/modeld/tests/dmon_lag/repro.cc deleted file mode 100644 index c4c1c65cbe..0000000000 --- a/selfdrive/modeld/tests/dmon_lag/repro.cc +++ /dev/null @@ -1,101 +0,0 @@ -// clang++ -O2 repro.cc && ./a.out - -#include -#include -#include - -#include -#include -#include -#include -#include - -static inline double millis_since_boot() { - struct timespec t; - clock_gettime(CLOCK_BOOTTIME, &t); - return t.tv_sec * 1000.0 + t.tv_nsec * 1e-6; -} - -#define MODEL_WIDTH 320 -#define MODEL_HEIGHT 640 - -// null function still breaks it -#define input_lambda(x) x - -// this is copied from models/dmonitoring.cc, and is the code that triggers the issue -void inner(uint8_t *resized_buf, float *net_input_buf) { - int resized_width = MODEL_WIDTH; - int resized_height = MODEL_HEIGHT; - - // one shot conversion, O(n) anyway - // yuvframe2tensor, normalize - for (int r = 0; r < MODEL_HEIGHT/2; r++) { - for (int c = 0; c < MODEL_WIDTH/2; c++) { - // Y_ul - net_input_buf[(c*MODEL_HEIGHT/2) + r] = input_lambda(resized_buf[(2*r*resized_width) + (2*c)]); - // Y_ur - net_input_buf[(c*MODEL_HEIGHT/2) + r + (2*(MODEL_WIDTH/2)*(MODEL_HEIGHT/2))] = input_lambda(resized_buf[(2*r*resized_width) + (2*c+1)]); - // Y_dl - net_input_buf[(c*MODEL_HEIGHT/2) + r + ((MODEL_WIDTH/2)*(MODEL_HEIGHT/2))] = input_lambda(resized_buf[(2*r*resized_width+1) + (2*c)]); - // Y_dr - net_input_buf[(c*MODEL_HEIGHT/2) + r + (3*(MODEL_WIDTH/2)*(MODEL_HEIGHT/2))] = input_lambda(resized_buf[(2*r*resized_width+1) + (2*c+1)]); - // U - net_input_buf[(c*MODEL_HEIGHT/2) + r + (4*(MODEL_WIDTH/2)*(MODEL_HEIGHT/2))] = input_lambda(resized_buf[(resized_width*resized_height) + (r*resized_width/2) + c]); - // V - net_input_buf[(c*MODEL_HEIGHT/2) + r + (5*(MODEL_WIDTH/2)*(MODEL_HEIGHT/2))] = input_lambda(resized_buf[(resized_width*resized_height) + ((resized_width/2)*(resized_height/2)) + (r*resized_width/2) + c]); - } - } -} - -float trial() { - int resized_width = MODEL_WIDTH; - int resized_height = MODEL_HEIGHT; - - int yuv_buf_len = (MODEL_WIDTH/2) * (MODEL_HEIGHT/2) * 6; // Y|u|v -> y|y|y|y|u|v - - // allocate the buffers - uint8_t *resized_buf = (uint8_t*)malloc(resized_width*resized_height*3/2); - float *net_input_buf = (float*)malloc(yuv_buf_len*sizeof(float)); - printf("allocate -- %p 0x%x -- %p 0x%lx\n", resized_buf, resized_width*resized_height*3/2, net_input_buf, yuv_buf_len*sizeof(float)); - - // test for bad buffers - static int CNT = 20; - float avg = 0.0; - for (int i = 0; i < CNT; i++) { - double s4 = millis_since_boot(); - inner(resized_buf, net_input_buf); - double s5 = millis_since_boot(); - avg += s5-s4; - } - avg /= CNT; - - // once it's bad, it's reliably bad - if (avg > 10) { - printf("HIT %f\n", avg); - printf("BAD\n"); - - for (int i = 0; i < 200; i++) { - double s4 = millis_since_boot(); - inner(resized_buf, net_input_buf); - double s5 = millis_since_boot(); - printf("%.2f ", s5-s4); - } - printf("\n"); - - exit(0); - } - - // don't free so we get a different buffer each time - //free(resized_buf); - //free(net_input_buf); - - return avg; -} - -int main() { - while (true) { - float ret = trial(); - printf("got %f\n", ret); - } -} - diff --git a/selfdrive/modeld/tests/tf_test/build.sh b/selfdrive/modeld/tests/tf_test/build.sh deleted file mode 100755 index df1d24761e..0000000000 --- a/selfdrive/modeld/tests/tf_test/build.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -clang++ -I /home/batman/one/external/tensorflow/include/ -L /home/batman/one/external/tensorflow/lib -Wl,-rpath=/home/batman/one/external/tensorflow/lib main.cc -ltensorflow diff --git a/selfdrive/modeld/tests/tf_test/main.cc b/selfdrive/modeld/tests/tf_test/main.cc deleted file mode 100644 index b00f7f95e8..0000000000 --- a/selfdrive/modeld/tests/tf_test/main.cc +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include -#include -#include "tensorflow/c/c_api.h" - -void* read_file(const char* path, size_t* out_len) { - FILE* f = fopen(path, "r"); - if (!f) { - return NULL; - } - fseek(f, 0, SEEK_END); - long f_len = ftell(f); - rewind(f); - - char* buf = (char*)calloc(f_len, 1); - assert(buf); - - size_t num_read = fread(buf, f_len, 1, f); - fclose(f); - - if (num_read != 1) { - free(buf); - return NULL; - } - - if (out_len) { - *out_len = f_len; - } - - return buf; -} - -static void DeallocateBuffer(void* data, size_t) { - free(data); -} - -int main(int argc, char* argv[]) { - TF_Buffer* buf; - TF_Graph* graph; - TF_Status* status; - char *path = argv[1]; - - // load model - { - size_t model_size; - char tmp[1024]; - snprintf(tmp, sizeof(tmp), "%s.pb", path); - printf("loading model %s\n", tmp); - uint8_t *model_data = (uint8_t *)read_file(tmp, &model_size); - buf = TF_NewBuffer(); - buf->data = model_data; - buf->length = model_size; - buf->data_deallocator = DeallocateBuffer; - printf("loaded model of size %d\n", model_size); - } - - // import graph - status = TF_NewStatus(); - graph = TF_NewGraph(); - TF_ImportGraphDefOptions *opts = TF_NewImportGraphDefOptions(); - TF_GraphImportGraphDef(graph, buf, opts, status); - TF_DeleteImportGraphDefOptions(opts); - TF_DeleteBuffer(buf); - if (TF_GetCode(status) != TF_OK) { - printf("FAIL: %s\n", TF_Message(status)); - } else { - printf("SUCCESS\n"); - } -} diff --git a/selfdrive/modeld/tests/tf_test/pb_loader.py b/selfdrive/modeld/tests/tf_test/pb_loader.py deleted file mode 100755 index 3e476628eb..0000000000 --- a/selfdrive/modeld/tests/tf_test/pb_loader.py +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env python3 -import sys -import tensorflow as tf - -with open(sys.argv[1], "rb") as f: - graph_def = tf.compat.v1.GraphDef() - graph_def.ParseFromString(f.read()) - #tf.io.write_graph(graph_def, '', sys.argv[1]+".try") diff --git a/selfdrive/modeld/tests/timing/benchmark.py b/selfdrive/modeld/tests/timing/benchmark.py deleted file mode 100755 index c629ec2fff..0000000000 --- a/selfdrive/modeld/tests/timing/benchmark.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python3 -# type: ignore - -import os -import time -import numpy as np - -import cereal.messaging as messaging -from openpilot.system.manager.process_config import managed_processes - - -N = int(os.getenv("N", "5")) -TIME = int(os.getenv("TIME", "30")) - -if __name__ == "__main__": - sock = messaging.sub_sock('modelV2', conflate=False, timeout=1000) - - execution_times = [] - - for _ in range(N): - os.environ['LOGPRINT'] = 'debug' - managed_processes['modeld'].start() - time.sleep(5) - - t = [] - start = time.monotonic() - while time.monotonic() - start < TIME: - msgs = messaging.drain_sock(sock, wait_for_one=True) - for m in msgs: - t.append(m.modelV2.modelExecutionTime) - - execution_times.append(np.array(t[10:]) * 1000) - managed_processes['modeld'].stop() - - print("\n\n") - print(f"ran modeld {N} times for {TIME}s each") - for _, t in enumerate(execution_times): - print(f"\tavg: {sum(t)/len(t):0.2f}ms, min: {min(t):0.2f}ms, max: {max(t):0.2f}ms") - print("\n\n") From c32c405f654e3327292834a9191adcec90bff1d3 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 2 Mar 2025 13:39:36 -0800 Subject: [PATCH 10/78] remove model shims (#34750) --- .gitignore | 1 + selfdrive/modeld/.gitignore | 1 - selfdrive/modeld/dmonitoringmodeld | 4 ---- selfdrive/modeld/modeld | 4 ---- system/manager/process_config.py | 9 +++++---- 5 files changed, 6 insertions(+), 13 deletions(-) delete mode 100644 selfdrive/modeld/.gitignore delete mode 100755 selfdrive/modeld/dmonitoringmodeld delete mode 100755 selfdrive/modeld/modeld diff --git a/.gitignore b/.gitignore index 4562e47817..834b463083 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ a.out *.pyxbldc *.vcd *.qm +*_pyx.cpp config.json clcache compile_commands.json diff --git a/selfdrive/modeld/.gitignore b/selfdrive/modeld/.gitignore deleted file mode 100644 index 742d3d1205..0000000000 --- a/selfdrive/modeld/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*_pyx.cpp diff --git a/selfdrive/modeld/dmonitoringmodeld b/selfdrive/modeld/dmonitoringmodeld deleted file mode 100755 index 90b43800fe..0000000000 --- a/selfdrive/modeld/dmonitoringmodeld +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" -exec "$DIR/dmonitoringmodeld.py" "$@" diff --git a/selfdrive/modeld/modeld b/selfdrive/modeld/modeld deleted file mode 100755 index 5ba4688554..0000000000 --- a/selfdrive/modeld/modeld +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" -exec "$DIR/modeld.py" "$@" diff --git a/system/manager/process_config.py b/system/manager/process_config.py index 120390ce5f..96315eeb29 100644 --- a/system/manager/process_config.py +++ b/system/manager/process_config.py @@ -75,10 +75,11 @@ procs = [ PythonProcess("micd", "system.micd", iscar), PythonProcess("timed", "system.timed", always_run, enabled=not PC), - # TODO Make python process once TG allows opening QCOM from child proc - NativeProcess("dmonitoringmodeld", "selfdrive/modeld", ["./dmonitoringmodeld"], driverview, enabled=(WEBCAM or not PC)), - # TODO Make python process once TG allows opening QCOM from child proc - NativeProcess("modeld", "selfdrive/modeld", ["./modeld"], only_onroad), + # TODO: Make python process once TG allows opening QCOM from child pro + # https://github.com/tinygrad/tinygrad/blob/ac9c96dae1656dc220ee4acc39cef4dd449aa850/tinygrad/device.py#L26 + NativeProcess("modeld", "selfdrive/modeld", ["./modeld.py"], only_onroad), + NativeProcess("dmonitoringmodeld", "selfdrive/modeld", ["./dmonitoringmodeld.py"], driverview, enabled=(WEBCAM or not PC)), + NativeProcess("sensord", "system/sensord", ["./sensord"], only_onroad, enabled=not PC), NativeProcess("ui", "selfdrive/ui", ["./ui"], always_run, watchdog_max_dt=(5 if not PC else None)), PythonProcess("soundd", "selfdrive.ui.soundd", only_onroad), From 29ff29bcb50e3f692216bb1441db9e6b58482cd1 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 2 Mar 2025 13:49:19 -0800 Subject: [PATCH 11/78] master-ci is dead --- Jenkinsfile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 330967c657..2609d2fe0f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -166,7 +166,7 @@ node { env.GIT_BRANCH = checkout(scm).GIT_BRANCH env.GIT_COMMIT = checkout(scm).GIT_COMMIT - def excludeBranches = ['master-ci', 'devel', 'devel-staging', 'release3', 'release3-staging', + def excludeBranches = ['__nightly', 'devel', 'devel-staging', 'release3', 'release3-staging', 'testing-closet*', 'hotfix-*'] def excludeRegex = excludeBranches.join('|').replaceAll('\\*', '.*') @@ -183,7 +183,7 @@ node { ]) } - if (env.BRANCH_NAME == 'master-ci') { + if (env.BRANCH_NAME == '__nightly') { parallel ( 'nightly': { deviceStage("build nightly", "tici-needs-can", [], [ @@ -203,8 +203,6 @@ node { // tici tests 'onroad tests': { deviceStage("onroad", "tici-needs-can", ["UNSAFE=1"], [ - // TODO: ideally, this test runs in master-ci, but it takes 5+m to build it - //["build master-ci", "cd $SOURCE_DIR/release && TARGET_DIR=$TEST_DIR $SOURCE_DIR/scripts/retry.sh ./build_devel.sh"], step("build openpilot", "cd system/manager && ./build.py"), step("check dirty", "release/check-dirty.sh"), step("onroad tests", "pytest selfdrive/test/test_onroad.py -s", [timeout: 60]), From e539e34f73c5e86f490acc8282bd47d54532036f Mon Sep 17 00:00:00 2001 From: Maxime Desroches Date: Sun, 2 Mar 2025 16:56:38 -0800 Subject: [PATCH 12/78] ci: only specify scene name once in UI preview test (#34752) remove this garbage --- .github/workflows/ui_preview.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ui_preview.yaml b/.github/workflows/ui_preview.yaml index 7936192ca8..75e6249b76 100644 --- a/.github/workflows/ui_preview.yaml +++ b/.github/workflows/ui_preview.yaml @@ -84,7 +84,7 @@ jobs: run: >- sudo apt-get install -y imagemagick - scenes="homescreen settings_device settings_software settings_toggles settings_developer offroad_alert update_available prime onroad onroad_disengaged onroad_override onroad_sidebar onroad_wide onroad_wide_sidebar onroad_alert_small onroad_alert_mid onroad_alert_full driver_camera body keyboard keyboard_uppercase" + scenes=$(find ${{ github.workspace }}/pr_ui/*.png -type f -printf "%f\n" | cut -d '.' -f 1 | grep -v 'pair_device') A=($scenes) DIFF="" From 2431bc626262037bd8b1409b1121a38104e6d36f Mon Sep 17 00:00:00 2001 From: Maxime Desroches Date: Sun, 2 Mar 2025 17:14:55 -0800 Subject: [PATCH 13/78] ci: fix firehose UI preview position (#34754) prev --- selfdrive/ui/tests/test_ui/run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/ui/tests/test_ui/run.py b/selfdrive/ui/tests/test_ui/run.py index 0c94c04256..35323cf000 100755 --- a/selfdrive/ui/tests/test_ui/run.py +++ b/selfdrive/ui/tests/test_ui/run.py @@ -52,7 +52,7 @@ def setup_settings_software(click, pm: PubMaster): time.sleep(UI_DELAY) def setup_settings_firehose(click, pm: PubMaster): - click(278, 836) + click(1780, 730) def setup_settings_developer(click, pm: PubMaster): CP = car.CarParams() From c52112ad4e4a2543475f7663da633abd02892886 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Mon, 3 Mar 2025 12:01:21 +0800 Subject: [PATCH 14/78] loggerd: eliminate recursion from handle_encoder_msg (#33453) * refactor handle_encoder_msg * removing the recursion only --------- Co-authored-by: Adeeb Shihadeh --- system/loggerd/loggerd.cc | 109 ++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 52 deletions(-) diff --git a/system/loggerd/loggerd.cc b/system/loggerd/loggerd.cc index daf0cc112e..ea0178fe80 100644 --- a/system/loggerd/loggerd.cc +++ b/system/loggerd/loggerd.cc @@ -64,6 +64,58 @@ struct RemoteEncoder { bool seen_first_packet = false; }; +size_t write_encode_data(LoggerdState *s, cereal::Event::Reader event, RemoteEncoder &re, const EncoderInfo &encoder_info) { + auto edata = (event.*(encoder_info.get_encode_data_func))(); + auto idx = edata.getIdx(); + auto flags = idx.getFlags(); + + // if we aren't recording yet, try to start, since we are in the correct segment + if (!re.recording) { + if (flags & V4L2_BUF_FLAG_KEYFRAME) { + // only create on iframe + if (re.dropped_frames) { + // this should only happen for the first segment, maybe + LOGW("%s: dropped %d non iframe packets before init", encoder_info.publish_name, re.dropped_frames); + re.dropped_frames = 0; + } + // if we aren't actually recording, don't create the writer + if (encoder_info.record) { + assert(encoder_info.filename != NULL); + re.writer.reset(new VideoWriter(s->logger.segmentPath().c_str(), + encoder_info.filename, idx.getType() != cereal::EncodeIndex::Type::FULL_H_E_V_C, + edata.getWidth(), edata.getHeight(), encoder_info.fps, idx.getType())); + // write the header + auto header = edata.getHeader(); + re.writer->write((uint8_t *)header.begin(), header.size(), idx.getTimestampEof() / 1000, true, false); + } + re.recording = true; + } else { + // this is a sad case when we aren't recording, but don't have an iframe + // nothing we can do but drop the frame + ++re.dropped_frames; + return 0; + } + } + + // we have to be recording if we are here + assert(re.recording); + + // if we are actually writing the video file, do so + if (re.writer) { + auto data = edata.getData(); + re.writer->write((uint8_t *)data.begin(), data.size(), idx.getTimestampEof() / 1000, false, flags & V4L2_BUF_FLAG_KEYFRAME); + } + + // put it in log stream as the idx packet + MessageBuilder bmsg; + auto evt = bmsg.initEvent(event.getValid()); + evt.setLogMonoTime(event.getLogMonoTime()); + (evt.*(encoder_info.set_encode_idx_func))(idx); + auto new_msg = bmsg.toBytes(); + s->logger.write((uint8_t *)new_msg.begin(), new_msg.size(), true); // always in qlog? + return new_msg.size(); +} + int handle_encoder_msg(LoggerdState *s, Message *msg, std::string &name, struct RemoteEncoder &re, const EncoderInfo &encoder_info) { int bytes_count = 0; @@ -72,7 +124,6 @@ int handle_encoder_msg(LoggerdState *s, Message *msg, std::string &name, struct auto event = cmsg.getRoot(); auto edata = (event.*(encoder_info.get_encode_data_func))(); auto idx = edata.getIdx(); - auto flags = idx.getFlags(); // encoderd can have started long before loggerd if (!re.seen_first_packet) { @@ -95,61 +146,15 @@ int handle_encoder_msg(LoggerdState *s, Message *msg, std::string &name, struct re.marked_ready_to_rotate = false; // we are in this segment now, process any queued messages before this one if (!re.q.empty()) { - for (auto &qmsg : re.q) { - bytes_count += handle_encoder_msg(s, qmsg, name, re, encoder_info); + for (auto qmsg : re.q) { + capnp::FlatArrayMessageReader reader({(capnp::word *)qmsg->getData(), qmsg->getSize() / sizeof(capnp::word)}); + bytes_count += write_encode_data(s, reader.getRoot(), re, encoder_info); + delete qmsg; } re.q.clear(); } } - - // if we aren't recording yet, try to start, since we are in the correct segment - if (!re.recording) { - if (flags & V4L2_BUF_FLAG_KEYFRAME) { - // only create on iframe - if (re.dropped_frames) { - // this should only happen for the first segment, maybe - LOGW("%s: dropped %d non iframe packets before init", name.c_str(), re.dropped_frames); - re.dropped_frames = 0; - } - // if we aren't actually recording, don't create the writer - if (encoder_info.record) { - assert(encoder_info.filename != NULL); - re.writer.reset(new VideoWriter(s->logger.segmentPath().c_str(), - encoder_info.filename, idx.getType() != cereal::EncodeIndex::Type::FULL_H_E_V_C, - edata.getWidth(), edata.getHeight(), encoder_info.fps, idx.getType())); - // write the header - auto header = edata.getHeader(); - re.writer->write((uint8_t *)header.begin(), header.size(), idx.getTimestampEof()/1000, true, false); - } - re.recording = true; - } else { - // this is a sad case when we aren't recording, but don't have an iframe - // nothing we can do but drop the frame - delete msg; - ++re.dropped_frames; - return bytes_count; - } - } - - // we have to be recording if we are here - assert(re.recording); - - // if we are actually writing the video file, do so - if (re.writer) { - auto data = edata.getData(); - re.writer->write((uint8_t *)data.begin(), data.size(), idx.getTimestampEof()/1000, false, flags & V4L2_BUF_FLAG_KEYFRAME); - } - - // put it in log stream as the idx packet - MessageBuilder bmsg; - auto evt = bmsg.initEvent(event.getValid()); - evt.setLogMonoTime(event.getLogMonoTime()); - (evt.*(encoder_info.set_encode_idx_func))(idx); - auto new_msg = bmsg.toBytes(); - s->logger.write((uint8_t *)new_msg.begin(), new_msg.size(), true); // always in qlog? - bytes_count += new_msg.size(); - - // free the message, we used it + bytes_count += write_encode_data(s, event, re, encoder_info); delete msg; } else if (offset_segment_num > s->logger.segment()) { // encoderd packet has a newer segment, this means encoderd has rolled over From a922b69239be31a56fe6f737cf3ab777026cc208 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 2 Mar 2025 20:12:22 -0800 Subject: [PATCH 15/78] jenkins: enable os04 test (#34757) This reverts commit a4980dbb0d97d18027830c892d44e51664eae925. --- Jenkinsfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 2609d2fe0f..b1a0746ea3 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -238,7 +238,6 @@ node { step("test exposure", "pytest system/camerad/test/test_exposure.py"), ]) }, - /* 'camerad OS04C10': { deviceStage("OS04C10", "tici-os04c10", ["UNSAFE=1"], [ step("build", "cd system/manager && ./build.py"), @@ -246,7 +245,6 @@ node { step("test exposure", "pytest system/camerad/test/test_exposure.py"), ]) }, - */ 'sensord': { deviceStage("LSM + MMC", "tici-lsmc", ["UNSAFE=1"], [ step("build", "cd system/manager && ./build.py"), From a2bc5061e495aa63d5cc025d6e8fc67d0172f58b Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 2 Mar 2025 20:22:06 -0800 Subject: [PATCH 16/78] camerad: fix bps flush (#34758) --- system/camerad/cameras/spectra.cc | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/system/camerad/cameras/spectra.cc b/system/camerad/cameras/spectra.cc index 7e991755ce..3e5941b13f 100644 --- a/system/camerad/cameras/spectra.cc +++ b/system/camerad/cameras/spectra.cc @@ -249,13 +249,6 @@ SpectraCamera::~SpectraCamera() { } int SpectraCamera::clear_req_queue() { - struct cam_req_mgr_flush_info req_mgr_flush_request = {0}; - req_mgr_flush_request.session_hdl = session_handle; - req_mgr_flush_request.link_hdl = link_handle; - req_mgr_flush_request.flush_type = CAM_REQ_MGR_FLUSH_TYPE_ALL; - int ret = do_cam_control(m->video0_fd, CAM_REQ_MGR_FLUSH_REQ, &req_mgr_flush_request, sizeof(req_mgr_flush_request)); - LOGD("flushed all req: %d", ret); - if (icp_dev_handle > 0) { struct cam_flush_dev_cmd cmd = { .session_handle = session_handle, @@ -264,8 +257,16 @@ int SpectraCamera::clear_req_queue() { }; int err = do_cam_control(m->icp_fd, CAM_FLUSH_REQ, &cmd, sizeof(cmd)); assert(err == 0); + LOGD("flushed bps: %d", err); } + struct cam_req_mgr_flush_info req_mgr_flush_request = {0}; + req_mgr_flush_request.session_hdl = session_handle; + req_mgr_flush_request.link_hdl = link_handle; + req_mgr_flush_request.flush_type = CAM_REQ_MGR_FLUSH_TYPE_ALL; + int ret = do_cam_control(m->video0_fd, CAM_REQ_MGR_FLUSH_REQ, &req_mgr_flush_request, sizeof(req_mgr_flush_request)); + LOGD("flushed all req: %d", ret); + for (int i = 0; i < MAX_IFE_BUFS; ++i) { destroySyncObjectAt(i); } @@ -938,16 +939,15 @@ bool SpectraCamera::enqueue_buffer(int i, uint64_t request_id) { } } - // all good, hand off frame if (ret == 0) { + // all good, hand off frame frame_ready = true; - } - - if (ret != 0) { + destroySyncObjectAt(i); + } else { + // need to start over on sync failures, + // otherwise future frames will tear clear_req_queue(); } - - destroySyncObjectAt(i); } // create output fences @@ -1378,14 +1378,14 @@ bool SpectraCamera::handle_camera_event(const cam_req_mgr_message *event_data) { return false; } - if (!enabled) return false; - // ID from the qcom camera request manager uint64_t request_id = event_data->u.frame_msg.request_id; // raw as opposed to our re-indexed frame ID uint64_t frame_id_raw = event_data->u.frame_msg.frame_id; + //LOGD("handle cam %d, request id %lu -> %lu, frame id raw %lu", cc.camera_num, request_id_last, request_id, frame_id_raw); + if (request_id != 0) { // next ready // check for skipped_last frames if (frame_id_raw > frame_id_raw_last + 1 && !skipped_last) { From 0f2bc09fe79a6cd450e1db216e6537e93574c2b4 Mon Sep 17 00:00:00 2001 From: programanichiro <99449198+programanichiro@users.noreply.github.com> Date: Mon, 3 Mar 2025 13:31:49 +0900 Subject: [PATCH 17/78] ja translation update (#34745) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Firehoseモード翻訳 * 翻訳調整。 * 翻訳調整。 * はみ出し、表現調整。 * Openpilot->openpilot * 翻訳調整。 * 句読点調整。 --- selfdrive/ui/translations/main_ja.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index 1715df664d..a5c21d29a6 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -309,17 +309,19 @@ FirehosePanel 🔥 Firehose Mode 🔥 - + 🔥 Firehoseモード 🔥 Enable Firehose Mode - + Firehoseを有効にする openpilot learns to drive by watching humans, like you, drive. Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models with better Experimental Mode. - + openpilotは人間であるあなたの運転から学び、AI学習します。 + +Firehoseモードを有効にすると、学習データを最大限アップロードし、openpilotの運転モデルを向上させることができます。より多くのデータはより大きなモデルを生み出し、Experimentalモードの精度向上につながります。 0% @@ -327,7 +329,7 @@ Firehose Mode allows you to maximize your training data uploads to improve openp Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable the toggle<br> 4. Leave it connected for at least 30 minutes<br><br>The toggle turns off once you restart your device. Repeat at least once a week for maximum effectiveness.<br><br><b>FAQ</b><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><i>Do I need to be on Wi-Fi?</i> Yes.<br><i>Do I need to bring the device inside?</i> No, you can enable once you're parked, however your uploads will be limited by your car's battery.<br> - + 以下の手順に従ってデバイスを準備してください:<br> 1. デバイスを室内に持ち込み、高速なUSB-C電源に接続してください<br> 2. Wi-Fiに接続してください<br> 3. 機能を有効にしてください<br> 4. 少なくとも30分間接続したままにしてください<br><br>デバイスを再起動すると、この機能はオフになります。最大の効果を得るために、少なくとも週に1回は繰り返してください。<br><br><b>FAQ</b><br><i>どのように運転するか、どこで運転するかは重要ですか?</i> いいえ、普段通りに運転してください。<br><i>高速なUSB-C電源とは何ですか?</i> スマフォやノートPC用のワット数の大きい充電器を使って下さい。<br><i>Wi-Fiに接続する必要がありますか?</i> その通りです。<br><i>デバイスを屋内に持ち込む必要がありますか?</i> いいえ、駐車後に有効にすることができますが、アップロードは車のバッテリーによって制限されます。<br> @@ -664,7 +666,7 @@ This may take up to a minute. Firehose - + データ学習 @@ -1142,15 +1144,15 @@ This may take up to a minute. WiFiPromptWidget Open - + 開く Maximize your training data uploads to improve openpilot's driving models. - + openpilotの運転モデルを改善するために、大容量の学習データをアップロードして下さい。 <span style='font-family: "Noto Color Emoji";'>🔥</span> Firehose Mode <span style='font-family: Noto Color Emoji;'>🔥</span> - + <span style='font-family: "Noto Color Emoji";'>🔥</span> Firehoseモード <span style='font-family: Noto Color Emoji;'>🔥</span> From 792e75582a3bab76650171711e37533ffa31a2c9 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 3 Mar 2025 00:57:17 -0600 Subject: [PATCH 18/78] Ford CAN FD: enable safety in release (#34759) bump --- opendbc_repo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opendbc_repo b/opendbc_repo index 966df198f0..bc839875bd 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit 966df198f063f0cd9d8f4afa0e68622966457f9a +Subproject commit bc839875bd0ca476be71dea2cbebc92a4544c40c From 1836d1594c70486f1d42b3345ee1c8d8512901b5 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 3 Mar 2025 09:28:16 -0800 Subject: [PATCH 19/78] Revert "selfdrived: remove ignored process list (#34491)", needed for C3 with NVMe for now This reverts commit 82722217be3ab050945c0240224ddcbab565f412. --- selfdrive/selfdrived/selfdrived.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/selfdrive/selfdrived/selfdrived.py b/selfdrive/selfdrived/selfdrived.py index 9d30090b8b..784925c966 100755 --- a/selfdrive/selfdrived/selfdrived.py +++ b/selfdrive/selfdrived/selfdrived.py @@ -26,6 +26,7 @@ from openpilot.system.version import get_build_metadata REPLAY = "REPLAY" in os.environ SIMULATION = "SIMULATION" in os.environ TESTING_CLOSET = "TESTING_CLOSET" in os.environ +IGNORE_PROCESSES = {"loggerd", "encoderd", "statsd"} LONGITUDINAL_PERSONALITY_MAP = {v: k for k, v in log.LongitudinalPersonality.schema.enumerants.items()} ThermalStatus = log.DeviceState.ThermalStatus @@ -258,7 +259,7 @@ class SelfdriveD: if not_running != self.not_running_prev: cloudlog.event("process_not_running", not_running=not_running, error=True) self.not_running_prev = not_running - if self.sm.recv_frame['managerState'] and not_running: + if self.sm.recv_frame['managerState'] and (not_running - IGNORE_PROCESSES): self.events.add(EventName.processNotRunning) else: if not SIMULATION and not self.rk.lagging: From 9200ae38c1584b57fc5f88caddc7e9a9975ea198 Mon Sep 17 00:00:00 2001 From: eFini Date: Tue, 4 Mar 2025 01:37:24 +0800 Subject: [PATCH 20/78] zhs/zht translation update (#34760) * updated CHT/CHS translations * better "firehose" translation --- selfdrive/ui/translations/main_zh-CHS.ts | 20 +++++++++++--------- selfdrive/ui/translations/main_zh-CHT.ts | 20 +++++++++++--------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index d5d5660691..e6c8734b15 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -309,25 +309,27 @@ FirehosePanel 🔥 Firehose Mode 🔥 - + 🔥 训练数据上传模式 🔥 Enable Firehose Mode - + 启用训练数据上传模式 openpilot learns to drive by watching humans, like you, drive. Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models with better Experimental Mode. - + openpilot 通过观察人类(像你一样的驾驶)来学习驾驶。 + +训练数据上传模式可让你最大化上传训练数据,以改进 openpilot 的驾驶模型。更多数据意味着更大的模型,并带来更优秀的实验模式。 0% - 5G {0%?} + 0% Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable the toggle<br> 4. Leave it connected for at least 30 minutes<br><br>The toggle turns off once you restart your device. Repeat at least once a week for maximum effectiveness.<br><br><b>FAQ</b><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><i>Do I need to be on Wi-Fi?</i> Yes.<br><i>Do I need to bring the device inside?</i> No, you can enable once you're parked, however your uploads will be limited by your car's battery.<br> - + 按照以下步骤准备您的设备:<br> 1. 将设备带到室内并连接到良好的 USB-C 充电器<br> 2. 连接 Wi-Fi<br> 3. 启用开关<br> 4. 保持连接至少 30 分钟<br><br>开关会在设备重新启动后自动关闭。请至少每周重复一次,以获得最佳效果。<br><br><b>常见问题</b><br><i>驾驶方式或地点重要吗?</i> 不,按照平常的方式驾驶即可。<br><i>什么是良好的 USB-C 充电器?</i> 任何快速手机或笔记本电脑充电器都可以。<br><i>我需要连接 Wi-Fi 吗?</i> 是的。<br><i>我需要把设备带到室内吗?</i> 不,您可以在停车后启用,但您的上传速度将受限于车辆的电池。<br> @@ -664,7 +666,7 @@ This may take up to a minute. Firehose - + 训练上传 @@ -1142,15 +1144,15 @@ This may take up to a minute. WiFiPromptWidget Open - + 开启 Maximize your training data uploads to improve openpilot's driving models. - + 最大化您的训练数据上传,以改善 openpilot 的驾驶模型。 <span style='font-family: "Noto Color Emoji";'>🔥</span> Firehose Mode <span style='font-family: Noto Color Emoji;'>🔥</span> - + <span style='font-family: "Noto Color Emoji";'>🔥</span> 训练数据上传模式 <span style='font-family: Noto Color Emoji;'>🔥</span> diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index a1ed78ed94..d750e9c46a 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -309,25 +309,27 @@ FirehosePanel 🔥 Firehose Mode 🔥 - + 🔥 訓練資料上傳模式 🔥 Enable Firehose Mode - + 啟用訓練資料上傳模式 openpilot learns to drive by watching humans, like you, drive. Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models with better Experimental Mode. - + openpilot 透過觀察人類(像你一樣的駕駛)來學習駕駛。 + +訓練資料上傳模式可讓你最大化上傳訓練數據,以改進 openpilot 的駕駛模型。更多數據意味著更大的模型,並帶來更優秀的實驗模式。 0% - 5G {0%?} + 0% Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable the toggle<br> 4. Leave it connected for at least 30 minutes<br><br>The toggle turns off once you restart your device. Repeat at least once a week for maximum effectiveness.<br><br><b>FAQ</b><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><i>Do I need to be on Wi-Fi?</i> Yes.<br><i>Do I need to bring the device inside?</i> No, you can enable once you're parked, however your uploads will be limited by your car's battery.<br> - + 按照以下步驟準備您的裝置:<br> 1. 將裝置帶到室內並連接到良好的 USB-C 充電器<br> 2. 連接 Wi-Fi<br> 3. 啟用開關<br> 4. 保持連接至少 30 分鐘<br><br>開關會在裝置重新啟動後自動關閉。請至少每週重複一次,以獲得最佳效果。<br><br><b>常見問題</b><br><i>駕駛方式或地點重要嗎?</i> 不,按照平常的方式駕駛即可。<br><i>什麼是良好的 USB-C 充電器?</i> 任何快速手機或筆記本電腦充電器都可以。<br><i>我需要連接 Wi-Fi 嗎?</i> 是的。<br><i>我需要把裝置帶到室內嗎?</i> 不,您可以在停車後啟用,但您的上傳速度將受限於車輛的電池。<br> @@ -664,7 +666,7 @@ This may take up to a minute. Firehose - + 訓練上傳 @@ -1142,15 +1144,15 @@ This may take up to a minute. WiFiPromptWidget Open - + 開啟 Maximize your training data uploads to improve openpilot's driving models. - + 最大化您的訓練數據上傳,以改善 openpilot 的駕駛模型。 <span style='font-family: "Noto Color Emoji";'>🔥</span> Firehose Mode <span style='font-family: Noto Color Emoji;'>🔥</span> - + <span style='font-family: "Noto Color Emoji";'>🔥</span> 訓練資料上傳模式 <span style='font-family: Noto Color Emoji;'>🔥</span> From 97ffda4adac0341c94918cfa164d207228684cef Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 3 Mar 2025 10:16:05 -0800 Subject: [PATCH 21/78] agnos 11.9 (#34762) --- launch_env.sh | 2 +- system/hardware/tici/agnos.json | 20 +++++------ system/hardware/tici/all-partitions.json | 44 ++++++++++++------------ 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/launch_env.sh b/launch_env.sh index 3300423055..88c6550443 100755 --- a/launch_env.sh +++ b/launch_env.sh @@ -7,7 +7,7 @@ export OPENBLAS_NUM_THREADS=1 export VECLIB_MAXIMUM_THREADS=1 if [ -z "$AGNOS_VERSION" ]; then - export AGNOS_VERSION="11.8" + export AGNOS_VERSION="11.9" fi export STAGING_ROOT="/data/safe_staging" diff --git a/system/hardware/tici/agnos.json b/system/hardware/tici/agnos.json index 7844dcbf68..6538560363 100644 --- a/system/hardware/tici/agnos.json +++ b/system/hardware/tici/agnos.json @@ -56,28 +56,28 @@ }, { "name": "boot", - "url": "https://commadist.azureedge.net/agnosupdate/boot-c7cba1ce64bf85384241fa063971855c5ffcb4d90a0d07bed4733d46b94d4170.img.xz", - "hash": "c7cba1ce64bf85384241fa063971855c5ffcb4d90a0d07bed4733d46b94d4170", - "hash_raw": "c7cba1ce64bf85384241fa063971855c5ffcb4d90a0d07bed4733d46b94d4170", + "url": "https://commadist.azureedge.net/agnosupdate/boot-bca7573652def58a0afc40bbdd550d63dc08ed2e925ace69032aef84bb9dc4ba.img.xz", + "hash": "bca7573652def58a0afc40bbdd550d63dc08ed2e925ace69032aef84bb9dc4ba", + "hash_raw": "bca7573652def58a0afc40bbdd550d63dc08ed2e925ace69032aef84bb9dc4ba", "size": 18475008, "sparse": false, "full_check": true, "has_ab": true, - "ondevice_hash": "6a9a71bf01f2013f35bda9594cefe3cb4a3835402a6cb0e95306fe4decf261c5" + "ondevice_hash": "8907415564e8a242548e871b534dcd53240fe4e4517700c6c85b5637e365f0b0" }, { "name": "system", - "url": "https://commadist.azureedge.net/agnosupdate/system-cd03486f6c7333dee21f59af771f9992ea90a9a04271c1506a663d658f391625.img.xz", - "hash": "990ff7005a5bee8e759c96ddba23f1258f043fb038cf74083bf7d2d9c9a29e39", - "hash_raw": "cd03486f6c7333dee21f59af771f9992ea90a9a04271c1506a663d658f391625", + "url": "https://commadist.azureedge.net/agnosupdate/system-061783c4826369c7aa711266e8e1d9eecfd0a6d6c8afc6042e4045617512be75.img.xz", + "hash": "affcc08700026f1726ef16337e031fffc5556435b2b0facea81c7ffb0b66560c", + "hash_raw": "061783c4826369c7aa711266e8e1d9eecfd0a6d6c8afc6042e4045617512be75", "size": 4404019200, "sparse": true, "full_check": false, "has_ab": true, - "ondevice_hash": "d922fffe1b5f02898465a2d6625294abb70d22643ebf2d6a94f5d7512291d1a4", + "ondevice_hash": "cc86836c6fc1c54f24dd0395e57e0b1ac6efe44d3ece833ab3ed456fe46a55cf", "alt": { - "hash": "cd03486f6c7333dee21f59af771f9992ea90a9a04271c1506a663d658f391625", - "url": "https://commadist.azureedge.net/agnosupdate/system-cd03486f6c7333dee21f59af771f9992ea90a9a04271c1506a663d658f391625.img", + "hash": "061783c4826369c7aa711266e8e1d9eecfd0a6d6c8afc6042e4045617512be75", + "url": "https://commadist.azureedge.net/agnosupdate/system-061783c4826369c7aa711266e8e1d9eecfd0a6d6c8afc6042e4045617512be75.img", "size": 4404019200 } } diff --git a/system/hardware/tici/all-partitions.json b/system/hardware/tici/all-partitions.json index b21225e4ac..5b3478f746 100644 --- a/system/hardware/tici/all-partitions.json +++ b/system/hardware/tici/all-partitions.json @@ -339,62 +339,62 @@ }, { "name": "boot", - "url": "https://commadist.azureedge.net/agnosupdate/boot-c7cba1ce64bf85384241fa063971855c5ffcb4d90a0d07bed4733d46b94d4170.img.xz", - "hash": "c7cba1ce64bf85384241fa063971855c5ffcb4d90a0d07bed4733d46b94d4170", - "hash_raw": "c7cba1ce64bf85384241fa063971855c5ffcb4d90a0d07bed4733d46b94d4170", + "url": "https://commadist.azureedge.net/agnosupdate/boot-bca7573652def58a0afc40bbdd550d63dc08ed2e925ace69032aef84bb9dc4ba.img.xz", + "hash": "bca7573652def58a0afc40bbdd550d63dc08ed2e925ace69032aef84bb9dc4ba", + "hash_raw": "bca7573652def58a0afc40bbdd550d63dc08ed2e925ace69032aef84bb9dc4ba", "size": 18475008, "sparse": false, "full_check": true, "has_ab": true, - "ondevice_hash": "6a9a71bf01f2013f35bda9594cefe3cb4a3835402a6cb0e95306fe4decf261c5" + "ondevice_hash": "8907415564e8a242548e871b534dcd53240fe4e4517700c6c85b5637e365f0b0" }, { "name": "system", - "url": "https://commadist.azureedge.net/agnosupdate/system-cd03486f6c7333dee21f59af771f9992ea90a9a04271c1506a663d658f391625.img.xz", - "hash": "990ff7005a5bee8e759c96ddba23f1258f043fb038cf74083bf7d2d9c9a29e39", - "hash_raw": "cd03486f6c7333dee21f59af771f9992ea90a9a04271c1506a663d658f391625", + "url": "https://commadist.azureedge.net/agnosupdate/system-061783c4826369c7aa711266e8e1d9eecfd0a6d6c8afc6042e4045617512be75.img.xz", + "hash": "affcc08700026f1726ef16337e031fffc5556435b2b0facea81c7ffb0b66560c", + "hash_raw": "061783c4826369c7aa711266e8e1d9eecfd0a6d6c8afc6042e4045617512be75", "size": 4404019200, "sparse": true, "full_check": false, "has_ab": true, - "ondevice_hash": "d922fffe1b5f02898465a2d6625294abb70d22643ebf2d6a94f5d7512291d1a4", + "ondevice_hash": "cc86836c6fc1c54f24dd0395e57e0b1ac6efe44d3ece833ab3ed456fe46a55cf", "alt": { - "hash": "cd03486f6c7333dee21f59af771f9992ea90a9a04271c1506a663d658f391625", - "url": "https://commadist.azureedge.net/agnosupdate/system-cd03486f6c7333dee21f59af771f9992ea90a9a04271c1506a663d658f391625.img", + "hash": "061783c4826369c7aa711266e8e1d9eecfd0a6d6c8afc6042e4045617512be75", + "url": "https://commadist.azureedge.net/agnosupdate/system-061783c4826369c7aa711266e8e1d9eecfd0a6d6c8afc6042e4045617512be75.img", "size": 4404019200 } }, { "name": "userdata_90", - "url": "https://commadist.azureedge.net/agnosupdate/userdata_90-554a22697b356cb150c2c803b4cb1de79403849e9be451c844d218d38b5bc236.img.xz", - "hash": "4f0a862e3aff4980e697ece63afaef6f9869d013ac2ca4c45193e41089ee4f5c", - "hash_raw": "554a22697b356cb150c2c803b4cb1de79403849e9be451c844d218d38b5bc236", + "url": "https://commadist.azureedge.net/agnosupdate/userdata_90-fd9d27a3ef5c1f63b85721798ba4ea10f2a4c71d0c8d9b59362a99f24dfff54a.img.xz", + "hash": "b77b66ae8178519dbd72443ff7bdd21b97d0d4d76425472bedc7d369958de37b", + "hash_raw": "fd9d27a3ef5c1f63b85721798ba4ea10f2a4c71d0c8d9b59362a99f24dfff54a", "size": 96636764160, "sparse": true, "full_check": true, "has_ab": false, - "ondevice_hash": "5d780092d51c569e6b8a28ab73f4029bcc3517698f496af5801f863c9865060f" + "ondevice_hash": "52d2b8e2486e7fa0cdeb2a6512a8058db43544c905367a2e1b81a5ad4636d4b7" }, { "name": "userdata_89", - "url": "https://commadist.azureedge.net/agnosupdate/userdata_89-6045b9a3f1ae6e0ee09b95da039b697ab8d8447cdd0796fa31afa9c7d324ee80.img.xz", - "hash": "ba49fef48573e9befdfb6334181753855cb83d3e1d8c6d4d83d510ea0141ec3f", - "hash_raw": "6045b9a3f1ae6e0ee09b95da039b697ab8d8447cdd0796fa31afa9c7d324ee80", + "url": "https://commadist.azureedge.net/agnosupdate/userdata_89-1042711c5f69146ff7680f09eab1b2eb6fe9da0411318e9ff913c27168cb0307.img.xz", + "hash": "cc24b1c78234f92cd8ef66541f3fb8924719fc4b7f42c26e26eb71ec21cd2e93", + "hash_raw": "1042711c5f69146ff7680f09eab1b2eb6fe9da0411318e9ff913c27168cb0307", "size": 95563022336, "sparse": true, "full_check": true, "has_ab": false, - "ondevice_hash": "19b63b184063c25ff2fc9f1c8d1c919c140c3e1295ebac6cb66e64c5cb609abe" + "ondevice_hash": "80bf38b8b60ea1ef1fc0849af4e18bf114761f98f5371476e2f762d0f8463204" }, { "name": "userdata_30", - "url": "https://commadist.azureedge.net/agnosupdate/userdata_30-498358c1e5347dc3f8c369523bd77b94ef73d6c6729b40f376209d0d32b356fe.img.xz", - "hash": "828d0911713af02de7fae4c583a2274783e344939f296c7c016866a8cf2cb63f", - "hash_raw": "498358c1e5347dc3f8c369523bd77b94ef73d6c6729b40f376209d0d32b356fe", + "url": "https://commadist.azureedge.net/agnosupdate/userdata_30-6d429550c42616e3f252034305f238ce0e90926762992ff3f92322f226caa5b6.img.xz", + "hash": "657b052cf6434ef19ff73bdeaf5b2511e5c42f64594ae37bac467a12b4cd673f", + "hash_raw": "6d429550c42616e3f252034305f238ce0e90926762992ff3f92322f226caa5b6", "size": 32212254720, "sparse": true, "full_check": true, "has_ab": false, - "ondevice_hash": "4beb60ffceff88b05daa014db50cb2f4e9acec3ed7ae1b89a8d3c84cfc3c1c92" + "ondevice_hash": "6437e5a5b7144103952950f2f59f8e70b98cd26ee5bfb06cbd0a13b2e2f343b7" } ] \ No newline at end of file From ec81e78c541fcb61b5ad8b621518d73a85da4827 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 3 Mar 2025 12:58:43 -0800 Subject: [PATCH 22/78] no gps localizer --- RELEASES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASES.md b/RELEASES.md index 37e4a01b20..8a5638bc84 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -12,6 +12,7 @@ Version 0.9.8 (2025-02-28) * More GPU time for bigger driving models * Power draw reduced 0.5W, which means your device runs cooler * Added toggle to enable driver monitoring even when openpilot is not engaged +* Localizer rewritten to remove GPS dependency at runtime * Firehose Mode for maximizing your training data uploads * Enable openpilot longitudinal control for Ford Q3 vehicles * New Toyota TSS2 longitudinal tune From e39e4b9a610ccfda1986002e0bbdae2372a79466 Mon Sep 17 00:00:00 2001 From: commaci-public <60409688+commaci-public@users.noreply.github.com> Date: Mon, 3 Mar 2025 14:47:18 -0800 Subject: [PATCH 23/78] [bot] Update Python packages (#34761) Update Python packages Co-authored-by: Vehicle Researcher --- msgq_repo | 2 +- opendbc_repo | 2 +- panda | 2 +- uv.lock | 12 ++++++------ 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/msgq_repo b/msgq_repo index 095f1e2361..ad9020c430 160000 --- a/msgq_repo +++ b/msgq_repo @@ -1 +1 @@ -Subproject commit 095f1e23613d47031a9b23e3f9ed5dd3fe01a06e +Subproject commit ad9020c430362d17c0edf97747d344389234be4d diff --git a/opendbc_repo b/opendbc_repo index bc839875bd..ca4f77b010 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit bc839875bd0ca476be71dea2cbebc92a4544c40c +Subproject commit ca4f77b0101d85a5e8d292e2e61f7a8c7492b9e2 diff --git a/panda b/panda index 2c802449fd..154b66782d 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 2c802449fd51d9904ca265d06b7a5f9969057ae3 +Subproject commit 154b66782ddf4b9293c4594bb5ee8bd9cd88f332 diff --git a/uv.lock b/uv.lock index fa933d5491..022e30508d 100644 --- a/uv.lock +++ b/uv.lock @@ -4279,7 +4279,7 @@ wheels = [ [[package]] name = "pytest" -version = "8.3.4" +version = "8.3.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -4287,9 +4287,9 @@ dependencies = [ { name = "packaging" }, { name = "pluggy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/05/35/30e0d83068951d90a01852cb1cef56e5d8a09d20c7f511634cc2f7e0372a/pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761", size = 1445919 } +sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891 } wheels = [ - { url = "https://files.pythonhosted.org/packages/11/92/76a1c94d3afee238333bc0a42b82935dd8f9cf8ce9e336ff87ee14d9e1cf/pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", size = 343083 }, + { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634 }, ] [[package]] @@ -4703,11 +4703,11 @@ wheels = [ [[package]] name = "scons" -version = "4.8.1" +version = "4.9.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b9/76/a2c1293642f9a448f2d012cabf525be69ca5abf4af289bc0935ac1554ee8/scons-4.8.1.tar.gz", hash = "sha256:5b641357904d2f56f7bfdbb37e165ab996b6143c948b9df0efc7305f54949daa", size = 3244174 } +sdist = { url = "https://files.pythonhosted.org/packages/61/7e/79e07dc2eb8874580934cd0c834a8a78f15d5b0d6155a424f6c7b35441c3/scons-4.9.0.tar.gz", hash = "sha256:f1a5e161bf3d1411d780d65d7919654b9405555994621d3d68e42d62114b592a", size = 3251763 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b8/a7/823091100c88d7d992c8c608d82a88ed59e227d13f8ccb33ea7a96d43d51/SCons-4.8.1-py3-none-any.whl", hash = "sha256:a4c3b434330e2d7d975002fd6783284ba348bf394db94c8f83fdc5bf69cdb8d7", size = 4123564 }, + { url = "https://files.pythonhosted.org/packages/18/f5/77635f6c68ed742a23e1f52977267e191ea7c2aec89b9604a86487405da1/scons-4.9.0-py3-none-any.whl", hash = "sha256:c8cc309db0f91cffdc27c1374fa3d31e9421bcb31d210de071b0b11adc84739b", size = 4130637 }, ] [[package]] From 159b1c9eb48551e6ac1d5f9281ac2218f320f499 Mon Sep 17 00:00:00 2001 From: ZwX1616 Date: Mon, 3 Mar 2025 15:15:36 -0800 Subject: [PATCH 24/78] Filet o Fish model (#34637) * 690b01c3 seems ok * correct temporal * push * inplace * bs * what thw * is this wrong * frames are skipped * new models * simplify decimation * clean up * clean up modelframe * need attr * lint * 0 --------- Co-authored-by: Comma Device --- selfdrive/modeld/constants.py | 8 +++++- selfdrive/modeld/modeld.py | 31 ++++++++++++++------- selfdrive/modeld/models/commonmodel.cc | 9 +++--- selfdrive/modeld/models/commonmodel.h | 5 ++-- selfdrive/modeld/models/commonmodel.pxd | 2 +- selfdrive/modeld/models/commonmodel_pyx.pyx | 4 +-- selfdrive/modeld/models/driving_policy.onnx | 4 +-- selfdrive/modeld/models/driving_vision.onnx | 2 +- 8 files changed, 42 insertions(+), 23 deletions(-) diff --git a/selfdrive/modeld/constants.py b/selfdrive/modeld/constants.py index 2bb7b8100c..5ca0a86bc8 100644 --- a/selfdrive/modeld/constants.py +++ b/selfdrive/modeld/constants.py @@ -14,8 +14,14 @@ class ModelConstants: # model inputs constants MODEL_FREQ = 20 + HISTORY_FREQ = 5 + HISTORY_LEN_SECONDS = 5 + TEMPORAL_SKIP = MODEL_FREQ // HISTORY_FREQ + FULL_HISTORY_BUFFER_LEN = MODEL_FREQ * HISTORY_LEN_SECONDS + INPUT_HISTORY_BUFFER_LEN = HISTORY_FREQ * HISTORY_LEN_SECONDS + FEATURE_LEN = 512 - FULL_HISTORY_BUFFER_LEN = 100 + DESIRE_LEN = 8 TRAFFIC_CONVENTION_LEN = 2 LAT_PLANNER_STATE_LEN = 4 diff --git a/selfdrive/modeld/modeld.py b/selfdrive/modeld/modeld.py index ee825d158f..ae1e75e3e9 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -56,16 +56,24 @@ class ModelState: prev_desire: np.ndarray # for tracking the rising edge of the pulse def __init__(self, context: CLContext): - self.frames = {'input_imgs': DrivingModelFrame(context), 'big_input_imgs': DrivingModelFrame(context)} + self.frames = { + 'input_imgs': DrivingModelFrame(context, ModelConstants.TEMPORAL_SKIP), + 'big_input_imgs': DrivingModelFrame(context, ModelConstants.TEMPORAL_SKIP) + } self.prev_desire = np.zeros(ModelConstants.DESIRE_LEN, dtype=np.float32) + self.full_features_buffer = np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.FEATURE_LEN), dtype=np.float32) + self.full_desire = np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.DESIRE_LEN), dtype=np.float32) + self.full_prev_desired_curv = np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.PREV_DESIRED_CURV_LEN), dtype=np.float32) + self.temporal_idxs = slice(-1-(ModelConstants.TEMPORAL_SKIP*(ModelConstants.INPUT_HISTORY_BUFFER_LEN-1)), None, ModelConstants.TEMPORAL_SKIP) + # policy inputs self.numpy_inputs = { - 'desire': np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.DESIRE_LEN), dtype=np.float32), + 'desire': np.zeros((1, ModelConstants.INPUT_HISTORY_BUFFER_LEN, ModelConstants.DESIRE_LEN), dtype=np.float32), 'traffic_convention': np.zeros((1, ModelConstants.TRAFFIC_CONVENTION_LEN), dtype=np.float32), 'lateral_control_params': np.zeros((1, ModelConstants.LATERAL_CONTROL_PARAMS_LEN), dtype=np.float32), - 'prev_desired_curv': np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.PREV_DESIRED_CURV_LEN), dtype=np.float32), - 'features_buffer': np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.FEATURE_LEN), dtype=np.float32), + 'prev_desired_curv': np.zeros((1, ModelConstants.INPUT_HISTORY_BUFFER_LEN, ModelConstants.PREV_DESIRED_CURV_LEN), dtype=np.float32), + 'features_buffer': np.zeros((1, ModelConstants.INPUT_HISTORY_BUFFER_LEN, ModelConstants.FEATURE_LEN), dtype=np.float32), } with open(VISION_METADATA_PATH, 'rb') as f: @@ -104,8 +112,9 @@ class ModelState: new_desire = np.where(inputs['desire'] - self.prev_desire > .99, inputs['desire'], 0) self.prev_desire[:] = inputs['desire'] - self.numpy_inputs['desire'][0,:-1] = self.numpy_inputs['desire'][0,1:] - self.numpy_inputs['desire'][0,-1] = new_desire + self.full_desire[0,:-1] = self.full_desire[0,1:] + self.full_desire[0,-1] = new_desire + self.numpy_inputs['desire'][:] = self.full_desire[0, self.temporal_idxs] self.numpy_inputs['traffic_convention'][:] = inputs['traffic_convention'] self.numpy_inputs['lateral_control_params'][:] = inputs['lateral_control_params'] @@ -128,15 +137,17 @@ class ModelState: self.vision_output = self.vision_run(**self.vision_inputs).numpy().flatten() vision_outputs_dict = self.parser.parse_vision_outputs(self.slice_outputs(self.vision_output, self.vision_output_slices)) - self.numpy_inputs['features_buffer'][0,:-1] = self.numpy_inputs['features_buffer'][0,1:] - self.numpy_inputs['features_buffer'][0,-1] = vision_outputs_dict['hidden_state'][0, :] + self.full_features_buffer[0,:-1] = self.full_features_buffer[0,1:] + self.full_features_buffer[0,-1] = vision_outputs_dict['hidden_state'][0, :] + self.numpy_inputs['features_buffer'][:] = self.full_features_buffer[0, self.temporal_idxs] self.policy_output = self.policy_run(**self.policy_inputs).numpy().flatten() policy_outputs_dict = self.parser.parse_policy_outputs(self.slice_outputs(self.policy_output, self.policy_output_slices)) # TODO model only uses last value now - self.numpy_inputs['prev_desired_curv'][0,:-1] = self.numpy_inputs['prev_desired_curv'][0,1:] - self.numpy_inputs['prev_desired_curv'][0,-1,:] = policy_outputs_dict['desired_curvature'][0, :] + self.full_prev_desired_curv[0,:-1] = self.full_prev_desired_curv[0,1:] + self.full_prev_desired_curv[0,-1,:] = policy_outputs_dict['desired_curvature'][0, :] + self.numpy_inputs['prev_desired_curv'][:] = self.full_prev_desired_curv[0, self.temporal_idxs] combined_outputs_dict = {**vision_outputs_dict, **policy_outputs_dict} if SEND_RAW_PRED: diff --git a/selfdrive/modeld/models/commonmodel.cc b/selfdrive/modeld/models/commonmodel.cc index 9973d18588..99155d9f1e 100644 --- a/selfdrive/modeld/models/commonmodel.cc +++ b/selfdrive/modeld/models/commonmodel.cc @@ -5,11 +5,12 @@ #include "common/clutil.h" -DrivingModelFrame::DrivingModelFrame(cl_device_id device_id, cl_context context) : ModelFrame(device_id, context) { +DrivingModelFrame::DrivingModelFrame(cl_device_id device_id, cl_context context, int _temporal_skip) : ModelFrame(device_id, context) { input_frames = std::make_unique(buf_size); + temporal_skip = _temporal_skip; input_frames_cl = CL_CHECK_ERR(clCreateBuffer(context, CL_MEM_READ_WRITE, buf_size, NULL, &err)); - img_buffer_20hz_cl = CL_CHECK_ERR(clCreateBuffer(context, CL_MEM_READ_WRITE, 2*frame_size_bytes, NULL, &err)); - region.origin = 1 * frame_size_bytes; + img_buffer_20hz_cl = CL_CHECK_ERR(clCreateBuffer(context, CL_MEM_READ_WRITE, (temporal_skip+1)*frame_size_bytes, NULL, &err)); + region.origin = temporal_skip * frame_size_bytes; region.size = frame_size_bytes; last_img_cl = CL_CHECK_ERR(clCreateSubBuffer(img_buffer_20hz_cl, CL_MEM_READ_WRITE, CL_BUFFER_CREATE_TYPE_REGION, ®ion, &err)); @@ -20,7 +21,7 @@ DrivingModelFrame::DrivingModelFrame(cl_device_id device_id, cl_context context) cl_mem* DrivingModelFrame::prepare(cl_mem yuv_cl, int frame_width, int frame_height, int frame_stride, int frame_uv_offset, const mat3& projection) { run_transform(yuv_cl, MODEL_WIDTH, MODEL_HEIGHT, frame_width, frame_height, frame_stride, frame_uv_offset, projection); - for (int i = 0; i < 1; i++) { + for (int i = 0; i < temporal_skip; i++) { CL_CHECK(clEnqueueCopyBuffer(q, img_buffer_20hz_cl, img_buffer_20hz_cl, (i+1)*frame_size_bytes, i*frame_size_bytes, frame_size_bytes, 0, nullptr, nullptr)); } loadyuv_queue(&loadyuv, q, y_cl, u_cl, v_cl, last_img_cl); diff --git a/selfdrive/modeld/models/commonmodel.h b/selfdrive/modeld/models/commonmodel.h index 14409943e4..176d7eb6dc 100644 --- a/selfdrive/modeld/models/commonmodel.h +++ b/selfdrive/modeld/models/commonmodel.h @@ -64,20 +64,21 @@ protected: class DrivingModelFrame : public ModelFrame { public: - DrivingModelFrame(cl_device_id device_id, cl_context context); + DrivingModelFrame(cl_device_id device_id, cl_context context, int _temporal_skip); ~DrivingModelFrame(); cl_mem* prepare(cl_mem yuv_cl, int frame_width, int frame_height, int frame_stride, int frame_uv_offset, const mat3& projection); const int MODEL_WIDTH = 512; const int MODEL_HEIGHT = 256; const int MODEL_FRAME_SIZE = MODEL_WIDTH * MODEL_HEIGHT * 3 / 2; - const int buf_size = MODEL_FRAME_SIZE * 2; + const int buf_size = MODEL_FRAME_SIZE * 2; // 2 frames are temporal_skip frames apart const size_t frame_size_bytes = MODEL_FRAME_SIZE * sizeof(uint8_t); private: LoadYUVState loadyuv; cl_mem img_buffer_20hz_cl, last_img_cl, input_frames_cl; cl_buffer_region region; + int temporal_skip; }; class MonitoringModelFrame : public ModelFrame { diff --git a/selfdrive/modeld/models/commonmodel.pxd b/selfdrive/modeld/models/commonmodel.pxd index b4f08b12aa..4ac64d9172 100644 --- a/selfdrive/modeld/models/commonmodel.pxd +++ b/selfdrive/modeld/models/commonmodel.pxd @@ -20,7 +20,7 @@ cdef extern from "selfdrive/modeld/models/commonmodel.h": cppclass DrivingModelFrame: int buf_size - DrivingModelFrame(cl_device_id, cl_context) + DrivingModelFrame(cl_device_id, cl_context, int) cppclass MonitoringModelFrame: int buf_size diff --git a/selfdrive/modeld/models/commonmodel_pyx.pyx b/selfdrive/modeld/models/commonmodel_pyx.pyx index 7b3a5bb342..5b7d11bc71 100644 --- a/selfdrive/modeld/models/commonmodel_pyx.pyx +++ b/selfdrive/modeld/models/commonmodel_pyx.pyx @@ -59,8 +59,8 @@ cdef class ModelFrame: cdef class DrivingModelFrame(ModelFrame): cdef cppDrivingModelFrame * _frame - def __cinit__(self, CLContext context): - self._frame = new cppDrivingModelFrame(context.device_id, context.context) + def __cinit__(self, CLContext context, int temporal_skip): + self._frame = new cppDrivingModelFrame(context.device_id, context.context, temporal_skip) self.frame = (self._frame) self.buf_size = self._frame.buf_size diff --git a/selfdrive/modeld/models/driving_policy.onnx b/selfdrive/modeld/models/driving_policy.onnx index f804b4ec31..cc2148c74b 100644 --- a/selfdrive/modeld/models/driving_policy.onnx +++ b/selfdrive/modeld/models/driving_policy.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5cae3285c876804e649b14adadcfb8be79a9bd5a1b928113e37f1f08e25e9688 -size 16581121 +oid sha256:5fd38c3b4d465d14a8ed128f8b1b265bff1589d42f398faa678b93f25b3385dc +size 15966721 diff --git a/selfdrive/modeld/models/driving_vision.onnx b/selfdrive/modeld/models/driving_vision.onnx index 06c87d8755..aee6d8f1bf 100644 --- a/selfdrive/modeld/models/driving_vision.onnx +++ b/selfdrive/modeld/models/driving_vision.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:29bbf79f9dfd7048c0013bb81e86d9b2979275b95ea1ed8a86d1a86a88695240 +oid sha256:897f80d0388250f99bba69b6a8434560cc0fd83157cbeb0bc134c67fe4e64624 size 34882971 From 68d22b960b85871bf61dfdb0e2d955c28fde647b Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 3 Mar 2025 18:28:49 -0600 Subject: [PATCH 25/78] rename steer_limited (#34763) rename --- selfdrive/controls/controlsd.py | 10 +++++----- selfdrive/controls/lib/latcontrol.py | 6 +++--- selfdrive/controls/lib/latcontrol_angle.py | 2 +- selfdrive/controls/lib/latcontrol_pid.py | 4 ++-- selfdrive/controls/lib/latcontrol_torque.py | 6 +++--- tools/tuning/measure_steering_accuracy.py | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index fb7dd3944c..14fd37040e 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -40,7 +40,7 @@ class Controls: 'driverMonitoringState', 'onroadEvents', 'driverAssistance'], poll='selfdriveState') self.pm = messaging.PubMaster(['carControl', 'controlsState']) - self.steer_limited = False + self.steer_limited_by_controls = False self.desired_curvature = 0.0 self.pose_calibrator = PoseCalibrator() @@ -112,7 +112,7 @@ class Controls: self.desired_curvature = clip_curvature(CS.vEgo, self.desired_curvature, model_v2.action.desiredCurvature) actuators.curvature = float(self.desired_curvature) steer, steeringAngleDeg, lac_log = self.LaC.update(CC.latActive, CS, self.VM, lp, - self.steer_limited, self.desired_curvature, + self.steer_limited_by_controls, self.desired_curvature, self.calibrated_pose) # TODO what if not available actuators.torque = float(steer) actuators.steeringAngleDeg = float(steeringAngleDeg) @@ -161,10 +161,10 @@ class Controls: if self.sm['selfdriveState'].active: CO = self.sm['carOutput'] if self.CP.steerControlType == car.CarParams.SteerControlType.angle: - self.steer_limited = abs(CC.actuators.steeringAngleDeg - CO.actuatorsOutput.steeringAngleDeg) > \ - STEER_ANGLE_SATURATION_THRESHOLD + self.steer_limited_by_controls = abs(CC.actuators.steeringAngleDeg - CO.actuatorsOutput.steeringAngleDeg) > \ + STEER_ANGLE_SATURATION_THRESHOLD else: - self.steer_limited = abs(CC.actuators.torque - CO.actuatorsOutput.torque) > 1e-2 + self.steer_limited_by_controls = abs(CC.actuators.torque - CO.actuatorsOutput.torque) > 1e-2 # TODO: both controlsState and carControl valids should be set by # sm.all_checks(), but this creates a circular dependency diff --git a/selfdrive/controls/lib/latcontrol.py b/selfdrive/controls/lib/latcontrol.py index f84f70be4f..f0121f73bc 100644 --- a/selfdrive/controls/lib/latcontrol.py +++ b/selfdrive/controls/lib/latcontrol.py @@ -17,14 +17,14 @@ class LatControl(ABC): self.steer_max = 1.0 @abstractmethod - def update(self, active, CS, VM, params, steer_limited, desired_curvature, calibrated_pose): + def update(self, active, CS, VM, params, steer_limited_by_controls, desired_curvature, calibrated_pose): pass def reset(self): self.sat_count = 0. - def _check_saturation(self, saturated, CS, steer_limited): - if saturated and CS.vEgo > self.sat_check_min_speed and not steer_limited and not CS.steeringPressed: + def _check_saturation(self, saturated, CS, steer_limited_by_controls): + if saturated and CS.vEgo > self.sat_check_min_speed and not steer_limited_by_controls and not CS.steeringPressed: self.sat_count += self.sat_count_rate else: self.sat_count -= self.sat_count_rate diff --git a/selfdrive/controls/lib/latcontrol_angle.py b/selfdrive/controls/lib/latcontrol_angle.py index 4162bd62dc..de07423fd4 100644 --- a/selfdrive/controls/lib/latcontrol_angle.py +++ b/selfdrive/controls/lib/latcontrol_angle.py @@ -11,7 +11,7 @@ class LatControlAngle(LatControl): super().__init__(CP, CI) self.sat_check_min_speed = 5. - def update(self, active, CS, VM, params, steer_limited, desired_curvature, calibrated_pose): + def update(self, active, CS, VM, params, steer_limited_by_controls, desired_curvature, calibrated_pose): angle_log = log.ControlsState.LateralAngleState.new_message() if not active: diff --git a/selfdrive/controls/lib/latcontrol_pid.py b/selfdrive/controls/lib/latcontrol_pid.py index dedc97a964..cf54125a77 100644 --- a/selfdrive/controls/lib/latcontrol_pid.py +++ b/selfdrive/controls/lib/latcontrol_pid.py @@ -17,7 +17,7 @@ class LatControlPID(LatControl): super().reset() self.pid.reset() - def update(self, active, CS, VM, params, steer_limited, desired_curvature, calibrated_pose): + def update(self, active, CS, VM, params, steer_limited_by_controls, desired_curvature, calibrated_pose): pid_log = log.ControlsState.LateralPIDState.new_message() pid_log.steeringAngleDeg = float(CS.steeringAngleDeg) pid_log.steeringRateDeg = float(CS.steeringRateDeg) @@ -43,6 +43,6 @@ class LatControlPID(LatControl): pid_log.i = float(self.pid.i) pid_log.f = float(self.pid.f) pid_log.output = float(output_steer) - pid_log.saturated = bool(self._check_saturation(self.steer_max - abs(output_steer) < 1e-3, CS, steer_limited)) + pid_log.saturated = bool(self._check_saturation(self.steer_max - abs(output_steer) < 1e-3, CS, steer_limited_by_controls)) return output_steer, angle_steers_des, pid_log diff --git a/selfdrive/controls/lib/latcontrol_torque.py b/selfdrive/controls/lib/latcontrol_torque.py index f677b7f897..7b00cce56b 100644 --- a/selfdrive/controls/lib/latcontrol_torque.py +++ b/selfdrive/controls/lib/latcontrol_torque.py @@ -37,7 +37,7 @@ class LatControlTorque(LatControl): self.torque_params.latAccelOffset = latAccelOffset self.torque_params.friction = friction - def update(self, active, CS, VM, params, steer_limited, desired_curvature, calibrated_pose): + def update(self, active, CS, VM, params, steer_limited_by_controls, desired_curvature, calibrated_pose): pid_log = log.ControlsState.LateralTorqueState.new_message() if not active: output_torque = 0.0 @@ -73,7 +73,7 @@ class LatControlTorque(LatControl): desired_lateral_accel - actual_lateral_accel, lateral_accel_deadzone, friction_compensation=True, gravity_adjusted=True) - freeze_integrator = steer_limited or CS.steeringPressed or CS.vEgo < 5 + freeze_integrator = steer_limited_by_controls or CS.steeringPressed or CS.vEgo < 5 output_torque = self.pid.update(pid_log.error, feedforward=ff, speed=CS.vEgo, @@ -87,7 +87,7 @@ class LatControlTorque(LatControl): pid_log.output = float(-output_torque) pid_log.actualLateralAccel = float(actual_lateral_accel) pid_log.desiredLateralAccel = float(desired_lateral_accel) - pid_log.saturated = bool(self._check_saturation(self.steer_max - abs(output_torque) < 1e-3, CS, steer_limited)) + pid_log.saturated = bool(self._check_saturation(self.steer_max - abs(output_torque) < 1e-3, CS, steer_limited_by_controls)) # TODO left is positive in this convention return -output_torque, 0.0, pid_log diff --git a/tools/tuning/measure_steering_accuracy.py b/tools/tuning/measure_steering_accuracy.py index 5294ffcc49..a2f437819f 100755 --- a/tools/tuning/measure_steering_accuracy.py +++ b/tools/tuning/measure_steering_accuracy.py @@ -49,7 +49,7 @@ class SteeringAccuracyTool: active = sm['controlsState'].active steer = sm['carOutput'].actuatorsOutput.torque standstill = sm['carState'].standstill - steer_limited = abs(sm['carControl'].actuators.torque - sm['carControl'].actuatorsOutput.torque) > 1e-2 + steer_limited_by_controls = abs(sm['carControl'].actuators.torque - sm['carControl'].actuatorsOutput.torque) > 1e-2 overriding = sm['carState'].steeringPressed changing_lanes = sm['modelV2'].meta.laneChangeState != 0 model_points = sm['modelV2'].position.y @@ -77,7 +77,7 @@ class SteeringAccuracyTool: self.speed_group_stats[group][angle_abs]["steer"] += abs(steer) if len(model_points): self.speed_group_stats[group][angle_abs]["dpp"] += abs(model_points[0]) - if steer_limited: + if steer_limited_by_controls: self.speed_group_stats[group][angle_abs]["limited"] += 1 if control_state.saturated: self.speed_group_stats[group][angle_abs]["saturated"] += 1 From 41346b2cc72f6a699b4497b07363f78df7c3786d Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 3 Mar 2025 16:40:35 -0800 Subject: [PATCH 26/78] agnos 11.10 (#34764) --- launch_env.sh | 2 +- system/hardware/tici/agnos.json | 12 ++++---- system/hardware/tici/all-partitions.json | 36 ++++++++++++------------ 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/launch_env.sh b/launch_env.sh index 88c6550443..049b9da279 100755 --- a/launch_env.sh +++ b/launch_env.sh @@ -7,7 +7,7 @@ export OPENBLAS_NUM_THREADS=1 export VECLIB_MAXIMUM_THREADS=1 if [ -z "$AGNOS_VERSION" ]; then - export AGNOS_VERSION="11.9" + export AGNOS_VERSION="11.10" fi export STAGING_ROOT="/data/safe_staging" diff --git a/system/hardware/tici/agnos.json b/system/hardware/tici/agnos.json index 6538560363..d42c8151ab 100644 --- a/system/hardware/tici/agnos.json +++ b/system/hardware/tici/agnos.json @@ -67,17 +67,17 @@ }, { "name": "system", - "url": "https://commadist.azureedge.net/agnosupdate/system-061783c4826369c7aa711266e8e1d9eecfd0a6d6c8afc6042e4045617512be75.img.xz", - "hash": "affcc08700026f1726ef16337e031fffc5556435b2b0facea81c7ffb0b66560c", - "hash_raw": "061783c4826369c7aa711266e8e1d9eecfd0a6d6c8afc6042e4045617512be75", + "url": "https://commadist.azureedge.net/agnosupdate/system-5612484e7f255659c0845de620e7c733afd2e1b939f9464f5ef039721bb7cba9.img.xz", + "hash": "e4872f4132111b7b28586d978dd01bb48ffa031e103d029ebede7613c1bc2aa6", + "hash_raw": "5612484e7f255659c0845de620e7c733afd2e1b939f9464f5ef039721bb7cba9", "size": 4404019200, "sparse": true, "full_check": false, "has_ab": true, - "ondevice_hash": "cc86836c6fc1c54f24dd0395e57e0b1ac6efe44d3ece833ab3ed456fe46a55cf", + "ondevice_hash": "4e5e680b4ac387ddc974b32dd3d5ec1d76282511eab974866b3b72399034985e", "alt": { - "hash": "061783c4826369c7aa711266e8e1d9eecfd0a6d6c8afc6042e4045617512be75", - "url": "https://commadist.azureedge.net/agnosupdate/system-061783c4826369c7aa711266e8e1d9eecfd0a6d6c8afc6042e4045617512be75.img", + "hash": "5612484e7f255659c0845de620e7c733afd2e1b939f9464f5ef039721bb7cba9", + "url": "https://commadist.azureedge.net/agnosupdate/system-5612484e7f255659c0845de620e7c733afd2e1b939f9464f5ef039721bb7cba9.img", "size": 4404019200 } } diff --git a/system/hardware/tici/all-partitions.json b/system/hardware/tici/all-partitions.json index 5b3478f746..e90e8c2ec4 100644 --- a/system/hardware/tici/all-partitions.json +++ b/system/hardware/tici/all-partitions.json @@ -350,51 +350,51 @@ }, { "name": "system", - "url": "https://commadist.azureedge.net/agnosupdate/system-061783c4826369c7aa711266e8e1d9eecfd0a6d6c8afc6042e4045617512be75.img.xz", - "hash": "affcc08700026f1726ef16337e031fffc5556435b2b0facea81c7ffb0b66560c", - "hash_raw": "061783c4826369c7aa711266e8e1d9eecfd0a6d6c8afc6042e4045617512be75", + "url": "https://commadist.azureedge.net/agnosupdate/system-5612484e7f255659c0845de620e7c733afd2e1b939f9464f5ef039721bb7cba9.img.xz", + "hash": "e4872f4132111b7b28586d978dd01bb48ffa031e103d029ebede7613c1bc2aa6", + "hash_raw": "5612484e7f255659c0845de620e7c733afd2e1b939f9464f5ef039721bb7cba9", "size": 4404019200, "sparse": true, "full_check": false, "has_ab": true, - "ondevice_hash": "cc86836c6fc1c54f24dd0395e57e0b1ac6efe44d3ece833ab3ed456fe46a55cf", + "ondevice_hash": "4e5e680b4ac387ddc974b32dd3d5ec1d76282511eab974866b3b72399034985e", "alt": { - "hash": "061783c4826369c7aa711266e8e1d9eecfd0a6d6c8afc6042e4045617512be75", - "url": "https://commadist.azureedge.net/agnosupdate/system-061783c4826369c7aa711266e8e1d9eecfd0a6d6c8afc6042e4045617512be75.img", + "hash": "5612484e7f255659c0845de620e7c733afd2e1b939f9464f5ef039721bb7cba9", + "url": "https://commadist.azureedge.net/agnosupdate/system-5612484e7f255659c0845de620e7c733afd2e1b939f9464f5ef039721bb7cba9.img", "size": 4404019200 } }, { "name": "userdata_90", - "url": "https://commadist.azureedge.net/agnosupdate/userdata_90-fd9d27a3ef5c1f63b85721798ba4ea10f2a4c71d0c8d9b59362a99f24dfff54a.img.xz", - "hash": "b77b66ae8178519dbd72443ff7bdd21b97d0d4d76425472bedc7d369958de37b", - "hash_raw": "fd9d27a3ef5c1f63b85721798ba4ea10f2a4c71d0c8d9b59362a99f24dfff54a", + "url": "https://commadist.azureedge.net/agnosupdate/userdata_90-16c037fa42ee99bc6ec92909efc8a8075a0e8a0232a7d90e39e7d40a7bd0ee8e.img.xz", + "hash": "c6fb215f2b297f7ff5b8f133bc5d687772b37f2fee42a44aa730e37a84a14e52", + "hash_raw": "16c037fa42ee99bc6ec92909efc8a8075a0e8a0232a7d90e39e7d40a7bd0ee8e", "size": 96636764160, "sparse": true, "full_check": true, "has_ab": false, - "ondevice_hash": "52d2b8e2486e7fa0cdeb2a6512a8058db43544c905367a2e1b81a5ad4636d4b7" + "ondevice_hash": "7199262f209abbb07be5eece505ac4d4c7ba8957f2d9ff7b1ac1ef2063461665" }, { "name": "userdata_89", - "url": "https://commadist.azureedge.net/agnosupdate/userdata_89-1042711c5f69146ff7680f09eab1b2eb6fe9da0411318e9ff913c27168cb0307.img.xz", - "hash": "cc24b1c78234f92cd8ef66541f3fb8924719fc4b7f42c26e26eb71ec21cd2e93", - "hash_raw": "1042711c5f69146ff7680f09eab1b2eb6fe9da0411318e9ff913c27168cb0307", + "url": "https://commadist.azureedge.net/agnosupdate/userdata_89-62c2c41470282b581ec1bbbe0375fb3b6c66df2f4bc3dc6c6fdf796f1797f136.img.xz", + "hash": "d66f894436fa11d4ff00f8a84e54d9e23a6492b0087f69bb958d2ab0bdc6dfba", + "hash_raw": "62c2c41470282b581ec1bbbe0375fb3b6c66df2f4bc3dc6c6fdf796f1797f136", "size": 95563022336, "sparse": true, "full_check": true, "has_ab": false, - "ondevice_hash": "80bf38b8b60ea1ef1fc0849af4e18bf114761f98f5371476e2f762d0f8463204" + "ondevice_hash": "f1d3685618f6d1bde24ce6109284c5d30ece2f4fd015be67e8b52ef7e06067a4" }, { "name": "userdata_30", - "url": "https://commadist.azureedge.net/agnosupdate/userdata_30-6d429550c42616e3f252034305f238ce0e90926762992ff3f92322f226caa5b6.img.xz", - "hash": "657b052cf6434ef19ff73bdeaf5b2511e5c42f64594ae37bac467a12b4cd673f", - "hash_raw": "6d429550c42616e3f252034305f238ce0e90926762992ff3f92322f226caa5b6", + "url": "https://commadist.azureedge.net/agnosupdate/userdata_30-3e71d8804c90a6dff5048edb976149f9ea177efa139dea47cb585cef76b26f6e.img.xz", + "hash": "1b201ecbd0e1573777811bf18fa90cb080bfbccb34a6dcfd39b412632e7ca699", + "hash_raw": "3e71d8804c90a6dff5048edb976149f9ea177efa139dea47cb585cef76b26f6e", "size": 32212254720, "sparse": true, "full_check": true, "has_ab": false, - "ondevice_hash": "6437e5a5b7144103952950f2f59f8e70b98cd26ee5bfb06cbd0a13b2e2f343b7" + "ondevice_hash": "47c28e63209556442cd9d2fd06a6c0e7fcf35c8a4e4fbcc550b9c089429ad0e0" } ] \ No newline at end of file From 701868d5cddb1fa2a4e84289b0e45c4232322c72 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 3 Mar 2025 18:21:02 -0800 Subject: [PATCH 27/78] firehose auto start + stats (#34747) * don't need that * stats * lil more * lil more * cleanup * tweaks --------- Co-authored-by: Comma Device --- common/params_keys.h | 2 +- selfdrive/ui/qt/offroad/firehose.cc | 99 +++++++++++++++-------------- selfdrive/ui/qt/offroad/firehose.h | 19 +++--- system/athena/athenad.py | 4 -- 4 files changed, 62 insertions(+), 62 deletions(-) diff --git a/common/params_keys.h b/common/params_keys.h index 40a69ebd88..2b540b744c 100644 --- a/common/params_keys.h +++ b/common/params_keys.h @@ -8,6 +8,7 @@ inline static std::unordered_map keys = { {"AdbEnabled", PERSISTENT}, {"AlwaysOnDM", PERSISTENT}, {"ApiCache_Device", PERSISTENT}, + {"ApiCache_FirehoseStats", PERSISTENT}, {"AssistNowToken", PERSISTENT}, {"AthenadPid", PERSISTENT}, {"AthenadUploadQueue", PERSISTENT}, @@ -36,7 +37,6 @@ inline static std::unordered_map keys = { {"ExperimentalLongitudinalEnabled", PERSISTENT | DEVELOPMENT_ONLY}, {"ExperimentalMode", PERSISTENT}, {"ExperimentalModeConfirmed", PERSISTENT}, - {"FirehoseMode", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION}, {"FirmwareQueryDone", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION}, {"ForcePowerDown", PERSISTENT}, {"GitBranch", PERSISTENT}, diff --git a/selfdrive/ui/qt/offroad/firehose.cc b/selfdrive/ui/qt/offroad/firehose.cc index 7b48b0fd9a..77474d00c2 100644 --- a/selfdrive/ui/qt/offroad/firehose.cc +++ b/selfdrive/ui/qt/offroad/firehose.cc @@ -10,6 +10,9 @@ #include #include #include +#include +#include +#include FirehosePanel::FirehosePanel(SettingsWindow *parent) : QWidget((QWidget*)parent) { layout = new QVBoxLayout(this); @@ -28,7 +31,7 @@ FirehosePanel::FirehosePanel(SettingsWindow *parent) : QWidget((QWidget*)parent) content_layout->setSpacing(20); // Top description - QLabel *description = new QLabel(tr("openpilot learns to drive by watching humans, like you, drive.\n\nFirehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models with better Experimental Mode.")); + QLabel *description = new QLabel(tr("openpilot learns to drive by watching humans, like you, drive.\n\nFirehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models, which means better Experimental Mode.")); description->setStyleSheet("font-size: 45px; padding-bottom: 20px;"); description->setWordWrap(true); content_layout->addWidget(description); @@ -40,41 +43,16 @@ FirehosePanel::FirehosePanel(SettingsWindow *parent) : QWidget((QWidget*)parent) line->setStyleSheet("background-color: #444444; margin-top: 5px; margin-bottom: 5px;"); content_layout->addWidget(line); - enable_firehose = new ParamControl("FirehoseMode", tr("Enable Firehose Mode"), "", ""); + toggle_label = new QLabel(tr("Firehose Mode: ACTIVE")); + toggle_label->setStyleSheet("font-size: 60px; font-weight: bold; color: white;"); + content_layout->addWidget(toggle_label); - content_layout->addWidget(enable_firehose); - - // Create progress bar container - progress_container = new QFrame(); - progress_container->hide(); - QHBoxLayout *progress_layout = new QHBoxLayout(progress_container); - progress_layout->setContentsMargins(10, 0, 10, 10); - progress_layout->setSpacing(20); - - progress_bar = new QProgressBar(); - progress_bar->setRange(0, 100); - progress_bar->setValue(0); - progress_bar->setTextVisible(false); - progress_bar->setStyleSheet(R"( - QProgressBar { - background-color: #444444; - border-radius: 10px; - height: 20px; - } - QProgressBar::chunk { - background-color: #3498db; - border-radius: 10px; - } - )"); - progress_bar->setFixedHeight(40); - - // Progress text - progress_text = new QLabel(tr("0%")); - progress_text->setStyleSheet("font-size: 40px; font-weight: bold; color: white;"); - - progress_layout->addWidget(progress_text); - - content_layout->addWidget(progress_container); + // Add contribution label + contribution_label = new QLabel("0 minutes"); + contribution_label->setStyleSheet("font-size: 52px; margin-top: 10px; margin-bottom: 10px;"); + contribution_label->setWordWrap(true); + contribution_label->hide(); + content_layout->addWidget(contribution_label); // Add a separator before detailed instructions QFrame *line2 = new QFrame(); @@ -85,22 +63,49 @@ FirehosePanel::FirehosePanel(SettingsWindow *parent) : QWidget((QWidget*)parent) // Detailed instructions at the bottom detailed_instructions = new QLabel(tr( - "Follow these steps to get your device ready:
" - "\t1. Bring your device inside and connect to a good USB-C adapter
" - "\t2. Connect to Wi-Fi
" - "\t3. Enable the toggle
" - "\t4. Leave it connected for at least 30 minutes
" + "For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.
" "
" - "The toggle turns off once you restart your device. Repeat at least once a week for maximum effectiveness." - "

FAQ
" - "Does it matter how or where I drive? Nope, just drive as you normally would.
" - "What's a good USB-C adapter? Any fast phone or laptop charger should be fine.
" - "Do I need to be on Wi-Fi? Yes.
" - "Do I need to bring the device inside? No, you can enable once you're parked, however your uploads will be limited by your car's battery.
" + "Firehose Mode can also work while you're driving if connected to a hotspot or unlimited SIM card.
" + "

" + "Frequently Asked Questions

" + "Does it matter how or where I drive? Nope, just drive as you normally would.

" + "What's a good USB-C adapter? Any fast phone or laptop charger should be fine.

" + "Does it matter which software I run? Yes, only upstream openpilot (and particular forks) are able to be used for training." )); - detailed_instructions->setStyleSheet("font-size: 40px; padding: 20px; color: #E4E4E4;"); + detailed_instructions->setStyleSheet("font-size: 40px; color: #E4E4E4;"); detailed_instructions->setWordWrap(true); content_layout->addWidget(detailed_instructions); layout->addWidget(content, 1); + + // Set up the API request for firehose stats + const QString dongle_id = QString::fromStdString(Params().get("DongleId")); + firehose_stats = new RequestRepeater(this, CommaApi::BASE_URL + "/v1/devices/" + dongle_id + "/firehose_stats", + "ApiCache_FirehoseStats", 30, true); + QObject::connect(firehose_stats, &RequestRepeater::requestDone, [=](const QString &response, bool success) { + if (success) { + QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8()); + QJsonObject json = doc.object(); + int count = json["firehose"].toInt(); + contribution_label->setText(tr("%1 %2 of your driving are in the training dataset so far.").arg(count).arg(count == 1 ? "segment" : "segments")); + contribution_label->show(); + } + }); + + QObject::connect(uiState(), &UIState::uiUpdate, this, &FirehosePanel::refresh); +} + +void FirehosePanel::refresh() { + auto deviceState = (*uiState()->sm)["deviceState"].getDeviceState(); + auto networkType = deviceState.getNetworkType(); + bool networkMetered = deviceState.getNetworkMetered(); + + bool is_active = !networkMetered && (networkType != cereal::DeviceState::NetworkType::NONE); + if (is_active) { + toggle_label->setText(tr("ACTIVE")); + toggle_label->setStyleSheet("font-size: 60px; font-weight: bold; color: #2ecc71;"); + } else { + toggle_label->setText(tr("INACTIVE: connect to unmetered network")); + toggle_label->setStyleSheet("font-size: 60px;"); + } } diff --git a/selfdrive/ui/qt/offroad/firehose.h b/selfdrive/ui/qt/offroad/firehose.h index 7f5899f9f0..9082cb0f99 100644 --- a/selfdrive/ui/qt/offroad/firehose.h +++ b/selfdrive/ui/qt/offroad/firehose.h @@ -2,10 +2,8 @@ #include #include -#include #include -#include "selfdrive/ui/qt/widgets/controls.h" -#include "common/params.h" +#include "selfdrive/ui/qt/request_repeater.h" // Forward declarations class SettingsWindow; @@ -17,12 +15,13 @@ public: private: QVBoxLayout *layout; - - ParamControl *enable_firehose; - QFrame *progress_container; - QProgressBar *progress_bar; - QLabel *progress_text; + QLabel *detailed_instructions; - - void updateFirehoseState(bool enabled); + QLabel *contribution_label; + QLabel *toggle_label; + + RequestRepeater *firehose_stats; + +private slots: + void refresh(); }; diff --git a/system/athena/athenad.py b/system/athena/athenad.py index 27440e84a6..b36bdb103d 100755 --- a/system/athena/athenad.py +++ b/system/athena/athenad.py @@ -508,10 +508,6 @@ def getSshAuthorizedKeys() -> str: def getGithubUsername() -> str: return Params().get("GithubUsername", encoding='utf8') or '' -@dispatcher.add_method -def getFirehoseMode() -> bool: - return Params().get_bool("FirehoseMode") or False - @dispatcher.add_method def getSimInfo(): return HARDWARE.get_sim_info() From 34a072890cc3c963ea6cb2cdaa23c96f3d802a93 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 3 Mar 2025 18:39:12 -0800 Subject: [PATCH 28/78] fix translations --- selfdrive/ui/qt/offroad/firehose.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/ui/qt/offroad/firehose.cc b/selfdrive/ui/qt/offroad/firehose.cc index 77474d00c2..ab1d0198c7 100644 --- a/selfdrive/ui/qt/offroad/firehose.cc +++ b/selfdrive/ui/qt/offroad/firehose.cc @@ -48,7 +48,7 @@ FirehosePanel::FirehosePanel(SettingsWindow *parent) : QWidget((QWidget*)parent) content_layout->addWidget(toggle_label); // Add contribution label - contribution_label = new QLabel("0 minutes"); + contribution_label = new QLabel(); contribution_label->setStyleSheet("font-size: 52px; margin-top: 10px; margin-bottom: 10px;"); contribution_label->setWordWrap(true); contribution_label->hide(); From 338b7c915fd37345fe925088c7444ddfdbab9e3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20R=C4=85czy?= Date: Mon, 3 Mar 2025 22:10:48 -0500 Subject: [PATCH 29/78] regen: use ci bucket for files (#34766) * Remove route meta mode * use get_url * Remove useless import --- selfdrive/test/process_replay/regen.py | 52 +++++++--------------- selfdrive/test/process_replay/regen_all.py | 2 +- 2 files changed, 18 insertions(+), 36 deletions(-) diff --git a/selfdrive/test/process_replay/regen.py b/selfdrive/test/process_replay/regen.py index e87b8347e1..4d00613f0a 100755 --- a/selfdrive/test/process_replay/regen.py +++ b/selfdrive/test/process_replay/regen.py @@ -12,10 +12,9 @@ from openpilot.selfdrive.test.process_replay.process_replay import CONFIGS, FAKE check_openpilot_enabled, check_most_messages_valid, get_custom_params_from_lr from openpilot.selfdrive.test.process_replay.vision_meta import DRIVER_CAMERA_FRAME_SIZES from openpilot.selfdrive.test.update_ci_routes import upload_route -from openpilot.tools.lib.route import Route from openpilot.tools.lib.framereader import FrameReader, BaseFrameReader, FrameType from openpilot.tools.lib.logreader import LogReader, LogIterable, save_log - +from openpilot.tools.lib.openpilotci import get_url class DummyFrameReader(BaseFrameReader): def __init__(self, w: int, h: int, frame_count: int, pix_val: int): @@ -55,45 +54,28 @@ def regen_segment( def setup_data_readers( - route: str, sidx: int, use_route_meta: bool, - needs_driver_cam: bool = True, needs_road_cam: bool = True, dummy_driver_cam: bool = False + route: str, sidx: int, needs_driver_cam: bool = True, needs_road_cam: bool = True, dummy_driver_cam: bool = False ) -> tuple[LogReader, dict[str, Any]]: - if use_route_meta: - r = Route(route) - lr = LogReader(r.log_paths()[sidx]) - frs = {} - if needs_road_cam and len(r.camera_paths()) > sidx and r.camera_paths()[sidx] is not None: - frs['roadCameraState'] = FrameReader(r.camera_paths()[sidx]) - if needs_road_cam and len(r.ecamera_paths()) > sidx and r.ecamera_paths()[sidx] is not None: - frs['wideRoadCameraState'] = FrameReader(r.ecamera_paths()[sidx]) - if needs_driver_cam: - if dummy_driver_cam: - frs['driverCameraState'] = DummyFrameReader.zero_dcamera() - elif len(r.dcamera_paths()) > sidx and r.dcamera_paths()[sidx] is not None: - device_type = next(str(msg.initData.deviceType) for msg in lr if msg.which() == "initData") - assert device_type != "neo", "Driver camera not supported on neo segments. Use dummy dcamera." - frs['driverCameraState'] = FrameReader(r.dcamera_paths()[sidx]) - else: - lr = LogReader(f"{route}/{sidx}/r") - frs = {} - if needs_road_cam: - frs['roadCameraState'] = FrameReader(f"cd:/{route.replace('|', '/')}/{sidx}/fcamera.hevc") - if next((True for m in lr if m.which() == "wideRoadCameraState"), False): - frs['wideRoadCameraState'] = FrameReader(f"cd:/{route.replace('|', '/')}/{sidx}/ecamera.hevc") - if needs_driver_cam: - if dummy_driver_cam: - frs['driverCameraState'] = DummyFrameReader.zero_dcamera() - else: - device_type = next(str(msg.initData.deviceType) for msg in lr if msg.which() == "initData") - assert device_type != "neo", "Driver camera not supported on neo segments. Use dummy dcamera." - frs['driverCameraState'] = FrameReader(f"cd:/{route.replace('|', '/')}/{sidx}/dcamera.hevc") + lr = LogReader(f"{route}/{sidx}/r") + frs = {} + if needs_road_cam: + frs['roadCameraState'] = FrameReader(get_url(route, str(sidx), "fcamera.hevc")) + if next((True for m in lr if m.which() == "wideRoadCameraState"), False): + frs['wideRoadCameraState'] = FrameReader(get_url(route, str(sidx), "ecamera.hevc")) + if needs_driver_cam: + if dummy_driver_cam: + frs['driverCameraState'] = DummyFrameReader.zero_dcamera() + else: + device_type = next(str(msg.initData.deviceType) for msg in lr if msg.which() == "initData") + assert device_type != "neo", "Driver camera not supported on neo segments. Use dummy dcamera." + frs['driverCameraState'] = FrameReader(get_url(route, str(sidx), "dcamera.hevc")) return lr, frs def regen_and_save( route: str, sidx: int, processes: str | Iterable[str] = "all", outdir: str = FAKEDATA, - upload: bool = False, use_route_meta: bool = False, disable_tqdm: bool = False, dummy_driver_cam: bool = False + upload: bool = False, disable_tqdm: bool = False, dummy_driver_cam: bool = False ) -> str: if not isinstance(processes, str) and not hasattr(processes, "__iter__"): raise ValueError("whitelist_proc must be a string or iterable") @@ -110,7 +92,7 @@ def regen_and_save( replayed_processes = CONFIGS all_vision_pubs = {pub for cfg in replayed_processes for pub in cfg.vision_pubs} - lr, frs = setup_data_readers(route, sidx, use_route_meta, + lr, frs = setup_data_readers(route, sidx, needs_driver_cam="driverCameraState" in all_vision_pubs, needs_road_cam="roadCameraState" in all_vision_pubs or "wideRoadCameraState" in all_vision_pubs, dummy_driver_cam=dummy_driver_cam) diff --git a/selfdrive/test/process_replay/regen_all.py b/selfdrive/test/process_replay/regen_all.py index 656a5b89e1..78a90b420c 100755 --- a/selfdrive/test/process_replay/regen_all.py +++ b/selfdrive/test/process_replay/regen_all.py @@ -17,7 +17,7 @@ def regen_job(segment, upload, disable_tqdm): sn = SegmentName(segment[1]) fake_dongle_id = 'regen' + ''.join(random.choice('0123456789ABCDEF') for _ in range(11)) try: - relr = regen_and_save(sn.route_name.canonical_name, sn.segment_num, upload=upload, use_route_meta=False, + relr = regen_and_save(sn.route_name.canonical_name, sn.segment_num, upload=upload, outdir=os.path.join(FAKEDATA, fake_dongle_id), disable_tqdm=disable_tqdm, dummy_driver_cam=True) relr = '|'.join(relr.split('/')[-2:]) return f' ("{segment[0]}", "{relr}"), ' From 9c9a060365582eed91548a6c3d1fb368f73bc56e Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 3 Mar 2025 19:11:53 -0800 Subject: [PATCH 30/78] saturated warning: remove redundant speed check --- selfdrive/selfdrived/selfdrived.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/selfdrive/selfdrived/selfdrived.py b/selfdrive/selfdrived/selfdrived.py index 784925c966..68716c1f64 100755 --- a/selfdrive/selfdrived/selfdrived.py +++ b/selfdrive/selfdrived/selfdrived.py @@ -331,8 +331,8 @@ class SelfdriveD: desired_lateral_accel = controlstate.desiredCurvature * (clipped_speed**2) undershooting = abs(desired_lateral_accel) / abs(1e-3 + actual_lateral_accel) > 1.2 turning = abs(desired_lateral_accel) > 1.0 - good_speed = CS.vEgo > 5 - if undershooting and turning and good_speed and lac.saturated: + # TODO: lac.saturated includes speed and other checks, should be pulled out + if undershooting and turning and lac.saturated: self.events.add(EventName.steerSaturated) # Check for FCW From 949aaaba2c6ddc57c54bbd7ca938b476d7b15545 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 3 Mar 2025 19:34:33 -0800 Subject: [PATCH 31/78] regenerate problem segments --- selfdrive/test/process_replay/ref_commit | 2 +- selfdrive/test/process_replay/test_processes.py | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 3c63f00300..d0f0d671d7 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -d343af55506b14a4011bfe43b2a49c7e3c387d75 \ No newline at end of file +a9487c6a5c2f0bb83c9d629ff64c8f64a4e4ca13 \ No newline at end of file diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py index 0fff34917f..927f54c0c3 100755 --- a/selfdrive/test/process_replay/test_processes.py +++ b/selfdrive/test/process_replay/test_processes.py @@ -42,22 +42,22 @@ source_segments = [ segments = [ ("BODY", "regenA67A128BCD8|2024-08-30--02-36-22--0"), - ("HYUNDAI", "regen9CBD921E93E|2024-08-30--02-38-51--0"), + ("HYUNDAI", "regenCCD47FEBC0C|2025-03-04--03-21-48--0"), ("HYUNDAI2", "regen306779F6870|2024-10-03--04-03-23--0"), - ("TOYOTA", "regen1CA7A48E6F7|2024-08-30--02-45-08--0"), + ("TOYOTA", "regen4A5115B248D|2025-03-04--03-21-43--0"), ("TOYOTA2", "regen6E484EDAB96|2024-08-30--02-47-37--0"), ("TOYOTA3", "regen4CE950B0267|2024-08-30--02-51-30--0"), - ("HONDA", "regenC8F0D6ADC5C|2024-08-30--02-54-01--0"), + ("HONDA", "regenB8CABEC09CC|2025-03-04--03-32-55--0"), ("HONDA2", "regen4B38A7428CD|2024-08-30--02-56-31--0"), ("CHRYSLER", "regenF3DBBA9E8DF|2024-08-30--02-59-03--0"), ("RAM", "regenDB02684E00A|2024-08-30--03-02-54--0"), - ("SUBARU", "regenAA1FF48CF1F|2024-08-30--03-06-45--0"), + ("SUBARU", "regen5E3347D0A0F|2025-03-04--03-23-55--0"), ("GM", "regen720F2BA4CF6|2024-08-30--03-09-15--0"), ("GM2", "regen9ADBECBCD1C|2024-08-30--03-13-04--0"), ("NISSAN", "regen58464878D07|2024-08-30--03-15-31--0"), ("VOLKSWAGEN", "regenED976DEB757|2024-08-30--03-18-02--0"), ("MAZDA", "regenACF84CCF482|2024-08-30--03-21-55--0"), - ("FORD", "regen756F8230C21|2024-11-07--00-08-24--0"), + ("FORD", "regenA75209BD115|2025-03-04--03-23-53--0"), ("RIVIAN", "bc095dc92e101734|000000db--ee9fe46e57--1"), ] From 6891b795c49070a8916946454a85fae0fddb84a6 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 3 Mar 2025 21:47:52 -0600 Subject: [PATCH 32/78] controls: limit max curvature from lateral acceleration (#34651) * limit max curvature with lateral accel too * not a guideline * roll compensation in curv clip * improve clipping and alerting * typo * clean up * no float * get ready * good idea * good * redundant * TODO * test * do max curvature clip last * flip --------- Co-authored-by: Bruce Wayne --- selfdrive/controls/controlsd.py | 8 ++--- selfdrive/controls/lib/drive_helpers.py | 34 +++++++++++++------ selfdrive/controls/lib/latcontrol.py | 7 ++-- selfdrive/controls/lib/latcontrol_angle.py | 4 +-- selfdrive/controls/lib/latcontrol_pid.py | 4 +-- selfdrive/controls/lib/latcontrol_torque.py | 4 +-- .../controls/lib/tests/test_latcontrol.py | 12 +++++-- selfdrive/selfdrived/selfdrived.py | 2 +- 8 files changed, 49 insertions(+), 26 deletions(-) diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 14fd37040e..dcc1c74794 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -109,11 +109,11 @@ class Controls: actuators.accel = float(self.LoC.update(CC.longActive, CS, long_plan.aTarget, long_plan.shouldStop, pid_accel_limits)) # Steering PID loop and lateral MPC - self.desired_curvature = clip_curvature(CS.vEgo, self.desired_curvature, model_v2.action.desiredCurvature) - actuators.curvature = float(self.desired_curvature) + self.desired_curvature, curvature_limited = clip_curvature(CS.vEgo, self.desired_curvature, model_v2.action.desiredCurvature, lp.roll) + actuators.curvature = self.desired_curvature steer, steeringAngleDeg, lac_log = self.LaC.update(CC.latActive, CS, self.VM, lp, self.steer_limited_by_controls, self.desired_curvature, - self.calibrated_pose) # TODO what if not available + self.calibrated_pose, curvature_limited) # TODO what if not available actuators.torque = float(steer) actuators.steeringAngleDeg = float(steeringAngleDeg) # Ensure no NaNs/Infs @@ -180,7 +180,7 @@ class Controls: cs.longitudinalPlanMonoTime = self.sm.logMonoTime['longitudinalPlan'] cs.lateralPlanMonoTime = self.sm.logMonoTime['modelV2'] - cs.desiredCurvature = float(self.desired_curvature) + cs.desiredCurvature = self.desired_curvature cs.longControlState = self.LoC.long_control_state cs.upAccelCmd = float(self.LoC.pid.p) cs.uiAccelCmd = float(self.LoC.pid.i) diff --git a/selfdrive/controls/lib/drive_helpers.py b/selfdrive/controls/lib/drive_helpers.py index dcb0093a18..41384abae8 100644 --- a/selfdrive/controls/lib/drive_helpers.py +++ b/selfdrive/controls/lib/drive_helpers.py @@ -1,5 +1,6 @@ import numpy as np from cereal import log +from opendbc.car.vehicle_model import ACCELERATION_DUE_TO_GRAVITY from openpilot.common.realtime import DT_CTRL MIN_SPEED = 1.0 @@ -7,20 +8,33 @@ CONTROL_N = 17 CAR_ROTATION_RADIUS = 0.0 # This is a turn radius smaller than most cars can achieve MAX_CURVATURE = 0.2 +MAX_VEL_ERR = 5.0 # m/s # EU guidelines -MAX_LATERAL_JERK = 5.0 -MAX_VEL_ERR = 5.0 +MAX_LATERAL_JERK = 5.0 # m/s^3 +MAX_LATERAL_ACCEL_NO_ROLL = 3.0 # m/s^2 -def clip_curvature(v_ego, prev_curvature, new_curvature): - new_curvature = np.clip(new_curvature, -MAX_CURVATURE, MAX_CURVATURE) - v_ego = max(MIN_SPEED, v_ego) - max_curvature_rate = MAX_LATERAL_JERK / (v_ego**2) # inexact calculation, check https://github.com/commaai/openpilot/pull/24755 - safe_desired_curvature = np.clip(new_curvature, - prev_curvature - max_curvature_rate * DT_CTRL, - prev_curvature + max_curvature_rate * DT_CTRL) - return safe_desired_curvature +def clamp(val, min_val, max_val): + clamped_val = float(np.clip(val, min_val, max_val)) + return clamped_val, clamped_val != val + + +def clip_curvature(v_ego, prev_curvature, new_curvature, roll): + # This function respects ISO lateral jerk and acceleration limits + a max curvature + v_ego = max(v_ego, MIN_SPEED) + max_curvature_rate = MAX_LATERAL_JERK / (v_ego ** 2) # inexact calculation, check https://github.com/commaai/openpilot/pull/24755 + new_curvature = np.clip(new_curvature, + prev_curvature - max_curvature_rate * DT_CTRL, + prev_curvature + max_curvature_rate * DT_CTRL) + + roll_compensation = roll * ACCELERATION_DUE_TO_GRAVITY + max_lat_accel = MAX_LATERAL_ACCEL_NO_ROLL + roll_compensation + min_lat_accel = -MAX_LATERAL_ACCEL_NO_ROLL + roll_compensation + new_curvature, limited_accel = clamp(new_curvature, min_lat_accel / v_ego ** 2, max_lat_accel / v_ego ** 2) + + new_curvature, limited_max_curv = clamp(new_curvature, -MAX_CURVATURE, MAX_CURVATURE) + return float(new_curvature), limited_accel or limited_max_curv def get_speed_error(modelV2: log.ModelDataV2, v_ego: float) -> float: diff --git a/selfdrive/controls/lib/latcontrol.py b/selfdrive/controls/lib/latcontrol.py index f0121f73bc..dcf0003430 100644 --- a/selfdrive/controls/lib/latcontrol.py +++ b/selfdrive/controls/lib/latcontrol.py @@ -17,14 +17,15 @@ class LatControl(ABC): self.steer_max = 1.0 @abstractmethod - def update(self, active, CS, VM, params, steer_limited_by_controls, desired_curvature, calibrated_pose): + def update(self, active, CS, VM, params, steer_limited_by_controls, desired_curvature, calibrated_pose, curvature_limited): pass def reset(self): self.sat_count = 0. - def _check_saturation(self, saturated, CS, steer_limited_by_controls): - if saturated and CS.vEgo > self.sat_check_min_speed and not steer_limited_by_controls and not CS.steeringPressed: + def _check_saturation(self, saturated, CS, steer_limited_by_controls, curvature_limited): + # Saturated only if control output is not being limited by car torque/angle rate limits + if (saturated or curvature_limited) and CS.vEgo > self.sat_check_min_speed and not steer_limited_by_controls and not CS.steeringPressed: self.sat_count += self.sat_count_rate else: self.sat_count -= self.sat_count_rate diff --git a/selfdrive/controls/lib/latcontrol_angle.py b/selfdrive/controls/lib/latcontrol_angle.py index de07423fd4..1b249a3d1a 100644 --- a/selfdrive/controls/lib/latcontrol_angle.py +++ b/selfdrive/controls/lib/latcontrol_angle.py @@ -11,7 +11,7 @@ class LatControlAngle(LatControl): super().__init__(CP, CI) self.sat_check_min_speed = 5. - def update(self, active, CS, VM, params, steer_limited_by_controls, desired_curvature, calibrated_pose): + def update(self, active, CS, VM, params, steer_limited_by_controls, desired_curvature, calibrated_pose, curvature_limited): angle_log = log.ControlsState.LateralAngleState.new_message() if not active: @@ -23,7 +23,7 @@ class LatControlAngle(LatControl): angle_steers_des += params.angleOffsetDeg angle_control_saturated = abs(angle_steers_des - CS.steeringAngleDeg) > STEER_ANGLE_SATURATION_THRESHOLD - angle_log.saturated = bool(self._check_saturation(angle_control_saturated, CS, False)) + angle_log.saturated = bool(self._check_saturation(angle_control_saturated, CS, False, curvature_limited)) angle_log.steeringAngleDeg = float(CS.steeringAngleDeg) angle_log.steeringAngleDesiredDeg = angle_steers_des return 0, float(angle_steers_des), angle_log diff --git a/selfdrive/controls/lib/latcontrol_pid.py b/selfdrive/controls/lib/latcontrol_pid.py index cf54125a77..1f1199565e 100644 --- a/selfdrive/controls/lib/latcontrol_pid.py +++ b/selfdrive/controls/lib/latcontrol_pid.py @@ -17,7 +17,7 @@ class LatControlPID(LatControl): super().reset() self.pid.reset() - def update(self, active, CS, VM, params, steer_limited_by_controls, desired_curvature, calibrated_pose): + def update(self, active, CS, VM, params, steer_limited_by_controls, desired_curvature, calibrated_pose, curvature_limited): pid_log = log.ControlsState.LateralPIDState.new_message() pid_log.steeringAngleDeg = float(CS.steeringAngleDeg) pid_log.steeringRateDeg = float(CS.steeringRateDeg) @@ -43,6 +43,6 @@ class LatControlPID(LatControl): pid_log.i = float(self.pid.i) pid_log.f = float(self.pid.f) pid_log.output = float(output_steer) - pid_log.saturated = bool(self._check_saturation(self.steer_max - abs(output_steer) < 1e-3, CS, steer_limited_by_controls)) + pid_log.saturated = bool(self._check_saturation(self.steer_max - abs(output_steer) < 1e-3, CS, steer_limited_by_controls, curvature_limited)) return output_steer, angle_steers_des, pid_log diff --git a/selfdrive/controls/lib/latcontrol_torque.py b/selfdrive/controls/lib/latcontrol_torque.py index 7b00cce56b..3aef57baca 100644 --- a/selfdrive/controls/lib/latcontrol_torque.py +++ b/selfdrive/controls/lib/latcontrol_torque.py @@ -37,7 +37,7 @@ class LatControlTorque(LatControl): self.torque_params.latAccelOffset = latAccelOffset self.torque_params.friction = friction - def update(self, active, CS, VM, params, steer_limited_by_controls, desired_curvature, calibrated_pose): + def update(self, active, CS, VM, params, steer_limited_by_controls, desired_curvature, calibrated_pose, curvature_limited): pid_log = log.ControlsState.LateralTorqueState.new_message() if not active: output_torque = 0.0 @@ -87,7 +87,7 @@ class LatControlTorque(LatControl): pid_log.output = float(-output_torque) pid_log.actualLateralAccel = float(actual_lateral_accel) pid_log.desiredLateralAccel = float(desired_lateral_accel) - pid_log.saturated = bool(self._check_saturation(self.steer_max - abs(output_torque) < 1e-3, CS, steer_limited_by_controls)) + pid_log.saturated = bool(self._check_saturation(self.steer_max - abs(output_torque) < 1e-3, CS, steer_limited_by_controls, curvature_limited)) # TODO left is positive in this convention return -output_torque, 0.0, pid_log diff --git a/selfdrive/controls/lib/tests/test_latcontrol.py b/selfdrive/controls/lib/tests/test_latcontrol.py index c7038dd581..564c93be0d 100644 --- a/selfdrive/controls/lib/tests/test_latcontrol.py +++ b/selfdrive/controls/lib/tests/test_latcontrol.py @@ -33,7 +33,15 @@ class TestLatControl: lp = generate_livePose() pose = Pose.from_live_pose(lp.livePose) + # Saturate for curvature limited and controller limited for _ in range(1000): - _, _, lac_log = controller.update(True, CS, VM, params, False, 1, pose) - + _, _, lac_log = controller.update(True, CS, VM, params, False, 0, pose, True) + assert lac_log.saturated + + for _ in range(1000): + _, _, lac_log = controller.update(True, CS, VM, params, False, 0, pose, False) + assert not lac_log.saturated + + for _ in range(1000): + _, _, lac_log = controller.update(True, CS, VM, params, False, 1, pose, False) assert lac_log.saturated diff --git a/selfdrive/selfdrived/selfdrived.py b/selfdrive/selfdrived/selfdrived.py index 68716c1f64..8b7db19c9a 100755 --- a/selfdrive/selfdrived/selfdrived.py +++ b/selfdrive/selfdrived/selfdrived.py @@ -328,7 +328,7 @@ class SelfdriveD: if lac.active and not recent_steer_pressed and not self.CP.notCar: clipped_speed = max(CS.vEgo, MIN_LATERAL_CONTROL_SPEED) actual_lateral_accel = controlstate.curvature * (clipped_speed**2) - desired_lateral_accel = controlstate.desiredCurvature * (clipped_speed**2) + desired_lateral_accel = self.sm['modelV2'].action.desiredCurvature * (clipped_speed**2) undershooting = abs(desired_lateral_accel) / abs(1e-3 + actual_lateral_accel) > 1.2 turning = abs(desired_lateral_accel) > 1.0 # TODO: lac.saturated includes speed and other checks, should be pulled out From f818c5528f808351e5350e26c88bce4f84a786b5 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 3 Mar 2025 22:24:16 -0600 Subject: [PATCH 33/78] bump opendbc (#34768) bump --- opendbc_repo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opendbc_repo b/opendbc_repo index ca4f77b010..34a109cc79 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit ca4f77b0101d85a5e8d292e2e61f7a8c7492b9e2 +Subproject commit 34a109cc7956dbf022f57b6bca2207f2719e25a7 From e5ba737db0f1991a02896480387dadca6ac46bf4 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 3 Mar 2025 22:56:59 -0800 Subject: [PATCH 34/78] Revert "Filet o Fish model (#34637)" This reverts commit 159b1c9eb48551e6ac1d5f9281ac2218f320f499. --- selfdrive/modeld/constants.py | 8 +----- selfdrive/modeld/modeld.py | 31 +++++++-------------- selfdrive/modeld/models/commonmodel.cc | 9 +++--- selfdrive/modeld/models/commonmodel.h | 5 ++-- selfdrive/modeld/models/commonmodel.pxd | 2 +- selfdrive/modeld/models/commonmodel_pyx.pyx | 4 +-- selfdrive/modeld/models/driving_policy.onnx | 4 +-- selfdrive/modeld/models/driving_vision.onnx | 2 +- 8 files changed, 23 insertions(+), 42 deletions(-) diff --git a/selfdrive/modeld/constants.py b/selfdrive/modeld/constants.py index 5ca0a86bc8..2bb7b8100c 100644 --- a/selfdrive/modeld/constants.py +++ b/selfdrive/modeld/constants.py @@ -14,14 +14,8 @@ class ModelConstants: # model inputs constants MODEL_FREQ = 20 - HISTORY_FREQ = 5 - HISTORY_LEN_SECONDS = 5 - TEMPORAL_SKIP = MODEL_FREQ // HISTORY_FREQ - FULL_HISTORY_BUFFER_LEN = MODEL_FREQ * HISTORY_LEN_SECONDS - INPUT_HISTORY_BUFFER_LEN = HISTORY_FREQ * HISTORY_LEN_SECONDS - FEATURE_LEN = 512 - + FULL_HISTORY_BUFFER_LEN = 100 DESIRE_LEN = 8 TRAFFIC_CONVENTION_LEN = 2 LAT_PLANNER_STATE_LEN = 4 diff --git a/selfdrive/modeld/modeld.py b/selfdrive/modeld/modeld.py index ae1e75e3e9..ee825d158f 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -56,24 +56,16 @@ class ModelState: prev_desire: np.ndarray # for tracking the rising edge of the pulse def __init__(self, context: CLContext): - self.frames = { - 'input_imgs': DrivingModelFrame(context, ModelConstants.TEMPORAL_SKIP), - 'big_input_imgs': DrivingModelFrame(context, ModelConstants.TEMPORAL_SKIP) - } + self.frames = {'input_imgs': DrivingModelFrame(context), 'big_input_imgs': DrivingModelFrame(context)} self.prev_desire = np.zeros(ModelConstants.DESIRE_LEN, dtype=np.float32) - self.full_features_buffer = np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.FEATURE_LEN), dtype=np.float32) - self.full_desire = np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.DESIRE_LEN), dtype=np.float32) - self.full_prev_desired_curv = np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.PREV_DESIRED_CURV_LEN), dtype=np.float32) - self.temporal_idxs = slice(-1-(ModelConstants.TEMPORAL_SKIP*(ModelConstants.INPUT_HISTORY_BUFFER_LEN-1)), None, ModelConstants.TEMPORAL_SKIP) - # policy inputs self.numpy_inputs = { - 'desire': np.zeros((1, ModelConstants.INPUT_HISTORY_BUFFER_LEN, ModelConstants.DESIRE_LEN), dtype=np.float32), + 'desire': np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.DESIRE_LEN), dtype=np.float32), 'traffic_convention': np.zeros((1, ModelConstants.TRAFFIC_CONVENTION_LEN), dtype=np.float32), 'lateral_control_params': np.zeros((1, ModelConstants.LATERAL_CONTROL_PARAMS_LEN), dtype=np.float32), - 'prev_desired_curv': np.zeros((1, ModelConstants.INPUT_HISTORY_BUFFER_LEN, ModelConstants.PREV_DESIRED_CURV_LEN), dtype=np.float32), - 'features_buffer': np.zeros((1, ModelConstants.INPUT_HISTORY_BUFFER_LEN, ModelConstants.FEATURE_LEN), dtype=np.float32), + 'prev_desired_curv': np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.PREV_DESIRED_CURV_LEN), dtype=np.float32), + 'features_buffer': np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.FEATURE_LEN), dtype=np.float32), } with open(VISION_METADATA_PATH, 'rb') as f: @@ -112,9 +104,8 @@ class ModelState: new_desire = np.where(inputs['desire'] - self.prev_desire > .99, inputs['desire'], 0) self.prev_desire[:] = inputs['desire'] - self.full_desire[0,:-1] = self.full_desire[0,1:] - self.full_desire[0,-1] = new_desire - self.numpy_inputs['desire'][:] = self.full_desire[0, self.temporal_idxs] + self.numpy_inputs['desire'][0,:-1] = self.numpy_inputs['desire'][0,1:] + self.numpy_inputs['desire'][0,-1] = new_desire self.numpy_inputs['traffic_convention'][:] = inputs['traffic_convention'] self.numpy_inputs['lateral_control_params'][:] = inputs['lateral_control_params'] @@ -137,17 +128,15 @@ class ModelState: self.vision_output = self.vision_run(**self.vision_inputs).numpy().flatten() vision_outputs_dict = self.parser.parse_vision_outputs(self.slice_outputs(self.vision_output, self.vision_output_slices)) - self.full_features_buffer[0,:-1] = self.full_features_buffer[0,1:] - self.full_features_buffer[0,-1] = vision_outputs_dict['hidden_state'][0, :] - self.numpy_inputs['features_buffer'][:] = self.full_features_buffer[0, self.temporal_idxs] + self.numpy_inputs['features_buffer'][0,:-1] = self.numpy_inputs['features_buffer'][0,1:] + self.numpy_inputs['features_buffer'][0,-1] = vision_outputs_dict['hidden_state'][0, :] self.policy_output = self.policy_run(**self.policy_inputs).numpy().flatten() policy_outputs_dict = self.parser.parse_policy_outputs(self.slice_outputs(self.policy_output, self.policy_output_slices)) # TODO model only uses last value now - self.full_prev_desired_curv[0,:-1] = self.full_prev_desired_curv[0,1:] - self.full_prev_desired_curv[0,-1,:] = policy_outputs_dict['desired_curvature'][0, :] - self.numpy_inputs['prev_desired_curv'][:] = self.full_prev_desired_curv[0, self.temporal_idxs] + self.numpy_inputs['prev_desired_curv'][0,:-1] = self.numpy_inputs['prev_desired_curv'][0,1:] + self.numpy_inputs['prev_desired_curv'][0,-1,:] = policy_outputs_dict['desired_curvature'][0, :] combined_outputs_dict = {**vision_outputs_dict, **policy_outputs_dict} if SEND_RAW_PRED: diff --git a/selfdrive/modeld/models/commonmodel.cc b/selfdrive/modeld/models/commonmodel.cc index 99155d9f1e..9973d18588 100644 --- a/selfdrive/modeld/models/commonmodel.cc +++ b/selfdrive/modeld/models/commonmodel.cc @@ -5,12 +5,11 @@ #include "common/clutil.h" -DrivingModelFrame::DrivingModelFrame(cl_device_id device_id, cl_context context, int _temporal_skip) : ModelFrame(device_id, context) { +DrivingModelFrame::DrivingModelFrame(cl_device_id device_id, cl_context context) : ModelFrame(device_id, context) { input_frames = std::make_unique(buf_size); - temporal_skip = _temporal_skip; input_frames_cl = CL_CHECK_ERR(clCreateBuffer(context, CL_MEM_READ_WRITE, buf_size, NULL, &err)); - img_buffer_20hz_cl = CL_CHECK_ERR(clCreateBuffer(context, CL_MEM_READ_WRITE, (temporal_skip+1)*frame_size_bytes, NULL, &err)); - region.origin = temporal_skip * frame_size_bytes; + img_buffer_20hz_cl = CL_CHECK_ERR(clCreateBuffer(context, CL_MEM_READ_WRITE, 2*frame_size_bytes, NULL, &err)); + region.origin = 1 * frame_size_bytes; region.size = frame_size_bytes; last_img_cl = CL_CHECK_ERR(clCreateSubBuffer(img_buffer_20hz_cl, CL_MEM_READ_WRITE, CL_BUFFER_CREATE_TYPE_REGION, ®ion, &err)); @@ -21,7 +20,7 @@ DrivingModelFrame::DrivingModelFrame(cl_device_id device_id, cl_context context, cl_mem* DrivingModelFrame::prepare(cl_mem yuv_cl, int frame_width, int frame_height, int frame_stride, int frame_uv_offset, const mat3& projection) { run_transform(yuv_cl, MODEL_WIDTH, MODEL_HEIGHT, frame_width, frame_height, frame_stride, frame_uv_offset, projection); - for (int i = 0; i < temporal_skip; i++) { + for (int i = 0; i < 1; i++) { CL_CHECK(clEnqueueCopyBuffer(q, img_buffer_20hz_cl, img_buffer_20hz_cl, (i+1)*frame_size_bytes, i*frame_size_bytes, frame_size_bytes, 0, nullptr, nullptr)); } loadyuv_queue(&loadyuv, q, y_cl, u_cl, v_cl, last_img_cl); diff --git a/selfdrive/modeld/models/commonmodel.h b/selfdrive/modeld/models/commonmodel.h index 176d7eb6dc..14409943e4 100644 --- a/selfdrive/modeld/models/commonmodel.h +++ b/selfdrive/modeld/models/commonmodel.h @@ -64,21 +64,20 @@ protected: class DrivingModelFrame : public ModelFrame { public: - DrivingModelFrame(cl_device_id device_id, cl_context context, int _temporal_skip); + DrivingModelFrame(cl_device_id device_id, cl_context context); ~DrivingModelFrame(); cl_mem* prepare(cl_mem yuv_cl, int frame_width, int frame_height, int frame_stride, int frame_uv_offset, const mat3& projection); const int MODEL_WIDTH = 512; const int MODEL_HEIGHT = 256; const int MODEL_FRAME_SIZE = MODEL_WIDTH * MODEL_HEIGHT * 3 / 2; - const int buf_size = MODEL_FRAME_SIZE * 2; // 2 frames are temporal_skip frames apart + const int buf_size = MODEL_FRAME_SIZE * 2; const size_t frame_size_bytes = MODEL_FRAME_SIZE * sizeof(uint8_t); private: LoadYUVState loadyuv; cl_mem img_buffer_20hz_cl, last_img_cl, input_frames_cl; cl_buffer_region region; - int temporal_skip; }; class MonitoringModelFrame : public ModelFrame { diff --git a/selfdrive/modeld/models/commonmodel.pxd b/selfdrive/modeld/models/commonmodel.pxd index 4ac64d9172..b4f08b12aa 100644 --- a/selfdrive/modeld/models/commonmodel.pxd +++ b/selfdrive/modeld/models/commonmodel.pxd @@ -20,7 +20,7 @@ cdef extern from "selfdrive/modeld/models/commonmodel.h": cppclass DrivingModelFrame: int buf_size - DrivingModelFrame(cl_device_id, cl_context, int) + DrivingModelFrame(cl_device_id, cl_context) cppclass MonitoringModelFrame: int buf_size diff --git a/selfdrive/modeld/models/commonmodel_pyx.pyx b/selfdrive/modeld/models/commonmodel_pyx.pyx index 5b7d11bc71..7b3a5bb342 100644 --- a/selfdrive/modeld/models/commonmodel_pyx.pyx +++ b/selfdrive/modeld/models/commonmodel_pyx.pyx @@ -59,8 +59,8 @@ cdef class ModelFrame: cdef class DrivingModelFrame(ModelFrame): cdef cppDrivingModelFrame * _frame - def __cinit__(self, CLContext context, int temporal_skip): - self._frame = new cppDrivingModelFrame(context.device_id, context.context, temporal_skip) + def __cinit__(self, CLContext context): + self._frame = new cppDrivingModelFrame(context.device_id, context.context) self.frame = (self._frame) self.buf_size = self._frame.buf_size diff --git a/selfdrive/modeld/models/driving_policy.onnx b/selfdrive/modeld/models/driving_policy.onnx index cc2148c74b..f804b4ec31 100644 --- a/selfdrive/modeld/models/driving_policy.onnx +++ b/selfdrive/modeld/models/driving_policy.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5fd38c3b4d465d14a8ed128f8b1b265bff1589d42f398faa678b93f25b3385dc -size 15966721 +oid sha256:5cae3285c876804e649b14adadcfb8be79a9bd5a1b928113e37f1f08e25e9688 +size 16581121 diff --git a/selfdrive/modeld/models/driving_vision.onnx b/selfdrive/modeld/models/driving_vision.onnx index aee6d8f1bf..06c87d8755 100644 --- a/selfdrive/modeld/models/driving_vision.onnx +++ b/selfdrive/modeld/models/driving_vision.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:897f80d0388250f99bba69b6a8434560cc0fd83157cbeb0bc134c67fe4e64624 +oid sha256:29bbf79f9dfd7048c0013bb81e86d9b2979275b95ea1ed8a86d1a86a88695240 size 34882971 From fe4585ee884a9e694671a194a9382a1c5cef5736 Mon Sep 17 00:00:00 2001 From: Jason Young <46612682+jyoung8607@users.noreply.github.com> Date: Tue, 4 Mar 2025 16:27:25 -0500 Subject: [PATCH 35/78] tools: notebook to search commaCarSegments for a CAN ID (#34771) --- .../examples/find_segments_with_message.ipynb | 279 ++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 tools/car_porting/examples/find_segments_with_message.ipynb diff --git a/tools/car_porting/examples/find_segments_with_message.ipynb b/tools/car_porting/examples/find_segments_with_message.ipynb new file mode 100644 index 0000000000..82b06c1f31 --- /dev/null +++ b/tools/car_porting/examples/find_segments_with_message.ipynb @@ -0,0 +1,279 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 30, + "id": "228a6736-de31-4255-9d72-a6ff391b968d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Found 221 qualifying vehicles:\n" + ] + } + ], + "source": [ + "from opendbc.car import structs\n", + "from opendbc.car.values import PLATFORMS\n", + "\n", + "print(f\"Found {len(PLATFORMS)} qualifying vehicles:\")\n", + "# for platform in PLATFORMS:\n", + "# print(f\" {platform}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "ed1c8aec-c274-4c61-b83d-711ea194bf86", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Collecting segments from commaCarSegments dataset:\n", + "No segments available for for DODGE_DURANGO\n", + "No segments available for for FORD_RANGER_MK2\n", + "No segments available for for HOLDEN_ASTRA\n", + "No segments available for for CADILLAC_ATS\n", + "No segments available for for CHEVROLET_MALIBU\n", + "No segments available for for CADILLAC_XT4\n", + "No segments available for for CHEVROLET_VOLT_2019\n", + "No segments available for for CHEVROLET_TRAVERSE\n", + "No segments available for for GMC_YUKON\n", + "No segments available for for HONDA_ODYSSEY_CHN\n", + "No segments available for for HYUNDAI_KONA_2022\n", + "No segments available for for HYUNDAI_NEXO_1ST_GEN\n", + "No segments available for for GENESIS_GV70_ELECTRIFIED_1ST_GEN\n", + "No segments available for for GENESIS_G80_2ND_GEN_FL\n", + "No segments available for for RIVIAN_R1_GEN1\n", + "No segments available for for SUBARU_FORESTER_HYBRID\n", + "No segments available for for TESLA_MODEL_3\n", + "No segments available for for TESLA_MODEL_Y\n", + "No segments available for for TOYOTA_RAV4_PRIME\n", + "No segments available for for TOYOTA_SIENNA_4TH_GEN\n", + "No segments available for for LEXUS_LC_TSS2\n", + "No segments available for for VOLKSWAGEN_CADDY_MK3\n", + "No segments available for for VOLKSWAGEN_CRAFTER_MK2\n", + "No segments available for for VOLKSWAGEN_JETTA_MK6\n", + "Collected 577 segments for analysis\n" + ] + } + ], + "source": [ + "import random\n", + "\n", + "from openpilot.tools.lib.logreader import LogReader\n", + "from openpilot.tools.lib.comma_car_segments import get_comma_car_segments_database\n", + "\n", + "database = get_comma_car_segments_database()\n", + "TEST_SEGMENTS = []\n", + "\n", + "MAX_SEGS_PER_PLATFORM = 3 # Increase this to search more segments\n", + "\n", + "print(\"Collecting segments from commaCarSegments dataset:\")\n", + "for platform in TEST_PLATFORMS:\n", + " if platform not in database:\n", + " print(f\"No segments available for for {platform}\")\n", + " continue\n", + " \n", + " all_segments = database[platform]\n", + "\n", + " NUM_SEGMENTS = min(len(all_segments), MAX_SEGS_PER_PLATFORM)\n", + "\n", + " # print(f\"Got {len(all_segments)} segments for platform {platform}, sampling {NUM_SEGMENTS} segments\")\n", + " TEST_SEGMENTS.extend(random.sample(all_segments, NUM_SEGMENTS))\n", + "\n", + "print(f\"Collected {len(TEST_SEGMENTS)} segments for analysis\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "0c75e8f2-4f5f-4f89-b8db-5223a6534a9f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Match found in d753e5427226080e/2023-12-30--10-14-03/9/s for CHRYSLER PACIFICA HYBRID 2018\n", + "Match found in 810855dc1450c716/2023-12-26--10-03-20/3/s for CHRYSLER PACIFICA HYBRID 2018\n", + "Match found in 7f268b92fc672c4d/2023-11-02--20-54-34/103/s for CHRYSLER PACIFICA HYBRID 2018\n", + "Match found in 1a10807c60c127fd/2023-12-09--19-21-30/49/s for CHRYSLER PACIFICA HYBRID 2019\n", + "Match found in b70b56b76a6217f2/2023-12-26--12-29-24/4/s for CHRYSLER PACIFICA HYBRID 2019\n", + "Match found in 86deeb65f10c3129/2023-12-29--07-38-12/179/s for CHRYSLER PACIFICA HYBRID 2019\n", + "Match found in 0a3e89f78b1d0071/2023-11-30--10-33-13/13/s for CHRYSLER PACIFICA 2018\n", + "Match found in 8fc6a1b72c8b1357/2023-11-30--17-35-04/10/s for CHRYSLER PACIFICA 2018\n", + "Match found in d5de6f3e9371e89e/2023-11-16--17-19-54/48/s for CHRYSLER PACIFICA 2018\n", + "Match found in 5fc1717be83fc0da/2024-01-03--13-16-03/27/s for CHRYSLER PACIFICA 2020\n", + "Match found in c1feb10d20626c65/2023-12-16--17-46-24/9/s for CHRYSLER PACIFICA 2020\n", + "Match found in c1feb10d20626c65/2023-11-21--17-40-18/25/s for CHRYSLER PACIFICA 2020\n", + "Match found in a63a23c3e628f288/2023-11-05--18-36-20/22/s for JEEP GRAND CHEROKEE V6 2018\n", + "Match found in 46b21f1c5f7aa885/2023-11-14--15-22-04/21/s for JEEP GRAND CHEROKEE V6 2018\n", + "Match found in a63a23c3e628f288/2023-12-13--09-15-47/27/s for JEEP GRAND CHEROKEE V6 2018\n", + "Match found in 4ffe7a3fb831a625/2024-01-04--09-15-33/22/s for JEEP GRAND CHEROKEE 2019\n", + "Match found in c5b49919572d2c5a/2023-12-17--15-54-06/73/s for JEEP GRAND CHEROKEE 2019\n", + "Match found in 9c2b832d06f93621/2024-01-25--13-52-19/8/s for JEEP GRAND CHEROKEE 2019\n", + "Match found in 1618132d68afc876/2023-11-24--10-21-12/4/s for HYUNDAI KONA ELECTRIC 2ND GEN\n", + "Match found in 1618132d68afc876/2023-08-27--09-32-14/13/s for HYUNDAI KONA 2ND GEN\n", + "Match found in 1618132d68afc876/2023-11-24--10-21-12/3/s for HYUNDAI KONA ELECTRIC 2ND GEN\n", + "Match found in df7fdd56970d90fe/2023-12-29--07-48-56/53/s for HYUNDAI IONIQ 6 2023\n", + "Match found in 0ad7facc77922c3e/2023-12-29--17-12-45/14/s for HYUNDAI IONIQ 6 2023\n", + "Match found in 0ad7facc77922c3e/2023-12-16--08-49-13/39/s for HYUNDAI IONIQ 6 2023\n", + "Match found in 78ad5150de133637/2023-09-13--16-15-57/0/s for KIA K8 HYBRID 1ST GEN\n", + "Match found in 78ad5150de133637/2023-09-13--16-15-57/2/s for KIA K8 HYBRID 1ST GEN\n", + "Match found in 78ad5150de133637/2023-09-13--16-15-57/1/s for KIA K8 HYBRID 1ST GEN\n", + "Match found in b153671049a867b3/2023-12-15--20-40-16/0/s for KIA NIRO EV 2ND GEN\n", + "Match found in b153671049a867b3/2024-01-12--17-43-31/2/s for KIA NIRO EV 2ND GEN\n", + "Match found in b153671049a867b3/2023-12-03--21-08-30/3/s for KIA NIRO EV 2ND GEN\n", + "Match found in 7387ab2a564c6d9f/2023-12-02--07-10-34/52/s for KIA NIRO HYBRID 2ND GEN\n", + "Match found in 7387ab2a564c6d9f/2024-01-06--16-24-36/1/s for KIA NIRO HYBRID 2ND GEN\n", + "Match found in 7387ab2a564c6d9f/2024-01-06--16-24-36/9/s for KIA NIRO HYBRID 2ND GEN\n", + "Match found in 2efdac7dc41207f1/2023-12-27--07-24-22/89/s for KIA EV6 2022\n", + "Match found in 5ac586afbb236b5d/2023-12-05--18-23-10/7/s for VOLKSWAGEN ARTEON 1ST GEN\n", + "Match found in c34ef43981b6d888/2024-01-18--16-00-06/9/s for VOLKSWAGEN ARTEON 1ST GEN\n", + "Match found in 5ac586afbb236b5d/2024-01-04--20-01-19/4/s for VOLKSWAGEN ARTEON 1ST GEN\n", + "Match found in 16758e226aa2f747/2023-12-16--10-24-39/13/s for VOLKSWAGEN ATLAS 1ST GEN\n", + "Match found in 3174d252cec3bf6f/2023-12-12--18-39-06/6/s for VOLKSWAGEN ATLAS 1ST GEN\n", + "Match found in e80066d826c705a9/2024-01-06--17-28-45/211/s for VOLKSWAGEN ATLAS 1ST GEN\n", + "Match found in 2cdded3a5da75b6a/2024-01-06--13-37-16/2/s for VOLKSWAGEN GOLF 7TH GEN\n", + "Match found in abe0b7fe730c51a9/2023-10-30--14-24-49/4/s for VOLKSWAGEN GOLF 7TH GEN\n", + "Match found in 8fe9ced03c94e256/2023-12-14--16-31-55/8/s for VOLKSWAGEN GOLF 7TH GEN\n", + "Match found in a97d27ce2a78958a/2024-01-09--06-57-35/9/s for VOLKSWAGEN JETTA 7TH GEN\n", + "Match found in 0649d406184b7131/2024-01-20--14-43-41/3/s for VOLKSWAGEN JETTA 7TH GEN\n", + "Match found in 0649d406184b7131/2023-11-07--16-30-10/17/s for VOLKSWAGEN JETTA 7TH GEN\n", + "Match found in 5405cac0c9d58c3d/2023-11-05--17-13-17/6/s for VOLKSWAGEN PASSAT 8TH GEN\n", + "Match found in 2d7d87433a67c925/2024-01-05--16-31-16/38/s for VOLKSWAGEN PASSAT 8TH GEN\n", + "Match found in 2d7d87433a67c925/2023-12-26--08-44-17/2/s for VOLKSWAGEN PASSAT 8TH GEN\n", + "Match found in 0cd0b7f7e31a3853/2021-11-03--19-30-22/0/s for SKODA KODIAQ 1ST GEN\n", + "Match found in 0bbe367c98fa1538/2023-07-01--19-42-26/7/s for VOLKSWAGEN POLO 6TH GEN\n", + "Match found in 0cd0b7f7e31a3853/2021-11-03--19-30-22/2/s for SKODA KODIAQ 1ST GEN\n", + "Match found in 7d82b2f3a9115f1f/2021-10-21--15-39-42/1/s for VOLKSWAGEN TAOS 1ST GEN\n", + "Match found in 7d82b2f3a9115f1f/2021-10-21--15-39-42/0/s for VOLKSWAGEN TAOS 1ST GEN\n", + "Match found in 7d82b2f3a9115f1f/2021-10-21--15-39-42/2/s for VOLKSWAGEN TAOS 1ST GEN\n", + "Match found in 2744c89a8dda9a51/2021-07-24--21-28-06/0/s for SKODA KODIAQ 1ST GEN\n", + "Match found in 2744c89a8dda9a51/2021-07-24--21-28-06/2/s for SKODA KODIAQ 1ST GEN\n", + "Match found in 2744c89a8dda9a51/2021-07-24--21-28-06/1/s for SKODA KODIAQ 1ST GEN\n", + "Match found in 4e144f64a2535890/2023-12-05--12-22-10/5/s for VOLKSWAGEN TIGUAN 2ND GEN\n", + "Match found in 1b5cf3b409037cc4/2023-12-11--10-23-35/5/s for VOLKSWAGEN TIGUAN 2ND GEN\n", + "Match found in 1b41980e9972d348/2023-10-29--15-13-08/3/s for VOLKSWAGEN TIGUAN 2ND GEN\n", + "Match found in a589dcc642fdb10a/2021-06-14--20-54-26/0/s for VOLKSWAGEN TOURAN 2ND GEN\n", + "Match found in a589dcc642fdb10a/2021-06-14--20-54-26/2/s for VOLKSWAGEN TOURAN 2ND GEN\n", + "Match found in a589dcc642fdb10a/2021-06-14--20-54-26/1/s for VOLKSWAGEN TOURAN 2ND GEN\n", + "Match found in 207b9d7ee3fb513a/2023-12-19--14-59-25/14/s for VOLKSWAGEN TRANSPORTER T6.1\n", + "Match found in a459f4556782eba1/2023-11-05--17-16-20/22/s for VOLKSWAGEN TRANSPORTER T6.1\n", + "Match found in a459f4556782eba1/2023-11-27--12-27-58/47/s for VOLKSWAGEN TRANSPORTER T6.1\n", + "Match found in 0cd0b7f7e31a3853/2021-11-18--00-38-32/0/s for SKODA KODIAQ 1ST GEN\n", + "Match found in 0cd0b7f7e31a3853/2021-11-18--00-38-32/1/s for SKODA KODIAQ 1ST GEN\n", + "Match found in 0cd0b7f7e31a3853/2021-11-18--00-38-32/2/s for SKODA KODIAQ 1ST GEN\n", + "Match found in a973e9182bc96a2c/2024-01-14--15-14-33/54/s for AUDI A3 3RD GEN\n", + "Match found in 23daff6c438612d2/2023-12-21--15-37-32/22/s for AUDI A3 3RD GEN\n", + "Match found in 23daff6c438612d2/2024-01-17--09-31-14/20/s for AUDI A3 3RD GEN\n", + "Match found in 6c6b466346192818/2021-06-06--14-17-47/0/s for AUDI Q2 1ST GEN\n", + "Match found in 6c6b466346192818/2021-06-06--14-17-47/1/s for AUDI Q2 1ST GEN\n", + "Match found in 6c6b466346192818/2021-06-06--14-17-47/2/s for AUDI Q2 1ST GEN\n", + "Match found in 839125529d3c3cdf/2023-11-29--15-49-50/56/s for AUDI Q3 2ND GEN\n", + "Match found in d7bfab70d5011e1d/2023-11-24--00-49-14/24/s for AUDI Q3 2ND GEN\n", + "Match found in 98a3015c4f16846d/2023-11-04--12-32-32/76/s for AUDI Q3 2ND GEN\n", + "Match found in fc6b6c9a3471c846/2021-05-27--13-39-56/2/s for SEAT LEON 3RD GEN\n", + "Match found in fc6b6c9a3471c846/2021-05-27--13-39-56/1/s for SEAT LEON 3RD GEN\n", + "Match found in aef9c04d6ec5cd57/2023-07-15--16-49-38/12/s for SEAT LEON 3RD GEN\n", + "Match found in 0bbe367c98fa1538/2023-03-04--17-46-11/2/s for VOLKSWAGEN POLO 6TH GEN\n", + "Match found in 0bbe367c98fa1538/2023-03-04--17-46-11/1/s for VOLKSWAGEN POLO 6TH GEN\n", + "Match found in 0bbe367c98fa1538/2023-03-04--17-46-11/0/s for VOLKSWAGEN POLO 6TH GEN\n", + "Match found in 026b6d18fba6417f/2021-03-26--09-17-04/0/s for SKODA SCALA 1ST GEN\n", + "Match found in 026b6d18fba6417f/2021-03-26--09-17-04/1/s for SKODA SCALA 1ST GEN\n", + "Match found in 026b6d18fba6417f/2021-03-26--09-17-04/2/s for SKODA SCALA 1ST GEN\n", + "Match found in 12d6ae3057c04b0d/2021-09-04--21-21-21/1/s for SKODA KODIAQ 1ST GEN\n", + "Match found in 12d6ae3057c04b0d/2021-09-04--21-21-21/0/s for SKODA KODIAQ 1ST GEN\n", + "Match found in 7d76baac7cf42e15/2024-01-13--03-42-46/2/s for SKODA KAROQ 1ST GEN\n", + "Match found in 8a5da7c1d1783730/2024-01-17--06-32-18/4/s for SKODA KODIAQ 1ST GEN\n", + "Match found in 8a5da7c1d1783730/2023-12-23--16-48-07/42/s for SKODA KODIAQ 1ST GEN\n", + "Match found in 2ca49a03c8084514/2023-12-27--08-54-31/4/s for SKODA KODIAQ 1ST GEN\n", + "Match found in 66e5edc3a16459c5/2021-05-25--19-00-29/1/s for SKODA OCTAVIA 3RD GEN\n", + "Match found in f5392228324cda8d/2023-10-29--14-05-24/120/s for SKODA OCTAVIA 3RD GEN\n", + "Match found in 3fa7570f2fcace3d/2023-11-11--07-57-34/1/s for SKODA OCTAVIA 3RD GEN\n", + "Match found in 54ada937747ef8ca/2023-11-09--16-13-28/12/s for SKODA SUPERB 3RD GEN\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Match found in 54ada937747ef8ca/2023-12-14--08-14-41/8/s for SKODA SUPERB 3RD GEN\n", + "Match found in 54ada937747ef8ca/2023-11-16--06-01-05/7/s for SKODA SUPERB 3RD GEN\n", + "Analysis finished\n" + ] + } + ], + "source": [ + "from openpilot.selfdrive.pandad import can_capnp_to_list\n", + "from openpilot.tools.lib.logreader import LogReader\n", + "\n", + "message_to_check = 0x3c0 # Volkswagen CAN ignition message\n", + "\n", + "segment_count = len(TEST_SEGMENTS)\n", + "for idx, segment in enumerate(TEST_SEGMENTS):\n", + " lr = LogReader(segment)\n", + " CP = lr.first(\"carParams\")\n", + " if CP is None:\n", + " continue\n", + "\n", + " can_packets = [msg for msg in lr if msg.which() == \"can\"]\n", + "\n", + " # print(f\"Evaluating segment {idx} of {segment_count} for {CP.carFingerprint}\")\n", + "\n", + " matched_segments = {}\n", + " for packet in can_packets:\n", + " for msg in packet.can:\n", + " if msg.address == message_to_check:\n", + " matched_segments.update({segment: CP.carFingerprint})\n", + "\n", + " if segment in matched_segments:\n", + " print(f\"Match found in {segment} for {CP.carFingerprint}\")\n", + "\n", + "print(f\"Analysis finished\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7724dd97-f62e-4fd3-9f64-63d49be669d2", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9f393e00-8efd-40fb-a41e-d312531a83e8", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "openpilot", + "language": "python", + "name": "openpilot" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From bc422a07384afed95b4c2037022c3517ef277cba Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 4 Mar 2025 15:54:43 -0600 Subject: [PATCH 36/78] juggle: use DBC dict generator (#34772) * juggle: support tesla DBC * better * fix * sort --- tools/cabana/dbc/generate_dbc_json.py | 6 +++--- tools/plotjuggler/juggle.py | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/cabana/dbc/generate_dbc_json.py b/tools/cabana/dbc/generate_dbc_json.py index 5e928e6054..d002a50ef8 100755 --- a/tools/cabana/dbc/generate_dbc_json.py +++ b/tools/cabana/dbc/generate_dbc_json.py @@ -7,7 +7,7 @@ from opendbc.car.fingerprints import MIGRATION from opendbc.car.values import PLATFORMS -def generate_dbc_json() -> str: +def generate_dbc_dict() -> dict[str, str]: dbc_map = {} for platform in PLATFORMS.values(): if platform != "MOCK": @@ -24,7 +24,7 @@ def generate_dbc_json() -> str: if MIGRATION[m] in dbc_map: dbc_map[m] = dbc_map[MIGRATION[m]] - return json.dumps(dict(sorted(dbc_map.items())), indent=2) + return dbc_map if __name__ == "__main__": @@ -35,5 +35,5 @@ if __name__ == "__main__": args = parser.parse_args() with open(args.out, 'w') as f: - f.write(generate_dbc_json()) + f.write(json.dumps(dict(sorted(generate_dbc_dict().items())), indent=2)) print(f"Generated and written to {args.out}") diff --git a/tools/plotjuggler/juggle.py b/tools/plotjuggler/juggle.py index 5b6bd0a418..f66782d6f3 100755 --- a/tools/plotjuggler/juggle.py +++ b/tools/plotjuggler/juggle.py @@ -13,6 +13,7 @@ from functools import partial from opendbc.car.fingerprints import MIGRATION from openpilot.common.basedir import BASEDIR from openpilot.common.swaglog import cloudlog +from openpilot.tools.cabana.dbc.generate_dbc_json import generate_dbc_dict from openpilot.tools.lib.logreader import LogReader, ReadMode, save_log from openpilot.selfdrive.test.process_replay.migration import migrate_all @@ -90,11 +91,10 @@ def juggle_route(route_or_segment_name, can, layout, dbc, should_migrate): if dbc is None: try: CP = lr.first('carParams') - platform = CP.carFingerprint - DBC = __import__(f"opendbc.car.{CP.brand}.values", fromlist=['DBC']).DBC - dbc = DBC[MIGRATION.get(CP.carFingerprint, CP.carFingerprint)]['pt'] + platform = MIGRATION.get(CP.carFingerprint, CP.carFingerprint) + dbc = generate_dbc_dict()[platform] except Exception: - cloudlog.error("Failed to get DBC name from logs!") + cloudlog.exception("Failed to get DBC name from logs!") with tempfile.NamedTemporaryFile(suffix='.rlog', dir=juggle_dir) as tmp: save_log(tmp.name, all_data, compress=False) From b8362fd7250d323fb4e200822d772a4735385b5c Mon Sep 17 00:00:00 2001 From: Alexandre Nobuharu Sato <66435071+AlexandreSato@users.noreply.github.com> Date: Tue, 4 Mar 2025 20:25:01 -0300 Subject: [PATCH 37/78] Multilang: update pt-BR translations (#34773) update pt-BR translations --- selfdrive/ui/translations/main_pt-BR.ts | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/selfdrive/ui/translations/main_pt-BR.ts b/selfdrive/ui/translations/main_pt-BR.ts index f2aa00d322..06b2ef7b35 100644 --- a/selfdrive/ui/translations/main_pt-BR.ts +++ b/selfdrive/ui/translations/main_pt-BR.ts @@ -309,25 +309,27 @@ FirehosePanel 🔥 Firehose Mode 🔥 - + 🔥 Mode Firehose 🔥 Enable Firehose Mode - + Habilitar Modo Firehose openpilot learns to drive by watching humans, like you, drive. Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models with better Experimental Mode. - + O openpilot aprende a dirigir observando humanos, como você, dirigirem. + +O Modo Firehose permite maximizar o envio de seus dados de treinamento para melhorar os modelos de direção do openpilot. Mais dados significam modelos maiores e um Modo Experimental melhor. 0% - 5G {0%?} + 5G {0%?} Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable the toggle<br> 4. Leave it connected for at least 30 minutes<br><br>The toggle turns off once you restart your device. Repeat at least once a week for maximum effectiveness.<br><br><b>FAQ</b><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><i>Do I need to be on Wi-Fi?</i> Yes.<br><i>Do I need to bring the device inside?</i> No, you can enable once you're parked, however your uploads will be limited by your car's battery.<br> - + Siga estes passos para preparar seu dispositivo:<br> 1. Leve o dispositivo para dentro e conecte-o a um bom adaptador USB-C<br> 2. Conecte-se ao Wi-Fi<br> 3. Ative a opção<br> 4. Deixe-o conectado por pelo menos 30 minutos<br><br>A opção será desativada quando você reiniciar o dispositivo. Repita esse processo pelo menos uma vez por semana para obter a máxima eficácia.<br><br><b>FAQ</b><br><i>Importa como ou onde eu dirijo?</i> Não, basta dirigir normalmente.<br><i>O que é um bom adaptador USB-C?</i> Qualquer carregador rápido de celular ou laptop deve servir..<br><i>Preciso estar conectado ao Wi-Fi?</i> Sim.<br><i>Preciso levar o dispositivo para dentro de casa?</i> Não, você pode ativar a opção enquanto estiver estacionado, mas seus envios serão limitados pela bateria do carro.<br>
@@ -668,7 +670,7 @@ Isso pode levar até um minuto. Firehose - + Firehose @@ -1146,15 +1148,15 @@ Isso pode levar até um minuto. WiFiPromptWidget Open - + Abrir Maximize your training data uploads to improve openpilot's driving models. - + Maximize seus envios de dados de treinamento para melhorar os modelos de direção do openpilot. <span style='font-family: "Noto Color Emoji";'>🔥</span> Firehose Mode <span style='font-family: Noto Color Emoji;'>🔥</span> - + <span style='font-family: "Noto Color Emoji";'>🔥</span> Mode Firehose <span style='font-family: Noto Color Emoji;'>🔥</span> From 7dfbf0b1e1860540a083a3511db98414733d15bb Mon Sep 17 00:00:00 2001 From: ZwX1616 Date: Tue, 4 Mar 2025 18:28:44 -0800 Subject: [PATCH 38/78] process_replay: set sensor in cameraState migration (#34776) set sensor in cameraState migration --- selfdrive/test/process_replay/migration.py | 1 + 1 file changed, 1 insertion(+) diff --git a/selfdrive/test/process_replay/migration.py b/selfdrive/test/process_replay/migration.py index 061da31de3..2d42d31619 100644 --- a/selfdrive/test/process_replay/migration.py +++ b/selfdrive/test/process_replay/migration.py @@ -358,6 +358,7 @@ def migrate_cameraStates(msgs): new_msg = messaging.new_message(msg.which()) new_camera_state = getattr(new_msg, new_msg.which()) + new_camera_state.sensor = camera_state.sensor new_camera_state.frameId = encode_id new_camera_state.encodeId = encode_id # timestampSof was added later so it might be missing on some old segments From 3e8e7e8e6df51d00e0008bc09c2a47acab7e3fc5 Mon Sep 17 00:00:00 2001 From: ZwX1616 Date: Tue, 4 Mar 2025 18:36:30 -0800 Subject: [PATCH 39/78] update model_replay route (#34774) * update route * Update selfdrive/test/process_replay/model_replay.py Co-authored-by: Maxime Desroches --------- Co-authored-by: Maxime Desroches --- selfdrive/test/process_replay/model_replay.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/selfdrive/test/process_replay/model_replay.py b/selfdrive/test/process_replay/model_replay.py index 50027574ba..8cd8222ddc 100755 --- a/selfdrive/test/process_replay/model_replay.py +++ b/selfdrive/test/process_replay/model_replay.py @@ -19,8 +19,8 @@ from openpilot.tools.lib.framereader import FrameReader, NumpyFrameReader from openpilot.tools.lib.logreader import LogReader, save_log from openpilot.tools.lib.github_utils import GithubUtils -TEST_ROUTE = "2f4452b03ccb98f0|2022-12-03--13-45-30" -SEGMENT = 6 +TEST_ROUTE = "8494c69d3c710e81|000001d4--2648a9a404" +SEGMENT = 4 MAX_FRAMES = 100 if PC else 400 NO_MODEL = "NO_MODEL" in os.environ From 3f9437e249d6822eb6590a2f4a0fe276e6a33842 Mon Sep 17 00:00:00 2001 From: ZwX1616 Date: Tue, 4 Mar 2025 20:24:17 -0800 Subject: [PATCH 40/78] process_replay: support lane changes in model_replay (#34777) * lane changes need to see these * newline * add lc probs --- selfdrive/test/process_replay/model_replay.py | 5 ++++- selfdrive/test/process_replay/process_replay.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/selfdrive/test/process_replay/model_replay.py b/selfdrive/test/process_replay/model_replay.py index 8cd8222ddc..36398af8ca 100755 --- a/selfdrive/test/process_replay/model_replay.py +++ b/selfdrive/test/process_replay/model_replay.py @@ -66,6 +66,8 @@ def generate_report(proposed, master, tmp, commit): (lambda x: get_idx_if_non_empty(x.action.desiredCurvature), "desiredCurvature"), (lambda x: get_idx_if_non_empty(x.leadsV3[0].x, 0), "leadsV3.x"), (lambda x: get_idx_if_non_empty(x.laneLines[1].y, 0), "laneLines.y"), + (lambda x: get_idx_if_non_empty(x.meta.desireState, 3), "desireState.laneChangeLeft"), + (lambda x: get_idx_if_non_empty(x.meta.desireState, 4), "desireState.laneChangeRight"), (lambda x: get_idx_if_non_empty(x.meta.disengagePredictions.gasPressProbs, 1), "gasPressProbs") ], "modelV2") DriverStateV2_Plots = zl([ @@ -143,7 +145,8 @@ def trim_logs_to_max_frames(logs, max_frames, frs_types, include_all_types): def model_replay(lr, frs): # modeld is using frame pairs - modeld_logs = trim_logs_to_max_frames(lr, MAX_FRAMES, {"roadCameraState", "wideRoadCameraState"}, {"roadEncodeIdx", "wideRoadEncodeIdx", "carParams"}) + modeld_logs = trim_logs_to_max_frames(lr, MAX_FRAMES, {"roadCameraState", "wideRoadCameraState"}, + {"roadEncodeIdx", "wideRoadEncodeIdx", "carParams", "carState", "carControl"}) dmodeld_logs = trim_logs_to_max_frames(lr, MAX_FRAMES, {"driverCameraState"}, {"driverEncodeIdx", "carParams"}) if not SEND_EXTRA_INPUTS: diff --git a/selfdrive/test/process_replay/process_replay.py b/selfdrive/test/process_replay/process_replay.py index 1135aeb874..34ca98fdc2 100755 --- a/selfdrive/test/process_replay/process_replay.py +++ b/selfdrive/test/process_replay/process_replay.py @@ -568,7 +568,7 @@ CONFIGS = [ ), ProcessConfig( proc_name="modeld", - pubs=["deviceState", "roadCameraState", "wideRoadCameraState", "liveCalibration", "driverMonitoringState", "carState"], + pubs=["deviceState", "roadCameraState", "wideRoadCameraState", "liveCalibration", "driverMonitoringState", "carState", "carControl"], subs=["modelV2", "drivingModelData", "cameraOdometry"], ignore=["logMonoTime", "modelV2.frameDropPerc", "modelV2.modelExecutionTime", "drivingModelData.frameDropPerc", "drivingModelData.modelExecutionTime"], should_recv_callback=ModeldCameraSyncRcvCallback(), From 31076b818df68ea171447ccafa07039311a11136 Mon Sep 17 00:00:00 2001 From: ZwX1616 Date: Tue, 4 Mar 2025 20:35:57 -0800 Subject: [PATCH 41/78] Filet o Fish model (#34775) * 690b01c3 seems ok * correct temporal * push * inplace * bs * what thw * is this wrong * frames are skipped * new models * simplify decimation * clean up * clean up modelframe * need attr * lint * 0 * use all samples * this should break - Revert "use all samples" This reverts commit 6c0d7943ac5fbb7ae60af1a1201e2423e4c3c105. * add lc probs * Revert "this should break - Revert "use all samples"" This reverts commit ca38c54333555266a0d2c885c28af28941841431. * Reapply "this should break - Revert "use all samples"" This reverts commit a3f0246f209f85f06b9090d9492bfba32ed8cfed. * Revert "Reapply "this should break - Revert "use all samples""" This reverts commit 7fd3d2a191b688e5ef7b4dcc8f5379e900af10f8. --------- Co-authored-by: Comma Device --- selfdrive/modeld/constants.py | 8 +++++- selfdrive/modeld/modeld.py | 31 ++++++++++++++------- selfdrive/modeld/models/commonmodel.cc | 9 +++--- selfdrive/modeld/models/commonmodel.h | 5 ++-- selfdrive/modeld/models/commonmodel.pxd | 2 +- selfdrive/modeld/models/commonmodel_pyx.pyx | 4 +-- selfdrive/modeld/models/driving_policy.onnx | 4 +-- selfdrive/modeld/models/driving_vision.onnx | 2 +- 8 files changed, 42 insertions(+), 23 deletions(-) diff --git a/selfdrive/modeld/constants.py b/selfdrive/modeld/constants.py index 2bb7b8100c..5ca0a86bc8 100644 --- a/selfdrive/modeld/constants.py +++ b/selfdrive/modeld/constants.py @@ -14,8 +14,14 @@ class ModelConstants: # model inputs constants MODEL_FREQ = 20 + HISTORY_FREQ = 5 + HISTORY_LEN_SECONDS = 5 + TEMPORAL_SKIP = MODEL_FREQ // HISTORY_FREQ + FULL_HISTORY_BUFFER_LEN = MODEL_FREQ * HISTORY_LEN_SECONDS + INPUT_HISTORY_BUFFER_LEN = HISTORY_FREQ * HISTORY_LEN_SECONDS + FEATURE_LEN = 512 - FULL_HISTORY_BUFFER_LEN = 100 + DESIRE_LEN = 8 TRAFFIC_CONVENTION_LEN = 2 LAT_PLANNER_STATE_LEN = 4 diff --git a/selfdrive/modeld/modeld.py b/selfdrive/modeld/modeld.py index ee825d158f..1e557942fe 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -56,16 +56,24 @@ class ModelState: prev_desire: np.ndarray # for tracking the rising edge of the pulse def __init__(self, context: CLContext): - self.frames = {'input_imgs': DrivingModelFrame(context), 'big_input_imgs': DrivingModelFrame(context)} + self.frames = { + 'input_imgs': DrivingModelFrame(context, ModelConstants.TEMPORAL_SKIP), + 'big_input_imgs': DrivingModelFrame(context, ModelConstants.TEMPORAL_SKIP) + } self.prev_desire = np.zeros(ModelConstants.DESIRE_LEN, dtype=np.float32) + self.full_features_buffer = np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.FEATURE_LEN), dtype=np.float32) + self.full_desire = np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.DESIRE_LEN), dtype=np.float32) + self.full_prev_desired_curv = np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.PREV_DESIRED_CURV_LEN), dtype=np.float32) + self.temporal_idxs = slice(-1-(ModelConstants.TEMPORAL_SKIP*(ModelConstants.INPUT_HISTORY_BUFFER_LEN-1)), None, ModelConstants.TEMPORAL_SKIP) + # policy inputs self.numpy_inputs = { - 'desire': np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.DESIRE_LEN), dtype=np.float32), + 'desire': np.zeros((1, ModelConstants.INPUT_HISTORY_BUFFER_LEN, ModelConstants.DESIRE_LEN), dtype=np.float32), 'traffic_convention': np.zeros((1, ModelConstants.TRAFFIC_CONVENTION_LEN), dtype=np.float32), 'lateral_control_params': np.zeros((1, ModelConstants.LATERAL_CONTROL_PARAMS_LEN), dtype=np.float32), - 'prev_desired_curv': np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.PREV_DESIRED_CURV_LEN), dtype=np.float32), - 'features_buffer': np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.FEATURE_LEN), dtype=np.float32), + 'prev_desired_curv': np.zeros((1, ModelConstants.INPUT_HISTORY_BUFFER_LEN, ModelConstants.PREV_DESIRED_CURV_LEN), dtype=np.float32), + 'features_buffer': np.zeros((1, ModelConstants.INPUT_HISTORY_BUFFER_LEN, ModelConstants.FEATURE_LEN), dtype=np.float32), } with open(VISION_METADATA_PATH, 'rb') as f: @@ -104,8 +112,9 @@ class ModelState: new_desire = np.where(inputs['desire'] - self.prev_desire > .99, inputs['desire'], 0) self.prev_desire[:] = inputs['desire'] - self.numpy_inputs['desire'][0,:-1] = self.numpy_inputs['desire'][0,1:] - self.numpy_inputs['desire'][0,-1] = new_desire + self.full_desire[0,:-1] = self.full_desire[0,1:] + self.full_desire[0,-1] = new_desire + self.numpy_inputs['desire'][:] = self.full_desire.reshape((1,ModelConstants.INPUT_HISTORY_BUFFER_LEN,ModelConstants.TEMPORAL_SKIP,-1)).max(axis=2) self.numpy_inputs['traffic_convention'][:] = inputs['traffic_convention'] self.numpy_inputs['lateral_control_params'][:] = inputs['lateral_control_params'] @@ -128,15 +137,17 @@ class ModelState: self.vision_output = self.vision_run(**self.vision_inputs).numpy().flatten() vision_outputs_dict = self.parser.parse_vision_outputs(self.slice_outputs(self.vision_output, self.vision_output_slices)) - self.numpy_inputs['features_buffer'][0,:-1] = self.numpy_inputs['features_buffer'][0,1:] - self.numpy_inputs['features_buffer'][0,-1] = vision_outputs_dict['hidden_state'][0, :] + self.full_features_buffer[0,:-1] = self.full_features_buffer[0,1:] + self.full_features_buffer[0,-1] = vision_outputs_dict['hidden_state'][0, :] + self.numpy_inputs['features_buffer'][:] = self.full_features_buffer[0, self.temporal_idxs] self.policy_output = self.policy_run(**self.policy_inputs).numpy().flatten() policy_outputs_dict = self.parser.parse_policy_outputs(self.slice_outputs(self.policy_output, self.policy_output_slices)) # TODO model only uses last value now - self.numpy_inputs['prev_desired_curv'][0,:-1] = self.numpy_inputs['prev_desired_curv'][0,1:] - self.numpy_inputs['prev_desired_curv'][0,-1,:] = policy_outputs_dict['desired_curvature'][0, :] + self.full_prev_desired_curv[0,:-1] = self.full_prev_desired_curv[0,1:] + self.full_prev_desired_curv[0,-1,:] = policy_outputs_dict['desired_curvature'][0, :] + self.numpy_inputs['prev_desired_curv'][:] = self.full_prev_desired_curv[0, self.temporal_idxs] combined_outputs_dict = {**vision_outputs_dict, **policy_outputs_dict} if SEND_RAW_PRED: diff --git a/selfdrive/modeld/models/commonmodel.cc b/selfdrive/modeld/models/commonmodel.cc index 9973d18588..99155d9f1e 100644 --- a/selfdrive/modeld/models/commonmodel.cc +++ b/selfdrive/modeld/models/commonmodel.cc @@ -5,11 +5,12 @@ #include "common/clutil.h" -DrivingModelFrame::DrivingModelFrame(cl_device_id device_id, cl_context context) : ModelFrame(device_id, context) { +DrivingModelFrame::DrivingModelFrame(cl_device_id device_id, cl_context context, int _temporal_skip) : ModelFrame(device_id, context) { input_frames = std::make_unique(buf_size); + temporal_skip = _temporal_skip; input_frames_cl = CL_CHECK_ERR(clCreateBuffer(context, CL_MEM_READ_WRITE, buf_size, NULL, &err)); - img_buffer_20hz_cl = CL_CHECK_ERR(clCreateBuffer(context, CL_MEM_READ_WRITE, 2*frame_size_bytes, NULL, &err)); - region.origin = 1 * frame_size_bytes; + img_buffer_20hz_cl = CL_CHECK_ERR(clCreateBuffer(context, CL_MEM_READ_WRITE, (temporal_skip+1)*frame_size_bytes, NULL, &err)); + region.origin = temporal_skip * frame_size_bytes; region.size = frame_size_bytes; last_img_cl = CL_CHECK_ERR(clCreateSubBuffer(img_buffer_20hz_cl, CL_MEM_READ_WRITE, CL_BUFFER_CREATE_TYPE_REGION, ®ion, &err)); @@ -20,7 +21,7 @@ DrivingModelFrame::DrivingModelFrame(cl_device_id device_id, cl_context context) cl_mem* DrivingModelFrame::prepare(cl_mem yuv_cl, int frame_width, int frame_height, int frame_stride, int frame_uv_offset, const mat3& projection) { run_transform(yuv_cl, MODEL_WIDTH, MODEL_HEIGHT, frame_width, frame_height, frame_stride, frame_uv_offset, projection); - for (int i = 0; i < 1; i++) { + for (int i = 0; i < temporal_skip; i++) { CL_CHECK(clEnqueueCopyBuffer(q, img_buffer_20hz_cl, img_buffer_20hz_cl, (i+1)*frame_size_bytes, i*frame_size_bytes, frame_size_bytes, 0, nullptr, nullptr)); } loadyuv_queue(&loadyuv, q, y_cl, u_cl, v_cl, last_img_cl); diff --git a/selfdrive/modeld/models/commonmodel.h b/selfdrive/modeld/models/commonmodel.h index 14409943e4..176d7eb6dc 100644 --- a/selfdrive/modeld/models/commonmodel.h +++ b/selfdrive/modeld/models/commonmodel.h @@ -64,20 +64,21 @@ protected: class DrivingModelFrame : public ModelFrame { public: - DrivingModelFrame(cl_device_id device_id, cl_context context); + DrivingModelFrame(cl_device_id device_id, cl_context context, int _temporal_skip); ~DrivingModelFrame(); cl_mem* prepare(cl_mem yuv_cl, int frame_width, int frame_height, int frame_stride, int frame_uv_offset, const mat3& projection); const int MODEL_WIDTH = 512; const int MODEL_HEIGHT = 256; const int MODEL_FRAME_SIZE = MODEL_WIDTH * MODEL_HEIGHT * 3 / 2; - const int buf_size = MODEL_FRAME_SIZE * 2; + const int buf_size = MODEL_FRAME_SIZE * 2; // 2 frames are temporal_skip frames apart const size_t frame_size_bytes = MODEL_FRAME_SIZE * sizeof(uint8_t); private: LoadYUVState loadyuv; cl_mem img_buffer_20hz_cl, last_img_cl, input_frames_cl; cl_buffer_region region; + int temporal_skip; }; class MonitoringModelFrame : public ModelFrame { diff --git a/selfdrive/modeld/models/commonmodel.pxd b/selfdrive/modeld/models/commonmodel.pxd index b4f08b12aa..4ac64d9172 100644 --- a/selfdrive/modeld/models/commonmodel.pxd +++ b/selfdrive/modeld/models/commonmodel.pxd @@ -20,7 +20,7 @@ cdef extern from "selfdrive/modeld/models/commonmodel.h": cppclass DrivingModelFrame: int buf_size - DrivingModelFrame(cl_device_id, cl_context) + DrivingModelFrame(cl_device_id, cl_context, int) cppclass MonitoringModelFrame: int buf_size diff --git a/selfdrive/modeld/models/commonmodel_pyx.pyx b/selfdrive/modeld/models/commonmodel_pyx.pyx index 7b3a5bb342..5b7d11bc71 100644 --- a/selfdrive/modeld/models/commonmodel_pyx.pyx +++ b/selfdrive/modeld/models/commonmodel_pyx.pyx @@ -59,8 +59,8 @@ cdef class ModelFrame: cdef class DrivingModelFrame(ModelFrame): cdef cppDrivingModelFrame * _frame - def __cinit__(self, CLContext context): - self._frame = new cppDrivingModelFrame(context.device_id, context.context) + def __cinit__(self, CLContext context, int temporal_skip): + self._frame = new cppDrivingModelFrame(context.device_id, context.context, temporal_skip) self.frame = (self._frame) self.buf_size = self._frame.buf_size diff --git a/selfdrive/modeld/models/driving_policy.onnx b/selfdrive/modeld/models/driving_policy.onnx index f804b4ec31..cc2148c74b 100644 --- a/selfdrive/modeld/models/driving_policy.onnx +++ b/selfdrive/modeld/models/driving_policy.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5cae3285c876804e649b14adadcfb8be79a9bd5a1b928113e37f1f08e25e9688 -size 16581121 +oid sha256:5fd38c3b4d465d14a8ed128f8b1b265bff1589d42f398faa678b93f25b3385dc +size 15966721 diff --git a/selfdrive/modeld/models/driving_vision.onnx b/selfdrive/modeld/models/driving_vision.onnx index 06c87d8755..aee6d8f1bf 100644 --- a/selfdrive/modeld/models/driving_vision.onnx +++ b/selfdrive/modeld/models/driving_vision.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:29bbf79f9dfd7048c0013bb81e86d9b2979275b95ea1ed8a86d1a86a88695240 +oid sha256:897f80d0388250f99bba69b6a8434560cc0fd83157cbeb0bc134c67fe4e64624 size 34882971 From 54f845c3699cd622689a3d8a596c9739710bfcba Mon Sep 17 00:00:00 2001 From: commaci-public <60409688+commaci-public@users.noreply.github.com> Date: Tue, 4 Mar 2025 22:54:05 -0800 Subject: [PATCH 42/78] [bot] Update Python packages (#34779) Update Python packages Co-authored-by: Vehicle Researcher --- opendbc_repo | 2 +- panda | 2 +- uv.lock | 32 ++++++++++++++++---------------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/opendbc_repo b/opendbc_repo index 34a109cc79..e7d08ac479 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit 34a109cc7956dbf022f57b6bca2207f2719e25a7 +Subproject commit e7d08ac4794c859e604d260da010d4685c164e5b diff --git a/panda b/panda index 154b66782d..3bf1f8e871 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 154b66782ddf4b9293c4594bb5ee8bd9cd88f332 +Subproject commit 3bf1f8e871f3c577fccba07f57958f30508a2187 diff --git a/uv.lock b/uv.lock index 022e30508d..fe3ee05e77 100644 --- a/uv.lock +++ b/uv.lock @@ -12,11 +12,11 @@ resolution-markers = [ [[package]] name = "aiohappyeyeballs" -version = "2.4.6" +version = "2.4.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/08/07/508f9ebba367fc3370162e53a3cfd12f5652ad79f0e0bfdf9f9847c6f159/aiohappyeyeballs-2.4.6.tar.gz", hash = "sha256:9b05052f9042985d32ecbe4b59a77ae19c006a78f1344d7fdad69d28ded3d0b0", size = 21726 } +sdist = { url = "https://files.pythonhosted.org/packages/de/7c/79a15272e88d2563c9d63599fa59f05778975f35b255bf8f90c8b12b4ada/aiohappyeyeballs-2.4.8.tar.gz", hash = "sha256:19728772cb12263077982d2f55453babd8bec6a052a926cd5c0c42796da8bf62", size = 22337 } wheels = [ - { url = "https://files.pythonhosted.org/packages/44/4c/03fb05f56551828ec67ceb3665e5dc51638042d204983a03b0a1541475b6/aiohappyeyeballs-2.4.6-py3-none-any.whl", hash = "sha256:147ec992cf873d74f5062644332c539fcd42956dc69453fe5204195e560517e1", size = 14543 }, + { url = "https://files.pythonhosted.org/packages/52/0e/b187e2bb3eeb2644515109657c4474d65a84e7123de249bf1e8467d04a65/aiohappyeyeballs-2.4.8-py3-none-any.whl", hash = "sha256:6cac4f5dd6e34a9644e69cf9021ef679e4394f54e58a183056d12009e42ea9e3", size = 15005 }, ] [[package]] @@ -760,13 +760,13 @@ wheels = [ [[package]] name = "libusb1" -version = "3.2.0" +version = "3.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d9/b7/9e833af6cb52fa2aece1c6a1378667ca0172bead14f63ffccc3cb9862df3/libusb1-3.2.0.tar.gz", hash = "sha256:a11a6095e718cd49418a96329314da271cca6be7b4317a142724523371ac8961", size = 105601 } +sdist = { url = "https://files.pythonhosted.org/packages/69/c7/3c441fb0628b5afdfe68768f90f8d6ce74dc08e72691fb78d0875db06c48/libusb1-3.3.0.tar.gz", hash = "sha256:b642aa518689f8e053f61955cba274e72bc8d0794c65d7990745aaae90dfc8a1", size = 107253 } wheels = [ - { url = "https://files.pythonhosted.org/packages/fc/35/d5bde9434fc734709960a94cc489d487184d0ab08e5867311d5a4c64fcea/libusb1-3.2.0-py3-none-any.whl", hash = "sha256:048d4fb79021ec05af667a32e51a911578fc63ab3ed48a4f4fe0f67da797f416", size = 65829 }, - { url = "https://files.pythonhosted.org/packages/a3/cd/ef05b2c67fff2d704aa0325993187ce6a6d04f40ba4be953766b47f5f949/libusb1-3.2.0-py3-none-win32.whl", hash = "sha256:5dc48d6f5207e184cb53278527e7d8e5f4051d8bc419bd15b564c37dc5cca268", size = 127781 }, - { url = "https://files.pythonhosted.org/packages/f9/82/8bcadf2794fa2d39ec100a4f3945db58c316d55c1a0e79ac2cf81c754282/libusb1-3.2.0-py3-none-win_amd64.whl", hash = "sha256:b13acc618263348c91bc4476fadada47be98b7924d6f60e79e3f1da67ac39ddc", size = 139410 }, + { url = "https://files.pythonhosted.org/packages/c7/48/b24b810b14595bd4680030f73a31119120069a8857f41554f00e00b57229/libusb1-3.3.0-py3-none-any.whl", hash = "sha256:7923ff2bbe43878e1c7cf733fde49cca844ecada29dbc436033bca6171cda41f", size = 67044 }, + { url = "https://files.pythonhosted.org/packages/3f/45/52980eedf3fb78711960a558465b3d998beed327fcd2b8483119527adc44/libusb1-3.3.0-py3-none-win32.whl", hash = "sha256:270f35b3a8faddd63d78de9b2341e49f6aed6083dceb4b04f47b95fd944e8d00", size = 128992 }, + { url = "https://files.pythonhosted.org/packages/af/d3/992bfd5bcd9d7a978563d3dabb11d0fce5cf7ceea73d9633fbadba93df4e/libusb1-3.3.0-py3-none-win_amd64.whl", hash = "sha256:61e2b4efdbacdd689bf4eab6b9afa2d6ee8a4bae20ffbf7c5785024d25fa3258", size = 140624 }, ] [[package]] @@ -1578,16 +1578,16 @@ wheels = [ [[package]] name = "protobuf" -version = "5.29.3" +version = "6.30.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f7/d1/e0a911544ca9993e0f17ce6d3cc0932752356c1b0a834397f28e63479344/protobuf-5.29.3.tar.gz", hash = "sha256:5da0f41edaf117bde316404bad1a486cb4ededf8e4a54891296f648e8e076620", size = 424945 } +sdist = { url = "https://files.pythonhosted.org/packages/53/6a/2629bb3529e5bdfbd6c4608ff5c7d942cd4beae85793f84ba543aab2548a/protobuf-6.30.0.tar.gz", hash = "sha256:852b675d276a7d028f660da075af1841c768618f76b90af771a8e2c29e6f5965", size = 429239 } wheels = [ - { url = "https://files.pythonhosted.org/packages/dc/7a/1e38f3cafa022f477ca0f57a1f49962f21ad25850c3ca0acd3b9d0091518/protobuf-5.29.3-cp310-abi3-win32.whl", hash = "sha256:3ea51771449e1035f26069c4c7fd51fba990d07bc55ba80701c78f886bf9c888", size = 422708 }, - { url = "https://files.pythonhosted.org/packages/61/fa/aae8e10512b83de633f2646506a6d835b151edf4b30d18d73afd01447253/protobuf-5.29.3-cp310-abi3-win_amd64.whl", hash = "sha256:a4fa6f80816a9a0678429e84973f2f98cbc218cca434abe8db2ad0bffc98503a", size = 434508 }, - { url = "https://files.pythonhosted.org/packages/dd/04/3eaedc2ba17a088961d0e3bd396eac764450f431621b58a04ce898acd126/protobuf-5.29.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a8434404bbf139aa9e1300dbf989667a83d42ddda9153d8ab76e0d5dcaca484e", size = 417825 }, - { url = "https://files.pythonhosted.org/packages/4f/06/7c467744d23c3979ce250397e26d8ad8eeb2bea7b18ca12ad58313c1b8d5/protobuf-5.29.3-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:daaf63f70f25e8689c072cfad4334ca0ac1d1e05a92fc15c54eb9cf23c3efd84", size = 319573 }, - { url = "https://files.pythonhosted.org/packages/a8/45/2ebbde52ad2be18d3675b6bee50e68cd73c9e0654de77d595540b5129df8/protobuf-5.29.3-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:c027e08a08be10b67c06bf2370b99c811c466398c357e615ca88c91c07f0910f", size = 319672 }, - { url = "https://files.pythonhosted.org/packages/fd/b2/ab07b09e0f6d143dfb839693aa05765257bceaa13d03bf1a696b78323e7a/protobuf-5.29.3-py3-none-any.whl", hash = "sha256:0a18ed4a24198528f2333802eb075e59dea9d679ab7a6c5efb017a59004d849f", size = 172550 }, + { url = "https://files.pythonhosted.org/packages/aa/76/8b1cbf762d98b09fcb29bbc6eca97dc6e1cd865b97a49c443aa23f1a9f82/protobuf-6.30.0-cp310-abi3-win32.whl", hash = "sha256:7337d76d8efe65ee09ee566b47b5914c517190196f414e5418fa236dfd1aed3e", size = 419141 }, + { url = "https://files.pythonhosted.org/packages/57/50/2ea2fb4533321438f5106723c70c303529ba184540e619ebe75e790d402e/protobuf-6.30.0-cp310-abi3-win_amd64.whl", hash = "sha256:9b33d51cc95a7ec4f407004c8b744330b6911a37a782e2629c67e1e8ac41318f", size = 430995 }, + { url = "https://files.pythonhosted.org/packages/a1/7d/a7dfa7aa3deda114920b1ed57c0026e85a976e74658db2784a0443510252/protobuf-6.30.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:52d4bb6fe76005860e1d0b8bfa126f5c97c19cc82704961f60718f50be16942d", size = 417570 }, + { url = "https://files.pythonhosted.org/packages/11/87/a9c7b020c4072dc34e3a2a3cde69366ffc623afff0e7f10f4e5275aaec01/protobuf-6.30.0-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:7940ab4dfd60d514b2e1d3161549ea7aed5be37d53bafde16001ac470a3e202b", size = 317310 }, + { url = "https://files.pythonhosted.org/packages/95/66/424db2262723781dc94208ff9ce201df2f44f18a46fbff3c067812c6b5b9/protobuf-6.30.0-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:d79bf6a202a536b192b7e8d295d7eece0c86fbd9b583d147faf8cfeff46bf598", size = 316203 }, + { url = "https://files.pythonhosted.org/packages/51/6f/21c2b7de96c3051f847a4a88a12fdf015ed6b7d50fc131fb101a739bd7a5/protobuf-6.30.0-py3-none-any.whl", hash = "sha256:e5ef216ea061b262b8994cb6b7d6637a4fb27b3fb4d8e216a6040c0b93bd10d7", size = 167054 }, ] [[package]] From 50d059f96b38a07fba1ea2f6e17db5c28edb49c7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 22:54:21 -0800 Subject: [PATCH 43/78] [bot] Update translations (#34778) Update translations Co-authored-by: Vehicle Researcher --- selfdrive/ui/translations/main_ar.ts | 24 ++++++++++++------- selfdrive/ui/translations/main_de.ts | 24 ++++++++++++------- selfdrive/ui/translations/main_es.ts | 24 ++++++++++++------- selfdrive/ui/translations/main_fr.ts | 24 ++++++++++++------- selfdrive/ui/translations/main_ja.ts | 30 ++++++++++++++---------- selfdrive/ui/translations/main_ko.ts | 30 ++++++++++++++---------- selfdrive/ui/translations/main_pt-BR.ts | 30 ++++++++++++++---------- selfdrive/ui/translations/main_th.ts | 24 ++++++++++++------- selfdrive/ui/translations/main_tr.ts | 24 ++++++++++++------- selfdrive/ui/translations/main_zh-CHS.ts | 30 ++++++++++++++---------- selfdrive/ui/translations/main_zh-CHT.ts | 30 ++++++++++++++---------- 11 files changed, 186 insertions(+), 108 deletions(-) diff --git a/selfdrive/ui/translations/main_ar.ts b/selfdrive/ui/translations/main_ar.ts index 00a98f70c3..8c667e246c 100644 --- a/selfdrive/ui/translations/main_ar.ts +++ b/selfdrive/ui/translations/main_ar.ts @@ -311,22 +311,30 @@ 🔥 Firehose Mode 🔥 - - Enable Firehose Mode - - openpilot learns to drive by watching humans, like you, drive. -Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models with better Experimental Mode. +Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models, which means better Experimental Mode. - 0% - 5G {0%?} + Firehose Mode: ACTIVE + - Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable the toggle<br> 4. Leave it connected for at least 30 minutes<br><br>The toggle turns off once you restart your device. Repeat at least once a week for maximum effectiveness.<br><br><b>FAQ</b><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><i>Do I need to be on Wi-Fi?</i> Yes.<br><i>Do I need to bring the device inside?</i> No, you can enable once you're parked, however your uploads will be limited by your car's battery.<br> + For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.<br><br>Firehose Mode can also work while you're driving if connected to a hotspot or unlimited SIM card.<br><br><br><b>Frequently Asked Questions</b><br><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><br><i>Does it matter which software I run?</i> Yes, only upstream openpilot (and particular forks) are able to be used for training. + + + + <b>%1 %2</b> of your driving are in the training dataset so far. + + + + ACTIVE + + + + <span stylesheet='font-size: 60px; font-weight: bold; color: #e74c3c;'>INACTIVE</span>: connect to unmetered network diff --git a/selfdrive/ui/translations/main_de.ts b/selfdrive/ui/translations/main_de.ts index 831e589b03..e7160fc903 100644 --- a/selfdrive/ui/translations/main_de.ts +++ b/selfdrive/ui/translations/main_de.ts @@ -311,22 +311,30 @@ 🔥 Firehose Mode 🔥 - - Enable Firehose Mode - - openpilot learns to drive by watching humans, like you, drive. -Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models with better Experimental Mode. +Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models, which means better Experimental Mode. - 0% - 5G {0%?} + Firehose Mode: ACTIVE + - Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable the toggle<br> 4. Leave it connected for at least 30 minutes<br><br>The toggle turns off once you restart your device. Repeat at least once a week for maximum effectiveness.<br><br><b>FAQ</b><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><i>Do I need to be on Wi-Fi?</i> Yes.<br><i>Do I need to bring the device inside?</i> No, you can enable once you're parked, however your uploads will be limited by your car's battery.<br> + For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.<br><br>Firehose Mode can also work while you're driving if connected to a hotspot or unlimited SIM card.<br><br><br><b>Frequently Asked Questions</b><br><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><br><i>Does it matter which software I run?</i> Yes, only upstream openpilot (and particular forks) are able to be used for training. + + + + <b>%1 %2</b> of your driving are in the training dataset so far. + + + + ACTIVE + + + + <span stylesheet='font-size: 60px; font-weight: bold; color: #e74c3c;'>INACTIVE</span>: connect to unmetered network diff --git a/selfdrive/ui/translations/main_es.ts b/selfdrive/ui/translations/main_es.ts index ed6d946214..afbe7424be 100644 --- a/selfdrive/ui/translations/main_es.ts +++ b/selfdrive/ui/translations/main_es.ts @@ -311,22 +311,30 @@ 🔥 Firehose Mode 🔥 - - Enable Firehose Mode - - openpilot learns to drive by watching humans, like you, drive. -Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models with better Experimental Mode. +Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models, which means better Experimental Mode. - 0% - 5G {0%?} + Firehose Mode: ACTIVE + - Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable the toggle<br> 4. Leave it connected for at least 30 minutes<br><br>The toggle turns off once you restart your device. Repeat at least once a week for maximum effectiveness.<br><br><b>FAQ</b><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><i>Do I need to be on Wi-Fi?</i> Yes.<br><i>Do I need to bring the device inside?</i> No, you can enable once you're parked, however your uploads will be limited by your car's battery.<br> + For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.<br><br>Firehose Mode can also work while you're driving if connected to a hotspot or unlimited SIM card.<br><br><br><b>Frequently Asked Questions</b><br><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><br><i>Does it matter which software I run?</i> Yes, only upstream openpilot (and particular forks) are able to be used for training. + + + + <b>%1 %2</b> of your driving are in the training dataset so far. + + + + ACTIVE + + + + <span stylesheet='font-size: 60px; font-weight: bold; color: #e74c3c;'>INACTIVE</span>: connect to unmetered network diff --git a/selfdrive/ui/translations/main_fr.ts b/selfdrive/ui/translations/main_fr.ts index f2eba9860a..8be7842ddf 100644 --- a/selfdrive/ui/translations/main_fr.ts +++ b/selfdrive/ui/translations/main_fr.ts @@ -311,22 +311,30 @@ 🔥 Firehose Mode 🔥 - - Enable Firehose Mode - - openpilot learns to drive by watching humans, like you, drive. -Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models with better Experimental Mode. +Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models, which means better Experimental Mode. - 0% - 5G {0%?} + Firehose Mode: ACTIVE + - Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable the toggle<br> 4. Leave it connected for at least 30 minutes<br><br>The toggle turns off once you restart your device. Repeat at least once a week for maximum effectiveness.<br><br><b>FAQ</b><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><i>Do I need to be on Wi-Fi?</i> Yes.<br><i>Do I need to bring the device inside?</i> No, you can enable once you're parked, however your uploads will be limited by your car's battery.<br> + For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.<br><br>Firehose Mode can also work while you're driving if connected to a hotspot or unlimited SIM card.<br><br><br><b>Frequently Asked Questions</b><br><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><br><i>Does it matter which software I run?</i> Yes, only upstream openpilot (and particular forks) are able to be used for training. + + + + <b>%1 %2</b> of your driving are in the training dataset so far. + + + + ACTIVE + + + + <span stylesheet='font-size: 60px; font-weight: bold; color: #e74c3c;'>INACTIVE</span>: connect to unmetered network diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index a5c21d29a6..d8c75ecf1c 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -311,25 +311,31 @@ 🔥 Firehose Mode 🔥 🔥 Firehoseモード 🔥 - - Enable Firehose Mode - Firehoseを有効にする - openpilot learns to drive by watching humans, like you, drive. -Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models with better Experimental Mode. - openpilotは人間であるあなたの運転から学び、AI学習します。 - -Firehoseモードを有効にすると、学習データを最大限アップロードし、openpilotの運転モデルを向上させることができます。より多くのデータはより大きなモデルを生み出し、Experimentalモードの精度向上につながります。 +Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models, which means better Experimental Mode. + - 0% - 5G {0%?} + Firehose Mode: ACTIVE + - Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable the toggle<br> 4. Leave it connected for at least 30 minutes<br><br>The toggle turns off once you restart your device. Repeat at least once a week for maximum effectiveness.<br><br><b>FAQ</b><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><i>Do I need to be on Wi-Fi?</i> Yes.<br><i>Do I need to bring the device inside?</i> No, you can enable once you're parked, however your uploads will be limited by your car's battery.<br> - 以下の手順に従ってデバイスを準備してください:<br> 1. デバイスを室内に持ち込み、高速なUSB-C電源に接続してください<br> 2. Wi-Fiに接続してください<br> 3. 機能を有効にしてください<br> 4. 少なくとも30分間接続したままにしてください<br><br>デバイスを再起動すると、この機能はオフになります。最大の効果を得るために、少なくとも週に1回は繰り返してください。<br><br><b>FAQ</b><br><i>どのように運転するか、どこで運転するかは重要ですか?</i> いいえ、普段通りに運転してください。<br><i>高速なUSB-C電源とは何ですか?</i> スマフォやノートPC用のワット数の大きい充電器を使って下さい。<br><i>Wi-Fiに接続する必要がありますか?</i> その通りです。<br><i>デバイスを屋内に持ち込む必要がありますか?</i> いいえ、駐車後に有効にすることができますが、アップロードは車のバッテリーによって制限されます。<br> + For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.<br><br>Firehose Mode can also work while you're driving if connected to a hotspot or unlimited SIM card.<br><br><br><b>Frequently Asked Questions</b><br><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><br><i>Does it matter which software I run?</i> Yes, only upstream openpilot (and particular forks) are able to be used for training. + + + + <b>%1 %2</b> of your driving are in the training dataset so far. + + + + ACTIVE + + + + <span stylesheet='font-size: 60px; font-weight: bold; color: #e74c3c;'>INACTIVE</span>: connect to unmetered network + diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index b497e39f21..9a1da3c396 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -311,25 +311,31 @@ 🔥 Firehose Mode 🔥 🔥 파이어호스 모드 🔥 - - Enable Firehose Mode - 파이어호스 모드 활성화 - openpilot learns to drive by watching humans, like you, drive. -Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models with better Experimental Mode. - 오픈파일럿은 여러분과 같은 사람이 운전하는 모습을 보면서 운전하는 법을 배웁니다. - -파이어호스 모드를 사용하면 훈련 데이터 업로드를 최대화하여 오픈파일럿의 주행 모델을 개선할 수 있습니다. 더 많은 데이터는 더 나은 실험 모드를 갖춘 더 큰 모델을 의미합니다. +Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models, which means better Experimental Mode. + - 0% - 0% + Firehose Mode: ACTIVE + - Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable the toggle<br> 4. Leave it connected for at least 30 minutes<br><br>The toggle turns off once you restart your device. Repeat at least once a week for maximum effectiveness.<br><br><b>FAQ</b><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><i>Do I need to be on Wi-Fi?</i> Yes.<br><i>Do I need to bring the device inside?</i> No, you can enable once you're parked, however your uploads will be limited by your car's battery.<br> - 다음 단계에 따라 장치를 준비하세요.:<br> 1. 장치를 내부로 가져와 올바른 USB-C 어댑터에 연결하세요.<br> 2. Wi-Fi에 연결하세요.<br> 3. 토글을 활성화하세요.<br> 4. 최소 30분 동안 연결 상태로 두세요.<br><br> 장치를 다시 시작하면 토글이 꺼집니다. 효과를 극대화하려면 적어도 일주일에 한 번씩 반복하세요.<br><br><b>자주 묻는 질문</b><br><i>운전 방법이나 장소가 중요한가요?</i> 아니요, 평소처럼 운전하세요.<br><i>올바른 USB-C 어댑터란 무엇인가요?</i> 휴대폰이나 노트북 고속 충전기라면 어떤 것이든 괜찮습니다.<br><i>Wi-Fi에 연결되어 있어야 하나요?</i> 예.<br><i>장치를 차 안으로 가져와야 하나요?</i> 아니요, 주차한 후에는 활성화할 수 있지만 차량의 배터리에 따라 업로드가 제한됩니다.<br> + For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.<br><br>Firehose Mode can also work while you're driving if connected to a hotspot or unlimited SIM card.<br><br><br><b>Frequently Asked Questions</b><br><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><br><i>Does it matter which software I run?</i> Yes, only upstream openpilot (and particular forks) are able to be used for training. + + + + <b>%1 %2</b> of your driving are in the training dataset so far. + + + + ACTIVE + + + + <span stylesheet='font-size: 60px; font-weight: bold; color: #e74c3c;'>INACTIVE</span>: connect to unmetered network + diff --git a/selfdrive/ui/translations/main_pt-BR.ts b/selfdrive/ui/translations/main_pt-BR.ts index 06b2ef7b35..0b224fa940 100644 --- a/selfdrive/ui/translations/main_pt-BR.ts +++ b/selfdrive/ui/translations/main_pt-BR.ts @@ -311,25 +311,31 @@ 🔥 Firehose Mode 🔥 🔥 Mode Firehose 🔥 - - Enable Firehose Mode - Habilitar Modo Firehose - openpilot learns to drive by watching humans, like you, drive. -Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models with better Experimental Mode. - O openpilot aprende a dirigir observando humanos, como você, dirigirem. - -O Modo Firehose permite maximizar o envio de seus dados de treinamento para melhorar os modelos de direção do openpilot. Mais dados significam modelos maiores e um Modo Experimental melhor. +Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models, which means better Experimental Mode. + - 0% - 5G {0%?} + Firehose Mode: ACTIVE + - Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable the toggle<br> 4. Leave it connected for at least 30 minutes<br><br>The toggle turns off once you restart your device. Repeat at least once a week for maximum effectiveness.<br><br><b>FAQ</b><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><i>Do I need to be on Wi-Fi?</i> Yes.<br><i>Do I need to bring the device inside?</i> No, you can enable once you're parked, however your uploads will be limited by your car's battery.<br> - Siga estes passos para preparar seu dispositivo:<br> 1. Leve o dispositivo para dentro e conecte-o a um bom adaptador USB-C<br> 2. Conecte-se ao Wi-Fi<br> 3. Ative a opção<br> 4. Deixe-o conectado por pelo menos 30 minutos<br><br>A opção será desativada quando você reiniciar o dispositivo. Repita esse processo pelo menos uma vez por semana para obter a máxima eficácia.<br><br><b>FAQ</b><br><i>Importa como ou onde eu dirijo?</i> Não, basta dirigir normalmente.<br><i>O que é um bom adaptador USB-C?</i> Qualquer carregador rápido de celular ou laptop deve servir..<br><i>Preciso estar conectado ao Wi-Fi?</i> Sim.<br><i>Preciso levar o dispositivo para dentro de casa?</i> Não, você pode ativar a opção enquanto estiver estacionado, mas seus envios serão limitados pela bateria do carro.<br> + For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.<br><br>Firehose Mode can also work while you're driving if connected to a hotspot or unlimited SIM card.<br><br><br><b>Frequently Asked Questions</b><br><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><br><i>Does it matter which software I run?</i> Yes, only upstream openpilot (and particular forks) are able to be used for training. + + + + <b>%1 %2</b> of your driving are in the training dataset so far. + + + + ACTIVE + + + + <span stylesheet='font-size: 60px; font-weight: bold; color: #e74c3c;'>INACTIVE</span>: connect to unmetered network + diff --git a/selfdrive/ui/translations/main_th.ts b/selfdrive/ui/translations/main_th.ts index 41dc3cad56..07c3892958 100644 --- a/selfdrive/ui/translations/main_th.ts +++ b/selfdrive/ui/translations/main_th.ts @@ -311,22 +311,30 @@ 🔥 Firehose Mode 🔥 - - Enable Firehose Mode - - openpilot learns to drive by watching humans, like you, drive. -Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models with better Experimental Mode. +Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models, which means better Experimental Mode. - 0% - 5G {0%?} + Firehose Mode: ACTIVE + - Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable the toggle<br> 4. Leave it connected for at least 30 minutes<br><br>The toggle turns off once you restart your device. Repeat at least once a week for maximum effectiveness.<br><br><b>FAQ</b><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><i>Do I need to be on Wi-Fi?</i> Yes.<br><i>Do I need to bring the device inside?</i> No, you can enable once you're parked, however your uploads will be limited by your car's battery.<br> + For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.<br><br>Firehose Mode can also work while you're driving if connected to a hotspot or unlimited SIM card.<br><br><br><b>Frequently Asked Questions</b><br><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><br><i>Does it matter which software I run?</i> Yes, only upstream openpilot (and particular forks) are able to be used for training. + + + + <b>%1 %2</b> of your driving are in the training dataset so far. + + + + ACTIVE + + + + <span stylesheet='font-size: 60px; font-weight: bold; color: #e74c3c;'>INACTIVE</span>: connect to unmetered network diff --git a/selfdrive/ui/translations/main_tr.ts b/selfdrive/ui/translations/main_tr.ts index 421a92b950..dda3cdec22 100644 --- a/selfdrive/ui/translations/main_tr.ts +++ b/selfdrive/ui/translations/main_tr.ts @@ -311,22 +311,30 @@ 🔥 Firehose Mode 🔥 - - Enable Firehose Mode - - openpilot learns to drive by watching humans, like you, drive. -Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models with better Experimental Mode. +Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models, which means better Experimental Mode. - 0% - 5G {0%?} + Firehose Mode: ACTIVE + - Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable the toggle<br> 4. Leave it connected for at least 30 minutes<br><br>The toggle turns off once you restart your device. Repeat at least once a week for maximum effectiveness.<br><br><b>FAQ</b><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><i>Do I need to be on Wi-Fi?</i> Yes.<br><i>Do I need to bring the device inside?</i> No, you can enable once you're parked, however your uploads will be limited by your car's battery.<br> + For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.<br><br>Firehose Mode can also work while you're driving if connected to a hotspot or unlimited SIM card.<br><br><br><b>Frequently Asked Questions</b><br><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><br><i>Does it matter which software I run?</i> Yes, only upstream openpilot (and particular forks) are able to be used for training. + + + + <b>%1 %2</b> of your driving are in the training dataset so far. + + + + ACTIVE + + + + <span stylesheet='font-size: 60px; font-weight: bold; color: #e74c3c;'>INACTIVE</span>: connect to unmetered network diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index e6c8734b15..01ac85a8ce 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -311,25 +311,31 @@ 🔥 Firehose Mode 🔥 🔥 训练数据上传模式 🔥 - - Enable Firehose Mode - 启用训练数据上传模式 - openpilot learns to drive by watching humans, like you, drive. -Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models with better Experimental Mode. - openpilot 通过观察人类(像你一样的驾驶)来学习驾驶。 - -训练数据上传模式可让你最大化上传训练数据,以改进 openpilot 的驾驶模型。更多数据意味着更大的模型,并带来更优秀的实验模式。 +Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models, which means better Experimental Mode. + - 0% - 0% + Firehose Mode: ACTIVE + - Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable the toggle<br> 4. Leave it connected for at least 30 minutes<br><br>The toggle turns off once you restart your device. Repeat at least once a week for maximum effectiveness.<br><br><b>FAQ</b><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><i>Do I need to be on Wi-Fi?</i> Yes.<br><i>Do I need to bring the device inside?</i> No, you can enable once you're parked, however your uploads will be limited by your car's battery.<br> - 按照以下步骤准备您的设备:<br> 1. 将设备带到室内并连接到良好的 USB-C 充电器<br> 2. 连接 Wi-Fi<br> 3. 启用开关<br> 4. 保持连接至少 30 分钟<br><br>开关会在设备重新启动后自动关闭。请至少每周重复一次,以获得最佳效果。<br><br><b>常见问题</b><br><i>驾驶方式或地点重要吗?</i> 不,按照平常的方式驾驶即可。<br><i>什么是良好的 USB-C 充电器?</i> 任何快速手机或笔记本电脑充电器都可以。<br><i>我需要连接 Wi-Fi 吗?</i> 是的。<br><i>我需要把设备带到室内吗?</i> 不,您可以在停车后启用,但您的上传速度将受限于车辆的电池。<br> + For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.<br><br>Firehose Mode can also work while you're driving if connected to a hotspot or unlimited SIM card.<br><br><br><b>Frequently Asked Questions</b><br><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><br><i>Does it matter which software I run?</i> Yes, only upstream openpilot (and particular forks) are able to be used for training. + + + + <b>%1 %2</b> of your driving are in the training dataset so far. + + + + ACTIVE + + + + <span stylesheet='font-size: 60px; font-weight: bold; color: #e74c3c;'>INACTIVE</span>: connect to unmetered network + diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index d750e9c46a..02d3593e60 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -311,25 +311,31 @@ 🔥 Firehose Mode 🔥 🔥 訓練資料上傳模式 🔥 - - Enable Firehose Mode - 啟用訓練資料上傳模式 - openpilot learns to drive by watching humans, like you, drive. -Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models with better Experimental Mode. - openpilot 透過觀察人類(像你一樣的駕駛)來學習駕駛。 - -訓練資料上傳模式可讓你最大化上傳訓練數據,以改進 openpilot 的駕駛模型。更多數據意味著更大的模型,並帶來更優秀的實驗模式。 +Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models, which means better Experimental Mode. + - 0% - 0% + Firehose Mode: ACTIVE + - Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable the toggle<br> 4. Leave it connected for at least 30 minutes<br><br>The toggle turns off once you restart your device. Repeat at least once a week for maximum effectiveness.<br><br><b>FAQ</b><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><i>Do I need to be on Wi-Fi?</i> Yes.<br><i>Do I need to bring the device inside?</i> No, you can enable once you're parked, however your uploads will be limited by your car's battery.<br> - 按照以下步驟準備您的裝置:<br> 1. 將裝置帶到室內並連接到良好的 USB-C 充電器<br> 2. 連接 Wi-Fi<br> 3. 啟用開關<br> 4. 保持連接至少 30 分鐘<br><br>開關會在裝置重新啟動後自動關閉。請至少每週重複一次,以獲得最佳效果。<br><br><b>常見問題</b><br><i>駕駛方式或地點重要嗎?</i> 不,按照平常的方式駕駛即可。<br><i>什麼是良好的 USB-C 充電器?</i> 任何快速手機或筆記本電腦充電器都可以。<br><i>我需要連接 Wi-Fi 嗎?</i> 是的。<br><i>我需要把裝置帶到室內嗎?</i> 不,您可以在停車後啟用,但您的上傳速度將受限於車輛的電池。<br> + For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.<br><br>Firehose Mode can also work while you're driving if connected to a hotspot or unlimited SIM card.<br><br><br><b>Frequently Asked Questions</b><br><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><br><i>Does it matter which software I run?</i> Yes, only upstream openpilot (and particular forks) are able to be used for training. + + + + <b>%1 %2</b> of your driving are in the training dataset so far. + + + + ACTIVE + + + + <span stylesheet='font-size: 60px; font-weight: bold; color: #e74c3c;'>INACTIVE</span>: connect to unmetered network + From a82db2d331384fade0a4b1062d58921afa56a1a9 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 5 Mar 2025 03:41:16 -0600 Subject: [PATCH 44/78] Revert "Filet o Fish model" (#34780) Revert "Filet o Fish model (#34775)" This reverts commit 31076b818df68ea171447ccafa07039311a11136. --- selfdrive/modeld/constants.py | 8 +----- selfdrive/modeld/modeld.py | 31 +++++++-------------- selfdrive/modeld/models/commonmodel.cc | 9 +++--- selfdrive/modeld/models/commonmodel.h | 5 ++-- selfdrive/modeld/models/commonmodel.pxd | 2 +- selfdrive/modeld/models/commonmodel_pyx.pyx | 4 +-- selfdrive/modeld/models/driving_policy.onnx | 4 +-- selfdrive/modeld/models/driving_vision.onnx | 2 +- 8 files changed, 23 insertions(+), 42 deletions(-) diff --git a/selfdrive/modeld/constants.py b/selfdrive/modeld/constants.py index 5ca0a86bc8..2bb7b8100c 100644 --- a/selfdrive/modeld/constants.py +++ b/selfdrive/modeld/constants.py @@ -14,14 +14,8 @@ class ModelConstants: # model inputs constants MODEL_FREQ = 20 - HISTORY_FREQ = 5 - HISTORY_LEN_SECONDS = 5 - TEMPORAL_SKIP = MODEL_FREQ // HISTORY_FREQ - FULL_HISTORY_BUFFER_LEN = MODEL_FREQ * HISTORY_LEN_SECONDS - INPUT_HISTORY_BUFFER_LEN = HISTORY_FREQ * HISTORY_LEN_SECONDS - FEATURE_LEN = 512 - + FULL_HISTORY_BUFFER_LEN = 100 DESIRE_LEN = 8 TRAFFIC_CONVENTION_LEN = 2 LAT_PLANNER_STATE_LEN = 4 diff --git a/selfdrive/modeld/modeld.py b/selfdrive/modeld/modeld.py index 1e557942fe..ee825d158f 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -56,24 +56,16 @@ class ModelState: prev_desire: np.ndarray # for tracking the rising edge of the pulse def __init__(self, context: CLContext): - self.frames = { - 'input_imgs': DrivingModelFrame(context, ModelConstants.TEMPORAL_SKIP), - 'big_input_imgs': DrivingModelFrame(context, ModelConstants.TEMPORAL_SKIP) - } + self.frames = {'input_imgs': DrivingModelFrame(context), 'big_input_imgs': DrivingModelFrame(context)} self.prev_desire = np.zeros(ModelConstants.DESIRE_LEN, dtype=np.float32) - self.full_features_buffer = np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.FEATURE_LEN), dtype=np.float32) - self.full_desire = np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.DESIRE_LEN), dtype=np.float32) - self.full_prev_desired_curv = np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.PREV_DESIRED_CURV_LEN), dtype=np.float32) - self.temporal_idxs = slice(-1-(ModelConstants.TEMPORAL_SKIP*(ModelConstants.INPUT_HISTORY_BUFFER_LEN-1)), None, ModelConstants.TEMPORAL_SKIP) - # policy inputs self.numpy_inputs = { - 'desire': np.zeros((1, ModelConstants.INPUT_HISTORY_BUFFER_LEN, ModelConstants.DESIRE_LEN), dtype=np.float32), + 'desire': np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.DESIRE_LEN), dtype=np.float32), 'traffic_convention': np.zeros((1, ModelConstants.TRAFFIC_CONVENTION_LEN), dtype=np.float32), 'lateral_control_params': np.zeros((1, ModelConstants.LATERAL_CONTROL_PARAMS_LEN), dtype=np.float32), - 'prev_desired_curv': np.zeros((1, ModelConstants.INPUT_HISTORY_BUFFER_LEN, ModelConstants.PREV_DESIRED_CURV_LEN), dtype=np.float32), - 'features_buffer': np.zeros((1, ModelConstants.INPUT_HISTORY_BUFFER_LEN, ModelConstants.FEATURE_LEN), dtype=np.float32), + 'prev_desired_curv': np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.PREV_DESIRED_CURV_LEN), dtype=np.float32), + 'features_buffer': np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.FEATURE_LEN), dtype=np.float32), } with open(VISION_METADATA_PATH, 'rb') as f: @@ -112,9 +104,8 @@ class ModelState: new_desire = np.where(inputs['desire'] - self.prev_desire > .99, inputs['desire'], 0) self.prev_desire[:] = inputs['desire'] - self.full_desire[0,:-1] = self.full_desire[0,1:] - self.full_desire[0,-1] = new_desire - self.numpy_inputs['desire'][:] = self.full_desire.reshape((1,ModelConstants.INPUT_HISTORY_BUFFER_LEN,ModelConstants.TEMPORAL_SKIP,-1)).max(axis=2) + self.numpy_inputs['desire'][0,:-1] = self.numpy_inputs['desire'][0,1:] + self.numpy_inputs['desire'][0,-1] = new_desire self.numpy_inputs['traffic_convention'][:] = inputs['traffic_convention'] self.numpy_inputs['lateral_control_params'][:] = inputs['lateral_control_params'] @@ -137,17 +128,15 @@ class ModelState: self.vision_output = self.vision_run(**self.vision_inputs).numpy().flatten() vision_outputs_dict = self.parser.parse_vision_outputs(self.slice_outputs(self.vision_output, self.vision_output_slices)) - self.full_features_buffer[0,:-1] = self.full_features_buffer[0,1:] - self.full_features_buffer[0,-1] = vision_outputs_dict['hidden_state'][0, :] - self.numpy_inputs['features_buffer'][:] = self.full_features_buffer[0, self.temporal_idxs] + self.numpy_inputs['features_buffer'][0,:-1] = self.numpy_inputs['features_buffer'][0,1:] + self.numpy_inputs['features_buffer'][0,-1] = vision_outputs_dict['hidden_state'][0, :] self.policy_output = self.policy_run(**self.policy_inputs).numpy().flatten() policy_outputs_dict = self.parser.parse_policy_outputs(self.slice_outputs(self.policy_output, self.policy_output_slices)) # TODO model only uses last value now - self.full_prev_desired_curv[0,:-1] = self.full_prev_desired_curv[0,1:] - self.full_prev_desired_curv[0,-1,:] = policy_outputs_dict['desired_curvature'][0, :] - self.numpy_inputs['prev_desired_curv'][:] = self.full_prev_desired_curv[0, self.temporal_idxs] + self.numpy_inputs['prev_desired_curv'][0,:-1] = self.numpy_inputs['prev_desired_curv'][0,1:] + self.numpy_inputs['prev_desired_curv'][0,-1,:] = policy_outputs_dict['desired_curvature'][0, :] combined_outputs_dict = {**vision_outputs_dict, **policy_outputs_dict} if SEND_RAW_PRED: diff --git a/selfdrive/modeld/models/commonmodel.cc b/selfdrive/modeld/models/commonmodel.cc index 99155d9f1e..9973d18588 100644 --- a/selfdrive/modeld/models/commonmodel.cc +++ b/selfdrive/modeld/models/commonmodel.cc @@ -5,12 +5,11 @@ #include "common/clutil.h" -DrivingModelFrame::DrivingModelFrame(cl_device_id device_id, cl_context context, int _temporal_skip) : ModelFrame(device_id, context) { +DrivingModelFrame::DrivingModelFrame(cl_device_id device_id, cl_context context) : ModelFrame(device_id, context) { input_frames = std::make_unique(buf_size); - temporal_skip = _temporal_skip; input_frames_cl = CL_CHECK_ERR(clCreateBuffer(context, CL_MEM_READ_WRITE, buf_size, NULL, &err)); - img_buffer_20hz_cl = CL_CHECK_ERR(clCreateBuffer(context, CL_MEM_READ_WRITE, (temporal_skip+1)*frame_size_bytes, NULL, &err)); - region.origin = temporal_skip * frame_size_bytes; + img_buffer_20hz_cl = CL_CHECK_ERR(clCreateBuffer(context, CL_MEM_READ_WRITE, 2*frame_size_bytes, NULL, &err)); + region.origin = 1 * frame_size_bytes; region.size = frame_size_bytes; last_img_cl = CL_CHECK_ERR(clCreateSubBuffer(img_buffer_20hz_cl, CL_MEM_READ_WRITE, CL_BUFFER_CREATE_TYPE_REGION, ®ion, &err)); @@ -21,7 +20,7 @@ DrivingModelFrame::DrivingModelFrame(cl_device_id device_id, cl_context context, cl_mem* DrivingModelFrame::prepare(cl_mem yuv_cl, int frame_width, int frame_height, int frame_stride, int frame_uv_offset, const mat3& projection) { run_transform(yuv_cl, MODEL_WIDTH, MODEL_HEIGHT, frame_width, frame_height, frame_stride, frame_uv_offset, projection); - for (int i = 0; i < temporal_skip; i++) { + for (int i = 0; i < 1; i++) { CL_CHECK(clEnqueueCopyBuffer(q, img_buffer_20hz_cl, img_buffer_20hz_cl, (i+1)*frame_size_bytes, i*frame_size_bytes, frame_size_bytes, 0, nullptr, nullptr)); } loadyuv_queue(&loadyuv, q, y_cl, u_cl, v_cl, last_img_cl); diff --git a/selfdrive/modeld/models/commonmodel.h b/selfdrive/modeld/models/commonmodel.h index 176d7eb6dc..14409943e4 100644 --- a/selfdrive/modeld/models/commonmodel.h +++ b/selfdrive/modeld/models/commonmodel.h @@ -64,21 +64,20 @@ protected: class DrivingModelFrame : public ModelFrame { public: - DrivingModelFrame(cl_device_id device_id, cl_context context, int _temporal_skip); + DrivingModelFrame(cl_device_id device_id, cl_context context); ~DrivingModelFrame(); cl_mem* prepare(cl_mem yuv_cl, int frame_width, int frame_height, int frame_stride, int frame_uv_offset, const mat3& projection); const int MODEL_WIDTH = 512; const int MODEL_HEIGHT = 256; const int MODEL_FRAME_SIZE = MODEL_WIDTH * MODEL_HEIGHT * 3 / 2; - const int buf_size = MODEL_FRAME_SIZE * 2; // 2 frames are temporal_skip frames apart + const int buf_size = MODEL_FRAME_SIZE * 2; const size_t frame_size_bytes = MODEL_FRAME_SIZE * sizeof(uint8_t); private: LoadYUVState loadyuv; cl_mem img_buffer_20hz_cl, last_img_cl, input_frames_cl; cl_buffer_region region; - int temporal_skip; }; class MonitoringModelFrame : public ModelFrame { diff --git a/selfdrive/modeld/models/commonmodel.pxd b/selfdrive/modeld/models/commonmodel.pxd index 4ac64d9172..b4f08b12aa 100644 --- a/selfdrive/modeld/models/commonmodel.pxd +++ b/selfdrive/modeld/models/commonmodel.pxd @@ -20,7 +20,7 @@ cdef extern from "selfdrive/modeld/models/commonmodel.h": cppclass DrivingModelFrame: int buf_size - DrivingModelFrame(cl_device_id, cl_context, int) + DrivingModelFrame(cl_device_id, cl_context) cppclass MonitoringModelFrame: int buf_size diff --git a/selfdrive/modeld/models/commonmodel_pyx.pyx b/selfdrive/modeld/models/commonmodel_pyx.pyx index 5b7d11bc71..7b3a5bb342 100644 --- a/selfdrive/modeld/models/commonmodel_pyx.pyx +++ b/selfdrive/modeld/models/commonmodel_pyx.pyx @@ -59,8 +59,8 @@ cdef class ModelFrame: cdef class DrivingModelFrame(ModelFrame): cdef cppDrivingModelFrame * _frame - def __cinit__(self, CLContext context, int temporal_skip): - self._frame = new cppDrivingModelFrame(context.device_id, context.context, temporal_skip) + def __cinit__(self, CLContext context): + self._frame = new cppDrivingModelFrame(context.device_id, context.context) self.frame = (self._frame) self.buf_size = self._frame.buf_size diff --git a/selfdrive/modeld/models/driving_policy.onnx b/selfdrive/modeld/models/driving_policy.onnx index cc2148c74b..f804b4ec31 100644 --- a/selfdrive/modeld/models/driving_policy.onnx +++ b/selfdrive/modeld/models/driving_policy.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5fd38c3b4d465d14a8ed128f8b1b265bff1589d42f398faa678b93f25b3385dc -size 15966721 +oid sha256:5cae3285c876804e649b14adadcfb8be79a9bd5a1b928113e37f1f08e25e9688 +size 16581121 diff --git a/selfdrive/modeld/models/driving_vision.onnx b/selfdrive/modeld/models/driving_vision.onnx index aee6d8f1bf..06c87d8755 100644 --- a/selfdrive/modeld/models/driving_vision.onnx +++ b/selfdrive/modeld/models/driving_vision.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:897f80d0388250f99bba69b6a8434560cc0fd83157cbeb0bc134c67fe4e64624 +oid sha256:29bbf79f9dfd7048c0013bb81e86d9b2979275b95ea1ed8a86d1a86a88695240 size 34882971 From e394569eaeaa3eb56dc28c4fd1c921be53078d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20Sch=C3=A4fer?= Date: Wed, 5 Mar 2025 13:33:45 -0800 Subject: [PATCH 45/78] Pre leak TinyGrad unbump (#34781) --- tinygrad_repo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tinygrad_repo b/tinygrad_repo index 6f39c4d653..70266e9f94 160000 --- a/tinygrad_repo +++ b/tinygrad_repo @@ -1 +1 @@ -Subproject commit 6f39c4d653737c056540194605dc18a7273df280 +Subproject commit 70266e9f94d5a247ccbb2f3a46e72a2fbdaf7a8e From d15599a30bd92e5e02b3ad932ec78a59ba33766d Mon Sep 17 00:00:00 2001 From: Jason Young <46612682+jyoung8607@users.noreply.github.com> Date: Wed, 5 Mar 2025 16:40:51 -0500 Subject: [PATCH 46/78] tools: updates to find_segments_with_message notebook (#34782) * cleanup, refactor, progress bar * more cleanup, add EXTRA_SEGMENTS * not everyone can see that route * add to README * update README * red panda support --- tools/car_porting/README.md | 39 ++- .../examples/find_segments_with_message.ipynb | 295 ++++++++---------- 2 files changed, 160 insertions(+), 174 deletions(-) diff --git a/tools/car_porting/README.md b/tools/car_porting/README.md index 68b0a57fb3..77492035ca 100644 --- a/tools/car_porting/README.md +++ b/tools/car_porting/README.md @@ -57,7 +57,21 @@ Traceback (most recent call last): AssertionError: 1 is not false : panda safety doesn't agree with openpilot: {'gasPressed': 116} ``` -### [tools/car_porting/examples/subaru_steer_temp_fault.ipynb](/tools/car_porting/examples/subaru_steer_temp_fault.ipynb) +## Jupyter notebooks + +To use these notebooks, install Jupyter within your [openpilot virtual environment](/tools/README.md). + +```bash +uv pip install jupyter ipykernel +``` + +Launching: + +```bash +jupyter notebook +``` + +### [examples/subaru_steer_temp_fault.ipynb](/tools/car_porting/examples/subaru_steer_temp_fault.ipynb) An example of searching through a database of segments for a specific condition, and plotting the results. @@ -65,7 +79,7 @@ An example of searching through a database of segments for a specific condition, *a plot of the steer_warning vs steering angle, where we can see it is clearly caused by a large steering angle change* -### [tools/car_porting/examples/subaru_long_accel.ipynb](/tools/car_porting/examples/subaru_long_accel.ipynb) +### [examples/subaru_long_accel.ipynb](/tools/car_porting/examples/subaru_long_accel.ipynb) An example of plotting the response of an actuator when it is active. @@ -73,7 +87,7 @@ An example of plotting the response of an actuator when it is active. *a plot of the brake_pressure vs acceleration, where we can see it is a fairly linear response.* -### [tools/car_porting/examples/ford_vin_fingerprint.ipynb](/tools/car_porting/examples/ford_vin_fingerprint.ipynb) +### [examples/ford_vin_fingerprint.ipynb](/tools/car_porting/examples/ford_vin_fingerprint.ipynb) In this example, we use the public comma car segments database to check if vin fingerprinting is feasible for ford. @@ -94,3 +108,22 @@ vin: 5LM5J7XC8MGXXXXXX real platform: FORD EXPLORER 6TH GEN determi vin: 3FTTW8E31PRXXXXXX real platform: FORD MAVERICK 1ST GEN determined platform: mock correct: False vin: 3FTTW8E99NRXXXXXX real platform: FORD MAVERICK 1ST GEN determined platform: mock correct: False ``` + +### [examples/find_segments_with_message.ipynb](/tools/car_porting/examples/find_segments_with_message.ipynb) + +Searches for segments where a set of given CAN message IDs are present. In the example, we search for all messages +used for CAN-based ignition detection. + +``` +Match found: 46b21f1c5f7aa885/2024-01-23--15-19-34/20/s JEEP GRAND CHEROKEE V6 2018 ['VW CAN Ign'] +Match found: a63a23c3e628f288/2023-11-05--18-36-20/8/s JEEP GRAND CHEROKEE V6 2018 ['VW CAN Ign'] +Match found: ce31b7a998781ba8/2024-01-19--07-05-29/23/s JEEP GRAND CHEROKEE 2019 ['VW CAN Ign'] +Match found: e1dfba62a4e33f7b/2023-12-25--19-31-00/4/s JEEP GRAND CHEROKEE 2019 ['VW CAN Ign'] +Match found: e1dfba62a4e33f7b/2024-01-10--14-33-57/2/s JEEP GRAND CHEROKEE 2019 ['VW CAN Ign'] +Match found: ae679616266f4096/2023-12-05--15-43-46/4/s RAM HD 5TH GEN ['Tesla 3/Y CAN Ign'] +Match found: ae679616266f4096/2023-11-18--17-49-42/3/s RAM HD 5TH GEN ['Tesla 3/Y CAN Ign'] +Match found: ae679616266f4096/2024-01-03--21-57-09/25/s RAM HD 5TH GEN ['Tesla 3/Y CAN Ign'] +Match found: 6dae2984cc53cd7f/2023-12-10--11-53-15/17/s FORD BRONCO SPORT 1ST GEN ['Rivian CAN Ign'] +Match found: 6dae2984cc53cd7f/2023-12-03--17-31-17/29/s FORD BRONCO SPORT 1ST GEN ['Rivian CAN Ign'] +Match found: 6dae2984cc53cd7f/2023-11-27--23-29-07/1/s FORD BRONCO SPORT 1ST GEN ['Rivian CAN Ign'] +``` diff --git a/tools/car_porting/examples/find_segments_with_message.ipynb b/tools/car_porting/examples/find_segments_with_message.ipynb index 82b06c1f31..4e688cc65b 100644 --- a/tools/car_porting/examples/find_segments_with_message.ipynb +++ b/tools/car_porting/examples/find_segments_with_message.ipynb @@ -2,30 +2,26 @@ "cells": [ { "cell_type": "code", - "execution_count": 30, - "id": "228a6736-de31-4255-9d72-a6ff391b968d", + "execution_count": 85, + "id": "facb8edc-9924-491a-a4dd-fe6135b0c6c4", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Found 221 qualifying vehicles:\n" - ] - } - ], + "outputs": [], "source": [ - "from opendbc.car import structs\n", - "from opendbc.car.values import PLATFORMS\n", + "# Import all cars from opendbc\n", "\n", - "print(f\"Found {len(PLATFORMS)} qualifying vehicles:\")\n", - "# for platform in PLATFORMS:\n", - "# print(f\" {platform}\")" + "from opendbc.car import structs\n", + "from opendbc.car.values import PLATFORMS as TEST_PLATFORMS\n", + "\n", + "# Example: add additional platforms/segments to test outside of commaCarSegments\n", + "\n", + "EXTRA_SEGMENTS = {\n", + " # \"81dd9e9fe256c397/0000001f--97c42cf98d\", # Volkswagen ID.4 test route, new car port, not in public dataset\n", + "}" ] }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 86, "id": "ed1c8aec-c274-4c61-b83d-711ea194bf86", "metadata": {}, "outputs": [ @@ -33,32 +29,32 @@ "name": "stdout", "output_type": "stream", "text": [ - "Collecting segments from commaCarSegments dataset:\n", - "No segments available for for DODGE_DURANGO\n", - "No segments available for for FORD_RANGER_MK2\n", - "No segments available for for HOLDEN_ASTRA\n", - "No segments available for for CADILLAC_ATS\n", - "No segments available for for CHEVROLET_MALIBU\n", - "No segments available for for CADILLAC_XT4\n", - "No segments available for for CHEVROLET_VOLT_2019\n", - "No segments available for for CHEVROLET_TRAVERSE\n", - "No segments available for for GMC_YUKON\n", - "No segments available for for HONDA_ODYSSEY_CHN\n", - "No segments available for for HYUNDAI_KONA_2022\n", - "No segments available for for HYUNDAI_NEXO_1ST_GEN\n", - "No segments available for for GENESIS_GV70_ELECTRIFIED_1ST_GEN\n", - "No segments available for for GENESIS_G80_2ND_GEN_FL\n", - "No segments available for for RIVIAN_R1_GEN1\n", - "No segments available for for SUBARU_FORESTER_HYBRID\n", - "No segments available for for TESLA_MODEL_3\n", - "No segments available for for TESLA_MODEL_Y\n", - "No segments available for for TOYOTA_RAV4_PRIME\n", - "No segments available for for TOYOTA_SIENNA_4TH_GEN\n", - "No segments available for for LEXUS_LC_TSS2\n", - "No segments available for for VOLKSWAGEN_CADDY_MK3\n", - "No segments available for for VOLKSWAGEN_CRAFTER_MK2\n", - "No segments available for for VOLKSWAGEN_JETTA_MK6\n", - "Collected 577 segments for analysis\n" + "Searching 221 platforms\n", + "No segments available for DODGE_DURANGO\n", + "No segments available for FORD_RANGER_MK2\n", + "No segments available for HOLDEN_ASTRA\n", + "No segments available for CADILLAC_ATS\n", + "No segments available for CHEVROLET_MALIBU\n", + "No segments available for CADILLAC_XT4\n", + "No segments available for CHEVROLET_VOLT_2019\n", + "No segments available for CHEVROLET_TRAVERSE\n", + "No segments available for GMC_YUKON\n", + "No segments available for HONDA_ODYSSEY_CHN\n", + "No segments available for HYUNDAI_KONA_2022\n", + "No segments available for HYUNDAI_NEXO_1ST_GEN\n", + "No segments available for GENESIS_GV70_ELECTRIFIED_1ST_GEN\n", + "No segments available for GENESIS_G80_2ND_GEN_FL\n", + "No segments available for RIVIAN_R1_GEN1\n", + "No segments available for SUBARU_FORESTER_HYBRID\n", + "No segments available for TESLA_MODEL_3\n", + "No segments available for TESLA_MODEL_Y\n", + "No segments available for TOYOTA_RAV4_PRIME\n", + "No segments available for TOYOTA_SIENNA_4TH_GEN\n", + "No segments available for LEXUS_LC_TSS2\n", + "No segments available for VOLKSWAGEN_CADDY_MK3\n", + "No segments available for VOLKSWAGEN_CRAFTER_MK2\n", + "No segments available for VOLKSWAGEN_JETTA_MK6\n", + "Searching 577 segments\n" ] } ], @@ -68,174 +64,131 @@ "from openpilot.tools.lib.logreader import LogReader\n", "from openpilot.tools.lib.comma_car_segments import get_comma_car_segments_database\n", "\n", - "database = get_comma_car_segments_database()\n", - "TEST_SEGMENTS = []\n", "\n", "MAX_SEGS_PER_PLATFORM = 3 # Increase this to search more segments\n", "\n", - "print(\"Collecting segments from commaCarSegments dataset:\")\n", + "database = get_comma_car_segments_database()\n", + "TEST_SEGMENTS = []\n", + "\n", + "print(f\"Searching {len(TEST_PLATFORMS)} platforms\")\n", + "\n", "for platform in TEST_PLATFORMS:\n", " if platform not in database:\n", - " print(f\"No segments available for for {platform}\")\n", + " print(f\"No segments available for {platform}\")\n", " continue\n", " \n", " all_segments = database[platform]\n", - "\n", " NUM_SEGMENTS = min(len(all_segments), MAX_SEGS_PER_PLATFORM)\n", - "\n", - " # print(f\"Got {len(all_segments)} segments for platform {platform}, sampling {NUM_SEGMENTS} segments\")\n", " TEST_SEGMENTS.extend(random.sample(all_segments, NUM_SEGMENTS))\n", "\n", - "print(f\"Collected {len(TEST_SEGMENTS)} segments for analysis\")\n" + "TEST_SEGMENTS.extend(EXTRA_SEGMENTS)\n", + "\n", + "print(f\"Searching {len(TEST_SEGMENTS)} segments\")" ] }, { "cell_type": "code", - "execution_count": 33, + "execution_count": null, "id": "0c75e8f2-4f5f-4f89-b8db-5223a6534a9f", "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Match found in d753e5427226080e/2023-12-30--10-14-03/9/s for CHRYSLER PACIFICA HYBRID 2018\n", - "Match found in 810855dc1450c716/2023-12-26--10-03-20/3/s for CHRYSLER PACIFICA HYBRID 2018\n", - "Match found in 7f268b92fc672c4d/2023-11-02--20-54-34/103/s for CHRYSLER PACIFICA HYBRID 2018\n", - "Match found in 1a10807c60c127fd/2023-12-09--19-21-30/49/s for CHRYSLER PACIFICA HYBRID 2019\n", - "Match found in b70b56b76a6217f2/2023-12-26--12-29-24/4/s for CHRYSLER PACIFICA HYBRID 2019\n", - "Match found in 86deeb65f10c3129/2023-12-29--07-38-12/179/s for CHRYSLER PACIFICA HYBRID 2019\n", - "Match found in 0a3e89f78b1d0071/2023-11-30--10-33-13/13/s for CHRYSLER PACIFICA 2018\n", - "Match found in 8fc6a1b72c8b1357/2023-11-30--17-35-04/10/s for CHRYSLER PACIFICA 2018\n", - "Match found in d5de6f3e9371e89e/2023-11-16--17-19-54/48/s for CHRYSLER PACIFICA 2018\n", - "Match found in 5fc1717be83fc0da/2024-01-03--13-16-03/27/s for CHRYSLER PACIFICA 2020\n", - "Match found in c1feb10d20626c65/2023-12-16--17-46-24/9/s for CHRYSLER PACIFICA 2020\n", - "Match found in c1feb10d20626c65/2023-11-21--17-40-18/25/s for CHRYSLER PACIFICA 2020\n", - "Match found in a63a23c3e628f288/2023-11-05--18-36-20/22/s for JEEP GRAND CHEROKEE V6 2018\n", - "Match found in 46b21f1c5f7aa885/2023-11-14--15-22-04/21/s for JEEP GRAND CHEROKEE V6 2018\n", - "Match found in a63a23c3e628f288/2023-12-13--09-15-47/27/s for JEEP GRAND CHEROKEE V6 2018\n", - "Match found in 4ffe7a3fb831a625/2024-01-04--09-15-33/22/s for JEEP GRAND CHEROKEE 2019\n", - "Match found in c5b49919572d2c5a/2023-12-17--15-54-06/73/s for JEEP GRAND CHEROKEE 2019\n", - "Match found in 9c2b832d06f93621/2024-01-25--13-52-19/8/s for JEEP GRAND CHEROKEE 2019\n", - "Match found in 1618132d68afc876/2023-11-24--10-21-12/4/s for HYUNDAI KONA ELECTRIC 2ND GEN\n", - "Match found in 1618132d68afc876/2023-08-27--09-32-14/13/s for HYUNDAI KONA 2ND GEN\n", - "Match found in 1618132d68afc876/2023-11-24--10-21-12/3/s for HYUNDAI KONA ELECTRIC 2ND GEN\n", - "Match found in df7fdd56970d90fe/2023-12-29--07-48-56/53/s for HYUNDAI IONIQ 6 2023\n", - "Match found in 0ad7facc77922c3e/2023-12-29--17-12-45/14/s for HYUNDAI IONIQ 6 2023\n", - "Match found in 0ad7facc77922c3e/2023-12-16--08-49-13/39/s for HYUNDAI IONIQ 6 2023\n", - "Match found in 78ad5150de133637/2023-09-13--16-15-57/0/s for KIA K8 HYBRID 1ST GEN\n", - "Match found in 78ad5150de133637/2023-09-13--16-15-57/2/s for KIA K8 HYBRID 1ST GEN\n", - "Match found in 78ad5150de133637/2023-09-13--16-15-57/1/s for KIA K8 HYBRID 1ST GEN\n", - "Match found in b153671049a867b3/2023-12-15--20-40-16/0/s for KIA NIRO EV 2ND GEN\n", - "Match found in b153671049a867b3/2024-01-12--17-43-31/2/s for KIA NIRO EV 2ND GEN\n", - "Match found in b153671049a867b3/2023-12-03--21-08-30/3/s for KIA NIRO EV 2ND GEN\n", - "Match found in 7387ab2a564c6d9f/2023-12-02--07-10-34/52/s for KIA NIRO HYBRID 2ND GEN\n", - "Match found in 7387ab2a564c6d9f/2024-01-06--16-24-36/1/s for KIA NIRO HYBRID 2ND GEN\n", - "Match found in 7387ab2a564c6d9f/2024-01-06--16-24-36/9/s for KIA NIRO HYBRID 2ND GEN\n", - "Match found in 2efdac7dc41207f1/2023-12-27--07-24-22/89/s for KIA EV6 2022\n", - "Match found in 5ac586afbb236b5d/2023-12-05--18-23-10/7/s for VOLKSWAGEN ARTEON 1ST GEN\n", - "Match found in c34ef43981b6d888/2024-01-18--16-00-06/9/s for VOLKSWAGEN ARTEON 1ST GEN\n", - "Match found in 5ac586afbb236b5d/2024-01-04--20-01-19/4/s for VOLKSWAGEN ARTEON 1ST GEN\n", - "Match found in 16758e226aa2f747/2023-12-16--10-24-39/13/s for VOLKSWAGEN ATLAS 1ST GEN\n", - "Match found in 3174d252cec3bf6f/2023-12-12--18-39-06/6/s for VOLKSWAGEN ATLAS 1ST GEN\n", - "Match found in e80066d826c705a9/2024-01-06--17-28-45/211/s for VOLKSWAGEN ATLAS 1ST GEN\n", - "Match found in 2cdded3a5da75b6a/2024-01-06--13-37-16/2/s for VOLKSWAGEN GOLF 7TH GEN\n", - "Match found in abe0b7fe730c51a9/2023-10-30--14-24-49/4/s for VOLKSWAGEN GOLF 7TH GEN\n", - "Match found in 8fe9ced03c94e256/2023-12-14--16-31-55/8/s for VOLKSWAGEN GOLF 7TH GEN\n", - "Match found in a97d27ce2a78958a/2024-01-09--06-57-35/9/s for VOLKSWAGEN JETTA 7TH GEN\n", - "Match found in 0649d406184b7131/2024-01-20--14-43-41/3/s for VOLKSWAGEN JETTA 7TH GEN\n", - "Match found in 0649d406184b7131/2023-11-07--16-30-10/17/s for VOLKSWAGEN JETTA 7TH GEN\n", - "Match found in 5405cac0c9d58c3d/2023-11-05--17-13-17/6/s for VOLKSWAGEN PASSAT 8TH GEN\n", - "Match found in 2d7d87433a67c925/2024-01-05--16-31-16/38/s for VOLKSWAGEN PASSAT 8TH GEN\n", - "Match found in 2d7d87433a67c925/2023-12-26--08-44-17/2/s for VOLKSWAGEN PASSAT 8TH GEN\n", - "Match found in 0cd0b7f7e31a3853/2021-11-03--19-30-22/0/s for SKODA KODIAQ 1ST GEN\n", - "Match found in 0bbe367c98fa1538/2023-07-01--19-42-26/7/s for VOLKSWAGEN POLO 6TH GEN\n", - "Match found in 0cd0b7f7e31a3853/2021-11-03--19-30-22/2/s for SKODA KODIAQ 1ST GEN\n", - "Match found in 7d82b2f3a9115f1f/2021-10-21--15-39-42/1/s for VOLKSWAGEN TAOS 1ST GEN\n", - "Match found in 7d82b2f3a9115f1f/2021-10-21--15-39-42/0/s for VOLKSWAGEN TAOS 1ST GEN\n", - "Match found in 7d82b2f3a9115f1f/2021-10-21--15-39-42/2/s for VOLKSWAGEN TAOS 1ST GEN\n", - "Match found in 2744c89a8dda9a51/2021-07-24--21-28-06/0/s for SKODA KODIAQ 1ST GEN\n", - "Match found in 2744c89a8dda9a51/2021-07-24--21-28-06/2/s for SKODA KODIAQ 1ST GEN\n", - "Match found in 2744c89a8dda9a51/2021-07-24--21-28-06/1/s for SKODA KODIAQ 1ST GEN\n", - "Match found in 4e144f64a2535890/2023-12-05--12-22-10/5/s for VOLKSWAGEN TIGUAN 2ND GEN\n", - "Match found in 1b5cf3b409037cc4/2023-12-11--10-23-35/5/s for VOLKSWAGEN TIGUAN 2ND GEN\n", - "Match found in 1b41980e9972d348/2023-10-29--15-13-08/3/s for VOLKSWAGEN TIGUAN 2ND GEN\n", - "Match found in a589dcc642fdb10a/2021-06-14--20-54-26/0/s for VOLKSWAGEN TOURAN 2ND GEN\n", - "Match found in a589dcc642fdb10a/2021-06-14--20-54-26/2/s for VOLKSWAGEN TOURAN 2ND GEN\n", - "Match found in a589dcc642fdb10a/2021-06-14--20-54-26/1/s for VOLKSWAGEN TOURAN 2ND GEN\n", - "Match found in 207b9d7ee3fb513a/2023-12-19--14-59-25/14/s for VOLKSWAGEN TRANSPORTER T6.1\n", - "Match found in a459f4556782eba1/2023-11-05--17-16-20/22/s for VOLKSWAGEN TRANSPORTER T6.1\n", - "Match found in a459f4556782eba1/2023-11-27--12-27-58/47/s for VOLKSWAGEN TRANSPORTER T6.1\n", - "Match found in 0cd0b7f7e31a3853/2021-11-18--00-38-32/0/s for SKODA KODIAQ 1ST GEN\n", - "Match found in 0cd0b7f7e31a3853/2021-11-18--00-38-32/1/s for SKODA KODIAQ 1ST GEN\n", - "Match found in 0cd0b7f7e31a3853/2021-11-18--00-38-32/2/s for SKODA KODIAQ 1ST GEN\n", - "Match found in a973e9182bc96a2c/2024-01-14--15-14-33/54/s for AUDI A3 3RD GEN\n", - "Match found in 23daff6c438612d2/2023-12-21--15-37-32/22/s for AUDI A3 3RD GEN\n", - "Match found in 23daff6c438612d2/2024-01-17--09-31-14/20/s for AUDI A3 3RD GEN\n", - "Match found in 6c6b466346192818/2021-06-06--14-17-47/0/s for AUDI Q2 1ST GEN\n", - "Match found in 6c6b466346192818/2021-06-06--14-17-47/1/s for AUDI Q2 1ST GEN\n", - "Match found in 6c6b466346192818/2021-06-06--14-17-47/2/s for AUDI Q2 1ST GEN\n", - "Match found in 839125529d3c3cdf/2023-11-29--15-49-50/56/s for AUDI Q3 2ND GEN\n", - "Match found in d7bfab70d5011e1d/2023-11-24--00-49-14/24/s for AUDI Q3 2ND GEN\n", - "Match found in 98a3015c4f16846d/2023-11-04--12-32-32/76/s for AUDI Q3 2ND GEN\n", - "Match found in fc6b6c9a3471c846/2021-05-27--13-39-56/2/s for SEAT LEON 3RD GEN\n", - "Match found in fc6b6c9a3471c846/2021-05-27--13-39-56/1/s for SEAT LEON 3RD GEN\n", - "Match found in aef9c04d6ec5cd57/2023-07-15--16-49-38/12/s for SEAT LEON 3RD GEN\n", - "Match found in 0bbe367c98fa1538/2023-03-04--17-46-11/2/s for VOLKSWAGEN POLO 6TH GEN\n", - "Match found in 0bbe367c98fa1538/2023-03-04--17-46-11/1/s for VOLKSWAGEN POLO 6TH GEN\n", - "Match found in 0bbe367c98fa1538/2023-03-04--17-46-11/0/s for VOLKSWAGEN POLO 6TH GEN\n", - "Match found in 026b6d18fba6417f/2021-03-26--09-17-04/0/s for SKODA SCALA 1ST GEN\n", - "Match found in 026b6d18fba6417f/2021-03-26--09-17-04/1/s for SKODA SCALA 1ST GEN\n", - "Match found in 026b6d18fba6417f/2021-03-26--09-17-04/2/s for SKODA SCALA 1ST GEN\n", - "Match found in 12d6ae3057c04b0d/2021-09-04--21-21-21/1/s for SKODA KODIAQ 1ST GEN\n", - "Match found in 12d6ae3057c04b0d/2021-09-04--21-21-21/0/s for SKODA KODIAQ 1ST GEN\n", - "Match found in 7d76baac7cf42e15/2024-01-13--03-42-46/2/s for SKODA KAROQ 1ST GEN\n", - "Match found in 8a5da7c1d1783730/2024-01-17--06-32-18/4/s for SKODA KODIAQ 1ST GEN\n", - "Match found in 8a5da7c1d1783730/2023-12-23--16-48-07/42/s for SKODA KODIAQ 1ST GEN\n", - "Match found in 2ca49a03c8084514/2023-12-27--08-54-31/4/s for SKODA KODIAQ 1ST GEN\n", - "Match found in 66e5edc3a16459c5/2021-05-25--19-00-29/1/s for SKODA OCTAVIA 3RD GEN\n", - "Match found in f5392228324cda8d/2023-10-29--14-05-24/120/s for SKODA OCTAVIA 3RD GEN\n", - "Match found in 3fa7570f2fcace3d/2023-11-11--07-57-34/1/s for SKODA OCTAVIA 3RD GEN\n", - "Match found in 54ada937747ef8ca/2023-11-09--16-13-28/12/s for SKODA SUPERB 3RD GEN\n" - ] + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "27a243c33de44498b2b946190df44b23", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "segments searched: 0%| | 0/577 [00:00 0:\n", + " message_names = [MESSAGES_TO_FIND[message] for message in matched_messages]\n", + " print(f\"Match found: {segment:<45} {CP.carFingerprint:<38} {message_names}\")\n", "\n", - "print(f\"Analysis finished\")\n" + " progress_bar.update()\n" ] }, { @@ -257,9 +210,9 @@ ], "metadata": { "kernelspec": { - "display_name": "openpilot", + "display_name": "Python 3 (ipykernel)", "language": "python", - "name": "openpilot" + "name": "python3" }, "language_info": { "codemirror_mode": { From 821148150b73c1ad7b7d192b64c684c09687f4b8 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 5 Mar 2025 15:42:22 -0800 Subject: [PATCH 47/78] Revert "make test_onroad faster (#34704) (#34783) * Revert "make test_onroad faster (#34704)" This reverts commit 470ec468300c3caa4881098f3b0b9e0954f286e1. * try this * add there * cleanup * try this * lil more * list * classic * don't skip test --- conftest.py | 4 +- pyproject.toml | 3 +- selfdrive/test/test_onroad.py | 85 +++++++++++++---------------------- 3 files changed, 36 insertions(+), 56 deletions(-) diff --git a/conftest.py b/conftest.py index a14a33c37d..9eda5d612a 100644 --- a/conftest.py +++ b/conftest.py @@ -77,8 +77,10 @@ def openpilot_class_fixture(): @pytest.fixture(scope="function") -def tici_setup_fixture(openpilot_function_fixture): +def tici_setup_fixture(request, openpilot_function_fixture): """Ensure a consistent state for tests on-device. Needs the openpilot function fixture to run first.""" + if 'skip_tici_setup' in request.keywords: + return HARDWARE.initialize_hardware() HARDWARE.set_power_save(False) os.system("pkill -9 -f athena") diff --git a/pyproject.toml b/pyproject.toml index e554a2f29d..58e714e3a6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -143,6 +143,7 @@ asyncio_default_fixture_loop_scope = "function" markers = [ "slow: tests that take awhile to run and can be skipped with -m 'not slow'", "tici: tests that are only meant to run on the C3/C3X", + "skip_tici_setup: mark test to skip tici setup fixture" ] testpaths = [ "common", @@ -215,7 +216,7 @@ lint.select = [ "E", "F", "W", "PIE", "C4", "ISC", "A", "B", "NPY", # numpy "UP", # pyupgrade - "TRY302", "TRY400", "TRY401", # try/excepts + "TRY203", "TRY400", "TRY401", # try/excepts "RUF008", "RUF100", "TID251", "PLR1704", diff --git a/selfdrive/test/test_onroad.py b/selfdrive/test/test_onroad.py index 23d1687770..7435239e5c 100644 --- a/selfdrive/test/test_onroad.py +++ b/selfdrive/test/test_onroad.py @@ -1,8 +1,6 @@ import math import json import os -import pathlib -import psutil import pytest import shutil import subprocess @@ -12,7 +10,7 @@ from collections import Counter, defaultdict from pathlib import Path from tabulate import tabulate -from cereal import car, log +from cereal import log import cereal.messaging as messaging from cereal.services import SERVICE_LIST from openpilot.common.basedir import BASEDIR @@ -23,6 +21,7 @@ from openpilot.selfdrive.test.helpers import set_params_enabled, release_only from openpilot.system.hardware import HARDWARE from openpilot.system.hardware.hw import Paths from openpilot.tools.lib.logreader import LogReader +from openpilot.tools.lib.log_time_series import msgs_to_time_series """ CPU usage budget @@ -112,6 +111,7 @@ def cputime_total(ct): @pytest.mark.tici +@pytest.mark.skip_tici_setup class TestOnroad: @classmethod @@ -119,7 +119,8 @@ class TestOnroad: if "DEBUG" in os.environ: segs = filter(lambda x: os.path.exists(os.path.join(x, "rlog.zst")), Path(Paths.log_root()).iterdir()) segs = sorted(segs, key=lambda x: x.stat().st_mtime) - cls.lr = list(LogReader(os.path.join(segs[-3], "rlog.zst"))) + cls.lr = list(LogReader(os.path.join(segs[-1], "rlog.zst"))) + cls.ts = msgs_to_time_series(cls.lr) return # setup env @@ -140,44 +141,31 @@ class TestOnroad: proc = subprocess.Popen(["python", manager_path]) sm = messaging.SubMaster(['carState']) - with Timeout(150, "controls didn't start"): - while sm.recv_frame['carState'] < 0: + with Timeout(30, "controls didn't start"): + while not sm.seen['carState']: sm.update(1000) - route = None - cls.segments = [] - with Timeout(300, "timed out waiting for logs"): - while route is None: - route = params.get("CurrentRoute", encoding="utf-8") - time.sleep(0.01) + route = params.get("CurrentRoute", encoding="utf-8") + assert route is not None - # test car params caching - params.put("CarParamsCache", car.CarParams().to_bytes()) - - while len(cls.segments) < 1: - segs = set() - if Path(Paths.log_root()).exists(): - segs = set(Path(Paths.log_root()).glob(f"{route}--*")) - cls.segments = sorted(segs, key=lambda s: int(str(s).rsplit('--')[-1])) - time.sleep(0.01) + segs = list(Path(Paths.log_root()).glob(f"{route}--*")) + assert len(segs) == 1 time.sleep(TEST_DURATION) - finally: - cls.gpu_procs = {psutil.Process(int(f.name)).name() for f in pathlib.Path('/sys/devices/virtual/kgsl/kgsl/proc/').iterdir() if f.is_dir()} - if proc is not None: proc.terminate() if proc.wait(60) is None: proc.kill() - cls.lrs = [list(LogReader(os.path.join(str(s), "rlog.zst"))) for s in cls.segments] - - cls.lr = list(LogReader(os.path.join(str(cls.segments[0]), "rlog.zst"))) - cls.log_path = cls.segments[0] + cls.lr = list(LogReader(os.path.join(str(segs[0]), "rlog.zst"))) + st = time.monotonic() + cls.ts = msgs_to_time_series(cls.lr) + print("msgs to time series", time.monotonic() - st) + log_path = segs[0] cls.log_sizes = {} - for f in cls.log_path.iterdir(): + for f in log_path.iterdir(): assert f.is_file() cls.log_sizes[f] = f.stat().st_size / 1e6 @@ -198,7 +186,7 @@ class TestOnroad: assert len(msgs) >= math.floor(SERVICE_LIST[s].frequency*int(TEST_DURATION*0.8)) def test_manager_starting_time(self): - st = self.msgs['managerState'][0].logMonoTime / 1e9 + st = self.ts['managerState']['t'][0] assert (st - self.manager_st) < 10, f"manager.py took {st - self.manager_st}s to publish the first 'managerState' msg" def test_cloudlog_size(self): @@ -226,7 +214,7 @@ class TestOnroad: result += "-------------- UI Draw Timing ------------------\n" result += "------------------------------------------------\n" - ts = [m.uiDebug.drawTimeMillis for m in self.msgs['uiDebug']] + ts = self.ts['uiDebug']['drawTimeMillis'] result += f"min {min(ts):.2f}ms\n" result += f"max {max(ts):.2f}ms\n" result += f"std {np.std(ts):.2f}ms\n" @@ -309,9 +297,6 @@ class TestOnroad: assert np.max(np.diff(mems)) <= 4, "Max memory increase too high" assert np.average(np.diff(mems)) <= 1, "Average memory increase too high" - def test_gpu_usage(self): - assert self.gpu_procs == {"weston", "ui", "camerad", "selfdrive.modeld.modeld", "selfdrive.modeld.dmonitoringmodeld"} - def test_camera_frame_timings(self, subtests): # test timing within a single camera result = "\n" @@ -319,7 +304,7 @@ class TestOnroad: result += "----------------- SOF Timing ------------------\n" result += "------------------------------------------------\n" for name in ['roadCameraState', 'wideRoadCameraState', 'driverCameraState']: - ts = [getattr(m, m.which()).timestampSof for m in self.lr if name in m.which()] + ts = self.ts[name]['timestampSof'] d_ms = np.diff(ts) / 1e6 d50 = np.abs(d_ms-50) result += f"{name} sof delta vs 50ms: min {min(d50):.2f}ms\n" @@ -338,33 +323,30 @@ class TestOnroad: # sanity checks within a single cam for cam in cams: with subtests.test(test="frame_skips", camera=cam): - cam_log = [getattr(x, x.which()) for x in self.msgs[cam]] - assert set(np.diff([x.frameId for x in cam_log])) == {1, }, "Frame ID skips" + assert set(np.diff(self.ts[cam]['frameId'])) == {1, }, "Frame ID skips" # EOF > SOF - eof_sof_diff = np.array([x.timestampEof - x.timestampSof for x in cam_log]) + eof_sof_diff = self.ts[cam]['timestampEof'] - self.ts[cam]['timestampSof'] assert np.all(eof_sof_diff > 0) assert np.all(eof_sof_diff < 50*1e6) - fid = {c: [getattr(m, m.which()).frameId for m in self.msgs[c]] for c in cams} - first_fid = [min(x) for x in fid.values()] + first_fid = {c: min(self.ts[c]['frameId']) for c in cams} if cam.endswith('CameraState'): # camerad guarantees that all cams start on frame ID 0 # (note loggerd also needs to start up fast enough to catch it) - assert set(first_fid) == {0, }, "Cameras don't start on frame ID 0" + assert set(first_fid.values()) == {0, }, "Cameras don't start on frame ID 0" else: # encoder guarantees all cams start on the same frame ID - assert len(set(first_fid)) == 1, "Cameras don't start on same frame ID" + assert len(set(first_fid.values())) == 1, "Cameras don't start on same frame ID" # we don't do a full segment rotation, so these might not match exactly - last_fid = [max(x) for x in fid.values()] - assert max(last_fid) - min(last_fid) < 10 + last_fid = {c: max(self.ts[c]['frameId']) for c in cams} + assert max(last_fid.values()) - min(last_fid.values()) < 10 - start, end = min(first_fid), min(last_fid) - all_ts = [[getattr(m, m.which()).timestampSof for m in self.msgs[c]] for c in cams] + start, end = min(first_fid.values()), min(last_fid.values()) for i in range(end-start): - ts = [round(x[i]/1e6, 1) for x in all_ts] - diff = max(ts) - min(ts) + ts = {c: round(self.ts[c]['timestampSof'][i]/1e6, 1) for c in cams} + diff = (max(ts.values()) - min(ts.values())) assert diff < 2, f"Cameras not synced properly: frame_id={start+i}, {diff=:.1f}ms, {ts=}" def test_mpc_execution_timings(self): @@ -438,12 +420,7 @@ class TestOnroad: @release_only def test_startup(self): - startup_alert = None - for msg in self.lrs[0]: - # can't use onroadEvents because the first msg can be dropped while loggerd is starting up - if msg.which() == "selfdriveState": - startup_alert = msg.selfdriveState.alertText1 - break + startup_alert = self.ts['selfdriveState']['alertText1'][0] expected = EVENTS[log.OnroadEvent.EventName.startup][ET.PERMANENT].alert_text_1 assert startup_alert == expected, "wrong startup alert" From 65bf2ec0ea5c2598d3e66340ecc6177f51dc112a Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 5 Mar 2025 15:58:03 -0800 Subject: [PATCH 48/78] test_onroad: add sanity check on ecode outputs (#34784) * test_onroad: add sanity check on ecode outputs * exact --- selfdrive/test/test_onroad.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/selfdrive/test/test_onroad.py b/selfdrive/test/test_onroad.py index 7435239e5c..9756010614 100644 --- a/selfdrive/test/test_onroad.py +++ b/selfdrive/test/test_onroad.py @@ -349,6 +349,25 @@ class TestOnroad: diff = (max(ts.values()) - min(ts.values())) assert diff < 2, f"Cameras not synced properly: frame_id={start+i}, {diff=:.1f}ms, {ts=}" + def test_camera_encoder_matches(self, subtests): + # sanity check that the frame metadata is consistent with the encoded frames + pairs = [('roadCameraState', 'roadEncodeIdx'), + ('wideRoadCameraState', 'wideRoadEncodeIdx'), + ('driverCameraState', 'driverEncodeIdx')] + for cam, enc in pairs: + with subtests.test(camera=cam, encoder=enc): + cam_frames = {fid: (sof, eof) for fid, sof, eof in zip( + self.ts[cam]['frameId'], + self.ts[cam]['timestampSof'], + self.ts[cam]['timestampEof'], + strict=True, + )} + for i, fid in enumerate(self.ts[enc]['frameId']): + cam_sof, cam_eof = cam_frames[fid] + enc_sof, enc_eof = self.ts[enc]['timestampSof'][i], self.ts[enc]['timestampEof'][i] + assert enc_sof == cam_sof, f"SOF mismatch: frameId={fid}, enc_sof={enc_sof}, cam_sof={cam_sof}" + assert enc_eof == cam_eof, f"EOF mismatch: frameId={fid}, enc_eof={enc_eof}, cam_eof={cam_eof}" + def test_mpc_execution_timings(self): result = "\n" result += "------------------------------------------------\n" From f4d17cbfdd8f2e1a50259d5d9776dd0d993d44a1 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 5 Mar 2025 16:54:35 -0800 Subject: [PATCH 49/78] camerad: sanity check tests (#34785) lil more --- system/camerad/sensors/os04c10.cc | 3 +++ system/camerad/test/test_camerad.py | 33 +++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/system/camerad/sensors/os04c10.cc b/system/camerad/sensors/os04c10.cc index b3a7e39bfb..d008e1d07b 100644 --- a/system/camerad/sensors/os04c10.cc +++ b/system/camerad/sensors/os04c10.cc @@ -43,6 +43,9 @@ OS04C10::OS04C10() { frame_data_type = 0x2c; mclk_frequency = 24000000; // Hz + // TODO: this was set from logs. actually calculate it out + readout_time_ns = 11000000; + ev_scale = 150.0; dc_gain_factor = 1; dc_gain_min_weight = 1; // always on is fine diff --git a/system/camerad/test/test_camerad.py b/system/camerad/test/test_camerad.py index e88a7bf4bf..0ab71bee46 100644 --- a/system/camerad/test/test_camerad.py +++ b/system/camerad/test/test_camerad.py @@ -64,7 +64,36 @@ class TestCamerad: laggy_frames = {k: v for k, v in diffs.items() if v > 1.1} assert len(laggy_frames) == 0, f"Frames not synced properly: {laggy_frames=}" + def test_sanity_checks(self, logs): + self._sanity_checks(logs) + + def _sanity_checks(self, ts): + for c in CAMERAS: + assert c in ts + assert len(ts[c]['t']) > 20 + + # not a valid request id + assert 0 not in ts[c]['requestId'] + + # should monotonically increase + assert np.all(np.diff(ts[c]['frameId']) >= 1) + assert np.all(np.diff(ts[c]['requestId']) >= 1) + + # EOF > SOF + assert np.all((ts[c]['timestampEof'] - ts[c]['timestampSof']) > 0) + + # logMonoTime > SOF + assert np.all((ts[c]['t'] - ts[c]['timestampSof']/1e9) > 0.001) + assert np.all((ts[c]['t'] - ts[c]['timestampEof']/1e9) > 0.001) + @pytest.mark.skip("TODO: enable this") - def test_stress_test(self, logs): + def test_stress_test(self): os.environ['SPECTRA_STRESS_TEST'] = '1' - run_and_log(["camerad", ], CAMERAS, 5) + logs = run_and_log(["camerad", ], CAMERAS, 15) + ts = msgs_to_time_series(logs) + + # we should see some jumps from introduced errors + assert np.max([ np.max(np.diff(ts[c]['frameId'])) for c in CAMERAS ]) > 1 + assert np.max([ np.max(np.diff(ts[c]['requestId'])) for c in CAMERAS ]) > 1 + + self._sanity_checks(ts) From 4bb0dfd59cd4decdb9b75577454398c4299b7b18 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 5 Mar 2025 17:12:30 -0800 Subject: [PATCH 50/78] camerad: cleaner queueing logic (#34786) --- system/camerad/cameras/spectra.cc | 251 ++++++++++++++---------------- system/camerad/cameras/spectra.h | 15 +- 2 files changed, 128 insertions(+), 138 deletions(-) diff --git a/system/camerad/cameras/spectra.cc b/system/camerad/cameras/spectra.cc index 3e5941b13f..063420823c 100644 --- a/system/camerad/cameras/spectra.cc +++ b/system/camerad/cameras/spectra.cc @@ -249,6 +249,7 @@ SpectraCamera::~SpectraCamera() { } int SpectraCamera::clear_req_queue() { + // for "non-realtime" BPS if (icp_dev_handle > 0) { struct cam_flush_dev_cmd cmd = { .session_handle = session_handle, @@ -260,6 +261,7 @@ int SpectraCamera::clear_req_queue() { LOGD("flushed bps: %d", err); } + // for "realtime" devices struct cam_req_mgr_flush_info req_mgr_flush_request = {0}; req_mgr_flush_request.session_hdl = session_handle; req_mgr_flush_request.link_hdl = link_handle; @@ -304,14 +306,7 @@ void SpectraCamera::camera_open(VisionIpcServer *v, cl_device_id device_id, cl_c LOGD("camera init %d", cc.camera_num); buf.init(device_id, ctx, this, v, ife_buf_depth, cc.stream_type); camera_map_bufs(); - enqueue_req_multi(1, ife_buf_depth); -} - -void SpectraCamera::enqueue_req_multi(uint64_t start, int n) { - for (uint64_t request_id = start; request_id < start + n; ++request_id) { - uint64_t idx = (request_id - 1) % ife_buf_depth; - enqueue_buffer(idx, request_id); - } + clearAndRequeue(1); } void SpectraCamera::sensors_start() { @@ -901,59 +896,14 @@ void SpectraCamera::config_ife(int idx, int request_id, bool init) { assert(ret == 0); } -// Enqueue buffer for the given index and return true if the frame is ready -bool SpectraCamera::enqueue_buffer(int i, uint64_t request_id) { - int ret; - bool frame_ready = false; - - // Before queuing up a new frame, wait for the - // previous one in this slot (index) to come in. - if (sync_objs_ife[i]) { - // TODO: write a test to stress test w/ a low timeout and check camera frame ids match - - struct cam_sync_wait sync_wait = {0}; - - // *** Wait for IFE *** - // in RAW_OUTPUT mode, this is just the frame readout from the sensor - // in IFE_PROCESSED mode, this is both frame readout and image processing (~1ms) - sync_wait.sync_obj = sync_objs_ife[i]; - sync_wait.timeout_ms = 100; - if (stress_test("IFE sync")) { - sync_wait.timeout_ms = 1; - } - ret = do_sync_control(m->cam_sync_fd, CAM_SYNC_WAIT, &sync_wait, sizeof(sync_wait)); - if (ret != 0) { - LOGE("failed to wait for IFE sync: %d %d", ret, sync_wait.sync_obj); - } - - // *** Wait for BPS *** - if (ret == 0 && sync_objs_bps[i]) { - sync_wait.sync_obj = sync_objs_bps[i]; - sync_wait.timeout_ms = 50; // typically 7ms - if (stress_test("BPS sync")) { - sync_wait.timeout_ms = 1; - } - ret = do_sync_control(m->cam_sync_fd, CAM_SYNC_WAIT, &sync_wait, sizeof(sync_wait)); - if (ret != 0) { - LOGE("failed to wait for BPS sync: %d %d", ret, sync_wait.sync_obj); - } - } - - if (ret == 0) { - // all good, hand off frame - frame_ready = true; - destroySyncObjectAt(i); - } else { - // need to start over on sync failures, - // otherwise future frames will tear - clear_req_queue(); - } - } +void SpectraCamera::enqueue_frame(uint64_t request_id) { + int i = request_id % ife_buf_depth; + assert(sync_objs_ife[i] == 0); // create output fences struct cam_sync_info sync_create = {0}; strcpy(sync_create.name, "NodeOutputPortFence"); - ret = do_sync_control(m->cam_sync_fd, CAM_SYNC_CREATE, &sync_create, sizeof(sync_create)); + int ret = do_sync_control(m->cam_sync_fd, CAM_SYNC_CREATE, &sync_create, sizeof(sync_create)); if (ret != 0) { LOGE("failed to create fence: %d %d", ret, sync_create.sync_obj); } else { @@ -985,8 +935,6 @@ bool SpectraCamera::enqueue_buffer(int i, uint64_t request_id) { // submit request to IFE and BPS config_ife(i, request_id); if (output_type == ISP_BPS_PROCESSED) config_bps(i, request_id); - - return frame_ready; } void SpectraCamera::destroySyncObjectAt(int index) { @@ -1371,90 +1319,129 @@ void SpectraCamera::camera_close() { LOGD("destroyed session %d: %d", cc.camera_num, ret); } -// Processes camera events and returns true if the frame is ready for further processing bool SpectraCamera::handle_camera_event(const cam_req_mgr_message *event_data) { - if (stress_test("skipping handling camera event")) { - LOGW("skipping event"); + /* + Handles camera SOF event. Returns true if the frame is valid for publishing. + */ + + uint64_t request_id = event_data->u.frame_msg.request_id; // ID from the camera request manager + uint64_t frame_id_raw = event_data->u.frame_msg.frame_id; // raw as opposed to our re-indexed frame ID + uint64_t timestamp = event_data->u.frame_msg.timestamp; // timestamped in the kernel's SOF IRQ callback + //LOGD("handle cam %d ts %lu req id %lu frame id %lu", cc.camera_num, timestamp, request_id, frame_id_raw); + + if (stress_test("skipping SOF event")) return false; + + if (!validateEvent(request_id, frame_id_raw)) { return false; } - // ID from the qcom camera request manager - uint64_t request_id = event_data->u.frame_msg.request_id; + // Update tracking variables + if (request_id == request_id_last + 1) { + skip_expected = false; + } + frame_id_raw_last = frame_id_raw; + request_id_last = request_id; - // raw as opposed to our re-indexed frame ID - uint64_t frame_id_raw = event_data->u.frame_msg.frame_id; - - //LOGD("handle cam %d, request id %lu -> %lu, frame id raw %lu", cc.camera_num, request_id_last, request_id, frame_id_raw); - - if (request_id != 0) { // next ready - // check for skipped_last frames - if (frame_id_raw > frame_id_raw_last + 1 && !skipped_last) { - LOGE("camera %d realign", cc.camera_num); - clear_req_queue(); - enqueue_req_multi(request_id + 1, ife_buf_depth - 1); - skipped_last = true; - } else if (frame_id_raw == frame_id_raw_last + 1) { - skipped_last = false; - } - - // check for dropped requests - if (request_id > request_id_last + 1) { - LOGE("camera %d dropped requests %ld %ld", cc.camera_num, request_id, request_id_last); - enqueue_req_multi(request_id_last + 1 + ife_buf_depth, request_id - (request_id_last + 1)); - } - - // metas - frame_id_raw_last = frame_id_raw; - request_id_last = request_id; - - int buf_idx = (request_id - 1) % ife_buf_depth; - uint64_t timestamp = event_data->u.frame_msg.timestamp; // this is timestamped in the kernel's SOF IRQ callback - if (syncFirstFrame(cc.camera_num, request_id, frame_id_raw, timestamp)) { - // wait for this frame's EOF, then queue up the next one - if (enqueue_buffer(buf_idx, request_id + ife_buf_depth)) { - // Frame is ready - - // in IFE_PROCESSED mode, we can't know the true EOF, so recover it with sensor readout time - uint64_t timestamp_eof = timestamp + sensor->readout_time_ns; - - // Update buffer and frame data - buf.cur_buf_idx = buf_idx; - buf.cur_frame_data = { - .frame_id = (uint32_t)(frame_id_raw - camera_sync_data[cc.camera_num].frame_id_offset), - .request_id = (uint32_t)request_id, - .timestamp_sof = timestamp, - .timestamp_eof = timestamp_eof, - .processing_time = float((nanos_since_boot() - timestamp_eof) * 1e-9) - }; - return true; - } - // LOGW("camerad %d synced req %d fid %d, publishing ts %.2f cereal_frame_id %d", cc.camera_num, (int)request_id, (int)frame_id_raw, (double)(timestamp)*1e-6, meta_data.frame_id); - } else { - // Frames not yet synced - enqueue_req_multi(request_id + ife_buf_depth, 1); - // LOGW("camerad %d not synced req %d fid %d", cc.camera_num, (int)request_id, (int)frame_id_raw); - } - } else { // not ready - if (frame_id_raw > frame_id_raw_last + 10) { - LOGE("camera %d reset after half second of no response", cc.camera_num); - clear_req_queue(); - enqueue_req_multi(request_id_last + 1, ife_buf_depth); - frame_id_raw_last = frame_id_raw; - skipped_last = true; - } + // Wait until frame's fully read out and processed + if (!waitForFrameReady(request_id)) { + // Reset queue on sync failure to prevent frame tearing + LOGE("camera %d sync failure %ld %ld ", cc.camera_num, request_id, frame_id_raw); + clearAndRequeue(request_id + 1); + return false; } - return false; + int buf_idx = request_id % ife_buf_depth; + bool ret = processFrame(buf_idx, request_id, frame_id_raw, timestamp); + destroySyncObjectAt(buf_idx); + enqueue_frame(request_id + ife_buf_depth); // request next frame for this slot + return ret; +} + +bool SpectraCamera::validateEvent(uint64_t request_id, uint64_t frame_id_raw) { + // check if the request ID is even valid. this happens after queued + // requests are cleared. unclear if it happens any other time. + if (request_id == 0) { + if (invalid_request_count++ > 10) { + LOGE("camera %d reset after half second of invalid requests", cc.camera_num); + clearAndRequeue(request_id_last + 1); + invalid_request_count = 0; + } + return false; + } + invalid_request_count = 0; + + // check for skips in frame_id or request_id + if (!skip_expected) { + if (frame_id_raw != frame_id_raw_last + 1) { + LOGE("camera %d frame ID skipped, %lu -> %lu", cc.camera_num, frame_id_raw_last, frame_id_raw); + clearAndRequeue(request_id + 1); + return false; + } + + if (request_id != request_id_last + 1) { + LOGE("camera %d requests skipped %ld -> %ld", cc.camera_num, request_id_last, request_id); + clearAndRequeue(request_id_last + 1); + return false; + } + } + return true; +} + +void SpectraCamera::clearAndRequeue(uint64_t from_request_id) { + // clear everything, then queue up a fresh set of frames + LOGW("clearing and requeuing camera %d from %lu", cc.camera_num, from_request_id); + clear_req_queue(); + for (uint64_t id = from_request_id; id < from_request_id + ife_buf_depth; ++id) { + enqueue_frame(id); + } + skip_expected = true; +} + +bool SpectraCamera::waitForFrameReady(uint64_t request_id) { + int buf_idx = request_id % ife_buf_depth; + assert(sync_objs_ife[buf_idx]); + + auto waitForSync = [&](uint32_t sync_obj, int timeout_ms, const char *sync_type) { + struct cam_sync_wait sync_wait = {}; + sync_wait.sync_obj = sync_obj; + sync_wait.timeout_ms = stress_test(sync_type) ? 1 : timeout_ms; + return do_sync_control(m->cam_sync_fd, CAM_SYNC_WAIT, &sync_wait, sizeof(sync_wait)) == 0; + }; + + // wait for frame from IFE + // - in RAW_OUTPUT mode, this time is just the frame readout from the sensor + // - in IFE_PROCESSED mode, this time also includes image processing (~1ms) + bool success = waitForSync(sync_objs_ife[buf_idx], 100, "IFE sync"); + if (success && sync_objs_bps[buf_idx]) { + // BPS is typically 7ms + success = waitForSync(sync_objs_bps[buf_idx], 50, "BPS sync"); + } + return success; +} + +bool SpectraCamera::processFrame(int buf_idx, uint64_t request_id, uint64_t frame_id_raw, uint64_t timestamp) { + if (!syncFirstFrame(cc.camera_num, request_id, frame_id_raw, timestamp)) { + return false; + } + + // in IFE_PROCESSED mode, we can't know the true EOF, so recover it with sensor readout time + uint64_t timestamp_eof = timestamp + sensor->readout_time_ns; + + // Update buffer and frame data + buf.cur_buf_idx = buf_idx; + buf.cur_frame_data = { + .frame_id = (uint32_t)(frame_id_raw - camera_sync_data[cc.camera_num].frame_id_offset), + .request_id = (uint32_t)request_id, + .timestamp_sof = timestamp, + .timestamp_eof = timestamp_eof, + .processing_time = float((nanos_since_boot() - timestamp_eof) * 1e-9) + }; + return true; } bool SpectraCamera::syncFirstFrame(int camera_id, uint64_t request_id, uint64_t raw_id, uint64_t timestamp) { if (first_frame_synced) return true; - // OX and OS cameras require a few frames for the FSIN to sync up - if (request_id < 3) { - return false; - } - // Store the frame data for this camera camera_sync_data[camera_id] = SyncData{timestamp, raw_id + 1}; @@ -1468,7 +1455,7 @@ bool SpectraCamera::syncFirstFrame(int camera_id, uint64_t request_id, uint64_t for (const auto &[_, sync_data] : camera_sync_data) { uint64_t diff = std::max(timestamp, sync_data.timestamp) - std::min(timestamp, sync_data.timestamp); - if (diff > 0.5*1e6) { // within 0.5ms + if (diff > 0.2*1e6) { // milliseconds all_cams_synced = false; } } diff --git a/system/camerad/cameras/spectra.h b/system/camerad/cameras/spectra.h index d9abf884c1..2070363a16 100644 --- a/system/camerad/cameras/spectra.h +++ b/system/camerad/cameras/spectra.h @@ -128,8 +128,7 @@ public: void config_ife(int idx, int request_id, bool init=false); int clear_req_queue(); - bool enqueue_buffer(int i, uint64_t request_id); - void enqueue_req_multi(uint64_t start, int n); + void enqueue_frame(uint64_t request_id); int sensors_init(); void sensors_start(); @@ -190,8 +189,8 @@ public: int sync_objs_bps[MAX_IFE_BUFS] = {}; uint64_t request_id_last = 0; uint64_t frame_id_raw_last = 0; - int64_t frame_id_offset = 0; - bool skipped_last = true; + int invalid_request_count = 0; + bool skip_expected = true; SpectraOutputType output_type; @@ -199,6 +198,10 @@ public: SpectraMaster *m; private: + void clearAndRequeue(uint64_t from_request_id); + bool validateEvent(uint64_t request_id, uint64_t frame_id_raw); + bool waitForFrameReady(uint64_t request_id); + bool processFrame(int buf_idx, uint64_t request_id, uint64_t frame_id_raw, uint64_t timestamp); static bool syncFirstFrame(int camera_id, uint64_t request_id, uint64_t raw_id, uint64_t timestamp); struct SyncData { uint64_t timestamp; @@ -208,11 +211,11 @@ private: inline static bool first_frame_synced = false; // a mode for stressing edge cases: realignment, sync failures, etc. - inline bool stress_test(const char* log, float prob=0.01) { + inline bool stress_test(const char* log, float prob=0.02) { static bool enable = getenv("SPECTRA_STRESS_TEST") != nullptr; bool triggered = enable && ((static_cast(rand()) / RAND_MAX) < prob); if (triggered) { - LOGE("stress test: %s", log); + LOGE("stress test (cam %d): %s", cc.camera_num, log); } return triggered; } From 8c2cd247f0abc603ed64c1a30260226f9a6975a0 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 5 Mar 2025 19:31:44 -0800 Subject: [PATCH 51/78] camerad: stress test (#34735) * refactor a bunch of stuff * prob * enable * rm print * cleanup --------- Co-authored-by: Comma Device --- system/camerad/cameras/spectra.h | 6 +++--- system/camerad/test/test_camerad.py | 9 ++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/system/camerad/cameras/spectra.h b/system/camerad/cameras/spectra.h index 2070363a16..fb1bbf874a 100644 --- a/system/camerad/cameras/spectra.h +++ b/system/camerad/cameras/spectra.h @@ -211,9 +211,9 @@ private: inline static bool first_frame_synced = false; // a mode for stressing edge cases: realignment, sync failures, etc. - inline bool stress_test(const char* log, float prob=0.02) { - static bool enable = getenv("SPECTRA_STRESS_TEST") != nullptr; - bool triggered = enable && ((static_cast(rand()) / RAND_MAX) < prob); + inline bool stress_test(const char* log) { + static double prob = std::stod(util::getenv("SPECTRA_ERROR_PROB", "-1"));; + bool triggered = (prob > 0) && ((static_cast(rand()) / RAND_MAX) < prob); if (triggered) { LOGE("stress test (cam %d): %s", cc.camera_num, log); } diff --git a/system/camerad/test/test_camerad.py b/system/camerad/test/test_camerad.py index 0ab71bee46..ab76985972 100644 --- a/system/camerad/test/test_camerad.py +++ b/system/camerad/test/test_camerad.py @@ -83,13 +83,12 @@ class TestCamerad: assert np.all((ts[c]['timestampEof'] - ts[c]['timestampSof']) > 0) # logMonoTime > SOF - assert np.all((ts[c]['t'] - ts[c]['timestampSof']/1e9) > 0.001) - assert np.all((ts[c]['t'] - ts[c]['timestampEof']/1e9) > 0.001) + assert np.all((ts[c]['t'] - ts[c]['timestampSof']/1e9) > 1e-7) + assert np.all((ts[c]['t'] - ts[c]['timestampEof']/1e9) > 1e-7) - @pytest.mark.skip("TODO: enable this") def test_stress_test(self): - os.environ['SPECTRA_STRESS_TEST'] = '1' - logs = run_and_log(["camerad", ], CAMERAS, 15) + os.environ['SPECTRA_ERROR_PROB'] = '0.008' + logs = run_and_log(["camerad", ], CAMERAS, 10) ts = msgs_to_time_series(logs) # we should see some jumps from introduced errors From 95adfd97f026deaae156a3e1ad8f7a04cdc6bc03 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 5 Mar 2025 20:37:30 -0800 Subject: [PATCH 52/78] bump opendbc --- opendbc_repo | 2 +- selfdrive/car/CARS_template.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/opendbc_repo b/opendbc_repo index e7d08ac479..c9c4972d80 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit e7d08ac4794c859e604d260da010d4685c164e5b +Subproject commit c9c4972d800086fa740f300d0adfe9b5da6cd145 diff --git a/selfdrive/car/CARS_template.md b/selfdrive/car/CARS_template.md index c7500ffad0..463683fd3c 100644 --- a/selfdrive/car/CARS_template.md +++ b/selfdrive/car/CARS_template.md @@ -12,11 +12,11 @@ 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. -# {{all_car_docs | length}} Supported Cars +# {{all_car_docs | selectattr('support_type', 'eq', SupportType.UPSTREAM) | list | length}} Supported Cars |{{Column | map(attribute='value') | join('|') | replace(hardware_col_name, wide_hardware_col_name)}}| |---|---|---|{% for _ in range((Column | length) - 3) %}{{':---:|'}}{% endfor +%} -{% for car_docs in all_car_docs %} +{% for car_docs in all_car_docs | selectattr('support_type', 'eq', SupportType.UPSTREAM) %} |{% for column in Column %}{{car_docs.get_column(column, star_icon, video_icon, footnote_tag)}}|{% endfor %} {% endfor %} From 59bb5c54b3d4b05c76e90d712dd2bbbc451f3577 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 5 Mar 2025 22:50:22 -0600 Subject: [PATCH 53/78] Rivian: cancel command (#34767) * test it * bump * bump * bump * bump * clean up * bump refs --- opendbc_repo | 2 +- selfdrive/test/process_replay/ref_commit | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/opendbc_repo b/opendbc_repo index c9c4972d80..b426c1c837 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit c9c4972d800086fa740f300d0adfe9b5da6cd145 +Subproject commit b426c1c837295565e706ec03e27c91aa5f0b6146 diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index d0f0d671d7..d42f143de3 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -a9487c6a5c2f0bb83c9d629ff64c8f64a4e4ca13 \ No newline at end of file +e3f35c6ced7dcf38635060944fa7017af5fe68cd \ No newline at end of file From f3bfdf6969854a554d60c0d14f693ede5173fa7d Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Thu, 6 Mar 2025 01:49:00 -0600 Subject: [PATCH 54/78] Rivian: don't show set speed in UI (#34705) * Rivian: don't show set speed in UI * stash * bump * use speed * bump * bump to master * update refs * default true --- opendbc_repo | 2 +- selfdrive/car/cruise.py | 3 +++ selfdrive/test/process_replay/ref_commit | 2 +- selfdrive/ui/qt/onroad/hud.cc | 5 ++++- selfdrive/ui/qt/onroad/hud.h | 1 + 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/opendbc_repo b/opendbc_repo index b426c1c837..de65067d80 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit b426c1c837295565e706ec03e27c91aa5f0b6146 +Subproject commit de65067d800ed1744ee111ee202da54bcf987b43 diff --git a/selfdrive/car/cruise.py b/selfdrive/car/cruise.py index 697d0273a5..b825808acb 100644 --- a/selfdrive/car/cruise.py +++ b/selfdrive/car/cruise.py @@ -56,6 +56,9 @@ class VCruiseHelper: if CS.cruiseState.speed == 0: self.v_cruise_kph = V_CRUISE_UNSET self.v_cruise_cluster_kph = V_CRUISE_UNSET + elif CS.cruiseState.speed == -1: + self.v_cruise_kph = -1 + self.v_cruise_cluster_kph = -1 else: self.v_cruise_kph = V_CRUISE_UNSET self.v_cruise_cluster_kph = V_CRUISE_UNSET diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index d42f143de3..10c773c2c0 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -e3f35c6ced7dcf38635060944fa7017af5fe68cd \ No newline at end of file +87088a3540ddfc26356d9b71a3a4f40efcbc9b3b \ No newline at end of file diff --git a/selfdrive/ui/qt/onroad/hud.cc b/selfdrive/ui/qt/onroad/hud.cc index c63962caf6..4cfa3d0e3c 100644 --- a/selfdrive/ui/qt/onroad/hud.cc +++ b/selfdrive/ui/qt/onroad/hud.cc @@ -26,6 +26,7 @@ void HudRenderer::updateState(const UIState &s) { // Handle older routes where vCruiseCluster is not set set_speed = car_state.getVCruiseCluster() == 0.0 ? controls_state.getVCruiseDEPRECATED() : car_state.getVCruiseCluster(); is_cruise_set = set_speed > 0 && set_speed != SET_SPEED_NA; + is_cruise_available = set_speed != -1; if (is_cruise_set && !is_metric) { set_speed *= KM_TO_MILE; @@ -47,7 +48,9 @@ void HudRenderer::draw(QPainter &p, const QRect &surface_rect) { p.fillRect(0, 0, surface_rect.width(), UI_HEADER_HEIGHT, bg); - drawSetSpeed(p, surface_rect); + if (is_cruise_available) { + drawSetSpeed(p, surface_rect); + } drawCurrentSpeed(p, surface_rect); p.restore(); diff --git a/selfdrive/ui/qt/onroad/hud.h b/selfdrive/ui/qt/onroad/hud.h index 0b1220a27a..b2ac379dbe 100644 --- a/selfdrive/ui/qt/onroad/hud.h +++ b/selfdrive/ui/qt/onroad/hud.h @@ -19,6 +19,7 @@ private: float speed = 0; float set_speed = 0; bool is_cruise_set = false; + bool is_cruise_available = true; bool is_metric = false; bool v_ego_cluster_seen = false; int status = STATUS_DISENGAGED; From 1506ff312229bcb7a00f66f2af383041495a96aa Mon Sep 17 00:00:00 2001 From: Robbe Derks Date: Thu, 6 Mar 2025 17:29:04 +0100 Subject: [PATCH 55/78] bump panda --- panda | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda b/panda index 3bf1f8e871..1d5b89956b 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 3bf1f8e871f3c577fccba07f57958f30508a2187 +Subproject commit 1d5b89956b32bbda2940724ce70c5166e44668c5 From 47f37d5fec38945d707ea27314087bdb5a9fb7a4 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Fri, 7 Mar 2025 02:14:53 +0800 Subject: [PATCH 56/78] remove numpy_fast.py (#34796) --- common/numpy_fast.py | 19 ------------------- tools/replay/ui.py | 5 ++--- 2 files changed, 2 insertions(+), 22 deletions(-) delete mode 100644 common/numpy_fast.py diff --git a/common/numpy_fast.py b/common/numpy_fast.py deleted file mode 100644 index 878c0005c8..0000000000 --- a/common/numpy_fast.py +++ /dev/null @@ -1,19 +0,0 @@ -def clip(x, lo, hi): - return max(lo, min(hi, x)) - -def interp(x, xp, fp): - N = len(xp) - - def get_interp(xv): - hi = 0 - while hi < N and xv > xp[hi]: - hi += 1 - low = hi - 1 - return fp[-1] if hi == N and xv > xp[low] else ( - fp[0] if hi == 0 else - (xv - xp[low]) * (fp[hi] - fp[low]) / (xp[hi] - xp[low]) + fp[low]) - - return [get_interp(v) for v in x] if hasattr(x, '__iter__') else get_interp(x) - -def mean(x): - return sum(x) / len(x) diff --git a/tools/replay/ui.py b/tools/replay/ui.py index 34e22ec595..6e40579902 100755 --- a/tools/replay/ui.py +++ b/tools/replay/ui.py @@ -8,7 +8,6 @@ import numpy as np import pygame import cereal.messaging as messaging -from openpilot.common.numpy_fast import clip from openpilot.common.basedir import BASEDIR from openpilot.common.transformations.camera import DEVICE_CAMERAS from openpilot.tools.replay.lib.ui_helpers import (UP, @@ -152,11 +151,11 @@ def ui_thread(addr): plot_arr[-1, name_to_arr_idx['angle_steers_k']] = angle_steers_k plot_arr[-1, name_to_arr_idx['gas']] = sm['carState'].gas # TODO gas is deprecated - plot_arr[-1, name_to_arr_idx['computer_gas']] = clip(sm['carControl'].actuators.accel/4.0, 0.0, 1.0) + plot_arr[-1, name_to_arr_idx['computer_gas']] = np.clip(sm['carControl'].actuators.accel/4.0, 0.0, 1.0) plot_arr[-1, name_to_arr_idx['user_brake']] = sm['carState'].brake plot_arr[-1, name_to_arr_idx['steer_torque']] = sm['carControl'].actuators.torque * ANGLE_SCALE # TODO brake is deprecated - plot_arr[-1, name_to_arr_idx['computer_brake']] = clip(-sm['carControl'].actuators.accel/4.0, 0.0, 1.0) + plot_arr[-1, name_to_arr_idx['computer_brake']] = np.clip(-sm['carControl'].actuators.accel/4.0, 0.0, 1.0) plot_arr[-1, name_to_arr_idx['v_ego']] = sm['carState'].vEgo plot_arr[-1, name_to_arr_idx['v_cruise']] = sm['carState'].cruiseState.speed plot_arr[-1, name_to_arr_idx['a_ego']] = sm['carState'].aEgo From 2c2c6e6437519470f99f095f004a4de77b6d7a68 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Fri, 7 Mar 2025 02:16:56 +0800 Subject: [PATCH 57/78] deleter: fix duplicate segments in get_preserved_segments return value (#34795) fix duplicate segments in get_preserved_segments return value --- system/loggerd/deleter.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/system/loggerd/deleter.py b/system/loggerd/deleter.py index 2a2bd5fe11..eb8fd35f21 100755 --- a/system/loggerd/deleter.py +++ b/system/loggerd/deleter.py @@ -22,9 +22,9 @@ def has_preserve_xattr(d: str) -> bool: return getxattr(os.path.join(Paths.log_root(), d), PRESERVE_ATTR_NAME) == PRESERVE_ATTR_VALUE -def get_preserved_segments(dirs_by_creation: list[str]) -> list[str]: +def get_preserved_segments(dirs_by_creation: list[str]) -> set[str]: # skip deleting most recent N preserved segments (and their prior segment) - preserved = [] + preserved = set() for n, d in enumerate(filter(has_preserve_xattr, reversed(dirs_by_creation))): if n == PRESERVE_COUNT: break @@ -40,7 +40,7 @@ def get_preserved_segments(dirs_by_creation: list[str]) -> list[str]: # preserve segment and two prior for _seg_num in range(max(0, seg_num - 2), seg_num + 1): - preserved.append(f"{date_str}--{_seg_num}") + preserved.add(f"{date_str}--{_seg_num}") return preserved From e3ce984701e519b87ee859a0b14903b411f399f4 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Fri, 7 Mar 2025 02:17:11 +0800 Subject: [PATCH 58/78] clutil: remove deprecated and unused code (#34793) remove deprecated and unused code --- common/clutil.cc | 106 ----------------------------------------------- common/clutil.h | 2 - 2 files changed, 108 deletions(-) diff --git a/common/clutil.cc b/common/clutil.cc index ee43ef36d5..f8381a7e09 100644 --- a/common/clutil.cc +++ b/common/clutil.cc @@ -96,109 +96,3 @@ cl_program cl_program_from_source(cl_context ctx, cl_device_id device_id, const } return prg; } - -cl_program cl_program_from_binary(cl_context ctx, cl_device_id device_id, const uint8_t* binary, size_t length, const char* args) { - cl_program prg = CL_CHECK_ERR(clCreateProgramWithBinary(ctx, 1, &device_id, &length, &binary, NULL, &err)); - if (int err = clBuildProgram(prg, 1, &device_id, args, NULL, NULL); err != 0) { - cl_print_build_errors(prg, device_id); - assert(0); - } - return prg; -} - -// Given a cl code and return a string representation -#define CL_ERR_TO_STR(err) case err: return #err -const char* cl_get_error_string(int err) { - switch (err) { - CL_ERR_TO_STR(CL_SUCCESS); - CL_ERR_TO_STR(CL_DEVICE_NOT_FOUND); - CL_ERR_TO_STR(CL_DEVICE_NOT_AVAILABLE); - CL_ERR_TO_STR(CL_COMPILER_NOT_AVAILABLE); - CL_ERR_TO_STR(CL_MEM_OBJECT_ALLOCATION_FAILURE); - CL_ERR_TO_STR(CL_OUT_OF_RESOURCES); - CL_ERR_TO_STR(CL_OUT_OF_HOST_MEMORY); - CL_ERR_TO_STR(CL_PROFILING_INFO_NOT_AVAILABLE); - CL_ERR_TO_STR(CL_MEM_COPY_OVERLAP); - CL_ERR_TO_STR(CL_IMAGE_FORMAT_MISMATCH); - CL_ERR_TO_STR(CL_IMAGE_FORMAT_NOT_SUPPORTED); - CL_ERR_TO_STR(CL_MAP_FAILURE); - CL_ERR_TO_STR(CL_MISALIGNED_SUB_BUFFER_OFFSET); - CL_ERR_TO_STR(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST); - CL_ERR_TO_STR(CL_COMPILE_PROGRAM_FAILURE); - CL_ERR_TO_STR(CL_LINKER_NOT_AVAILABLE); - CL_ERR_TO_STR(CL_LINK_PROGRAM_FAILURE); - CL_ERR_TO_STR(CL_DEVICE_PARTITION_FAILED); - CL_ERR_TO_STR(CL_KERNEL_ARG_INFO_NOT_AVAILABLE); - CL_ERR_TO_STR(CL_INVALID_VALUE); - CL_ERR_TO_STR(CL_INVALID_DEVICE_TYPE); - CL_ERR_TO_STR(CL_INVALID_PLATFORM); - CL_ERR_TO_STR(CL_INVALID_DEVICE); - CL_ERR_TO_STR(CL_INVALID_CONTEXT); - CL_ERR_TO_STR(CL_INVALID_QUEUE_PROPERTIES); - CL_ERR_TO_STR(CL_INVALID_COMMAND_QUEUE); - CL_ERR_TO_STR(CL_INVALID_HOST_PTR); - CL_ERR_TO_STR(CL_INVALID_MEM_OBJECT); - CL_ERR_TO_STR(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR); - CL_ERR_TO_STR(CL_INVALID_IMAGE_SIZE); - CL_ERR_TO_STR(CL_INVALID_SAMPLER); - CL_ERR_TO_STR(CL_INVALID_BINARY); - CL_ERR_TO_STR(CL_INVALID_BUILD_OPTIONS); - CL_ERR_TO_STR(CL_INVALID_PROGRAM); - CL_ERR_TO_STR(CL_INVALID_PROGRAM_EXECUTABLE); - CL_ERR_TO_STR(CL_INVALID_KERNEL_NAME); - CL_ERR_TO_STR(CL_INVALID_KERNEL_DEFINITION); - CL_ERR_TO_STR(CL_INVALID_KERNEL); - CL_ERR_TO_STR(CL_INVALID_ARG_INDEX); - CL_ERR_TO_STR(CL_INVALID_ARG_VALUE); - CL_ERR_TO_STR(CL_INVALID_ARG_SIZE); - CL_ERR_TO_STR(CL_INVALID_KERNEL_ARGS); - CL_ERR_TO_STR(CL_INVALID_WORK_DIMENSION); - CL_ERR_TO_STR(CL_INVALID_WORK_GROUP_SIZE); - CL_ERR_TO_STR(CL_INVALID_WORK_ITEM_SIZE); - CL_ERR_TO_STR(CL_INVALID_GLOBAL_OFFSET); - CL_ERR_TO_STR(CL_INVALID_EVENT_WAIT_LIST); - CL_ERR_TO_STR(CL_INVALID_EVENT); - CL_ERR_TO_STR(CL_INVALID_OPERATION); - CL_ERR_TO_STR(CL_INVALID_GL_OBJECT); - CL_ERR_TO_STR(CL_INVALID_BUFFER_SIZE); - CL_ERR_TO_STR(CL_INVALID_MIP_LEVEL); - CL_ERR_TO_STR(CL_INVALID_GLOBAL_WORK_SIZE); - CL_ERR_TO_STR(CL_INVALID_PROPERTY); - CL_ERR_TO_STR(CL_INVALID_IMAGE_DESCRIPTOR); - CL_ERR_TO_STR(CL_INVALID_COMPILER_OPTIONS); - CL_ERR_TO_STR(CL_INVALID_LINKER_OPTIONS); - CL_ERR_TO_STR(CL_INVALID_DEVICE_PARTITION_COUNT); - case -69: return "CL_INVALID_PIPE_SIZE"; - case -70: return "CL_INVALID_DEVICE_QUEUE"; - case -71: return "CL_INVALID_SPEC_ID"; - case -72: return "CL_MAX_SIZE_RESTRICTION_EXCEEDED"; - case -1002: return "CL_INVALID_D3D10_DEVICE_KHR"; - case -1003: return "CL_INVALID_D3D10_RESOURCE_KHR"; - case -1004: return "CL_D3D10_RESOURCE_ALREADY_ACQUIRED_KHR"; - case -1005: return "CL_D3D10_RESOURCE_NOT_ACQUIRED_KHR"; - case -1006: return "CL_INVALID_D3D11_DEVICE_KHR"; - case -1007: return "CL_INVALID_D3D11_RESOURCE_KHR"; - case -1008: return "CL_D3D11_RESOURCE_ALREADY_ACQUIRED_KHR"; - case -1009: return "CL_D3D11_RESOURCE_NOT_ACQUIRED_KHR"; - case -1010: return "CL_INVALID_DX9_MEDIA_ADAPTER_KHR"; - case -1011: return "CL_INVALID_DX9_MEDIA_SURFACE_KHR"; - case -1012: return "CL_DX9_MEDIA_SURFACE_ALREADY_ACQUIRED_KHR"; - case -1013: return "CL_DX9_MEDIA_SURFACE_NOT_ACQUIRED_KHR"; - case -1093: return "CL_INVALID_EGL_OBJECT_KHR"; - case -1092: return "CL_EGL_RESOURCE_NOT_ACQUIRED_KHR"; - case -1001: return "CL_PLATFORM_NOT_FOUND_KHR"; - case -1057: return "CL_DEVICE_PARTITION_FAILED_EXT"; - case -1058: return "CL_INVALID_PARTITION_COUNT_EXT"; - case -1059: return "CL_INVALID_PARTITION_NAME_EXT"; - case -1094: return "CL_INVALID_ACCELERATOR_INTEL"; - case -1095: return "CL_INVALID_ACCELERATOR_TYPE_INTEL"; - case -1096: return "CL_INVALID_ACCELERATOR_DESCRIPTOR_INTEL"; - case -1097: return "CL_ACCELERATOR_TYPE_NOT_SUPPORTED_INTEL"; - case -1000: return "CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR"; - case -1098: return "CL_INVALID_VA_API_MEDIA_ADAPTER_INTEL"; - case -1099: return "CL_INVALID_VA_API_MEDIA_SURFACE_INTEL"; - case -1100: return "CL_VA_API_MEDIA_SURFACE_ALREADY_ACQUIRED_INTEL"; - case -1101: return "CL_VA_API_MEDIA_SURFACE_NOT_ACQUIRED_INTEL"; - default: return "CL_UNKNOWN_ERROR"; - } -} diff --git a/common/clutil.h b/common/clutil.h index c8bd2cd38f..b364e79d45 100644 --- a/common/clutil.h +++ b/common/clutil.h @@ -25,6 +25,4 @@ cl_device_id cl_get_device_id(cl_device_type device_type); cl_context cl_create_context(cl_device_id device_id); void cl_release_context(cl_context context); cl_program cl_program_from_source(cl_context ctx, cl_device_id device_id, const std::string& src, const char* args = nullptr); -cl_program cl_program_from_binary(cl_context ctx, cl_device_id device_id, const uint8_t* binary, size_t length, const char* args = nullptr); cl_program cl_program_from_file(cl_context ctx, cl_device_id device_id, const char* path, const char* args); -const char* cl_get_error_string(int err); From e9f7c01a3a5767cd4e805543e7c87f33535295e8 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Fri, 7 Mar 2025 02:17:58 +0800 Subject: [PATCH 59/78] camerad: move output_type to config (#34792) move output_type to config --- system/camerad/cameras/camera_common.cc | 2 +- system/camerad/cameras/camera_qcom2.cc | 2 +- system/camerad/cameras/hw.h | 11 +++++++++ system/camerad/cameras/spectra.cc | 31 ++++++++++++------------- system/camerad/cameras/spectra.h | 11 +-------- 5 files changed, 29 insertions(+), 28 deletions(-) diff --git a/system/camerad/cameras/camera_common.cc b/system/camerad/cameras/camera_common.cc index a08ebdecf9..f6c2681dea 100644 --- a/system/camerad/cameras/camera_common.cc +++ b/system/camerad/cameras/camera_common.cc @@ -15,7 +15,7 @@ void CameraBuf::init(cl_device_id device_id, cl_context context, SpectraCamera * const SensorInfo *sensor = cam->sensor.get(); // RAW frames from ISP - if (cam->output_type != ISP_IFE_PROCESSED) { + if (cam->cc.output_type != ISP_IFE_PROCESSED) { camera_bufs_raw = std::make_unique(frame_buf_count); const int raw_frame_size = (sensor->frame_height + sensor->extra_height) * sensor->frame_stride; diff --git a/system/camerad/cameras/camera_qcom2.cc b/system/camerad/cameras/camera_qcom2.cc index d969d092e9..ec77941ad2 100644 --- a/system/camerad/cameras/camera_qcom2.cc +++ b/system/camerad/cameras/camera_qcom2.cc @@ -55,7 +55,7 @@ public: float fl_pix = 0; std::unique_ptr pm; - CameraState(SpectraMaster *master, const CameraConfig &config) : camera(master, config, config.stream_type == VISION_STREAM_DRIVER ? ISP_BPS_PROCESSED : ISP_IFE_PROCESSED) {}; + CameraState(SpectraMaster *master, const CameraConfig &config) : camera(master, config) {}; ~CameraState(); void init(VisionIpcServer *v, cl_device_id device_id, cl_context ctx); void update_exposure_score(float desired_ev, int exp_t, int exp_g_idx, float exp_gain); diff --git a/system/camerad/cameras/hw.h b/system/camerad/cameras/hw.h index bc40e01345..d299627ce9 100644 --- a/system/camerad/cameras/hw.h +++ b/system/camerad/cameras/hw.h @@ -6,6 +6,13 @@ #include "media/cam_isp_ife.h" + +typedef enum { + ISP_RAW_OUTPUT, // raw frame from sensor + ISP_IFE_PROCESSED, // fully processed image through the IFE + ISP_BPS_PROCESSED, // fully processed image through the BPS +} SpectraOutputType; + // For the comma 3/3X three camera platform struct CameraConfig { @@ -17,6 +24,7 @@ struct CameraConfig { bool enabled; uint32_t phy; bool vignetting_correction; + SpectraOutputType output_type; }; // NOTE: to be able to disable road and wide road, we still have to configure the sensor over i2c @@ -30,6 +38,7 @@ const CameraConfig WIDE_ROAD_CAMERA_CONFIG = { .enabled = !getenv("DISABLE_WIDE_ROAD"), .phy = CAM_ISP_IFE_IN_RES_PHY_0, .vignetting_correction = false, + .output_type = ISP_IFE_PROCESSED, }; const CameraConfig ROAD_CAMERA_CONFIG = { @@ -41,6 +50,7 @@ const CameraConfig ROAD_CAMERA_CONFIG = { .enabled = !getenv("DISABLE_ROAD"), .phy = CAM_ISP_IFE_IN_RES_PHY_1, .vignetting_correction = true, + .output_type = ISP_IFE_PROCESSED, }; const CameraConfig DRIVER_CAMERA_CONFIG = { @@ -52,6 +62,7 @@ const CameraConfig DRIVER_CAMERA_CONFIG = { .enabled = !getenv("DISABLE_DRIVER"), .phy = CAM_ISP_IFE_IN_RES_PHY_2, .vignetting_correction = false, + .output_type = ISP_BPS_PROCESSED, }; const CameraConfig ALL_CAMERA_CONFIGS[] = {WIDE_ROAD_CAMERA_CONFIG, ROAD_CAMERA_CONFIG, DRIVER_CAMERA_CONFIG}; diff --git a/system/camerad/cameras/spectra.cc b/system/camerad/cameras/spectra.cc index 063420823c..c70c427766 100644 --- a/system/camerad/cameras/spectra.cc +++ b/system/camerad/cameras/spectra.cc @@ -233,12 +233,11 @@ void SpectraMaster::init() { // *** SpectraCamera *** -SpectraCamera::SpectraCamera(SpectraMaster *master, const CameraConfig &config, SpectraOutputType out) +SpectraCamera::SpectraCamera(SpectraMaster *master, const CameraConfig &config) : m(master), enabled(config.enabled), - cc(config), - output_type(out) { - ife_buf_depth = (out == ISP_RAW_OUTPUT) ? 4 : VIPC_BUFFER_COUNT; + cc(config) { + ife_buf_depth = (cc.output_type == ISP_RAW_OUTPUT) ? 4 : VIPC_BUFFER_COUNT; assert(ife_buf_depth < MAX_IFE_BUFS); } @@ -290,7 +289,7 @@ void SpectraCamera::camera_open(VisionIpcServer *v, cl_device_id device_id, cl_c uv_height = VENUS_UV_SCANLINES(COLOR_FMT_NV12, sensor->frame_height); uv_offset = stride*y_height; yuv_size = uv_offset + stride*uv_height; - if (output_type != ISP_RAW_OUTPUT) { + if (cc.output_type != ISP_RAW_OUTPUT) { uv_offset = ALIGNED_SIZE(uv_offset, 0x1000); yuv_size = uv_offset + ALIGNED_SIZE(stride*uv_height, 0x1000); } @@ -299,7 +298,7 @@ void SpectraCamera::camera_open(VisionIpcServer *v, cl_device_id device_id, cl_c open = true; configISP(); - if (output_type == ISP_BPS_PROCESSED) configICP(); + if (cc.output_type == ISP_BPS_PROCESSED) configICP(); configCSIPHY(); linkDevices(); @@ -736,7 +735,7 @@ void SpectraCamera::config_ife(int idx, int request_id, bool init) { buf_desc[0].offset = ife_cmd.aligned_size()*idx; // stream of IFE register writes - bool is_raw = output_type != ISP_IFE_PROCESSED; + bool is_raw = cc.output_type != ISP_IFE_PROCESSED; if (!is_raw) { if (init) { buf_desc[0].length = build_initial_config((unsigned char*)ife_cmd.ptr + buf_desc[0].offset, cc, sensor.get(), patches); @@ -825,7 +824,7 @@ void SpectraCamera::config_ife(int idx, int request_id, bool init) { pkt->io_configs_offset = sizeof(struct cam_cmd_buf_desc)*pkt->num_cmd_buf; struct cam_buf_io_cfg *io_cfg = (struct cam_buf_io_cfg *)((char*)&pkt->payload + pkt->io_configs_offset); - if (output_type != ISP_IFE_PROCESSED) { + if (cc.output_type != ISP_IFE_PROCESSED) { io_cfg[0].mem_handle[0] = buf_handle_raw[idx]; io_cfg[0].planes[0] = (struct cam_plane_cfg){ .width = sensor->frame_width, @@ -934,7 +933,7 @@ void SpectraCamera::enqueue_frame(uint64_t request_id) { // submit request to IFE and BPS config_ife(i, request_id); - if (output_type == ISP_BPS_PROCESSED) config_bps(i, request_id); + if (cc.output_type == ISP_BPS_PROCESSED) config_bps(i, request_id); } void SpectraCamera::destroySyncObjectAt(int index) { @@ -967,7 +966,7 @@ void SpectraCamera::camera_map_bufs() { mem_mgr_map_cmd.mmu_hdls[1] = m->icp_device_iommu; } - if (output_type != ISP_IFE_PROCESSED) { + if (cc.output_type != ISP_IFE_PROCESSED) { // RAW bayer images mem_mgr_map_cmd.fd = buf.camera_bufs_raw[i].fd; ret = do_cam_control(m->video0_fd, CAM_REQ_MGR_MAP_BUF, &mem_mgr_map_cmd, sizeof(mem_mgr_map_cmd)); @@ -976,7 +975,7 @@ void SpectraCamera::camera_map_bufs() { buf_handle_raw[i] = mem_mgr_map_cmd.out.buf_handle; } - if (output_type != ISP_RAW_OUTPUT) { + if (cc.output_type != ISP_RAW_OUTPUT) { // final processed images VisionBuf *vb = buf.vipc_server->get_buffer(buf.stream_type, i); mem_mgr_map_cmd.fd = vb->fd; @@ -1073,7 +1072,7 @@ void SpectraCamera::configISP() { }, }; - if (output_type != ISP_IFE_PROCESSED) { + if (cc.output_type != ISP_IFE_PROCESSED) { in_port_info.line_start = 0; in_port_info.line_stop = sensor->frame_height + sensor->extra_height - 1; in_port_info.height = sensor->frame_height + sensor->extra_height; @@ -1096,7 +1095,7 @@ void SpectraCamera::configISP() { // allocate IFE memory, then configure it ife_cmd.init(m, 67984, 0x20, false, m->device_iommu, m->cdm_iommu, ife_buf_depth); - if (output_type == ISP_IFE_PROCESSED) { + if (cc.output_type == ISP_IFE_PROCESSED) { assert(sensor->gamma_lut_rgb.size() == 64); ife_gamma_lut.init(m, sensor->gamma_lut_rgb.size()*sizeof(uint32_t), 0x20, false, m->device_iommu, m->cdm_iommu, 3); // 3 for RGB for (int i = 0; i < 3; i++) { @@ -1248,7 +1247,7 @@ void SpectraCamera::linkDevices() { ret = device_control(m->isp_fd, CAM_START_DEV, session_handle, isp_dev_handle); LOGD("start isp: %d", ret); assert(ret == 0); - if (output_type == ISP_BPS_PROCESSED) { + if (cc.output_type == ISP_BPS_PROCESSED) { ret = device_control(m->icp_fd, CAM_START_DEV, session_handle, icp_dev_handle); LOGD("start icp: %d", ret); assert(ret == 0); @@ -1263,7 +1262,7 @@ void SpectraCamera::camera_close() { // LOGD("stop sensor: %d", ret); int ret = device_control(m->isp_fd, CAM_STOP_DEV, session_handle, isp_dev_handle); LOGD("stop isp: %d", ret); - if (output_type == ISP_BPS_PROCESSED) { + if (cc.output_type == ISP_BPS_PROCESSED) { ret = device_control(m->icp_fd, CAM_STOP_DEV, session_handle, icp_dev_handle); LOGD("stop icp: %d", ret); } @@ -1292,7 +1291,7 @@ void SpectraCamera::camera_close() { LOGD("-- Release devices"); ret = device_control(m->isp_fd, CAM_RELEASE_DEV, session_handle, isp_dev_handle); LOGD("release isp: %d", ret); - if (output_type == ISP_BPS_PROCESSED) { + if (cc.output_type == ISP_BPS_PROCESSED) { ret = device_control(m->icp_fd, CAM_RELEASE_DEV, session_handle, icp_dev_handle); LOGD("release icp: %d", ret); } diff --git a/system/camerad/cameras/spectra.h b/system/camerad/cameras/spectra.h index fb1bbf874a..21f1970326 100644 --- a/system/camerad/cameras/spectra.h +++ b/system/camerad/cameras/spectra.h @@ -22,7 +22,6 @@ const int MIPI_SETTLE_CNT = 33; // Calculated by camera_freqs.py // For use with the Titan 170 ISP in the SDM845 // https://github.com/commaai/agnos-kernel-sdm845 - // CSLDeviceType/CSLPacketOpcodesIFE from camx // cam_packet_header.op_code = (device << 24) | (opcode); #define CSLDeviceTypeImageSensor (0x01 << 24) @@ -31,12 +30,6 @@ const int MIPI_SETTLE_CNT = 33; // Calculated by camera_freqs.py #define OpcodesIFEInitialConfig 0x0 #define OpcodesIFEUpdate 0x1 -typedef enum { - ISP_RAW_OUTPUT, // raw frame from sensor - ISP_IFE_PROCESSED, // fully processed image through the IFE - ISP_BPS_PROCESSED, // fully processed image through the BPS -} SpectraOutputType; - std::optional device_acquire(int fd, int32_t session_handle, void *data, uint32_t num_resources=1); int device_config(int fd, int32_t session_handle, int32_t dev_handle, uint64_t packet_handle); int device_control(int fd, int op_code, int session_handle, int dev_handle); @@ -117,7 +110,7 @@ public: class SpectraCamera { public: - SpectraCamera(SpectraMaster *master, const CameraConfig &config, SpectraOutputType out); + SpectraCamera(SpectraMaster *master, const CameraConfig &config); ~SpectraCamera(); void camera_open(VisionIpcServer *v, cl_device_id device_id, cl_context ctx); @@ -192,8 +185,6 @@ public: int invalid_request_count = 0; bool skip_expected = true; - SpectraOutputType output_type; - CameraBuf buf; SpectraMaster *m; From 88fa3cdd90ec3de6710feb2a3bd5fe9d1175790f Mon Sep 17 00:00:00 2001 From: Mauricio Alvarez Leon <65101411+BBBmau@users.noreply.github.com> Date: Thu, 6 Mar 2025 10:18:12 -0800 Subject: [PATCH 60/78] `op adb`: change directory to match ssh (#34770) Update adb_shell.sh --- tools/adb_shell.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/adb_shell.sh b/tools/adb_shell.sh index 985c5c0726..f757f7d4d0 100755 --- a/tools/adb_shell.sh +++ b/tools/adb_shell.sh @@ -1,7 +1,7 @@ #!/usr/bin/env expect spawn adb shell expect "#" -send "cd usr/comma\r" +send "cd data/openpilot\r" send "export TERM=xterm-256color\r" send "su comma\r" send "clear\r" From 63f60505db90d1cba6a87511ff6f8b245bcb6e8f Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 6 Mar 2025 10:55:39 -0800 Subject: [PATCH 61/78] ui: no scroll terms (#34797) * remove scroller * match setup style * rm that --- selfdrive/assets/offroad/tc.html | 44 ------------------------ selfdrive/ui/qt/offroad/onboarding.cc | 49 ++++++++------------------- selfdrive/ui/qt/offroad/onboarding.h | 3 -- 3 files changed, 14 insertions(+), 82 deletions(-) delete mode 100644 selfdrive/assets/offroad/tc.html diff --git a/selfdrive/assets/offroad/tc.html b/selfdrive/assets/offroad/tc.html deleted file mode 100644 index f88daf08f2..0000000000 --- a/selfdrive/assets/offroad/tc.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - openpilot Terms of Service - - - - -

The Terms and Conditions below are effective for all users

-

Last Updated on October 18, 2019

-

Please read these Terms of Use (“Terms”) carefully before using openpilot which is open-sourced software developed by Comma.ai, Inc., a corporation organized under the laws of Delaware (“comma,” “us,” “we,” or “our”).

-

Before using and by accessing openpilot, you indicate that you have read, understood, and agree to these Terms. These Terms apply to all users and others who access or use openpilot. If others use openpilot through your user account or vehicle, you are responsible to ensure that they only use openpilot when it is safe to do so, and in compliance with these Terms and with applicable law. If you disagree with any part of the Terms, you should not access or use openpilot.

-

Communications

-

You agree that comma may contact you by email or telephone in connection with openpilot or for other business purposes. You may opt out of receiving email messages at any time by contacting us at support@comma.ai.

-

We collect, use, and share information from and about you and your vehicle in connection with openpilot. You consent to comma accessing the systems associated with openpilot, without additional notice or consent, for the purposes of providing openpilot, data collection, software updates, safety and cybersecurity, suspension or removal of your account, and as disclosed in the Privacy Policy (available at https://connect.comma.ai/privacy).

-

Safety

-

openpilot performs the functions of Adaptive Cruise Control (ACC) and Lane Keeping Assist System (LKAS) designed for use in compatible motor vehicles. While using openpilot, it is your responsibility to obey all laws, traffic rules, and traffic regulations governing your vehicle and its operation. Access to and use of openpilot is at your own risk and responsibility, and openpilot should be accessed and/or used only when you can do so safely.

-

openpilot does not make your vehicle “autonomous” or capable of operation without the active monitoring of a licensed driver. It is designed to assist a licensed driver. A licensed driver must pay attention to the road, remain aware of navigation at all times, and be prepared to take immediate action. Failure to do so can cause damage, injury, or death.

-

Supported Locations and Models

-

openpilot is compatible only with particular makes and models of vehicles. For a complete list of currently supported vehicles, visit https://comma.ai. openpilot will not function properly when installed in an incompatible vehicle. openpilot is compatible only within the geographical boundaries of the United States of America.

-

Indemnification

-

To the maximum extent allowable by law, you agree to defend, indemnify and hold harmless comma, and its employees, partners, suppliers, contractors, investors, agents, officers, directors, and affiliates, from and against any and all claims, damages, causes of action, penalties, interest, demands, obligations, losses, liabilities, costs or debt, additional taxes, and expenses (including but not limited to attorneys’ fees), resulting from or arising out of (i) your use and access of, or inability to use or access, openpilot, (ii) your breach of these Terms, (iii) the inaccuracy of any information, representation or warranty made by you, (iv) activities of anyone other than you in connection with openpilot conducted through your comma device or account, (v) any other of your activities under or in connection with these Terms or openpilot.

-

Limitation of Liability

-

In no event shall comma, nor its directors, employees, partners, agents, suppliers, or affiliates, be liable for any indirect, incidental, special, consequential or punitive damages, including without limitation, loss of profits, data, use, goodwill, or other intangible losses, resulting from (i) your access to or use of or inability to access or use of the Software; or (ii) any conduct or content of any third party on the Software whether based on warranty, contract, tort (including negligence) or any other legal theory, whether or not we have been informed of the possibility of such damage, and even if a remedy set forth herein is found to have failed of its essential purpose.

-

No Warranty or Obligations to Maintain or Service

-

comma provides openpilot without representations, conditions, or warranties of any kind. openpilot is provided on an “AS IS” and “AS AVAILABLE” basis, including with all faults and errors as may occur. To the extent permitted by law and unless prohibited by law, comma on behalf of itself and all persons and parties acting by, through, or for comma, explicitly disclaims all warranties or conditions, express, implied, or collateral, including any implied warranties of merchantability, satisfactory quality, and fitness for a particular purpose in respect of openpilot.

-

To the extent permitted by law, comma does not warrant the operation, performance, or availability of openpilot under all conditions. comma is not responsible for any failures caused by server errors, misdirected or redirected transmissions, failed internet connections, interruptions or failures in the transmission of data, any computer virus, or any acts or omissions of third parties that damage the network or impair wireless service.

-

We undertake reasonable measures to preserve and secure information collected through our openpilot. However, no data collection, transmission or storage system is 100% secure, and there is always a risk that your information may be intercepted without our consent. In using openpilot, you acknowledge that comma is not responsible for intercepted information, and you hereby release us from any and all claims arising out of or related to the use of intercepted information in any unauthorized manner.

-

By providing openpilot, comma does not transfer or license its intellectual property or grant rights in its brand names, nor does comma make representations with respect to third-party intellectual property rights.

-

We are not obligated to provide any maintenance or support for openpilot, technical or otherwise. If we voluntarily provide any maintenance or support for openpilot, we may stop any such maintenance, support, or services at any time in our sole discretion.

-

Modification of Software

-

In no event shall comma, nor its directors, employees, partners, agents, suppliers, or affiliates, be liable if you choose to modify the software.

-

Changes

-

We reserve the right, at our sole discretion, to modify or replace these Terms at any time. If a revision is material we will provide at least 15 days’ notice prior to any new terms taking effect. What constitutes a material change will be determined at our sole discretion.

-

By continuing to access or use our Software after any revisions become effective, you agree to be bound by the revised terms. If you do not agree to the new terms, you are no longer authorized to use the Software.

-

Contact Us

-

If you have any questions about these Terms, please contact us at support@comma.ai.

- - diff --git a/selfdrive/ui/qt/offroad/onboarding.cc b/selfdrive/ui/qt/offroad/onboarding.cc index bae7e3bdf3..1390566671 100644 --- a/selfdrive/ui/qt/offroad/onboarding.cc +++ b/selfdrive/ui/qt/offroad/onboarding.cc @@ -4,7 +4,6 @@ #include #include -#include #include #include @@ -12,7 +11,6 @@ #include "common/params.h" #include "selfdrive/ui/qt/util.h" #include "selfdrive/ui/qt/widgets/input.h" -#include "selfdrive/ui/qt/widgets/scrollview.h" TrainingGuide::TrainingGuide(QWidget *parent) : QFrame(parent) { setAttribute(Qt::WA_OpaquePaintEvent); @@ -85,29 +83,25 @@ void TrainingGuide::paintEvent(QPaintEvent *event) { } void TermsPage::showEvent(QShowEvent *event) { - // late init, building QML widget takes 200ms - if (layout()) { - return; - } - QVBoxLayout *main_layout = new QVBoxLayout(this); main_layout->setContentsMargins(45, 35, 45, 45); main_layout->setSpacing(0); - QLabel *title = new QLabel(tr("Terms & Conditions")); - title->setStyleSheet("font-size: 90px; font-weight: 600;"); - main_layout->addWidget(title); + QVBoxLayout *vlayout = new QVBoxLayout(); + vlayout->setContentsMargins(165, 165, 165, 0); + main_layout->addLayout(vlayout); - QLabel *text = new QLabel(this); - text->setTextFormat(Qt::RichText); - text->setWordWrap(true); - text->setText(QString::fromStdString(util::read_file("../assets/offroad/tc.html"))); - text->setStyleSheet("font-size:50px; font-weight: 200; color: #C9C9C9; background-color:#1B1B1B; padding:50px 50px;"); - ScrollView *scroll = new ScrollView(text, this); + QLabel *title = new QLabel(tr("Welcome to openpilot")); + title->setStyleSheet("font-size: 90px; font-weight: 500;"); + vlayout->addWidget(title, 0, Qt::AlignTop | Qt::AlignLeft); - main_layout->addSpacing(30); - main_layout->addWidget(scroll); - main_layout->addSpacing(50); + vlayout->addSpacing(90); + QLabel *desc = new QLabel(tr("You must accept the Terms and Conditions to use openpilot. Read the latest terms at https://comma.ai/terms before continuing.")); + desc->setWordWrap(true); + desc->setStyleSheet("font-size: 80px; font-weight: 300;"); + vlayout->addWidget(desc, 0); + + vlayout->addStretch(); QHBoxLayout* buttons = new QHBoxLayout; buttons->setMargin(0); @@ -118,8 +112,7 @@ void TermsPage::showEvent(QShowEvent *event) { buttons->addWidget(decline_btn); QObject::connect(decline_btn, &QPushButton::clicked, this, &TermsPage::declinedTerms); - accept_btn = new QPushButton(tr("Scroll to accept")); - accept_btn->setEnabled(false); + accept_btn = new QPushButton(tr("Agree")); accept_btn->setStyleSheet(R"( QPushButton { background-color: #465BEA; @@ -127,23 +120,9 @@ void TermsPage::showEvent(QShowEvent *event) { QPushButton:pressed { background-color: #3049F4; } - QPushButton:disabled { - background-color: #4F4F4F; - } )"); buttons->addWidget(accept_btn); QObject::connect(accept_btn, &QPushButton::clicked, this, &TermsPage::acceptedTerms); - QScrollBar *scroll_bar = scroll->verticalScrollBar(); - connect(scroll_bar, &QScrollBar::valueChanged, this, [this, scroll_bar](int value) { - if (value == scroll_bar->maximum()) { - enableAccept(); - } - }); -} - -void TermsPage::enableAccept() { - accept_btn->setText(tr("Agree")); - accept_btn->setEnabled(true); } void DeclinePage::showEvent(QShowEvent *event) { diff --git a/selfdrive/ui/qt/offroad/onboarding.h b/selfdrive/ui/qt/offroad/onboarding.h index a1b6895ba0..db229c5fa6 100644 --- a/selfdrive/ui/qt/offroad/onboarding.h +++ b/selfdrive/ui/qt/offroad/onboarding.h @@ -65,9 +65,6 @@ class TermsPage : public QFrame { public: explicit TermsPage(QWidget *parent = 0) : QFrame(parent) {} -public slots: - void enableAccept(); - private: void showEvent(QShowEvent *event) override; From 08fea7fa2784e19986501e9b611ade7a7a75ef90 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Thu, 6 Mar 2025 13:20:56 -0800 Subject: [PATCH 62/78] Fix torque control layout --- tools/plotjuggler/layouts/max-torque-debug.xml | 2 +- tools/plotjuggler/layouts/torque-controller.xml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/plotjuggler/layouts/max-torque-debug.xml b/tools/plotjuggler/layouts/max-torque-debug.xml index 8cfd30599e..9a6693165e 100644 --- a/tools/plotjuggler/layouts/max-torque-debug.xml +++ b/tools/plotjuggler/layouts/max-torque-debug.xml @@ -24,7 +24,7 @@ - + diff --git a/tools/plotjuggler/layouts/torque-controller.xml b/tools/plotjuggler/layouts/torque-controller.xml index b4edfdcc18..5a0a7625e0 100644 --- a/tools/plotjuggler/layouts/torque-controller.xml +++ b/tools/plotjuggler/layouts/torque-controller.xml @@ -24,8 +24,8 @@ - - + + @@ -114,8 +114,8 @@ - - + + From c3a83ccc638d595820875107b07954081ee4eb72 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 6 Mar 2025 16:00:48 -0800 Subject: [PATCH 63/78] simplify release build --- release/build_release.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/release/build_release.sh b/release/build_release.sh index d09f762263..735ef5e043 100755 --- a/release/build_release.sh +++ b/release/build_release.sh @@ -92,14 +92,9 @@ git add -f . git commit --amend -m "openpilot v$VERSION" # Run tests -TEST_FILES="tools/" -cd $SOURCE_DIR -cp -pR -n --parents $TEST_FILES $BUILD_DIR/ cd $BUILD_DIR RELEASE=1 pytest -n0 -s selfdrive/test/test_onroad.py -#system/manager/test/test_manager.py -pytest selfdrive/car/tests/test_car_interfaces.py -rm -rf $TEST_FILES +#pytest selfdrive/car/tests/test_car_interfaces.py if [ ! -z "$RELEASE_BRANCH" ]; then echo "[-] pushing release T=$SECONDS" From ca7b4340c191a245c572ed708117b9779d769683 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 6 Mar 2025 16:57:37 -0800 Subject: [PATCH 64/78] camerad: make recovery reset threshold based on queue depth (#34803) Co-authored-by: Comma Device --- system/camerad/cameras/spectra.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/camerad/cameras/spectra.cc b/system/camerad/cameras/spectra.cc index c70c427766..713d5ba1cc 100644 --- a/system/camerad/cameras/spectra.cc +++ b/system/camerad/cameras/spectra.cc @@ -1360,7 +1360,7 @@ bool SpectraCamera::validateEvent(uint64_t request_id, uint64_t frame_id_raw) { // check if the request ID is even valid. this happens after queued // requests are cleared. unclear if it happens any other time. if (request_id == 0) { - if (invalid_request_count++ > 10) { + if (invalid_request_count++ > ife_buf_depth+2) { LOGE("camera %d reset after half second of invalid requests", cc.camera_num); clearAndRequeue(request_id_last + 1); invalid_request_count = 0; From ae3a715f516277d807bddc2439155be58288188e Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Thu, 6 Mar 2025 18:52:46 -0800 Subject: [PATCH 65/78] test_fw_query_on_routes: support no FW --- selfdrive/debug/test_fw_query_on_routes.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/selfdrive/debug/test_fw_query_on_routes.py b/selfdrive/debug/test_fw_query_on_routes.py index f23c285908..1216b7299f 100755 --- a/selfdrive/debug/test_fw_query_on_routes.py +++ b/selfdrive/debug/test_fw_query_on_routes.py @@ -65,8 +65,7 @@ if __name__ == "__main__": CP = msg.carParams car_fw = [fw for fw in CP.carFw if not fw.logging] if len(car_fw) == 0: - print("no fw") - break + print("WARNING: no fw") live_fingerprint = CP.carFingerprint live_fingerprint = MIGRATION.get(live_fingerprint, live_fingerprint) @@ -98,7 +97,7 @@ if __name__ == "__main__": print("New style (exact):", exact_matches) print("New style (fuzzy):", fuzzy_matches) - padding = max([len(fw.brand or UNKNOWN_BRAND) for fw in car_fw]) + padding = max([len(fw.brand or UNKNOWN_BRAND) for fw in car_fw] + [0]) for version in sorted(car_fw, key=lambda fw: fw.brand): subaddr = None if version.subAddress == 0 else hex(version.subAddress) print(f" Brand: {version.brand or UNKNOWN_BRAND:{padding}}, bus: {version.bus} - " + From 11618c617fc6f1ccc91f938e087382ba5a2e57c4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 6 Mar 2025 19:42:47 -0800 Subject: [PATCH 66/78] [bot] Update translations (#34804) Update translations Co-authored-by: Vehicle Researcher --- selfdrive/ui/translations/main_ar.ts | 16 ++++++++-------- selfdrive/ui/translations/main_de.ts | 16 ++++++++-------- selfdrive/ui/translations/main_es.ts | 16 ++++++++-------- selfdrive/ui/translations/main_fr.ts | 16 ++++++++-------- selfdrive/ui/translations/main_ja.ts | 16 ++++++++-------- selfdrive/ui/translations/main_ko.ts | 16 ++++++++-------- selfdrive/ui/translations/main_pt-BR.ts | 16 ++++++++-------- selfdrive/ui/translations/main_th.ts | 16 ++++++++-------- selfdrive/ui/translations/main_tr.ts | 16 ++++++++-------- selfdrive/ui/translations/main_zh-CHS.ts | 16 ++++++++-------- selfdrive/ui/translations/main_zh-CHT.ts | 16 ++++++++-------- 11 files changed, 88 insertions(+), 88 deletions(-) diff --git a/selfdrive/ui/translations/main_ar.ts b/selfdrive/ui/translations/main_ar.ts index 8c667e246c..6471159616 100644 --- a/selfdrive/ui/translations/main_ar.ts +++ b/selfdrive/ui/translations/main_ar.ts @@ -1003,22 +1003,22 @@ This may take up to a minute.
TermsPage - - Terms & Conditions - الشروط والأحكام - Decline رفض - - Scroll to accept - قم بالتمرير للقبول - Agree أوافق + + Welcome to openpilot + + + + You must accept the Terms and Conditions to use openpilot. Read the latest terms at <span style='color: #465BEA;'>https://comma.ai/terms</span> before continuing. + + TogglesPanel diff --git a/selfdrive/ui/translations/main_de.ts b/selfdrive/ui/translations/main_de.ts index e7160fc903..bdda0484d4 100644 --- a/selfdrive/ui/translations/main_de.ts +++ b/selfdrive/ui/translations/main_de.ts @@ -987,22 +987,22 @@ This may take up to a minute. TermsPage - - Terms & Conditions - Benutzungsbedingungen - Decline Ablehnen - - Scroll to accept - Scrolle herunter um zu akzeptieren - Agree Zustimmen + + Welcome to openpilot + + + + You must accept the Terms and Conditions to use openpilot. Read the latest terms at <span style='color: #465BEA;'>https://comma.ai/terms</span> before continuing. + + TogglesPanel diff --git a/selfdrive/ui/translations/main_es.ts b/selfdrive/ui/translations/main_es.ts index afbe7424be..8168e126e3 100644 --- a/selfdrive/ui/translations/main_es.ts +++ b/selfdrive/ui/translations/main_es.ts @@ -987,22 +987,22 @@ Esto puede tardar un minuto. TermsPage - - Terms & Conditions - Términos & Condiciones - Decline Rechazar - - Scroll to accept - Desliza para aceptar - Agree Aceptar + + Welcome to openpilot + + + + You must accept the Terms and Conditions to use openpilot. Read the latest terms at <span style='color: #465BEA;'>https://comma.ai/terms</span> before continuing. + + TogglesPanel diff --git a/selfdrive/ui/translations/main_fr.ts b/selfdrive/ui/translations/main_fr.ts index 8be7842ddf..3fe002e03d 100644 --- a/selfdrive/ui/translations/main_fr.ts +++ b/selfdrive/ui/translations/main_fr.ts @@ -987,22 +987,22 @@ Cela peut prendre jusqu'à une minute. TermsPage - - Terms & Conditions - Termes & Conditions - Decline Refuser - - Scroll to accept - Faire défiler pour accepter - Agree Accepter + + Welcome to openpilot + + + + You must accept the Terms and Conditions to use openpilot. Read the latest terms at <span style='color: #465BEA;'>https://comma.ai/terms</span> before continuing. + + TogglesPanel diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index d8c75ecf1c..d242875937 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -983,22 +983,22 @@ This may take up to a minute. TermsPage - - Terms & Conditions - 利用規約 - Decline 拒否 - - Scroll to accept - スクロールして同意 - Agree 同意 + + Welcome to openpilot + + + + You must accept the Terms and Conditions to use openpilot. Read the latest terms at <span style='color: #465BEA;'>https://comma.ai/terms</span> before continuing. + + TogglesPanel diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index 9a1da3c396..6c6c73da16 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -983,22 +983,22 @@ This may take up to a minute. TermsPage - - Terms & Conditions - 이용약관 - Decline 거절 - - Scroll to accept - 동의하려면 아래로 스크롤하세요 - Agree 동의 + + Welcome to openpilot + + + + You must accept the Terms and Conditions to use openpilot. Read the latest terms at <span style='color: #465BEA;'>https://comma.ai/terms</span> before continuing. + + TogglesPanel diff --git a/selfdrive/ui/translations/main_pt-BR.ts b/selfdrive/ui/translations/main_pt-BR.ts index 0b224fa940..16edf605ad 100644 --- a/selfdrive/ui/translations/main_pt-BR.ts +++ b/selfdrive/ui/translations/main_pt-BR.ts @@ -987,22 +987,22 @@ Isso pode levar até um minuto. TermsPage - - Terms & Conditions - Termos & Condições - Decline Declinar - - Scroll to accept - Role a tela para aceitar - Agree Concordo + + Welcome to openpilot + + + + You must accept the Terms and Conditions to use openpilot. Read the latest terms at <span style='color: #465BEA;'>https://comma.ai/terms</span> before continuing. + + TogglesPanel diff --git a/selfdrive/ui/translations/main_th.ts b/selfdrive/ui/translations/main_th.ts index 07c3892958..fc5e690ce0 100644 --- a/selfdrive/ui/translations/main_th.ts +++ b/selfdrive/ui/translations/main_th.ts @@ -983,22 +983,22 @@ This may take up to a minute. TermsPage - - Terms & Conditions - ข้อตกลงและเงื่อนไข - Decline ปฏิเสธ - - Scroll to accept - เลื่อนเพื่อตอบรับข้อตกลง - Agree ยอมรับ + + Welcome to openpilot + + + + You must accept the Terms and Conditions to use openpilot. Read the latest terms at <span style='color: #465BEA;'>https://comma.ai/terms</span> before continuing. + + TogglesPanel diff --git a/selfdrive/ui/translations/main_tr.ts b/selfdrive/ui/translations/main_tr.ts index dda3cdec22..8484f23160 100644 --- a/selfdrive/ui/translations/main_tr.ts +++ b/selfdrive/ui/translations/main_tr.ts @@ -981,22 +981,22 @@ This may take up to a minute. TermsPage - - Terms & Conditions - Şartlar ve Koşullar - Decline Reddet - - Scroll to accept - Kabul etmek için kaydırın - Agree Kabul et + + Welcome to openpilot + + + + You must accept the Terms and Conditions to use openpilot. Read the latest terms at <span style='color: #465BEA;'>https://comma.ai/terms</span> before continuing. + + TogglesPanel diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index 01ac85a8ce..69a2c0c594 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -983,22 +983,22 @@ This may take up to a minute. TermsPage - - Terms & Conditions - 条款和条件 - Decline 拒绝 - - Scroll to accept - 滑动以接受 - Agree 同意 + + Welcome to openpilot + + + + You must accept the Terms and Conditions to use openpilot. Read the latest terms at <span style='color: #465BEA;'>https://comma.ai/terms</span> before continuing. + + TogglesPanel diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index 02d3593e60..6d50bf92b8 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -983,22 +983,22 @@ This may take up to a minute. TermsPage - - Terms & Conditions - 條款和條件 - Decline 拒絕 - - Scroll to accept - 滑動至頁尾接受條款 - Agree 接受 + + Welcome to openpilot + + + + You must accept the Terms and Conditions to use openpilot. Read the latest terms at <span style='color: #465BEA;'>https://comma.ai/terms</span> before continuing. + + TogglesPanel From e61a4ac76e0adee12e2ca6c420151fed05d2196f Mon Sep 17 00:00:00 2001 From: commaci-public <60409688+commaci-public@users.noreply.github.com> Date: Thu, 6 Mar 2025 19:43:02 -0800 Subject: [PATCH 67/78] [bot] Update Python packages (#34805) Update Python packages Co-authored-by: Vehicle Researcher --- opendbc_repo | 2 +- uv.lock | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/opendbc_repo b/opendbc_repo index de65067d80..866beab8fa 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit de65067d800ed1744ee111ee202da54bcf987b43 +Subproject commit 866beab8faec5acd47bd042bc12183dccfa11c39 diff --git a/uv.lock b/uv.lock index fe3ee05e77..9fc1627ec6 100644 --- a/uv.lock +++ b/uv.lock @@ -12,11 +12,11 @@ resolution-markers = [ [[package]] name = "aiohappyeyeballs" -version = "2.4.8" +version = "2.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/de/7c/79a15272e88d2563c9d63599fa59f05778975f35b255bf8f90c8b12b4ada/aiohappyeyeballs-2.4.8.tar.gz", hash = "sha256:19728772cb12263077982d2f55453babd8bec6a052a926cd5c0c42796da8bf62", size = 22337 } +sdist = { url = "https://files.pythonhosted.org/packages/a2/0c/458958007041f4b4de2d307e6b75d9e7554dad0baf26fe7a48b741aac126/aiohappyeyeballs-2.5.0.tar.gz", hash = "sha256:18fde6204a76deeabc97c48bdd01d5801cfda5d6b9c8bbeb1aaaee9d648ca191", size = 22494 } wheels = [ - { url = "https://files.pythonhosted.org/packages/52/0e/b187e2bb3eeb2644515109657c4474d65a84e7123de249bf1e8467d04a65/aiohappyeyeballs-2.4.8-py3-none-any.whl", hash = "sha256:6cac4f5dd6e34a9644e69cf9021ef679e4394f54e58a183056d12009e42ea9e3", size = 15005 }, + { url = "https://files.pythonhosted.org/packages/1b/9a/e4886864ce06e1579bd428208127fbdc0d62049c751e4e9e3b509c0059dc/aiohappyeyeballs-2.5.0-py3-none-any.whl", hash = "sha256:0850b580748c7071db98bffff6d4c94028d0d3035acc20fd721a0ce7e8cac35d", size = 15128 }, ] [[package]] @@ -628,7 +628,7 @@ wheels = [ [[package]] name = "gymnasium" -version = "1.1.0" +version = "1.1.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cloudpickle" }, @@ -636,9 +636,9 @@ dependencies = [ { name = "numpy" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3c/74/db400493fbb86ff6b20ab46e798ac79a366a7db31ece785499e5e5bfd873/gymnasium-1.1.0.tar.gz", hash = "sha256:dedb5c8c83047d3927ef8b841fb4ebadaeaa43ab954e2e3aca7eadcf4226c5f2", size = 827655 } +sdist = { url = "https://files.pythonhosted.org/packages/90/69/70cd29e9fc4953d013b15981ee71d4c9ef4d8b2183e6ef2fe89756746dce/gymnasium-1.1.1.tar.gz", hash = "sha256:8bd9ea9bdef32c950a444ff36afc785e1d81051ec32d30435058953c20d2456d", size = 829326 } wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/2a/f931b9b7515c16e5285ecb0e6c2d773266a4f781332f24456e7c0d516c8d/gymnasium-1.1.0-py3-none-any.whl", hash = "sha256:8632bbb860512e565a46cd30fa8325ce8fbdac09b9c4f04171a772d6e95b232b", size = 965463 }, + { url = "https://files.pythonhosted.org/packages/f9/68/2bdc7b46b5f543dd865575f9d19716866bdb76e50dd33b71ed1a3dd8bb42/gymnasium-1.1.1-py3-none-any.whl", hash = "sha256:9c167ec0a2b388666e37f63b2849cd2552f7f5b71938574c637bb36487eb928a", size = 965410 }, ] [[package]] @@ -701,14 +701,14 @@ wheels = [ [[package]] name = "jinja2" -version = "3.1.5" +version = "3.1.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/af/92/b3130cbbf5591acf9ade8708c365f3238046ac7cb8ccba6e81abccb0ccff/jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb", size = 244674 } +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115 } wheels = [ - { url = "https://files.pythonhosted.org/packages/bd/0f/2ba5fbcd631e3e88689309dbe978c5769e883e4b84ebfe7da30b43275c5a/jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb", size = 134596 }, + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899 }, ] [[package]] @@ -4919,14 +4919,14 @@ wheels = [ [[package]] name = "types-requests" -version = "2.32.0.20250301" +version = "2.32.0.20250306" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/87/88/365d6b46f1088ddeccbc89c26190c3180088ef6e7c8d162fc619496aab96/types_requests-2.32.0.20250301.tar.gz", hash = "sha256:3d909dc4eaab159c0d964ebe8bfa326a7afb4578d8706408d417e17d61b0c500", size = 22977 } +sdist = { url = "https://files.pythonhosted.org/packages/09/1a/beaeff79ef9efd186566ba5f0d95b44ae21f6d31e9413bcfbef3489b6ae3/types_requests-2.32.0.20250306.tar.gz", hash = "sha256:0962352694ec5b2f95fda877ee60a159abdf84a0fc6fdace599f20acb41a03d1", size = 23012 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b9/c2/e44564e8995dbc1738c2acacb8009d59c8cb19327da95a1b5c5d9cb68364/types_requests-2.32.0.20250301-py3-none-any.whl", hash = "sha256:0003e0124e2cbefefb88222ff822b48616af40c74df83350f599a650c8de483b", size = 20671 }, + { url = "https://files.pythonhosted.org/packages/99/26/645d89f56004aa0ba3b96fec27793e3c7e62b40982ee069e52568922b6db/types_requests-2.32.0.20250306-py3-none-any.whl", hash = "sha256:25f2cbb5c8710b2022f8bbee7b2b66f319ef14aeea2f35d80f18c9dbf3b60a0b", size = 20673 }, ] [[package]] From 0789877cd3d6049632ea0d390b3df90c8fadfed8 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 7 Mar 2025 00:44:09 -0600 Subject: [PATCH 68/78] paramsd: fix unbounded yaw rate while calibrating (#34806) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * rm * comments * default values when yaw rate invalid * clean up Revert "default values when yaw rate invalid" This reverts commit e983abb3b009f15a57ebdfbadd4f616aba5b266e. do the same for yaw rate we do for roll and * 1 is fine * update refs --------- Co-authored-by: Kacper Rączy --- selfdrive/locationd/locationd.py | 2 +- selfdrive/locationd/paramsd.py | 29 ++++++++++++------------ selfdrive/test/process_replay/ref_commit | 2 +- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/selfdrive/locationd/locationd.py b/selfdrive/locationd/locationd.py index 0216b69767..80789b8886 100755 --- a/selfdrive/locationd/locationd.py +++ b/selfdrive/locationd/locationd.py @@ -147,13 +147,13 @@ class LocationEstimator: self.car_speed = abs(msg.vEgo) elif which == "liveCalibration": + # Note that we use this message during calibration if len(msg.rpyCalib) > 0: calib = np.array(msg.rpyCalib) if calib.min() < -CALIB_RPY_SANITY_CHECK or calib.max() > CALIB_RPY_SANITY_CHECK: return HandleLogResult.INPUT_INVALID self.device_from_calib = rot_from_euler(calib) - self.calibrated = msg.calStatus == log.LiveCalibrationData.Status.calibrated elif which == "cameraOdometry": if not self._validate_timestamp(t): diff --git a/selfdrive/locationd/paramsd.py b/selfdrive/locationd/paramsd.py index 24bf6619cf..258fc97e5a 100755 --- a/selfdrive/locationd/paramsd.py +++ b/selfdrive/locationd/paramsd.py @@ -46,18 +46,25 @@ class ParamsLearner: self.yaw_rate_std = 0.0 self.roll = 0.0 self.steering_angle = 0.0 - self.roll_valid = False def handle_log(self, t, which, msg): if which == 'livePose': device_pose = Pose.from_live_pose(msg) calibrated_pose = self.calibrator.build_calibrated_pose(device_pose) - self.yaw_rate, self.yaw_rate_std = calibrated_pose.angular_velocity.z, calibrated_pose.angular_velocity.z_std + + yaw_rate_valid = msg.angularVelocityDevice.valid and self.calibrator.calib_valid + yaw_rate_valid = yaw_rate_valid and 0 < self.yaw_rate_std < 10 # rad/s + yaw_rate_valid = yaw_rate_valid and abs(self.yaw_rate) < 1 # rad/s + if yaw_rate_valid: + self.yaw_rate, self.yaw_rate_std = calibrated_pose.angular_velocity.z, calibrated_pose.angular_velocity.z_std + else: + # This is done to bound the yaw rate estimate when localizer values are invalid or calibrating + self.yaw_rate, self.yaw_rate_std = 0.0, np.radians(1) localizer_roll, localizer_roll_std = device_pose.orientation.x, device_pose.orientation.x_std localizer_roll_std = np.radians(1) if np.isnan(localizer_roll_std) else localizer_roll_std - self.roll_valid = (localizer_roll_std < ROLL_STD_MAX) and (ROLL_MIN < localizer_roll < ROLL_MAX) and msg.sensorsOK - if self.roll_valid: + roll_valid = (localizer_roll_std < ROLL_STD_MAX) and (ROLL_MIN < localizer_roll < ROLL_MAX) and msg.sensorsOK + if roll_valid: roll = localizer_roll # Experimentally found multiplier of 2 to be best trade-off between stability and accuracy or similar? roll_std = 2 * localizer_roll_std @@ -67,18 +74,12 @@ class ParamsLearner: roll_std = np.radians(10.0) self.roll = np.clip(roll, self.roll - ROLL_MAX_DELTA, self.roll + ROLL_MAX_DELTA) - yaw_rate_valid = msg.angularVelocityDevice.valid and self.calibrator.calib_valid - yaw_rate_valid = yaw_rate_valid and 0 < self.yaw_rate_std < 10 # rad/s - yaw_rate_valid = yaw_rate_valid and abs(self.yaw_rate) < 1 # rad/s - if self.active: if msg.posenetOK: - - if yaw_rate_valid: - self.kf.predict_and_observe(t, - ObservationKind.ROAD_FRAME_YAW_RATE, - np.array([[-self.yaw_rate]]), - np.array([np.atleast_2d(self.yaw_rate_std**2)])) + self.kf.predict_and_observe(t, + ObservationKind.ROAD_FRAME_YAW_RATE, + np.array([[-self.yaw_rate]]), + np.array([np.atleast_2d(self.yaw_rate_std**2)])) self.kf.predict_and_observe(t, ObservationKind.ROAD_ROLL, diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 10c773c2c0..54df53fd91 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -87088a3540ddfc26356d9b71a3a4f40efcbc9b3b \ No newline at end of file +465979047295dad5da3a552db9227ed776a26a79 \ No newline at end of file From a0a9df2d5530aa8acdcb22258587c3281ad2a3de Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Sat, 8 Mar 2025 02:23:46 +0800 Subject: [PATCH 69/78] loggerd: enhance ZstdFileWriter test coverage with variable data sizes (#34812) enhance ZstdFileWriter test coverage --- system/loggerd/tests/test_zstd_writer.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/system/loggerd/tests/test_zstd_writer.cc b/system/loggerd/tests/test_zstd_writer.cc index f116bb2d5e..479e866a14 100644 --- a/system/loggerd/tests/test_zstd_writer.cc +++ b/system/loggerd/tests/test_zstd_writer.cc @@ -18,15 +18,21 @@ TEST_CASE("ZstdFileWriter writes and compresses data correctly in loops", "[Zstd // Step 1: Write compressed data to file in a loop { ZstdFileWriter writer(filename, LOG_COMPRESSION_LEVEL); + // Write various data sizes including edge cases + std::vector testSizes = {dataSize, 1, 0, dataSize * 2}; // Normal, minimal, empty, large for (int i = 0; i < iterations; ++i) { - std::string testData = util::random_string(dataSize); + size_t currentSize = testSizes[i % testSizes.size()]; + std::string testData = util::random_string(currentSize); totalTestData.append(testData); + writer.write((void *)testData.c_str(), testData.size()); } } // Step 2: Decompress the file and verify the data auto compressedContent = util::read_file(filename); + REQUIRE(compressedContent.size() > 0); + REQUIRE(compressedContent.size() < totalTestData.size()); std::string decompressedData = zstd_decompress(compressedContent); // Step 3: Verify that the decompressed data matches the original accumulated data From 3e629acf79eaf92e1ea688d7965e28aedbbfd312 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Sat, 8 Mar 2025 02:31:01 +0800 Subject: [PATCH 70/78] camerad: use ALL_CAMERA_CONFIGS array (#34810) use ALL_CAMERA_CONFIGS array --- system/camerad/cameras/camera_qcom2.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/camerad/cameras/camera_qcom2.cc b/system/camerad/cameras/camera_qcom2.cc index ec77941ad2..f050070d63 100644 --- a/system/camerad/cameras/camera_qcom2.cc +++ b/system/camerad/cameras/camera_qcom2.cc @@ -268,7 +268,7 @@ void camerad_thread() { // *** per-cam init *** std::vector> cams; - for (const auto &config : {WIDE_ROAD_CAMERA_CONFIG, ROAD_CAMERA_CONFIG, DRIVER_CAMERA_CONFIG}) { + for (const auto &config : ALL_CAMERA_CONFIGS) { auto cam = std::make_unique(&m, config); cam->init(&v, device_id, ctx); cams.emplace_back(std::move(cam)); From fa79b29cba971ba87de58986e2f69a814d12f318 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Sat, 8 Mar 2025 05:08:05 +0800 Subject: [PATCH 71/78] soundd: use with statement for wave.open to ensure proper resource cleanup (#34815) use with statement for wave.open to ensure proper resource cleanup --- selfdrive/ui/soundd.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/selfdrive/ui/soundd.py b/selfdrive/ui/soundd.py index 3cd6ae5820..8b5fc8bd04 100644 --- a/selfdrive/ui/soundd.py +++ b/selfdrive/ui/soundd.py @@ -69,14 +69,13 @@ class Soundd: for sound in sound_list: filename, play_count, volume = sound_list[sound] - wavefile = wave.open(BASEDIR + "/selfdrive/assets/sounds/" + filename, 'r') + with wave.open(BASEDIR + "/selfdrive/assets/sounds/" + filename, 'r') as wavefile: + assert wavefile.getnchannels() == 1 + assert wavefile.getsampwidth() == 2 + assert wavefile.getframerate() == SAMPLE_RATE - assert wavefile.getnchannels() == 1 - assert wavefile.getsampwidth() == 2 - assert wavefile.getframerate() == SAMPLE_RATE - - length = wavefile.getnframes() - self.loaded_sounds[sound] = np.frombuffer(wavefile.readframes(length), dtype=np.int16).astype(np.float32) / (2**16/2) + length = wavefile.getnframes() + self.loaded_sounds[sound] = np.frombuffer(wavefile.readframes(length), dtype=np.int16).astype(np.float32) / (2**16/2) def get_sound_data(self, frames): # get "frames" worth of data from the current alert sound, looping when required From 2d2efb3f58fb2f30a87f5da03997c3715e6def47 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Sat, 8 Mar 2025 06:20:49 +0800 Subject: [PATCH 72/78] pyui: implement styled label and text box (#34813) implement styled label --- system/ui/lib/application.py | 3 ++- system/ui/lib/button.py | 1 + system/ui/lib/label.py | 48 ++++++++++++++++++++++++++++++++++-- system/ui/reset.py | 12 ++++----- system/ui/text.py | 2 +- 5 files changed, 55 insertions(+), 11 deletions(-) diff --git a/system/ui/lib/application.py b/system/ui/lib/application.py index 22c6ed71f2..c7b7a36e5d 100644 --- a/system/ui/lib/application.py +++ b/system/ui/lib/application.py @@ -15,6 +15,7 @@ DEBUG_FPS = os.getenv("DEBUG_FPS") == '1' STRICT_MODE = os.getenv("STRICT_MODE") == '1' DEFAULT_TEXT_SIZE = 60 +DEFAULT_TEXT_COLOR = rl.Color(200, 200, 200, 255) FONT_DIR = os.path.join(BASEDIR, "selfdrive/assets/fonts") @@ -118,7 +119,7 @@ class GuiApplication: rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiControlProperty.BORDER_WIDTH, 0) rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.TEXT_SIZE, DEFAULT_TEXT_SIZE) rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.BACKGROUND_COLOR, rl.color_to_int(rl.BLACK)) - rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiControlProperty.TEXT_COLOR_NORMAL, rl.color_to_int(rl.Color(200, 200, 200, 255))) + rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiControlProperty.TEXT_COLOR_NORMAL, rl.color_to_int(DEFAULT_TEXT_COLOR)) rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.BACKGROUND_COLOR, rl.color_to_int(rl.Color(30, 30, 30, 255))) rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiControlProperty.BASE_COLOR_NORMAL, rl.color_to_int(rl.Color(50, 50, 50, 255))) diff --git a/system/ui/lib/button.py b/system/ui/lib/button.py index 9bcf3f7e01..034189275f 100644 --- a/system/ui/lib/button.py +++ b/system/ui/lib/button.py @@ -54,6 +54,7 @@ def gui_button( if button_style != ButtonStyle.TRANSPARENT: rl.draw_rectangle_rounded(rect, roundness, 20, bg_color) else: + rl.draw_rectangle_rounded(rect, roundness, 20, rl.BLACK) rl.draw_rectangle_rounded_lines_ex(rect, roundness, 20, 2, rl.WHITE) font = gui_app.font(font_weight) diff --git a/system/ui/lib/label.py b/system/ui/lib/label.py index 37b66582f9..ccfd89a2ec 100644 --- a/system/ui/lib/label.py +++ b/system/ui/lib/label.py @@ -1,11 +1,55 @@ import pyray as rl +from openpilot.system.ui.lib.application import gui_app, FontWeight, DEFAULT_TEXT_SIZE, DEFAULT_TEXT_COLOR from openpilot.system.ui.lib.utils import GuiStyleContext -def gui_label(rect, text, font_size): + +def gui_label( + rect: rl.Rectangle, + text: str, + font_size: int = DEFAULT_TEXT_SIZE, + color: rl.Color = DEFAULT_TEXT_COLOR, + font_weight: FontWeight = FontWeight.NORMAL, + alignment: int = rl.GuiTextAlignment.TEXT_ALIGN_LEFT, + alignment_vertical: int = rl.GuiTextAlignmentVertical.TEXT_ALIGN_MIDDLE +): + # Set font based on the provided weight + font = gui_app.font(font_weight) + + # Measure text size + text_size = rl.measure_text_ex(font, text, font_size, 0) + + # Calculate horizontal position based on alignment + text_x = rect.x + { + rl.GuiTextAlignment.TEXT_ALIGN_LEFT: 0, + rl.GuiTextAlignment.TEXT_ALIGN_CENTER: (rect.width - text_size.x) / 2, + rl.GuiTextAlignment.TEXT_ALIGN_RIGHT: rect.width - text_size.x, + }.get(alignment, 0) + + # Calculate vertical position based on alignment + text_y = rect.y + { + rl.GuiTextAlignmentVertical.TEXT_ALIGN_TOP: 0, + rl.GuiTextAlignmentVertical.TEXT_ALIGN_MIDDLE: (rect.height - text_size.y) / 2, + rl.GuiTextAlignmentVertical.TEXT_ALIGN_BOTTOM: rect.height - text_size.y, + }.get(alignment_vertical, 0) + + # Draw the text in the specified rectangle + rl.draw_text_ex(font, text, rl.Vector2(text_x, text_y), font_size, 0, color) + + +def gui_text_box( + rect: rl.Rectangle, + text: str, + font_size: int = DEFAULT_TEXT_SIZE, + color: rl.Color = DEFAULT_TEXT_COLOR, + alignment: int = rl.GuiTextAlignment.TEXT_ALIGN_LEFT, + alignment_vertical: int = rl.GuiTextAlignmentVertical.TEXT_ALIGN_TOP +): styles = [ + (rl.GuiControl.DEFAULT, rl.GuiControlProperty.TEXT_COLOR_NORMAL, rl.color_to_int(color)), (rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.TEXT_SIZE, font_size), (rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.TEXT_LINE_SPACING, font_size), - (rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.TEXT_ALIGNMENT_VERTICAL, rl.GuiTextAlignmentVertical.TEXT_ALIGN_TOP), + (rl.GuiControl.DEFAULT, rl.GuiControlProperty.TEXT_ALIGNMENT, alignment), + (rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.TEXT_ALIGNMENT_VERTICAL, alignment_vertical), (rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.TEXT_WRAP_MODE, rl.GuiTextWrapMode.TEXT_WRAP_WORD) ] diff --git a/system/ui/reset.py b/system/ui/reset.py index a5a8a84b04..80a1c10ea8 100755 --- a/system/ui/reset.py +++ b/system/ui/reset.py @@ -7,7 +7,7 @@ from enum import IntEnum from openpilot.system.ui.lib.application import gui_app, FontWeight from openpilot.system.ui.lib.button import gui_button, ButtonStyle -from openpilot.system.ui.lib.label import gui_label +from openpilot.system.ui.lib.label import gui_label, gui_text_box NVME = "/dev/nvme0n1" USERDATA = "/dev/disk/by-partlabel/userdata" @@ -51,13 +51,11 @@ class Reset: threading.Timer(0.1, self.do_reset).start() def render(self, rect: rl.Rectangle): - rl.gui_set_font(gui_app.font(FontWeight.BOLD)) - label_rect = rl.Rectangle(rect.x + 140, rect.y, rect.width - 280, rect.height) - gui_label(label_rect, "System Reset", 90) - rl.gui_set_font(gui_app.font(FontWeight.NORMAL)) + label_rect = rl.Rectangle(rect.x + 140, rect.y, rect.width - 280, 100) + gui_label(label_rect, "System Reset", 100, font_weight=FontWeight.BOLD) - label_rect.y += 150 - gui_label(label_rect, self.get_body_text(), 80) + text_rect = rl.Rectangle(rect.x + 140, rect.y + 140, rect.width - 280, rect.height - 90 - 100) + gui_text_box(text_rect, self.get_body_text(), 90) button_height = 160 button_spacing = 50 diff --git a/system/ui/text.py b/system/ui/text.py index 77a0d267e4..33299605d6 100755 --- a/system/ui/text.py +++ b/system/ui/text.py @@ -39,7 +39,7 @@ def main(): text_content = sys.argv[1] if len(sys.argv) > 1 else DEMO_TEXT - textarea_rect = rl.Rectangle(MARGIN, MARGIN, gui_app.width - MARGIN * 2, gui_app.height - MARGIN * 2 - BUTTON_SIZE.y - SPACING) + textarea_rect = rl.Rectangle(MARGIN, MARGIN, gui_app.width - MARGIN * 2, gui_app.height - MARGIN * 2) wrapped_lines = wrap_text(text_content, FONT_SIZE, textarea_rect.width - 20) content_rect = rl.Rectangle(0, 0, textarea_rect.width - 20, len(wrapped_lines) * LINE_HEIGHT) scroll_panel = GuiScrollPanel(show_vertical_scroll_bar=True) From d807b5c476658dba7760d30949baa619074c4a4e Mon Sep 17 00:00:00 2001 From: ZwX1616 Date: Fri, 7 Mar 2025 14:24:22 -0800 Subject: [PATCH 73/78] Filet o Fish model (#34798) * 690b01c3 seems ok * correct temporal * push * inplace * bs * what thw * is this wrong * frames are skipped * new models * simplify decimation * clean up * clean up modelframe * need attr * lint * 0 * use all samples * this should break - Revert "use all samples" This reverts commit 6c0d7943ac5fbb7ae60af1a1201e2423e4c3c105. * add lc probs * Revert "this should break - Revert "use all samples"" This reverts commit ca38c54333555266a0d2c885c28af28941841431. * Reapply "this should break - Revert "use all samples"" This reverts commit a3f0246f209f85f06b9090d9492bfba32ed8cfed. * Revert "Reapply "this should break - Revert "use all samples""" This reverts commit 7fd3d2a191b688e5ef7b4dcc8f5379e900af10f8. * new fish * e07ce1de-bdea-463e-b5bc-a38ce8d43f4f/700 --------- Co-authored-by: Comma Device --- selfdrive/modeld/constants.py | 8 +++++- selfdrive/modeld/modeld.py | 31 ++++++++++++++------- selfdrive/modeld/models/commonmodel.cc | 9 +++--- selfdrive/modeld/models/commonmodel.h | 5 ++-- selfdrive/modeld/models/commonmodel.pxd | 2 +- selfdrive/modeld/models/commonmodel_pyx.pyx | 4 +-- selfdrive/modeld/models/driving_policy.onnx | 4 +-- selfdrive/modeld/models/driving_vision.onnx | 2 +- 8 files changed, 42 insertions(+), 23 deletions(-) diff --git a/selfdrive/modeld/constants.py b/selfdrive/modeld/constants.py index 2bb7b8100c..5ca0a86bc8 100644 --- a/selfdrive/modeld/constants.py +++ b/selfdrive/modeld/constants.py @@ -14,8 +14,14 @@ class ModelConstants: # model inputs constants MODEL_FREQ = 20 + HISTORY_FREQ = 5 + HISTORY_LEN_SECONDS = 5 + TEMPORAL_SKIP = MODEL_FREQ // HISTORY_FREQ + FULL_HISTORY_BUFFER_LEN = MODEL_FREQ * HISTORY_LEN_SECONDS + INPUT_HISTORY_BUFFER_LEN = HISTORY_FREQ * HISTORY_LEN_SECONDS + FEATURE_LEN = 512 - FULL_HISTORY_BUFFER_LEN = 100 + DESIRE_LEN = 8 TRAFFIC_CONVENTION_LEN = 2 LAT_PLANNER_STATE_LEN = 4 diff --git a/selfdrive/modeld/modeld.py b/selfdrive/modeld/modeld.py index ee825d158f..1e557942fe 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -56,16 +56,24 @@ class ModelState: prev_desire: np.ndarray # for tracking the rising edge of the pulse def __init__(self, context: CLContext): - self.frames = {'input_imgs': DrivingModelFrame(context), 'big_input_imgs': DrivingModelFrame(context)} + self.frames = { + 'input_imgs': DrivingModelFrame(context, ModelConstants.TEMPORAL_SKIP), + 'big_input_imgs': DrivingModelFrame(context, ModelConstants.TEMPORAL_SKIP) + } self.prev_desire = np.zeros(ModelConstants.DESIRE_LEN, dtype=np.float32) + self.full_features_buffer = np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.FEATURE_LEN), dtype=np.float32) + self.full_desire = np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.DESIRE_LEN), dtype=np.float32) + self.full_prev_desired_curv = np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.PREV_DESIRED_CURV_LEN), dtype=np.float32) + self.temporal_idxs = slice(-1-(ModelConstants.TEMPORAL_SKIP*(ModelConstants.INPUT_HISTORY_BUFFER_LEN-1)), None, ModelConstants.TEMPORAL_SKIP) + # policy inputs self.numpy_inputs = { - 'desire': np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.DESIRE_LEN), dtype=np.float32), + 'desire': np.zeros((1, ModelConstants.INPUT_HISTORY_BUFFER_LEN, ModelConstants.DESIRE_LEN), dtype=np.float32), 'traffic_convention': np.zeros((1, ModelConstants.TRAFFIC_CONVENTION_LEN), dtype=np.float32), 'lateral_control_params': np.zeros((1, ModelConstants.LATERAL_CONTROL_PARAMS_LEN), dtype=np.float32), - 'prev_desired_curv': np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.PREV_DESIRED_CURV_LEN), dtype=np.float32), - 'features_buffer': np.zeros((1, ModelConstants.FULL_HISTORY_BUFFER_LEN, ModelConstants.FEATURE_LEN), dtype=np.float32), + 'prev_desired_curv': np.zeros((1, ModelConstants.INPUT_HISTORY_BUFFER_LEN, ModelConstants.PREV_DESIRED_CURV_LEN), dtype=np.float32), + 'features_buffer': np.zeros((1, ModelConstants.INPUT_HISTORY_BUFFER_LEN, ModelConstants.FEATURE_LEN), dtype=np.float32), } with open(VISION_METADATA_PATH, 'rb') as f: @@ -104,8 +112,9 @@ class ModelState: new_desire = np.where(inputs['desire'] - self.prev_desire > .99, inputs['desire'], 0) self.prev_desire[:] = inputs['desire'] - self.numpy_inputs['desire'][0,:-1] = self.numpy_inputs['desire'][0,1:] - self.numpy_inputs['desire'][0,-1] = new_desire + self.full_desire[0,:-1] = self.full_desire[0,1:] + self.full_desire[0,-1] = new_desire + self.numpy_inputs['desire'][:] = self.full_desire.reshape((1,ModelConstants.INPUT_HISTORY_BUFFER_LEN,ModelConstants.TEMPORAL_SKIP,-1)).max(axis=2) self.numpy_inputs['traffic_convention'][:] = inputs['traffic_convention'] self.numpy_inputs['lateral_control_params'][:] = inputs['lateral_control_params'] @@ -128,15 +137,17 @@ class ModelState: self.vision_output = self.vision_run(**self.vision_inputs).numpy().flatten() vision_outputs_dict = self.parser.parse_vision_outputs(self.slice_outputs(self.vision_output, self.vision_output_slices)) - self.numpy_inputs['features_buffer'][0,:-1] = self.numpy_inputs['features_buffer'][0,1:] - self.numpy_inputs['features_buffer'][0,-1] = vision_outputs_dict['hidden_state'][0, :] + self.full_features_buffer[0,:-1] = self.full_features_buffer[0,1:] + self.full_features_buffer[0,-1] = vision_outputs_dict['hidden_state'][0, :] + self.numpy_inputs['features_buffer'][:] = self.full_features_buffer[0, self.temporal_idxs] self.policy_output = self.policy_run(**self.policy_inputs).numpy().flatten() policy_outputs_dict = self.parser.parse_policy_outputs(self.slice_outputs(self.policy_output, self.policy_output_slices)) # TODO model only uses last value now - self.numpy_inputs['prev_desired_curv'][0,:-1] = self.numpy_inputs['prev_desired_curv'][0,1:] - self.numpy_inputs['prev_desired_curv'][0,-1,:] = policy_outputs_dict['desired_curvature'][0, :] + self.full_prev_desired_curv[0,:-1] = self.full_prev_desired_curv[0,1:] + self.full_prev_desired_curv[0,-1,:] = policy_outputs_dict['desired_curvature'][0, :] + self.numpy_inputs['prev_desired_curv'][:] = self.full_prev_desired_curv[0, self.temporal_idxs] combined_outputs_dict = {**vision_outputs_dict, **policy_outputs_dict} if SEND_RAW_PRED: diff --git a/selfdrive/modeld/models/commonmodel.cc b/selfdrive/modeld/models/commonmodel.cc index 9973d18588..99155d9f1e 100644 --- a/selfdrive/modeld/models/commonmodel.cc +++ b/selfdrive/modeld/models/commonmodel.cc @@ -5,11 +5,12 @@ #include "common/clutil.h" -DrivingModelFrame::DrivingModelFrame(cl_device_id device_id, cl_context context) : ModelFrame(device_id, context) { +DrivingModelFrame::DrivingModelFrame(cl_device_id device_id, cl_context context, int _temporal_skip) : ModelFrame(device_id, context) { input_frames = std::make_unique(buf_size); + temporal_skip = _temporal_skip; input_frames_cl = CL_CHECK_ERR(clCreateBuffer(context, CL_MEM_READ_WRITE, buf_size, NULL, &err)); - img_buffer_20hz_cl = CL_CHECK_ERR(clCreateBuffer(context, CL_MEM_READ_WRITE, 2*frame_size_bytes, NULL, &err)); - region.origin = 1 * frame_size_bytes; + img_buffer_20hz_cl = CL_CHECK_ERR(clCreateBuffer(context, CL_MEM_READ_WRITE, (temporal_skip+1)*frame_size_bytes, NULL, &err)); + region.origin = temporal_skip * frame_size_bytes; region.size = frame_size_bytes; last_img_cl = CL_CHECK_ERR(clCreateSubBuffer(img_buffer_20hz_cl, CL_MEM_READ_WRITE, CL_BUFFER_CREATE_TYPE_REGION, ®ion, &err)); @@ -20,7 +21,7 @@ DrivingModelFrame::DrivingModelFrame(cl_device_id device_id, cl_context context) cl_mem* DrivingModelFrame::prepare(cl_mem yuv_cl, int frame_width, int frame_height, int frame_stride, int frame_uv_offset, const mat3& projection) { run_transform(yuv_cl, MODEL_WIDTH, MODEL_HEIGHT, frame_width, frame_height, frame_stride, frame_uv_offset, projection); - for (int i = 0; i < 1; i++) { + for (int i = 0; i < temporal_skip; i++) { CL_CHECK(clEnqueueCopyBuffer(q, img_buffer_20hz_cl, img_buffer_20hz_cl, (i+1)*frame_size_bytes, i*frame_size_bytes, frame_size_bytes, 0, nullptr, nullptr)); } loadyuv_queue(&loadyuv, q, y_cl, u_cl, v_cl, last_img_cl); diff --git a/selfdrive/modeld/models/commonmodel.h b/selfdrive/modeld/models/commonmodel.h index 14409943e4..176d7eb6dc 100644 --- a/selfdrive/modeld/models/commonmodel.h +++ b/selfdrive/modeld/models/commonmodel.h @@ -64,20 +64,21 @@ protected: class DrivingModelFrame : public ModelFrame { public: - DrivingModelFrame(cl_device_id device_id, cl_context context); + DrivingModelFrame(cl_device_id device_id, cl_context context, int _temporal_skip); ~DrivingModelFrame(); cl_mem* prepare(cl_mem yuv_cl, int frame_width, int frame_height, int frame_stride, int frame_uv_offset, const mat3& projection); const int MODEL_WIDTH = 512; const int MODEL_HEIGHT = 256; const int MODEL_FRAME_SIZE = MODEL_WIDTH * MODEL_HEIGHT * 3 / 2; - const int buf_size = MODEL_FRAME_SIZE * 2; + const int buf_size = MODEL_FRAME_SIZE * 2; // 2 frames are temporal_skip frames apart const size_t frame_size_bytes = MODEL_FRAME_SIZE * sizeof(uint8_t); private: LoadYUVState loadyuv; cl_mem img_buffer_20hz_cl, last_img_cl, input_frames_cl; cl_buffer_region region; + int temporal_skip; }; class MonitoringModelFrame : public ModelFrame { diff --git a/selfdrive/modeld/models/commonmodel.pxd b/selfdrive/modeld/models/commonmodel.pxd index b4f08b12aa..4ac64d9172 100644 --- a/selfdrive/modeld/models/commonmodel.pxd +++ b/selfdrive/modeld/models/commonmodel.pxd @@ -20,7 +20,7 @@ cdef extern from "selfdrive/modeld/models/commonmodel.h": cppclass DrivingModelFrame: int buf_size - DrivingModelFrame(cl_device_id, cl_context) + DrivingModelFrame(cl_device_id, cl_context, int) cppclass MonitoringModelFrame: int buf_size diff --git a/selfdrive/modeld/models/commonmodel_pyx.pyx b/selfdrive/modeld/models/commonmodel_pyx.pyx index 7b3a5bb342..5b7d11bc71 100644 --- a/selfdrive/modeld/models/commonmodel_pyx.pyx +++ b/selfdrive/modeld/models/commonmodel_pyx.pyx @@ -59,8 +59,8 @@ cdef class ModelFrame: cdef class DrivingModelFrame(ModelFrame): cdef cppDrivingModelFrame * _frame - def __cinit__(self, CLContext context): - self._frame = new cppDrivingModelFrame(context.device_id, context.context) + def __cinit__(self, CLContext context, int temporal_skip): + self._frame = new cppDrivingModelFrame(context.device_id, context.context, temporal_skip) self.frame = (self._frame) self.buf_size = self._frame.buf_size diff --git a/selfdrive/modeld/models/driving_policy.onnx b/selfdrive/modeld/models/driving_policy.onnx index f804b4ec31..3601bbb5da 100644 --- a/selfdrive/modeld/models/driving_policy.onnx +++ b/selfdrive/modeld/models/driving_policy.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5cae3285c876804e649b14adadcfb8be79a9bd5a1b928113e37f1f08e25e9688 -size 16581121 +oid sha256:98f0121ccb6f850077b04cc91bd33d370fc6cbdc2bd35f1ab55628a15a813f36 +size 15966721 diff --git a/selfdrive/modeld/models/driving_vision.onnx b/selfdrive/modeld/models/driving_vision.onnx index 06c87d8755..aee6d8f1bf 100644 --- a/selfdrive/modeld/models/driving_vision.onnx +++ b/selfdrive/modeld/models/driving_vision.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:29bbf79f9dfd7048c0013bb81e86d9b2979275b95ea1ed8a86d1a86a88695240 +oid sha256:897f80d0388250f99bba69b6a8434560cc0fd83157cbeb0bc134c67fe4e64624 size 34882971 From d469ce669bf18d67924235056aa3a4686bde0fbe Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 7 Mar 2025 16:58:18 -0800 Subject: [PATCH 74/78] test_models: missing skip dashcam for panda safety found when using release safety FW --- selfdrive/car/tests/test_models.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py index 291a46888e..7f0cf4a979 100644 --- a/selfdrive/car/tests/test_models.py +++ b/selfdrive/car/tests/test_models.py @@ -266,6 +266,9 @@ class TestCarModelBase(unittest.TestCase): def test_panda_safety_tx_cases(self, data=None): """Asserts we can tx common messages""" + if self.CP.dashcamOnly: + self.skipTest("no need to check panda safety for dashcamOnly") + if self.CP.notCar: self.skipTest("Skipping test for notCar") From 7090c1be5988a73383496a0ebad39ea56a9bb18e Mon Sep 17 00:00:00 2001 From: commaci-public <60409688+commaci-public@users.noreply.github.com> Date: Fri, 7 Mar 2025 17:25:07 -0800 Subject: [PATCH 75/78] [bot] Update Python packages (#34818) Update Python packages Co-authored-by: Vehicle Researcher --- opendbc_repo | 2 +- uv.lock | 38 +++++++++++++++++++------------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/opendbc_repo b/opendbc_repo index 866beab8fa..3a5b13ed55 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit 866beab8faec5acd47bd042bc12183dccfa11c39 +Subproject commit 3a5b13ed55fa02f7637e5ab0e67211e40f86bc21 diff --git a/uv.lock b/uv.lock index 9fc1627ec6..8da47bf004 100644 --- a/uv.lock +++ b/uv.lock @@ -4678,27 +4678,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.9.9" +version = "0.9.10" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6f/c3/418441a8170e8d53d05c0b9dad69760dbc7b8a12c10dbe6db1e1205d2377/ruff-0.9.9.tar.gz", hash = "sha256:0062ed13f22173e85f8f7056f9a24016e692efeea8704d1a5e8011b8aa850933", size = 3717448 } +sdist = { url = "https://files.pythonhosted.org/packages/20/8e/fafaa6f15c332e73425d9c44ada85360501045d5ab0b81400076aff27cf6/ruff-0.9.10.tar.gz", hash = "sha256:9bacb735d7bada9cfb0f2c227d3658fc443d90a727b47f206fb33f52f3c0eac7", size = 3759776 } wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/c3/2c4afa9ba467555d074b146d9aed0633a56ccdb900839fb008295d037b89/ruff-0.9.9-py3-none-linux_armv6l.whl", hash = "sha256:628abb5ea10345e53dff55b167595a159d3e174d6720bf19761f5e467e68d367", size = 10027252 }, - { url = "https://files.pythonhosted.org/packages/33/d1/439e58487cf9eac26378332e25e7d5ade4b800ce1eec7dc2cfc9b0d7ca96/ruff-0.9.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b6cd1428e834b35d7493354723543b28cc11dc14d1ce19b685f6e68e07c05ec7", size = 10840721 }, - { url = "https://files.pythonhosted.org/packages/50/44/fead822c38281ba0122f1b76b460488a175a9bd48b130650a6fb6dbcbcf9/ruff-0.9.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5ee162652869120ad260670706f3cd36cd3f32b0c651f02b6da142652c54941d", size = 10161439 }, - { url = "https://files.pythonhosted.org/packages/11/ae/d404a2ab8e61ddf6342e09cc6b7f7846cce6b243e45c2007dbe0ca928a5d/ruff-0.9.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3aa0f6b75082c9be1ec5a1db78c6d4b02e2375c3068438241dc19c7c306cc61a", size = 10336264 }, - { url = "https://files.pythonhosted.org/packages/6a/4e/7c268aa7d84cd709fb6f046b8972313142cffb40dfff1d2515c5e6288d54/ruff-0.9.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:584cc66e89fb5f80f84b05133dd677a17cdd86901d6479712c96597a3f28e7fe", size = 9908774 }, - { url = "https://files.pythonhosted.org/packages/cc/26/c618a878367ef1b76270fd027ca93692657d3f6122b84ba48911ef5f2edc/ruff-0.9.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abf3369325761a35aba75cd5c55ba1b5eb17d772f12ab168fbfac54be85cf18c", size = 11428127 }, - { url = "https://files.pythonhosted.org/packages/d7/9a/c5588a93d9bfed29f565baf193fe802fa676a0c837938137ea6cf0576d8c/ruff-0.9.9-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3403a53a32a90ce929aa2f758542aca9234befa133e29f4933dcef28a24317be", size = 12133187 }, - { url = "https://files.pythonhosted.org/packages/3e/ff/e7980a7704a60905ed7e156a8d73f604c846d9bd87deda9cabfa6cba073a/ruff-0.9.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:18454e7fa4e4d72cffe28a37cf6a73cb2594f81ec9f4eca31a0aaa9ccdfb1590", size = 11602937 }, - { url = "https://files.pythonhosted.org/packages/24/78/3690444ad9e3cab5c11abe56554c35f005b51d1d118b429765249095269f/ruff-0.9.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fadfe2c88724c9617339f62319ed40dcdadadf2888d5afb88bf3adee7b35bfb", size = 13771698 }, - { url = "https://files.pythonhosted.org/packages/6e/bf/e477c2faf86abe3988e0b5fd22a7f3520e820b2ee335131aca2e16120038/ruff-0.9.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6df104d08c442a1aabcfd254279b8cc1e2cbf41a605aa3e26610ba1ec4acf0b0", size = 11249026 }, - { url = "https://files.pythonhosted.org/packages/f7/82/cdaffd59e5a8cb5b14c408c73d7a555a577cf6645faaf83e52fe99521715/ruff-0.9.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:d7c62939daf5b2a15af48abbd23bea1efdd38c312d6e7c4cedf5a24e03207e17", size = 10220432 }, - { url = "https://files.pythonhosted.org/packages/fe/a4/2507d0026225efa5d4412b6e294dfe54725a78652a5c7e29e6bd0fc492f3/ruff-0.9.9-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:9494ba82a37a4b81b6a798076e4a3251c13243fc37967e998efe4cce58c8a8d1", size = 9874602 }, - { url = "https://files.pythonhosted.org/packages/d5/be/f3aab1813846b476c4bcffe052d232244979c3cd99d751c17afb530ca8e4/ruff-0.9.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:4efd7a96ed6d36ef011ae798bf794c5501a514be369296c672dab7921087fa57", size = 10851212 }, - { url = "https://files.pythonhosted.org/packages/8b/45/8e5fd559bea0d2f57c4e12bf197a2fade2fac465aa518284f157dfbca92b/ruff-0.9.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:ab90a7944c5a1296f3ecb08d1cbf8c2da34c7e68114b1271a431a3ad30cb660e", size = 11327490 }, - { url = "https://files.pythonhosted.org/packages/42/55/e6c90f13880aeef327746052907e7e930681f26a164fe130ddac28b08269/ruff-0.9.9-py3-none-win32.whl", hash = "sha256:6b4c376d929c25ecd6d87e182a230fa4377b8e5125a4ff52d506ee8c087153c1", size = 10227912 }, - { url = "https://files.pythonhosted.org/packages/35/b2/da925693cb82a1208aa34966c0f36cb222baca94e729dd22a587bc22d0f3/ruff-0.9.9-py3-none-win_amd64.whl", hash = "sha256:837982ea24091d4c1700ddb2f63b7070e5baec508e43b01de013dc7eff974ff1", size = 11355632 }, - { url = "https://files.pythonhosted.org/packages/31/d8/de873d1c1b020d668d8ec9855d390764cb90cf8f6486c0983da52be8b7b7/ruff-0.9.9-py3-none-win_arm64.whl", hash = "sha256:3ac78f127517209fe6d96ab00f3ba97cafe38718b23b1db3e96d8b2d39e37ddf", size = 10435860 }, + { url = "https://files.pythonhosted.org/packages/73/b2/af7c2cc9e438cbc19fafeec4f20bfcd72165460fe75b2b6e9a0958c8c62b/ruff-0.9.10-py3-none-linux_armv6l.whl", hash = "sha256:eb4d25532cfd9fe461acc83498361ec2e2252795b4f40b17e80692814329e42d", size = 10049494 }, + { url = "https://files.pythonhosted.org/packages/6d/12/03f6dfa1b95ddd47e6969f0225d60d9d7437c91938a310835feb27927ca0/ruff-0.9.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:188a6638dab1aa9bb6228a7302387b2c9954e455fb25d6b4470cb0641d16759d", size = 10853584 }, + { url = "https://files.pythonhosted.org/packages/02/49/1c79e0906b6ff551fb0894168763f705bf980864739572b2815ecd3c9df0/ruff-0.9.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5284dcac6b9dbc2fcb71fdfc26a217b2ca4ede6ccd57476f52a587451ebe450d", size = 10155692 }, + { url = "https://files.pythonhosted.org/packages/5b/01/85e8082e41585e0e1ceb11e41c054e9e36fed45f4b210991052d8a75089f/ruff-0.9.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47678f39fa2a3da62724851107f438c8229a3470f533894b5568a39b40029c0c", size = 10369760 }, + { url = "https://files.pythonhosted.org/packages/a1/90/0bc60bd4e5db051f12445046d0c85cc2c617095c0904f1aa81067dc64aea/ruff-0.9.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:99713a6e2766b7a17147b309e8c915b32b07a25c9efd12ada79f217c9c778b3e", size = 9912196 }, + { url = "https://files.pythonhosted.org/packages/66/ea/0b7e8c42b1ec608033c4d5a02939c82097ddcb0b3e393e4238584b7054ab/ruff-0.9.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:524ee184d92f7c7304aa568e2db20f50c32d1d0caa235d8ddf10497566ea1a12", size = 11434985 }, + { url = "https://files.pythonhosted.org/packages/d5/86/3171d1eff893db4f91755175a6e1163c5887be1f1e2f4f6c0c59527c2bfd/ruff-0.9.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:df92aeac30af821f9acf819fc01b4afc3dfb829d2782884f8739fb52a8119a16", size = 12155842 }, + { url = "https://files.pythonhosted.org/packages/89/9e/700ca289f172a38eb0bca752056d0a42637fa17b81649b9331786cb791d7/ruff-0.9.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de42e4edc296f520bb84954eb992a07a0ec5a02fecb834498415908469854a52", size = 11613804 }, + { url = "https://files.pythonhosted.org/packages/f2/92/648020b3b5db180f41a931a68b1c8575cca3e63cec86fd26807422a0dbad/ruff-0.9.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d257f95b65806104b6b1ffca0ea53f4ef98454036df65b1eda3693534813ecd1", size = 13823776 }, + { url = "https://files.pythonhosted.org/packages/5e/a6/cc472161cd04d30a09d5c90698696b70c169eeba2c41030344194242db45/ruff-0.9.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b60dec7201c0b10d6d11be00e8f2dbb6f40ef1828ee75ed739923799513db24c", size = 11302673 }, + { url = "https://files.pythonhosted.org/packages/6c/db/d31c361c4025b1b9102b4d032c70a69adb9ee6fde093f6c3bf29f831c85c/ruff-0.9.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:d838b60007da7a39c046fcdd317293d10b845001f38bcb55ba766c3875b01e43", size = 10235358 }, + { url = "https://files.pythonhosted.org/packages/d1/86/d6374e24a14d4d93ebe120f45edd82ad7dcf3ef999ffc92b197d81cdc2a5/ruff-0.9.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:ccaf903108b899beb8e09a63ffae5869057ab649c1e9231c05ae354ebc62066c", size = 9886177 }, + { url = "https://files.pythonhosted.org/packages/00/62/a61691f6eaaac1e945a1f3f59f1eea9a218513139d5b6c2b8f88b43b5b8f/ruff-0.9.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f9567d135265d46e59d62dc60c0bfad10e9a6822e231f5b24032dba5a55be6b5", size = 10864747 }, + { url = "https://files.pythonhosted.org/packages/ee/94/2c7065e1d92a8a8a46d46d9c3cf07b0aa7e0a1e0153d74baa5e6620b4102/ruff-0.9.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5f202f0d93738c28a89f8ed9eaba01b7be339e5d8d642c994347eaa81c6d75b8", size = 11360441 }, + { url = "https://files.pythonhosted.org/packages/a7/8f/1f545ea6f9fcd7bf4368551fb91d2064d8f0577b3079bb3f0ae5779fb773/ruff-0.9.10-py3-none-win32.whl", hash = "sha256:bfb834e87c916521ce46b1788fbb8484966e5113c02df216680102e9eb960029", size = 10247401 }, + { url = "https://files.pythonhosted.org/packages/4f/18/fb703603ab108e5c165f52f5b86ee2aa9be43bb781703ec87c66a5f5d604/ruff-0.9.10-py3-none-win_amd64.whl", hash = "sha256:f2160eeef3031bf4b17df74e307d4c5fb689a6f3a26a2de3f7ef4044e3c484f1", size = 11366360 }, + { url = "https://files.pythonhosted.org/packages/35/85/338e603dc68e7d9994d5d84f24adbf69bae760ba5efd3e20f5ff2cec18da/ruff-0.9.10-py3-none-win_arm64.whl", hash = "sha256:5fd804c0327a5e5ea26615550e706942f348b197d5475ff34c19733aee4b2e69", size = 10436892 }, ] [[package]] From 878ca53d78e9ee787ae9c0a58d43a9f0e4e39ff6 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 7 Mar 2025 19:01:11 -0800 Subject: [PATCH 76/78] hw: remove unused function --- system/hardware/base.h | 2 -- system/hardware/pc/hardware.h | 8 -------- system/hardware/tici/hardware.h | 7 ------- 3 files changed, 17 deletions(-) diff --git a/system/hardware/base.h b/system/hardware/base.h index 732f0f99e0..baf0f3c3da 100644 --- a/system/hardware/base.h +++ b/system/hardware/base.h @@ -34,8 +34,6 @@ public: static bool get_ssh_enabled() { return false; } static void set_ssh_enabled(bool enabled) {} - static void config_cpu_rendering(bool offscreen); - static bool PC() { return false; } static bool TICI() { return false; } static bool AGNOS() { return false; } diff --git a/system/hardware/pc/hardware.h b/system/hardware/pc/hardware.h index 5dea184ca6..978dd771c8 100644 --- a/system/hardware/pc/hardware.h +++ b/system/hardware/pc/hardware.h @@ -12,12 +12,4 @@ public: static bool PC() { return true; } static bool TICI() { return util::getenv("TICI", 0) == 1; } static bool AGNOS() { return util::getenv("TICI", 0) == 1; } - - static void config_cpu_rendering(bool offscreen) { - if (offscreen) { - setenv("QT_QPA_PLATFORM", "offscreen", 1); - } - setenv("__GLX_VENDOR_LIBRARY_NAME", "mesa", 1); - setenv("LP_NUM_THREADS", "0", 1); // disable threading so we stay on our assigned CPU - } }; diff --git a/system/hardware/tici/hardware.h b/system/hardware/tici/hardware.h index 7d73f86ee9..179ef54a9b 100644 --- a/system/hardware/tici/hardware.h +++ b/system/hardware/tici/hardware.h @@ -109,11 +109,4 @@ public: static bool get_ssh_enabled() { return Params().getBool("SshEnabled"); } static void set_ssh_enabled(bool enabled) { Params().putBool("SshEnabled", enabled); } - - static void config_cpu_rendering(bool offscreen) { - if (offscreen) { - setenv("QT_QPA_PLATFORM", "eglfs", 1); // offscreen doesn't work with EGL/GLES - } - setenv("LP_NUM_THREADS", "0", 1); // disable threading so we stay on our assigned CPU - } }; From ce355250be726f9bc8f0ac165a6cde41586a983d Mon Sep 17 00:00:00 2001 From: commaci-public <60409688+commaci-public@users.noreply.github.com> Date: Fri, 7 Mar 2025 22:04:03 -0800 Subject: [PATCH 77/78] [bot] Update Python packages (#34819) Update Python packages Co-authored-by: Vehicle Researcher --- opendbc_repo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opendbc_repo b/opendbc_repo index 3a5b13ed55..0efdb71b8f 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit 3a5b13ed55fa02f7637e5ab0e67211e40f86bc21 +Subproject commit 0efdb71b8f2440ee51a806d057f20a553b849a3a From b98e10acc1b060867d3c4393708cbca1853b9f67 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Sun, 9 Mar 2025 12:28:08 +0800 Subject: [PATCH 78/78] pandad_api_impl: add nogil to can_list_to_can_capnp (#34823) add nogil to can_list_to_can_capnp --- selfdrive/pandad/pandad_api_impl.pyx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/selfdrive/pandad/pandad_api_impl.pyx b/selfdrive/pandad/pandad_api_impl.pyx index e571c4aa58..6683b843ae 100644 --- a/selfdrive/pandad/pandad_api_impl.pyx +++ b/selfdrive/pandad/pandad_api_impl.pyx @@ -17,14 +17,17 @@ cdef extern from "opendbc/can/common.h": vector[CanFrame] frames cdef extern from "can_list_to_can_capnp.cc": - void can_list_to_can_capnp_cpp(const vector[CanFrame] &can_list, string &out, bool sendcan, bool valid) + void can_list_to_can_capnp_cpp(const vector[CanFrame] &can_list, string &out, bool sendcan, bool valid) nogil void can_capnp_to_can_list_cpp(const vector[string] &strings, vector[CanData] &can_data, bool sendcan) def can_list_to_can_capnp(can_msgs, msgtype='can', valid=True): cdef CanFrame *f cdef vector[CanFrame] can_list + cdef uint32_t cpp_can_msgs_len = len(can_msgs) + + with nogil: + can_list.reserve(cpp_can_msgs_len) - can_list.reserve(len(can_msgs)) for can_msg in can_msgs: f = &(can_list.emplace_back()) f.address = can_msg[0] @@ -32,7 +35,10 @@ def can_list_to_can_capnp(can_msgs, msgtype='can', valid=True): f.src = can_msg[2] cdef string out - can_list_to_can_capnp_cpp(can_list, out, msgtype == 'sendcan', valid) + cdef bool is_sendcan = (msgtype == 'sendcan') + cdef bool is_valid = valid + with nogil: + can_list_to_can_capnp_cpp(can_list, out, is_sendcan, is_valid) return out def can_capnp_to_list(strings, msgtype='can'):