IQ.Pilot Release Commit @ 98a2c61
This commit is contained in:
@@ -51,8 +51,8 @@
|
||||
},
|
||||
"python/_iqclosure/iqpilot/common/git_creds.py": {
|
||||
"mode": 420,
|
||||
"sha256": "957a07c0a852b24d5778ff42216a0159aee25e453699f6e14725e62ef581db4d",
|
||||
"size": 6192
|
||||
"sha256": "aab57b08d1907d0a761111e2a9a415af990475a55307c0ced6f2573664abbc49",
|
||||
"size": 7327
|
||||
},
|
||||
"python/_iqclosure/iqpilot/common/gpio.py": {
|
||||
"mode": 420,
|
||||
@@ -76,8 +76,8 @@
|
||||
},
|
||||
"python/_iqclosure/iqpilot/common/realtime.py": {
|
||||
"mode": 420,
|
||||
"sha256": "ff112acc1fdc227e2ffa4b0fa74f27b967a488bb72fe21c5be82fc70d1104f02",
|
||||
"size": 3488
|
||||
"sha256": "95b2e4eb3d78b607945cc6fad29c97a2e133eff4c427620d5c04b044f78abe10",
|
||||
"size": 3763
|
||||
},
|
||||
"python/_iqclosure/iqpilot/common/spinner.py": {
|
||||
"mode": 420,
|
||||
@@ -286,13 +286,13 @@
|
||||
},
|
||||
"python/_iqclosure/iqpilot/system/manager/process.py": {
|
||||
"mode": 420,
|
||||
"sha256": "4fb7af7d336ccdf7f0f54e50135618d191a56003bf7647d8dd98814c412f0ae4",
|
||||
"size": 11456
|
||||
"sha256": "d036d82e2163a249186238375fb82f8dca250fae2272428ea47a46e4d6a8649d",
|
||||
"size": 11519
|
||||
},
|
||||
"python/_iqclosure/iqpilot/system/manager/process_config.py": {
|
||||
"mode": 420,
|
||||
"sha256": "458355df663aed2a81c234ab693658040e11c97ad3abec8a2da222d00ce75a35",
|
||||
"size": 11240
|
||||
"sha256": "810bbd9bf9d211b1c54bfaaf56992b52e9a08a4cd0d1919d43a0a3b907401313",
|
||||
"size": 11656
|
||||
},
|
||||
"python/_iqclosure/iqpilot/system/micd.py": {
|
||||
"mode": 420,
|
||||
@@ -351,28 +351,28 @@
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/backups/archive_codec.cpython-312-aarch64-linux-gnu.so": {
|
||||
"mode": 493,
|
||||
"sha256": "e0449bd6ce019d9752980caf4f3cdc8bfe592d31e83fc1dc30c70171d581e0fb",
|
||||
"size": 135536
|
||||
"sha256": "80cd58a10f6356fcad68063a474458653acbae17dfc8a66791256ec1fc109036",
|
||||
"size": 135552
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/backups/backup_keys.cpython-312-aarch64-linux-gnu.so": {
|
||||
"mode": 493,
|
||||
"sha256": "21403090115a8c9312a21ae8af0904e74f13d2b87a4801603dabe595efa70217",
|
||||
"sha256": "81e12476cedca56039fe9bf194cc9fd1a80b223c987e212a3208c64ff1390b26",
|
||||
"size": 67664
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/backups/backup_orchestrator.cpython-312-aarch64-linux-gnu.so": {
|
||||
"mode": 493,
|
||||
"sha256": "b1e1a82addf9d3de383c80f78e279ac63875d693e938e5f1840f941f5191ffc9",
|
||||
"size": 204624
|
||||
"sha256": "9d7e7fd9d1a3d2ff6ba8140fbe3743502151768f7d2c22625ffe2a78b3c8cd7b",
|
||||
"size": 204640
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/backups/cbc_vault.cpython-312-aarch64-linux-gnu.so": {
|
||||
"mode": 493,
|
||||
"sha256": "db35b67432069f507401cffc2f299e2b8ae2d1b97c4c316f4a9247253cd8393a",
|
||||
"size": 69752
|
||||
"sha256": "c39b482f192406ab8f3ec4733f2da8131ec1d9d5c791189035e42504d8e6132f",
|
||||
"size": 69768
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/backups/imahelper.cpython-312-aarch64-linux-gnu.so": {
|
||||
"mode": 493,
|
||||
"sha256": "937701d3f6fab98f31c0bfd57f731dadb1e851684096582bab8c36d363d4558e",
|
||||
"size": 203072
|
||||
"sha256": "5524a08ebc9918fabf6d8c7d2ccdb89ac67cbf8f017e4d00989bf88dc9720b12",
|
||||
"size": 203088
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/flockd/__init__.py": {
|
||||
"mode": 420,
|
||||
@@ -381,12 +381,12 @@
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/flockd/flockd.cpython-312-aarch64-linux-gnu.so": {
|
||||
"mode": 493,
|
||||
"sha256": "b17aad237c258b7ccb0a5daf89bb097ea09c86dfcd5c71727d83da2c7909bcb2",
|
||||
"size": 202168
|
||||
"sha256": "364a06ba9338c61fe904c6c93e3be7bc567b0881cffaaa62b7cba0d67a5f3c04",
|
||||
"size": 202184
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/flockd/signatures.cpython-312-aarch64-linux-gnu.so": {
|
||||
"mode": 493,
|
||||
"sha256": "9116cf44650d16b16505fec4252f2aa43dade0698e79bbb202f5f45f6941449c",
|
||||
"sha256": "08a7990bb84f88505eb5e58745b339b59ada3cc2b802c5f2396281cb03af1c84",
|
||||
"size": 68080
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/hephaestus/__init__.py": {
|
||||
@@ -396,68 +396,68 @@
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/hephaestus/_vendor/localapi_runtime.zip": {
|
||||
"mode": 420,
|
||||
"sha256": "b351039bd804ee830cb97d170b844416a93d16a11d96eea0a06e6e7784956054",
|
||||
"sha256": "ec5e60ae7ebed56e6613216115b25e3f7388afd374619a656642118b0506642a",
|
||||
"size": 2100238
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/hephaestus/ble_auth.cpython-312-aarch64-linux-gnu.so": {
|
||||
"mode": 493,
|
||||
"sha256": "225305ece452c6c814a7ff09cb4b3e056e6058abf2ad0f4da45ea9973ee72ad2",
|
||||
"size": 268064
|
||||
"sha256": "b9d5402b525987bc9939bf30113debde997d07a7ab0a5922bf1954cea7cb7757",
|
||||
"size": 268080
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/hephaestus/ble_gatt.cpython-312-aarch64-linux-gnu.so": {
|
||||
"mode": 493,
|
||||
"sha256": "11cc70c1969f9dd881a70f34acd19b236f5fafa24db3cca8460dfa30a613f2ca",
|
||||
"size": 406216
|
||||
"sha256": "68787d021840f0e1ee1babd3e4e781324c9b4e1bb8de38e78ac9fb57d967ba7c",
|
||||
"size": 406176
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/hephaestus/ble_rpc_dispatch.cpython-312-aarch64-linux-gnu.so": {
|
||||
"mode": 493,
|
||||
"sha256": "e53a4d22b74a31ea6701cc391fc9d7df5942062e6d9ecc213710ef3fa56ca6e4",
|
||||
"sha256": "405fbafd6e385b7f6fa5f20b1ef1fa38cbd04952edef764efffbecbbebcd8f14",
|
||||
"size": 68048
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/hephaestus/ble_transportd.cpython-312-aarch64-linux-gnu.so": {
|
||||
"mode": 493,
|
||||
"sha256": "dad03a293a193ad4d33cfc1c32ffc865e702fd4cb6456143a75511c47ef084cf",
|
||||
"size": 335728
|
||||
"sha256": "2449bf7779155e546ea14a5c10ee16be174da6993f6ab25e2aa59de007b5078b",
|
||||
"size": 335776
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/hephaestus/bt_gamepad.cpython-312-aarch64-linux-gnu.so": {
|
||||
"mode": 493,
|
||||
"sha256": "8b9130dd51450ed3b703a68c995c4ce08dbad4818044138cc7518abbbb9f48da",
|
||||
"size": 271680
|
||||
"sha256": "951fbff54e5fd1c667ca73359ea015e9cf79dcd55abb7f8b1bc857a38e11a54a",
|
||||
"size": 271696
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/hephaestus/cloud_routes.cpython-312-aarch64-linux-gnu.so": {
|
||||
"mode": 493,
|
||||
"sha256": "31d289bdb733dfebe80961b42a8d6a76347889c7fa97007ec827dac9985874f8",
|
||||
"sha256": "2fa9a1e9352721a03f2eaa4ecf3719787baafc35fb37d71e0b6372656cde6d5f",
|
||||
"size": 134408
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/hephaestus/hephaestusd.cpython-312-aarch64-linux-gnu.so": {
|
||||
"mode": 493,
|
||||
"sha256": "3f1b2f23b2ef27f0cdeadc291cde98a0affd70658d01e6c943c6dd220f6775ea",
|
||||
"size": 3715848
|
||||
"sha256": "d342ef73b4fd9d60407c60d0c3768668e8bdbb0d9702f163aec4893f8d49af6c",
|
||||
"size": 3715880
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/hephaestus/kwp2000.cpython-312-aarch64-linux-gnu.so": {
|
||||
"mode": 493,
|
||||
"sha256": "133d8474b5d458bc6f4d1303f921b9891464a82e88dcd0e1ab0af75d9b309886",
|
||||
"size": 136448
|
||||
"sha256": "cf6cc790e765adc5913c23ff32dea23588c1fb8608c6a8043fbc9b1bb2b662e8",
|
||||
"size": 136472
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/hephaestus/manage_hephaestusd.cpython-312-aarch64-linux-gnu.so": {
|
||||
"mode": 493,
|
||||
"sha256": "76395e8f587f650a30633194a173797946d86eff4ed97faefb1c937bd3b2a0c7",
|
||||
"sha256": "4d66dbd069d90ee956feac23130c5a14338f3d66492180dd3cd945f8a5c4ddad",
|
||||
"size": 68208
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/hephaestus/motd.cpython-312-aarch64-linux-gnu.so": {
|
||||
"mode": 493,
|
||||
"sha256": "7b9bdb554b6ea169c2eeb24c74e7396c314b8120365e2650d0a315e89f9ed370",
|
||||
"sha256": "d5227394abae38d2118d7e1df8a142ad2137a28e02679d29d2426c3ac8a60ba8",
|
||||
"size": 67840
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/hephaestus/tp20.cpython-312-aarch64-linux-gnu.so": {
|
||||
"mode": 493,
|
||||
"sha256": "34e7846abcd1adf3038bdda93e6fac85e71bd843f51dea03a7c058f1be3fbed4",
|
||||
"size": 135648
|
||||
"sha256": "59cba66846b23370b9c7b20d108db8bf6f1c7dbc8a49958621905e0cb322fbe9",
|
||||
"size": 135664
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/hephaestus/vw_pq_flasher.cpython-312-aarch64-linux-gnu.so": {
|
||||
"mode": 493,
|
||||
"sha256": "28c6e7b7f1d8ce04fec673fae9b3d61c17e34ead497d6c5c31b7145ce1251feb",
|
||||
"size": 269568
|
||||
"sha256": "cc1be0247694a84b596e1333d53fa23a44fa2353b8b635f95b0329a5ffef5585",
|
||||
"size": 269600
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/uploaderd/__init__.py": {
|
||||
"mode": 420,
|
||||
@@ -466,8 +466,8 @@
|
||||
},
|
||||
"python/iqpilot_private/konn3kt/uploaderd/iquploaderd.cpython-312-aarch64-linux-gnu.so": {
|
||||
"mode": 493,
|
||||
"sha256": "5b359de266caca30a36922510d6eb8148c371117f9de9884ba40d2cf59c917b9",
|
||||
"size": 204280
|
||||
"sha256": "8a4926ba1d3bcf80326f699b1f9c775cd1fbe9d4c7981ba47d8232a8d4aedf79",
|
||||
"size": 204296
|
||||
},
|
||||
"runtime": {
|
||||
"entries": {
|
||||
@@ -510,25 +510,25 @@
|
||||
}
|
||||
},
|
||||
"signatures": {
|
||||
"python/iqpilot_private/konn3kt/backups/archive_codec.cpython-312-aarch64-linux-gnu.so": "3woPJlhuOMUSFXoJmkDRMYUaB92k+DN3oVWIF5MXT017jl+2xfqQtzQ/ElREnon3SJQzoUl1b3gziO9w8xfWAA==",
|
||||
"python/iqpilot_private/konn3kt/backups/backup_keys.cpython-312-aarch64-linux-gnu.so": "9PBGNS4oqUIG/Q1qC5Ahc/2zksGoK9cVaVRJR5LOe/z7j3uLgFxd/5z500NNtm0OxFySGQtJPF+mbuF2iirOBg==",
|
||||
"python/iqpilot_private/konn3kt/backups/backup_orchestrator.cpython-312-aarch64-linux-gnu.so": "4z564REmz4fZaCTWtm+A2kWE0QpDo706Ue3ZpDF4gZr8/sn+VWgNC54pK4ke1AiKi8Q062sPN2vHBGwoufJzDw==",
|
||||
"python/iqpilot_private/konn3kt/backups/cbc_vault.cpython-312-aarch64-linux-gnu.so": "UZNYlPkre3vkKEBZJWgaKOlyDp0ZZcXHeVomUJtaEeE26xB4jwxJ6af4LTC3ePq2x2Tlk8sBYqifCxhPQe5NAA==",
|
||||
"python/iqpilot_private/konn3kt/backups/imahelper.cpython-312-aarch64-linux-gnu.so": "qCQEhyUzeOdkZP1KHk+46aoV4JMYw14RLUt7uk/i1fNrmtDL+PdbzW78VGSN/Rx0/LUcSkqs1JglW88vVfefDg==",
|
||||
"python/iqpilot_private/konn3kt/flockd/flockd.cpython-312-aarch64-linux-gnu.so": "VOiMhBDEXKfhkxZ7iYvUZoFxFd4rLoRj+Ve/F+aqZi59PpnJSrMg/YfECDHBokkThk4h1ltPlxa9Dn7qAKc7BQ==",
|
||||
"python/iqpilot_private/konn3kt/flockd/signatures.cpython-312-aarch64-linux-gnu.so": "wPTnKdQFxPoPgBvh7YhVRL0uM9+81vpkKKP1RZdCxUWMBn7cB/XfiDHyxq8I6l0g0YCTdWFnRzbxDTnsuOPYBQ==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/ble_auth.cpython-312-aarch64-linux-gnu.so": "3aW1fuOPBfWsSnz/1f3KpjElnWW29uek0qKzP0rKN0MODmqv3HoIZfWxzKQyrIYivJnCTG6XIAjwH0u3IZCKAw==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/ble_gatt.cpython-312-aarch64-linux-gnu.so": "VXk+vwJBH9AmA50BbIlhJOLRFl+RTjOmqTw3h6gdt0OO1bIBH0KvBzFuuAQ08fQxqdumffC6I3U4816Lti8YCQ==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/ble_rpc_dispatch.cpython-312-aarch64-linux-gnu.so": "6CuLsxr/i/vdwmhaMvGUvPLuyf/rCQDKD4FAhefZZA1SNeNQe+JikmQgTKIRK8rsZnysmHYYOufqAY0HblLFBg==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/ble_transportd.cpython-312-aarch64-linux-gnu.so": "nd4FM7UAwEGVQeuWhybGZmKTmCvvkAvSQTu0XBVTlOic+C0WYHYu7qfFnxvx5LJAp+qWoPB1iHdiY2QwcxGxDg==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/bt_gamepad.cpython-312-aarch64-linux-gnu.so": "TBb/fVj4cvVsiWn4aGgWE0npbkAVr4tl8iyceqZoye1dY3fwofjHOpCY/sbY5j1ZHR2H2garFWefY6bCu3piDA==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/cloud_routes.cpython-312-aarch64-linux-gnu.so": "GUR2UOxQ0uLBe3dMM2/wy9yvPvXLT+H9UzVEpKQF4v0858XiOVGSetI5poGUgJQRN/uHJLpq4AhVsP5skHtHAQ==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/hephaestusd.cpython-312-aarch64-linux-gnu.so": "qr7jtGz9X/npoWL5rx1RPY+wnCh+O+8ONo05o5MAElB7HUFWMs0Udef8WO2Xox7vTjVWk0c3xoXGfIo3YCe3BA==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/kwp2000.cpython-312-aarch64-linux-gnu.so": "N02iLJw3SHYRWTc1OrPhHe/6M8M3utM89Fh8p8e+tTDqsbEkbqTRmMP2Ef8IMH+5r9k24+y3R+OV6tPy6Q/wBg==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/manage_hephaestusd.cpython-312-aarch64-linux-gnu.so": "o/5/vvZ4pAz2Bo3sFWr40ztcwqJ48/DLtnSEqXeglcEAWlfTiXlMGOrsH1UIdA3MQbiLbx9IgpH6Y1NNh6NwCg==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/motd.cpython-312-aarch64-linux-gnu.so": "ovdy4zjoZ9GMMTwAox6mL4RO56ry0yh/v7vzUyQqxe2xZtoxMf4b7CC+ntIkHB/P1Admghd0HXlRNUBRZ+eABQ==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/tp20.cpython-312-aarch64-linux-gnu.so": "hIEtlZhxGDMMhsturD7KzH362pdtH1RZsfL/N7aYR5TsODVR255rjc3gKE7Qdsfh/+MChQ8cFXWErMXlNzrIAw==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/vw_pq_flasher.cpython-312-aarch64-linux-gnu.so": "1q0GMB/Wq/FuQ5rACM9nLl9norwGsoZwn1BPjp1OZAcXpFOkgLVGYRdUuZi3OKuW/FuFTjWQMrfq4VTc0UYrBg==",
|
||||
"python/iqpilot_private/konn3kt/uploaderd/iquploaderd.cpython-312-aarch64-linux-gnu.so": "37a/+B+GI+mZAk2XtsdIeDYKZmpvnKIR5exngcukpkVeKmyhgkJ+xbMxsmwGcwuIZkvKdcKoXLb3KwZteatdAQ=="
|
||||
"python/iqpilot_private/konn3kt/backups/archive_codec.cpython-312-aarch64-linux-gnu.so": "tV3zvq8PZd4MgIU1hjzjpVxS8puOkVUUsJsSYb2fjeOqkBv6KG3oIlN+TPGiwwO7YX8dO8dFivZWGnktKWKPCg==",
|
||||
"python/iqpilot_private/konn3kt/backups/backup_keys.cpython-312-aarch64-linux-gnu.so": "kG8Ifpx65b0dhdTdfFhLr65vGa1O5enjiCI9N3aGd5+aOE7DdKJPID4Q3vIIjMZqMdoKPTdBLj3MaPEYXL3pCg==",
|
||||
"python/iqpilot_private/konn3kt/backups/backup_orchestrator.cpython-312-aarch64-linux-gnu.so": "1Dh3vRWc91DfHWg7pw9GhZ6O5eT335f4utjxSzHh8Y1wvwButYfsEO5DUZ2KNss5IAKDy7O4/CpnACD/64UYDg==",
|
||||
"python/iqpilot_private/konn3kt/backups/cbc_vault.cpython-312-aarch64-linux-gnu.so": "6Fdo8Du4ZUMt8241uRDjLVoy1a2flzQNeXMfaVuRaMU8aYZZixqvaYPeanZDPOTvpy6PxaFVZYYnBR/cqokNCw==",
|
||||
"python/iqpilot_private/konn3kt/backups/imahelper.cpython-312-aarch64-linux-gnu.so": "YTL4x/JaFnZCALPoyET84LvOcISGB5vrpTYn5b87kSDdcWPDwiTyEAXUuueOQGRQXVzZJj4UC+zal2DEA2QlAw==",
|
||||
"python/iqpilot_private/konn3kt/flockd/flockd.cpython-312-aarch64-linux-gnu.so": "KHqjlPIClO9hg2LxyOzRismA38ysUPxci0KCiHrydE8W7Nbd3LMMR1/9/rUvPUfRYY/szpkfvkZTlMwo26R5BQ==",
|
||||
"python/iqpilot_private/konn3kt/flockd/signatures.cpython-312-aarch64-linux-gnu.so": "Uas3ReVuTgjJxr1elZ/26R8/6StRaFrMPD16t7GWGj6PTG+CiUOPn4oiiJgfumevnrYw4xGGLRsfZQhFHaUHAA==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/ble_auth.cpython-312-aarch64-linux-gnu.so": "39bSI5v9Mg9VQLo3PmfUBmfHE1hKjTD2Jfgak/W3m1FJ7eXROhUjts6bsY5pXsHDx6MTcEw35IUr7Q8v+3bQBg==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/ble_gatt.cpython-312-aarch64-linux-gnu.so": "hB1aGUsLCYcFSLxGxg1nuRzbrA1Uv/StOQv0V/0L8v73Z7xakXYFW8h/C5xD2/hNIGFMaNc7GLOyc2GwN7tVAg==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/ble_rpc_dispatch.cpython-312-aarch64-linux-gnu.so": "LlBVzMoPeK8ypvzgXXYkqmooV6V1lHtS6Ym5VPj/fNFn79hWfhbsjwY9A463hs3QzaxGh5OWwcc1pmFc6USODw==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/ble_transportd.cpython-312-aarch64-linux-gnu.so": "nq7AH2XYZuAxhGfHfgc3haBGbu5bDwOI15mI++Be3VYsVah0P+Fqd0F5G6dZjIFo5fbuO0FH7/LHOlEnxRQcBw==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/bt_gamepad.cpython-312-aarch64-linux-gnu.so": "m2y/Lozqs16IZsrpL+OOQ0MQCWEB+EuyacYa/TFch4KxwPHVrEnh+zKtGdeIhcd7pVkUd1IRkFVnWGGvBx+pCg==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/cloud_routes.cpython-312-aarch64-linux-gnu.so": "+njDWbhjEsFL1WzGlL0fN5ygbqGbfwInwaAquDeC5aYgbrwvJOdnwonJgxV0fd0ABzIwfuUFzSMZg6F3qI84BA==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/hephaestusd.cpython-312-aarch64-linux-gnu.so": "G8sfe52XB1m4Lc197oLD51bwbXOZXkpOtAsgiMHZHwbayEFsPeI2Ls/R4ZOcPYTjztXDKYt68Ig8QJblRanTCQ==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/kwp2000.cpython-312-aarch64-linux-gnu.so": "jr8rsgKsxDYBuY58XqIqMkb9pW78Jb6rBGaEHLZRtWS6z58td37+PBesMzzg4J1GNov4RKcZfMbaANBui1OnAA==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/manage_hephaestusd.cpython-312-aarch64-linux-gnu.so": "QbprGqwfKC9bo4xs8pNieYI/TOwLOUNv4YVHhXPS/2xVU5bS+aDr71aD/o4PF3UmkJrMW/94b8X22Dy19SYEDQ==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/motd.cpython-312-aarch64-linux-gnu.so": "Iv9RL4rXHell9BfRp6PoWxD3TnT+WLugypT3aG4Ukf/iMqPVPizGtqfJY/axQY8jItBGTXcIyfZA9O6juGpfBg==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/tp20.cpython-312-aarch64-linux-gnu.so": "KKD5TdLEDBtDy+YoUgglFkpHVJjvn9K4xlzUF7doWIAo1+n3ySTYQ4V7+iJ04H0Axs3Gsp0d0ytDui5qw09+Cw==",
|
||||
"python/iqpilot_private/konn3kt/hephaestus/vw_pq_flasher.cpython-312-aarch64-linux-gnu.so": "C4po9GxTKUlww19PaUJUi+kUTBTTVYyUMjAvAhNYAVcOS6mpVNMIBX7UCt3XcTtlLU+q+goE0Mw68LvoMza4AQ==",
|
||||
"python/iqpilot_private/konn3kt/uploaderd/iquploaderd.cpython-312-aarch64-linux-gnu.so": "l1lWA8GLEToT4GDa96aEt6TFO8RDP/WSHgXV+9mge8cHQ82UVrVJKX98andFvKDaNGPjZgR+gK5gslEMt2dVCg=="
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
mxOyhKQjRuoHrbPQQSnMJaJzcXKHxcSlSDfdKtivSLLcyR4S/xnfQ+cT/LW9JnoF6qbUc1uKFn8BEKF+HUOADA==
|
||||
HlmJ/WkPaO0L0omQG7BWUtHYKzp2ZTFvaVu4BDpACrkluSoWeyX0suOZlU29fJvRI+nWhBEkRW7807toLyrNAQ==
|
||||
|
||||
@@ -6,6 +6,7 @@ import subprocess
|
||||
from iqpilot.common.params import Params
|
||||
|
||||
PARAM = "GitAuthBlob"
|
||||
PARAMS_DIR = os.environ.get("PARAMS_DIR", "/data/params/d")
|
||||
KEY_DIR = "/data/konn3kt"
|
||||
KEY_PATH = os.path.join(KEY_DIR, "git_auth.key")
|
||||
HELPER_PATH = os.path.join(KEY_DIR, "git_credential_helper.py")
|
||||
@@ -51,6 +52,48 @@ if __name__ == "__main__":
|
||||
'''
|
||||
|
||||
|
||||
def _params_get(name: str) -> bytes | None:
|
||||
# Params -> cereal -> iqdbc: that chain is unavailable mid-bootstrap (this module's
|
||||
# callers install those very packages), so fall back to the params file directly,
|
||||
# exactly like the embedded credential helper does.
|
||||
try:
|
||||
return Params().get(name)
|
||||
except Exception:
|
||||
try:
|
||||
with open(os.path.join(PARAMS_DIR, name), "rb") as f:
|
||||
return f.read()
|
||||
except OSError:
|
||||
return None
|
||||
|
||||
|
||||
def _params_put(name: str, value: bytes) -> None:
|
||||
try:
|
||||
Params().put(name, value)
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
os.makedirs(PARAMS_DIR, exist_ok=True)
|
||||
tmp = os.path.join(PARAMS_DIR, f".tmp_{name}")
|
||||
fd = os.open(tmp, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o644)
|
||||
with os.fdopen(fd, "wb") as f:
|
||||
f.write(value)
|
||||
f.flush()
|
||||
os.fsync(f.fileno())
|
||||
os.replace(tmp, os.path.join(PARAMS_DIR, name))
|
||||
|
||||
|
||||
def _params_remove(name: str) -> None:
|
||||
try:
|
||||
Params().remove(name)
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
os.unlink(os.path.join(PARAMS_DIR, name))
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
def _load_or_create_key() -> bytes:
|
||||
from cryptography.fernet import Fernet
|
||||
try:
|
||||
@@ -80,7 +123,7 @@ def set_credentials(username: str, token: str) -> None:
|
||||
blob = Fernet(_load_or_create_key()).encrypt(
|
||||
json.dumps({"u": username, "t": token}).encode()
|
||||
)
|
||||
Params().put(PARAM, blob)
|
||||
_params_put(PARAM, blob)
|
||||
try:
|
||||
install_credential_helper(DEFAULT_REPO_DIR)
|
||||
except Exception:
|
||||
@@ -89,7 +132,7 @@ def set_credentials(username: str, token: str) -> None:
|
||||
|
||||
def get_credentials() -> tuple[str, str] | None:
|
||||
"""Return (username, token), or None if unset / unreadable."""
|
||||
blob = Params().get(PARAM)
|
||||
blob = _params_get(PARAM)
|
||||
if not blob:
|
||||
return None
|
||||
try:
|
||||
@@ -101,7 +144,7 @@ def get_credentials() -> tuple[str, str] | None:
|
||||
|
||||
|
||||
def clear_credentials() -> None:
|
||||
Params().remove(PARAM)
|
||||
_params_remove(PARAM)
|
||||
|
||||
|
||||
def has_credentials() -> bool:
|
||||
|
||||
@@ -76,6 +76,13 @@ class Ratekeeper:
|
||||
self.avg_dt = MovingAverage(100)
|
||||
self.avg_dt.add_value(self._interval)
|
||||
|
||||
def reset(self) -> None:
|
||||
self._remaining = 0.0
|
||||
self._last_monitor_time = -1.
|
||||
self._next_frame_time = -1.
|
||||
self.avg_dt = MovingAverage(100)
|
||||
self.avg_dt.add_value(self._interval)
|
||||
|
||||
@property
|
||||
def frame(self) -> int:
|
||||
return self._frame
|
||||
@@ -84,6 +91,10 @@ class Ratekeeper:
|
||||
def remaining(self) -> float:
|
||||
return self._remaining
|
||||
|
||||
@property
|
||||
def lag(self) -> float:
|
||||
return max(0., -self._remaining)
|
||||
|
||||
@property
|
||||
def lagging(self) -> bool:
|
||||
expected_dt = self._interval * (1 / 0.9)
|
||||
|
||||
@@ -104,7 +104,7 @@ class ManagerProcess(ABC):
|
||||
self.stop(sig=signal.SIGKILL)
|
||||
self.start()
|
||||
|
||||
def stop(self, retry: bool = True, block: bool = True, sig: signal.Signals | None = None) -> int | None:
|
||||
def stop(self, retry: bool = True, block: bool = True, sig: signal.Signals | None = None, timeout: float = 5) -> int | None:
|
||||
if self.proc is None:
|
||||
return None
|
||||
|
||||
@@ -119,7 +119,7 @@ class ManagerProcess(ABC):
|
||||
if not block:
|
||||
return None
|
||||
|
||||
join_process(self.proc, 5)
|
||||
join_process(self.proc, timeout)
|
||||
|
||||
# If process failed to die send SIGKILL
|
||||
if self.proc.exitcode is None and retry:
|
||||
@@ -245,8 +245,8 @@ class BundleProcess(NativeProcess):
|
||||
_normalize_bundle_modes(self.bundle)
|
||||
super().start()
|
||||
|
||||
def stop(self, retry: bool = True, block: bool = True, sig: signal.Signals | None = None) -> int | None:
|
||||
return super().stop(retry=retry, block=block, sig=signal.SIGTERM if sig is None else sig)
|
||||
def stop(self, retry: bool = True, block: bool = True, sig: signal.Signals | None = None, timeout: float = 5) -> int | None:
|
||||
return super().stop(retry=retry, block=block, sig=signal.SIGTERM if sig is None else sig, timeout=timeout)
|
||||
|
||||
|
||||
class PythonProcess(ManagerProcess):
|
||||
|
||||
@@ -75,6 +75,11 @@ def navd_onroad(started: bool, params: Params, CP: car.CarParams) -> bool:
|
||||
def navrenderd_onroad(started: bool, params: Params, CP: car.CarParams) -> bool:
|
||||
return started and params.get_bool("NavigationEnabled") and params.get_bool("OnScreenNavigation")
|
||||
|
||||
def navincidentd_onroad(started: bool, params: Params, CP: car.CarParams) -> bool:
|
||||
return started and params.get_bool("NavigationEnabled") and bool(params.get("WazePoliceApiKey")) and (
|
||||
params.get_int("WazePoliceAlertMode") > 0 or params.get_bool("WazePoliceShadow")
|
||||
)
|
||||
|
||||
def iqmapd_needed(params: Params) -> bool:
|
||||
return (
|
||||
params.get_bool("IQRoadNameOverlay")
|
||||
@@ -195,6 +200,7 @@ procs += [
|
||||
BundleProcess("backup_manager_k3", "iqpilot_hephaestusd_private", "iqpilot_private.konn3kt.backups.backup_orchestrator",
|
||||
and_(only_offroad, hephaestus_ready_shim, not_low_power)),
|
||||
BundleProcess("navd", "iqpilot_navd_private", "iqpilot_private.navd.navd", navd_onroad, restart_if_crash=True),
|
||||
BundleProcess("navincidentd", "iqpilot_navd_private", "iqpilot_private.navd.navincidentd", navincidentd_onroad, restart_if_crash=True),
|
||||
BundleProcess("navrenderd", "iqpilot_navd_private", "iqpilot_private.navd.navrenderd", navrenderd_onroad, restart_if_crash=True),
|
||||
BundleProcess("iqmapd", "iqpilot_navd_private", "iqpilot_private.navd.iqmapd", iqmapd_onroad, restart_if_crash=True),
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -610,7 +610,8 @@ class CarController(CarControllerBase):
|
||||
leadDistance = hud_control.leadDistance if self.CCS is mlbcan else \
|
||||
(min(8, hud_control.leadDistance) if hud_control.leadDistance != 0 else 0)
|
||||
self.leadDistanceBars = min(3, hud_control.leadDistanceBars)
|
||||
acc_hud_status = self.CCS.acc_hud_status_value(CS.out.cruiseState.available, CS.out.accFaulted, CC.longActive, CC.cruiseControl.override)
|
||||
acc_hud_status = self.CCS.acc_hud_status_value(CS.out.cruiseState.available, CS.out.accFaulted, CC.longActive,
|
||||
CC.cruiseControl.override or CS.out.gasPressed)
|
||||
set_speed = hud_control.setSpeed * CV.MS_TO_KPH
|
||||
decel = dVisual(self.CCS, CS)
|
||||
hud_kwargs = {"hud_text": self._mlb_acc_hud_text(hud_control, set_speed),
|
||||
|
||||
@@ -347,4 +347,6 @@ class CarInterface(CarInterfaceBase):
|
||||
@staticmethod
|
||||
def _get_params_iq(stock_cp: structs.CarParams, ret: structs.IQCarParams, candidate, fingerprint: dict[int, dict[int, int]], car_fw: list[structs.CarParams.CarFw], alpha_long: bool, is_release_iq: bool, docs: bool) -> structs.IQCarParams:
|
||||
ret.longitudinalStoppingSpeedOverride = get_longitudinal_stopping_speed_override(candidate, stock_cp.flags)
|
||||
override_excluded_platforms = VolkswagenFlags.MLB | VolkswagenFlags.MEB | VolkswagenFlags.MQB_EVO
|
||||
ret.longActiveWithGasOverride = alpha_long and not bool(stock_cp.flags & override_excluded_platforms)
|
||||
return ret
|
||||
|
||||
@@ -112,7 +112,7 @@ def create_acc_accel_control(packer, bus, acc_type, accel, acc_control, stopping
|
||||
"ACS_Sollbeschl": accel if acc_enabled else 3.01,
|
||||
"ACS_zul_Regelabw": comfortBand if acc_enabled else 1.27,
|
||||
"ACS_max_AendGrad": jerkLimit if acc_enabled else 5.08,
|
||||
"ACS_Schubabsch": 0,
|
||||
"ACS_Schubabsch": 1 if acc_enabled and accel > 0.05 else 0,
|
||||
"ACS_MomEingriff": 0,
|
||||
"ACS_ADR_Schub": 0,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
"""
|
||||
Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos/
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from iqdbc.can import CANPacker
|
||||
from iqdbc.car.volkswagen import pqcan
|
||||
|
||||
|
||||
@pytest.mark.parametrize("accel, acc_control, expected", [
|
||||
(-1.0, 1, False),
|
||||
(0.0, 1, False),
|
||||
(0.05, 1, False),
|
||||
(0.051, 1, True),
|
||||
(1.0, 1, True),
|
||||
(1.0, 0, False),
|
||||
])
|
||||
def test_positive_acceleration_prevents_fuel_cutoff(accel, acc_control, expected):
|
||||
packer = CANPacker("vw_pq")
|
||||
messages = pqcan.create_acc_accel_control(
|
||||
packer, 0, 1, accel, acc_control, False, False, False, 0.2, 0.3, False,
|
||||
)
|
||||
assert len(messages) == 1
|
||||
_, data, _ = messages[0]
|
||||
assert bool(data[1] & 0x80) is expected
|
||||
@@ -100,6 +100,23 @@ class TestVolkswagenPlatformConfigs:
|
||||
assert bool(params.flags & VolkswagenFlagsIQ.IQ_PQ_ACC_FTS_EPB) is expected
|
||||
assert bool(params.safetyConfigs[-1].safetyParam & VolkswagenSafetyFlags.PQ_ACC_FTS_EPB) is expected
|
||||
|
||||
@pytest.mark.parametrize("candidate, alpha_long, expected", (
|
||||
(CAR.VOLKSWAGEN_PASSAT_B7, False, False),
|
||||
(CAR.VOLKSWAGEN_PASSAT_B7, True, True),
|
||||
(CAR.VOLKSWAGEN_GOLF_MK7, False, False),
|
||||
(CAR.VOLKSWAGEN_GOLF_MK7, True, True),
|
||||
(CAR.AUDI_Q5_MK1, True, False),
|
||||
(CAR.VOLKSWAGEN_ID4_MK1, True, False),
|
||||
(CAR.VOLKSWAGEN_GOLF_MK8, True, False),
|
||||
))
|
||||
def test_supported_vw_longitudinal_stays_active_during_gas_override(self, candidate, alpha_long, expected):
|
||||
fingerprints = {bus: {} for bus in range(7)}
|
||||
params = CarInterface.get_params(candidate, fingerprints, [], alpha_long=alpha_long, is_release=False, docs=False)
|
||||
params_iq = CarInterface.get_params_iq(params, candidate, fingerprints, [], alpha_long=alpha_long, is_release_iq=False, docs=False)
|
||||
assert params_iq.longActiveWithGasOverride is expected
|
||||
if expected:
|
||||
assert bool(params.safetyConfigs[-1].safetyParam & VolkswagenSafetyFlags.ALLOW_LONG_ACCEL_WITH_GAS_PRESSED) is alpha_long
|
||||
|
||||
|
||||
@pytest.mark.parametrize("button_type", (
|
||||
structs.CarState.ButtonEvent.Type.setCruise,
|
||||
|
||||
@@ -250,6 +250,8 @@ class TestVolkswagenPqLongSafety(TestVolkswagenPqSafetyBase, common.Longitudinal
|
||||
self._rx(self._user_gas_msg(1))
|
||||
self.safety.set_controls_allowed(True)
|
||||
self.assertTrue(self._tx(self._accel_msg(0.5)))
|
||||
self.assertTrue(self._tx(self._accel_msg(0.0)))
|
||||
self.assertTrue(self._tx(self._accel_msg(-0.5)))
|
||||
|
||||
|
||||
class TestVolkswagenPqLowlineSafety(TestVolkswagenPqSafetyBase):
|
||||
|
||||
1
artifacts/package_sources/tinygrad/.iqpilot-revision
Normal file
1
artifacts/package_sources/tinygrad/.iqpilot-revision
Normal file
@@ -0,0 +1 @@
|
||||
95bfc521351d3acba7338605686155a9ee8b0009
|
||||
93
artifacts/runtime/env_sync.sh
Executable file
93
artifacts/runtime/env_sync.sh
Executable file
@@ -0,0 +1,93 @@
|
||||
#!/usr/bin/env bash
|
||||
# Python env + proprietary runtime sync for the openpilot tree.
|
||||
#
|
||||
# Two callers, same steps:
|
||||
# - launch_chffrplus.sh sources this at boot and calls sync_python_env. When an
|
||||
# update was already prepared this is a warm no-op; when there is real work
|
||||
# (local dev edits, failed prep) it runs under the boot spinner as before.
|
||||
# - updated.py executes this standalone right after an update is applied to
|
||||
# disk, so the heavy uv/package work happens offroad with the stack idle
|
||||
# instead of at boot alongside everything else starting at once.
|
||||
#
|
||||
# Variables assigned here (VENV_SITE_PACKAGES, BASE_SITE_PACKAGES, ...) are
|
||||
# intentionally global: the sourced caller composes PYTHONPATH from them.
|
||||
|
||||
sync_python_env() {
|
||||
local DIR
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." >/dev/null && pwd )"
|
||||
|
||||
# Best-effort: install the verified runtime before anything starts the services that
|
||||
# need it. This only succeeds on a tree that has built _verified_import.so, so on a
|
||||
# prebuilt release install it is a no-op -- there the runtime arrives with the IQ.OS
|
||||
# flash, whose image bakes it in. What actually fixes the 20+ minute first-install hang
|
||||
# is --no-block on the service starts below: hephaestusd/ble-transportd/flockd each
|
||||
# ExecStartPre-wait up to 600s for /usr/libexec/iqpilot/iqpilot_bundle_runner.
|
||||
if [ -x "$DIR/iqpilot/system/proprietary_runtime/install_verified_runtime.sh" ]; then
|
||||
"$DIR/iqpilot/system/proprietary_runtime/install_verified_runtime.sh" || true
|
||||
fi
|
||||
|
||||
# Install/update proprietary runtime bundles.
|
||||
if [ -f "$DIR/artifacts/runtime/ensure_private_installed.sh" ]; then
|
||||
bash "$DIR/artifacts/runtime/ensure_private_installed.sh" || true
|
||||
elif [ -x "$DIR/scripts/iqpilot/ensure_navd_private_installed.sh" ]; then
|
||||
# Backward-compat fallback for older trees.
|
||||
"$DIR/scripts/iqpilot/ensure_navd_private_installed.sh" || true
|
||||
fi
|
||||
|
||||
PYTHONPATH="$DIR" /usr/local/venv/bin/python3 -c "from iqpilot.common.git_creds import install_credential_helper; install_credential_helper('$DIR')" 2>/dev/null || true
|
||||
PACKAGE_LOCK_SHA="$(sha256sum "$DIR/uv.lock" | awk '{print $1}')"
|
||||
INSTALLED_PACKAGE_LOCK_SHA="$(cat "$DIR/.iqpilot-package-lock-sha256" 2>/dev/null || true)"
|
||||
BASE_SITE_PACKAGES="$(/usr/local/venv/bin/python3 -c 'import site; print(site.getsitepackages()[0])')"
|
||||
PROJECT_RAYLIB="$("$DIR/.venv/bin/python3" -c 'import importlib.metadata; print(importlib.metadata.distribution("raylib").locate_file(""))' 2>/dev/null || true)"
|
||||
if [[ "$PROJECT_RAYLIB" = "$DIR/.venv"/* ]]; then
|
||||
sudo rm -rf "$DIR/.venv"
|
||||
rm -f "$DIR/.iqpilot-package-lock-sha256"
|
||||
INSTALLED_PACKAGE_LOCK_SHA=""
|
||||
fi
|
||||
VENV_SITE_PACKAGES="$("$DIR/.venv/bin/python3" -c 'import site; print(site.getsitepackages()[0])' 2>/dev/null || true)"
|
||||
PACKAGES_READY=0
|
||||
if [ -d "$DIR/artifacts/package_runtime" ] && PYTHONPATH="$DIR/artifacts/package_runtime" /usr/local/venv/bin/python3 -c "import iqdbc, msgq, panda, rednose, teleoprtc, tinygrad" 2>/dev/null; then
|
||||
PACKAGES_READY=1
|
||||
elif [ "$PACKAGE_LOCK_SHA" = "$INSTALLED_PACKAGE_LOCK_SHA" ] && "$DIR/.venv/bin/python3" -c "import iqdbc, msgq, panda, rednose, teleoprtc, tinygrad" 2>/dev/null \
|
||||
&& "$DIR/.venv/bin/python3" "$DIR/iqpilot/system/runtime_packages_verify.py"; then
|
||||
# a top-level import passes on a partially extracted install (lazy backends),
|
||||
# so readiness also requires every wheel RECORD file to exist on disk
|
||||
PACKAGES_READY=1
|
||||
fi
|
||||
if [ "$PACKAGES_READY" != "1" ]; then
|
||||
UV_CACHE_DIR="$DIR/.uv-cache"
|
||||
if [ ! -x "$DIR/.venv/bin/python3" ]; then
|
||||
UV_CACHE_DIR="$UV_CACHE_DIR" uv venv --python /usr/local/venv/bin/python3 "$DIR/.venv" || return 1
|
||||
VENV_SITE_PACKAGES="$("$DIR/.venv/bin/python3" -c 'import site; print(site.getsitepackages()[0])')"
|
||||
fi
|
||||
sudo chown -R "$(id -u):$(id -g)" "$DIR/.venv" "$UV_CACHE_DIR" "$DIR/artifacts/package_sources" 2>/dev/null || true
|
||||
IQDBC_PACKAGE_SOURCE=""
|
||||
PACKAGE_SOURCES=()
|
||||
while IFS=$'\t' read -r package_name package_source; do
|
||||
PACKAGE_SOURCES+=("$package_source")
|
||||
if [ "$package_name" = "iqdbc" ]; then
|
||||
IQDBC_PACKAGE_SOURCE="$package_source"
|
||||
fi
|
||||
done < <(/usr/local/venv/bin/python3 "$DIR/iqpilot/system/runtime_package_sources.py" "$DIR")
|
||||
if [ "${#PACKAGE_SOURCES[@]}" = "0" ] || [ -z "$IQDBC_PACKAGE_SOURCE" ]; then
|
||||
return 1
|
||||
fi
|
||||
PACKAGE_BUILD_PYTHONPATH="$BASE_SITE_PACKAGES:$VENV_SITE_PACKAGES"
|
||||
UV_CACHE_DIR="$UV_CACHE_DIR" PYTHONPATH="$PACKAGE_BUILD_PYTHONPATH" PATH="/usr/local/venv/bin:/usr/bin:$PATH" \
|
||||
uv pip install --python "$DIR/.venv/bin/python" --no-build-isolation --no-deps --reinstall "$IQDBC_PACKAGE_SOURCE" || return 1
|
||||
UV_CACHE_DIR="$UV_CACHE_DIR" PYTHONPATH="$PACKAGE_BUILD_PYTHONPATH" PATH="/usr/local/venv/bin:/usr/bin:$PATH" \
|
||||
uv pip install --python "$DIR/.venv/bin/python" --no-build-isolation --no-deps --reinstall "${PACKAGE_SOURCES[@]}" || return 1
|
||||
printf '%s\n' "$PACKAGE_LOCK_SHA" > "$DIR/.iqpilot-package-lock-sha256"
|
||||
fi
|
||||
if [ -n "$VENV_SITE_PACKAGES" ]; then
|
||||
printf 'import site; site.addsitedir("%s")\n' "$BASE_SITE_PACKAGES" | sudo tee "$VENV_SITE_PACKAGES/iqpilot-system-venv.pth" >/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
sync_python_env
|
||||
exit $?
|
||||
fi
|
||||
|
||||
# NOTE: keep this file in lockstep with the launch-time expectations above --
|
||||
# updated.py invokes it standalone and launch_chffrplus.sh sources it.
|
||||
@@ -41,6 +41,12 @@ def config_realtime_process(cores: int | list[int], priority: int) -> None:
|
||||
set_core_affinity(c)
|
||||
|
||||
|
||||
def config_background_thread() -> None:
|
||||
if sys.platform == 'linux' and not PC:
|
||||
os.sched_setscheduler(0, os.SCHED_OTHER, os.sched_param(0))
|
||||
set_core_affinity(list(range(os.cpu_count() or 1)))
|
||||
|
||||
|
||||
def lock_memory() -> None:
|
||||
"""mlockall this process so memory reclaim/compaction can't stall it. RT control
|
||||
procs only (locking ui/modeld would worsen pressure). Best-effort."""
|
||||
|
||||
@@ -6,7 +6,7 @@ from iqpilot.common.markdown import parse_markdown
|
||||
|
||||
class TestMarkdown:
|
||||
def test_all_release_notes(self):
|
||||
with open(os.path.join(BASEDIR, "docs", "CHANGELOG.md")) as f:
|
||||
with open(os.path.join(BASEDIR, "iqpilot", "docs", "CHANGELOG.md")) as f:
|
||||
release_notes = f.read().split("\n\n")
|
||||
assert len(release_notes) > 10
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
import pytest
|
||||
|
||||
from iqpilot.common.realtime import Ratekeeper
|
||||
from iqpilot.common.realtime import config_background_thread, Ratekeeper
|
||||
|
||||
|
||||
class MonotonicClock:
|
||||
@@ -47,3 +47,18 @@ def test_ratekeeper_reset_preserves_frame_count(monkeypatch):
|
||||
|
||||
rk.reset()
|
||||
assert rk.frame == frame
|
||||
|
||||
|
||||
def test_config_background_thread_restores_normal_scheduling(monkeypatch):
|
||||
calls = []
|
||||
monkeypatch.setattr("iqpilot.common.realtime.sys.platform", "linux")
|
||||
monkeypatch.setattr("iqpilot.common.realtime.PC", False)
|
||||
monkeypatch.setattr("iqpilot.common.realtime.os.cpu_count", lambda: 8)
|
||||
monkeypatch.setattr("iqpilot.common.realtime.os.SCHED_OTHER", 0, raising=False)
|
||||
monkeypatch.setattr("iqpilot.common.realtime.os.sched_param", lambda priority: priority, raising=False)
|
||||
monkeypatch.setattr("iqpilot.common.realtime.os.sched_setscheduler", lambda pid, policy, param: calls.append((pid, policy, param)), raising=False)
|
||||
monkeypatch.setattr("iqpilot.common.realtime.os.sched_setaffinity", lambda pid, cores: calls.append((pid, set(cores))), raising=False)
|
||||
|
||||
config_background_thread()
|
||||
|
||||
assert calls == [(0, 0, 0), (0, set(range(8)))]
|
||||
|
||||
321
iqpilot/docs/CHANGELOG.md
Normal file
321
iqpilot/docs/CHANGELOG.md
Normal file
@@ -0,0 +1,321 @@
|
||||
# IQ.Pilot User Changelog
|
||||
|
||||
## IQ.Pilot 1.0c Changelog
|
||||
|
||||
### Features
|
||||
|
||||
#### Navigate on IQ.Pilot
|
||||
|
||||
- Added Navigate on IQ.Pilot as a complete on-device navigation experience.
|
||||
- Added destination search with Home, Work, and Recent shortcuts.
|
||||
- Added live turn-by-turn guidance with automatic rerouting after a missed turn or route deviation.
|
||||
- Added traffic-aware online routing with automatic traffic refresh, delay tracking, closure awareness, and fresh-route metadata.
|
||||
- Added AMap destination search and routing for configured mainland China devices.
|
||||
- Added an interactive off-road map with panning and current-location display.
|
||||
- Added a split on-road map view so the camera, model path, route, current position, and upcoming maneuver remain visible together.
|
||||
- Added route-aware longitudinal planning for turns, highway exits, and highway forks.
|
||||
- Added route-aware lane-change guidance for supported highway exits.
|
||||
- Added route-commanded automatic turn signals on supported vehicles.
|
||||
- Added optional exit-lane-change assistance with Blind Spot Monitoring awareness.
|
||||
- Improved low-speed maneuver guidance so the model keeps the requested turn path while waiting and carries it through the committed turn.
|
||||
- Added route cancellation and saved-destination management from the Navigate screen in the Konn3kt app.
|
||||
|
||||
#### IQ Speed Assist
|
||||
|
||||
- Added the new IQ Speed Assist architecture.
|
||||
- Added TomTom speed-limit data alongside dashboard, Mapbox, and offline OpenStreetMap sources.
|
||||
- Added percentage-based offset zones for low, medium, and higher speed ranges.
|
||||
- Added direct integration of upcoming speed limits into the longitudinal cruise envelope for earlier and smoother reactions.
|
||||
|
||||
#### Construction Zone Assist
|
||||
|
||||
- Added optional camera-based Construction Zone Assist.
|
||||
- Added road-camera detection of bright orange work-zone barrels and markers.
|
||||
- Added an adjustable work-zone target speed with a 60 mph default.
|
||||
- Added daylight, road-speed, and active-zone state checks to reduce detections from unrelated reflective objects.
|
||||
|
||||
#### Camera Alerts
|
||||
|
||||
- Added direct Flock/ALPR hardware detection from nearby Bluetooth and Wi-Fi radio signatures.
|
||||
- Added warnings for mapped speed cameras, red-light cameras, and ALPR/Flock Safety cameras.
|
||||
- Direct radio detection works without internet access or preexisting map data, and can warn about a nearby unit before appearing in the map database.
|
||||
- Added optional speed-camera slowdown using the detected camera limit and a configurable safety factor.
|
||||
- Added optional haptic feedback on supported Hyundai/Kia/Genesis vehicles when approaching a speed camera.
|
||||
|
||||
#### IQ.Dynamic
|
||||
|
||||
- Added configurable IQ.Dynamic activation for curves, low road speeds, slower or stopped lead vehicles, and model-predicted stops.
|
||||
- Added separate road-speed, lead-speed, and model-stop timing controls.
|
||||
- Added on-device IQ.Dynamic configuration by double-tapping IQ.Dynamic in the longitudinal mode selector.
|
||||
- Added on-road IQ longitudinal-mode cycling through the nucleus icon on BIG UI devices.
|
||||
- Added optional stock-radar blending on supported Volkswagen PQ vehicles for more stable highway following.
|
||||
- Added IQ Force Stops for model-predicted stop lights and stop signs when no lead vehicle is present.
|
||||
- Added adjustable minimum stop length and stopping distance.
|
||||
|
||||
#### General Longitudinal Updates
|
||||
|
||||
- Added end-to-end cruise convergence so the vehicle returns toward the selected cruise speed as the road opens in IQ.Pilot (E2E) mode.
|
||||
- Added Smooth Stops for gentler final braking at regular and model-predicted stops.
|
||||
- Added smoother pull-away behavior and departure chimes when a lead moves or the path opens.
|
||||
- Added an optional Experimental Lead MPC mode.
|
||||
- Added earlier reactions to upcoming curves.
|
||||
|
||||
#### IQ Steering Assistance Behavior (SAB)
|
||||
|
||||
- Added a distinct lateral-only engagement border separate from full lateral-and-longitudinal engagement.
|
||||
- Added Always-On Lateral support through compatible Hyundai LFA buttons.
|
||||
- Added an optional mode that pauses steering torque when the driver takes the wheel and resumes after release.
|
||||
|
||||
#### Lane Changes
|
||||
|
||||
- Added a model-based road-edge guard that blocks unsafe lane changes with an alert.
|
||||
|
||||
#### Lateral Tuning
|
||||
|
||||
- Added configurable steering smoothing, slew limiting, and curvature lookahead.
|
||||
- Improved curve entry and reduced abrupt steering changes while preserving quick avoidance responses.
|
||||
- Added angle-based steering and optional torque blending for Volkswagen vehicles with ALC.
|
||||
- Added Volkswagen PQ HCA7 steering support and live-learned curvature correction on supported MEB vehicles.
|
||||
|
||||
#### Driving Models
|
||||
|
||||
- Added automatic model refresh and redownload when an installed model needs an update.
|
||||
- Added a clear Driving Model Updating state, and engagement now waits until the selected model is ready.
|
||||
|
||||
#### IQ eMac
|
||||
|
||||
- Added IQ eMac for running supported big driving models on an Apple Silicon Mac over USB.
|
||||
- Added a Big Model selector with Off, BRH, Lebowski, and RDF choices.
|
||||
- Added one-time model download and compilation on the Mac, with cached models for later drives.
|
||||
- Added automatic USB network setup with a one-time Mac administrator prompt when required.
|
||||
- Added USB AMD eGPU-dock support with automatic detection and recovery tools.
|
||||
|
||||
#### IQ eMac App
|
||||
|
||||
- Added a native Mac app for starting, monitoring, restarting, and stopping IQ eMac.
|
||||
- Added live connection, model, download, compilation, inference rate, latency, and session status.
|
||||
- Added persistent menu-bar operation with compact live statistics.
|
||||
|
||||
#### Home Screen and Off-Road UI
|
||||
|
||||
- Added a new IQ.Pilot home screen with dedicated Routes, Navigation, Video, and status views.
|
||||
- Added a selectable home-panel widget and an expanded status bar.
|
||||
- Added 60 fps BIG UI presentation and improved Comma 4 visuals.
|
||||
- Added connected Wi-Fi, vehicle state, temperature, Konn3kt status, and installed IQ.OS version displays.
|
||||
- Added automatic mph or km/h selection based on the device location.
|
||||
- Added smoother navigation, transitions, animations, and controls.
|
||||
- Added Polish and expanded translations throughout the Comma 4 UI and IQ.Pilot settings.
|
||||
|
||||
#### On-Road UI
|
||||
|
||||
- Added a glowing orb for the primary lead vehicle.
|
||||
- Added live Konn3kt accent colors across borders, lane lines, controls, and sliders.
|
||||
- Updated the acceleration bar with IQ.Pilot's teal and pink visual style.
|
||||
- Added on-road longitudinal personality selection.
|
||||
- Added a Silent Mode bell control.
|
||||
- Added Night Mode for automatic display sleep after sunset.
|
||||
- Added a gradual volume ramp for immediate warning alerts.
|
||||
- Added screen recording through Konn3kt.
|
||||
|
||||
#### Dashcam and Routes
|
||||
|
||||
- Increased dashcam (qcam) video resolution by 5x.
|
||||
- Added a master dashcam control for route logging, video, and audio.
|
||||
- Added crash-safe recording with recovery after power loss or an interrupted route.
|
||||
- Added an on-device Routes screen with drive details and upload status.
|
||||
- Added model path, steering angle, driver-monitoring state, speed, and cruise-speed overlays to the route viewer in the Konn3kt app.
|
||||
|
||||
#### Live View, Audio, and WebSSH
|
||||
|
||||
- Added live on-road video over cellular/Wi-Fi with the model path overlay.
|
||||
- Added full-resolution HDR driver-camera video on Comma 4.
|
||||
- Added microphone audio and two-way voice communication through Konn3kt.
|
||||
- Added an on-road indicator while Live View is active.
|
||||
- Added road, wide, and driver-camera snapshots.
|
||||
- Added faster camera switching, adaptive video quality, and dual-camera picture-in-picture.
|
||||
- Improved Konn3kt WebSSH connection reliability.
|
||||
|
||||
#### Konn3kt Services
|
||||
|
||||
- Konn3kt now remains available when IQ.Pilot is stopped or cannot open its main UI.
|
||||
- Added remote recovery access over Wi-Fi and cellular.
|
||||
- Added faster reconnection after network or IP-address changes.
|
||||
- Added dedicated route, log, and crash-log uploading.
|
||||
- Added Volkswagen and Tesla odometer display.
|
||||
- Added encrypted device backup and restore.
|
||||
- Added supported Volkswagen coding, diagnostic controls, and EPS flashing through Konn3kt.
|
||||
|
||||
#### Konn3kt Bluetooth Control
|
||||
|
||||
- Added direct Bluetooth control from the Konn3kt app across supported IQ.OS devices.
|
||||
- Added Bluetooth synchronization for vehicle, display, network, navigation, and driving settings.
|
||||
- Added automatic discovery and pairing without manual network configuration.
|
||||
- Added automatic Bluetooth fallback when Wi-Fi or cellular service is unavailable.
|
||||
- Added setup-stage Wi-Fi configuration, channel selection, and installation control.
|
||||
|
||||
#### Volkswagen PQ and MQB
|
||||
|
||||
- Expanded Volkswagen PQ and MQB vehicle support.
|
||||
- Added Volkswagen Passat B7/NMS and SEAT Alhambra Stop-and-Go support.
|
||||
- Added Stop-and-Go and automatic-resume improvements across supported PQ and MQB vehicles.
|
||||
- Added stock-radar blending with IQ.Dynamic on supported PQ vehicles.
|
||||
- Added automatic PQ steering-patch detection and minimum-steering-speed handling.
|
||||
- Added Volkswagen PQ firmware backup, patching, programming, and recovery tools.
|
||||
- Added PQ and MQB steering coding and compatibility checks through Konn3kt.
|
||||
- Added continued PQ and MQB lateral control during cruise faults.
|
||||
- Added an MQB Steering Lockout toggle that reduces low-speed steering torque to prevent LKAS faults on sensitive MQB vehicles.
|
||||
|
||||
#### Volkswagen MEB and MQBevo
|
||||
|
||||
- Added official Volkswagen MEB and MQBevo support.
|
||||
- Added supported Volkswagen ID.3, ID.4, ID.5, and Golf Mk8 configurations through model year 2025.
|
||||
- Added platform-specific steering, zero-speed steering, and ACC display support.
|
||||
- Added vehicle Drive/Park state handling and reliable device wake support.
|
||||
|
||||
#### Toyota and Lexus
|
||||
|
||||
- Added Toyota and Lexus Stop-and-Go support with an optional compatibility mode.
|
||||
- Added SDSU support.
|
||||
- Fixed ignition handling so the device returns off-road in Park.
|
||||
|
||||
#### Hyundai, Kia, and Genesis
|
||||
|
||||
- Added more supported Hyundai, Kia, and Genesis variants.
|
||||
- Added expanded CAN-FD, HDA2, Camera SCC, radar-track, and corner-radar support.
|
||||
- Added Auto Cruise Control and Auto Engage options on compatible vehicles.
|
||||
- Added custom steering maximum and steering-rate controls.
|
||||
- Added lane-change-specific steering-rate controls.
|
||||
- Added speed-camera haptics and Always-On Lateral support through compatible LFA buttons.
|
||||
|
||||
#### Honda, Subaru, and Tesla
|
||||
|
||||
- Added smoother final braking on supported Honda vehicles.
|
||||
- Added Subaru Creep from Standstill.
|
||||
- Added support for additional Tesla configurations and Model Y steering firmware.
|
||||
- Fixed Tesla stock-DAS cancellation so cruise speed remains available for IQ.Pilot longitudinal control.
|
||||
- Added an optional Tesla FSD/Autosteer visualization mode while IQ.Pilot steers.
|
||||
|
||||
#### IQ.OS
|
||||
|
||||
- Updated device firmware to IQ.OS 4.9.7.
|
||||
- Added support for Comma 3, Comma 3X, Comma 4, Konik A1/M, and Mr.One C3/C3 Lite.
|
||||
- Added per-unit Comma 4 display calibration and HDR camera color support.
|
||||
- Reduced Comma 3 cold-boot time from 39 seconds to 21 seconds.
|
||||
- Improved USB link recovery for IQ eMac and eGPU configurations.
|
||||
- Improved Konik A1 audio reliability.
|
||||
- Added assisted GPS acquisition through Konn3kt.
|
||||
|
||||
#### FastSleep and Power Management
|
||||
|
||||
- Added FastSleep deep standby after the vehicle is parked.
|
||||
- Added faster standby when vehicle battery voltage begins to drop.
|
||||
- Added staged low-voltage shutdown protection.
|
||||
- Kept Konn3kt recovery access available while high-power IQ.Pilot services sleep.
|
||||
- Added immediate wake when ignition or charging is detected.
|
||||
|
||||
#### Bluetooth Setup and Controller Support
|
||||
|
||||
- Added zero-touch Bluetooth onboarding with Konn3kt pairing and setup progress.
|
||||
- Added IQ.OS update confirmation through Konn3kt.
|
||||
- Kept Bluetooth controls available independently from the main IQ.Pilot process.
|
||||
|
||||
#### Network, Cellular, and eSIM
|
||||
|
||||
- Added a new Network settings experience on Comma 3 and Comma 4.
|
||||
- Added a direct Wi-Fi Disconnect action.
|
||||
- Added automatic cellular reconnection after APN changes.
|
||||
- Added SIM recovery for Comma 3X devices with a worn tray-presence switch.
|
||||
- Added experimental eSIM setup and profile management through QR or manual activation codes.
|
||||
|
||||
#### Device and Recovery Controls
|
||||
|
||||
- Added Force On-Road for a temporary ten-minute diagnostic session while parked.
|
||||
- Added Update & Reboot on the crash and recovery screen.
|
||||
- Added USB Storage mode to access device storage over USB.
|
||||
|
||||
#### Updater and Installation
|
||||
|
||||
- Added a new IQ.Pilot and IQ.OS update workflow.
|
||||
- Added Predownload Only and Predownload + Preinstall modes.
|
||||
- Added interrupted-installation recovery.
|
||||
|
||||
#### Reliability and Camera Fault Recovery
|
||||
|
||||
- Added independent recovery for navigation and map services.
|
||||
- Added automatic wide-camera fault detection so the road and driver cameras can continue operating, with an on-road warning after fallback.
|
||||
- Improved calibration recovery and protected driving services from map-service communication stalls.
|
||||
|
||||
---
|
||||
|
||||
### Technical Changes
|
||||
|
||||
- Reduced the IQ.Pilot total installation size to just 139.48 MiB.
|
||||
- Removed the legacy openpilot source mirror, compatibility directories, and obsolete source aliases.
|
||||
- Removed every Git submodule from the IQ.Pilot repository.
|
||||
- Updated release builds to vendor the exact pinned component sources and required LFS assets into a self-contained installation without nested Git repositories or private source URLs.
|
||||
- Added navigation-memory handling so important fork and exit guidance remains available when a model output briefly omits it.
|
||||
- Added on-device map rendering and route-state services designed specifically for IQ.Pilot.
|
||||
- Reduced navigation CPU, GPU, and memory overhead so the map can remain open for long drives without competing with the driving model.
|
||||
- Added full offline routing through a packaged Valhalla runtime.
|
||||
- Added offline navigation that can operate without Mapbox or an active internet connection.
|
||||
- Added support for keeping multiple offline regions installed simultaneously.
|
||||
- Added offline raster map tiles for the on-screen map, not only route calculation and road metadata.
|
||||
- Added separate Online On-Screen Maps and Offline On-Screen Maps controls.
|
||||
- Added resumable regional map downloads for unstable cellular and hotspot connections.
|
||||
- Added combined download progress for routing databases and rendered map tiles.
|
||||
- Added automatic recognition of already installed map regions.
|
||||
- Added automatic restoration of missing offline-map data.
|
||||
- Added a pinned IQ.Pilot mapd v2 fork with binary verification and automatic quarantine of incompatible mapd builds.
|
||||
- Added a hosted regional tile-bundle service with a secondary fallback source.
|
||||
- Added background tile decoding and bounded texture caching to keep map work off the UI render path.
|
||||
- Added automatic stock-radar set-speed and following-gap synchronization on supported Volkswagen vehicles.
|
||||
- Hardened Experimental Lead MPC with model-horizon validation and automatic radar-trajectory fallback when model lead data is missing, malformed, or non-finite.
|
||||
- Added Bluetooth-controller commands for testing or controlling Always-On Lateral in Joystick Mode.
|
||||
- Added the unified IQModeld runtime.
|
||||
- Added a native IQModeld bridge for current combined models and legacy split models.
|
||||
- Added fused vision-and-policy execution for supported supercombo bundles.
|
||||
- Added zero-copy camera-frame handling through the current tinygrad runner.
|
||||
- Added combined-artifact, combined-split, fused, tinygrad, and ONNX runner support under one manager.
|
||||
- Added signed and notarized Mac packaging with improved USB transport diagnostics.
|
||||
- Added stable border-crossing detection and last-known-location fallback for IQ Auto Units.
|
||||
- Added tappable branch information in the BIG UI header.
|
||||
- Fixed live language updates and several previously untranslated or malformed translations.
|
||||
- Added qlog-only route visualization, allowing the model path and driving telemetry to be viewed even when only a qlog and qcam are uploaded, and no rlog is available.
|
||||
- Hardened Qualcomm encoder polling and H.264 filtering for more reliable route recording.
|
||||
- Fixed upload queues that could stall behind a missing build-version file.
|
||||
- Fixed route-upload cache invalidation when a file is replaced at the same path, preventing stale upload state from being reused.
|
||||
- Added automatic LocalAPI deployment and configuration.
|
||||
- Fixed periodic Konn3kt disconnects caused by numeric heartbeat parameters terminating the connection writer.
|
||||
- Added authenticated BLE requests, replay protection, and a dedicated settings RPC dispatcher.
|
||||
- Added live propagation of BLE setting changes to the device UI and active IQ.Pilot services.
|
||||
- Added TRW450 ACC handling for the Volkswagen Passat B7/NMS.
|
||||
- Added MQB standstill handling for supported non-EPB ACC vehicles.
|
||||
- Added dedicated PQ radar engagement, cancellation, set-speed, acceleration, and following-gap management.
|
||||
- Added model-year ECU fingerprint checks and expanded Passat identification.
|
||||
- Added explicit Volkswagen car-readiness state handling.
|
||||
- Added on-car MLB longitudinal refinements and HCA steering-status configuration for compatible Audi and Porsche platforms.
|
||||
- Corrected Porsche Macan vehicle selection and Volkswagen-group settings presentation.
|
||||
- Added MEB camera-harness support for lateral control with stock ACC and compatible gateway-harness support for IQ.Pilot longitudinal control.
|
||||
- Added broader Hyundai/Kia/Genesis vehicle parameter and fingerprint diagnostics.
|
||||
- Added guarded Tesla vehicle-bus parsing for supported harness configurations.
|
||||
- Added kernel-level USB 3 logging support.
|
||||
- Added updated USB 3 receive equalization and VGA calibration for improved link stability.
|
||||
- Added 2 GB compressed zram swap for additional memory headroom.
|
||||
- Fixed GPS clock synchronization to interpret and apply timestamps in UTC.
|
||||
- Forced the Qualcomm camera BPS pipeline to its maximum clock for more consistent frame processing.
|
||||
- Disabled unsupported EGL zero-copy paths on Comma 4 while retaining them on compatible Comma 3 and Comma 3X hardware.
|
||||
- Added in-process audio-stream retries so an unavailable Konik A1 audio DSP does not crash-loop the alert service.
|
||||
- Added cached Konn3kt-assisted GPS data with freshness checks for faster GNSS acquisition when no local AssistNow token is configured.
|
||||
- Added measured-voltage power decisions while FastSleep is active.
|
||||
- Added an authenticated Bluetooth GATT transport and RPC dispatcher.
|
||||
- Added live remote CAN streaming from a device into Cabana through Konn3kt.
|
||||
- Updated Cabana and Jotpluggler to current upstream tool foundations while retaining Konn3kt device, route, DBC, and direct remote-stream support.
|
||||
- Added replay support for IQ.Pilot's crash-safe H.264 fragmented-MP4 recordings, including correct container seeking, decoder-delay handling, and multi-frame packet output.
|
||||
- Added a precompiled release pipeline for comma 3, comma 3X, and comma 4.
|
||||
- Added automatic runtime-package bootstrap, revision pinning, and credential reuse for fresh devices and updates.
|
||||
- Added the iq command center for setup, environment checks, builds, quality checks, package synchronization, status, branch switching, updates, service control, fast restart, and optional reboot.
|
||||
- Added an IQ.Pilot process layout built around independent model, navigation, map, uploader, backup, and perception services.
|
||||
- Added clearer on-device build, process-state, and diagnostic output.
|
||||
- Improved Panda SPI NACK handling for more reliable device-to-vehicle communication.
|
||||
- Hardened calibration by clearing invalid saved calibration, preserving stable solutions during excessive spread on supported comma 3/3X hardware, and rejecting implausible camera-height data before model or path projection.
|
||||
- Added validation for every public vehicle platform and route plus expanded deterministic and ARM64 process-replay coverage.
|
||||
Binary file not shown.
Binary file not shown.
@@ -12,7 +12,7 @@ from iqpilot.cereal import car, log, custom
|
||||
|
||||
from iqpilot.common.iq_perf import PerfSample, PerfTraceEmitter, PerfTraceRing
|
||||
from iqpilot.common.params import Params, UnknownKeyName
|
||||
from iqpilot.common.realtime import config_realtime_process, lock_memory, Priority, Ratekeeper
|
||||
from iqpilot.common.realtime import config_background_thread, config_realtime_process, lock_memory, Priority, Ratekeeper
|
||||
from iqpilot.common.swaglog import cloudlog, ForwardingHandler
|
||||
|
||||
from iqdbc.car import DT_CTRL, structs
|
||||
@@ -497,6 +497,7 @@ class Car:
|
||||
pass
|
||||
|
||||
def params_thread(self, evt):
|
||||
config_background_thread()
|
||||
while not evt.is_set():
|
||||
self.is_metric = self.params.get_bool("IsMetric")
|
||||
self.experimental_mode = self.params.get_bool("ExperimentalMode") and self.CP.openpilotLongitudinalControl
|
||||
|
||||
@@ -91,9 +91,5 @@ class LongControl:
|
||||
freeze_integrator=gas_override)
|
||||
self.smooth.reset()
|
||||
|
||||
if gas_override:
|
||||
# safety blocks braking while the gas is pressed, and a blocked tx drops the whole frame
|
||||
output_accel = max(output_accel, 0.0)
|
||||
|
||||
self.last_output_accel = np.clip(output_accel, accel_limits[0], accel_limits[1])
|
||||
return self.last_output_accel
|
||||
|
||||
@@ -16,17 +16,17 @@ from iqpilot.selfdrive.controls.lib.latcontrol_torque import TORQUE_NN_MODEL_PAT
|
||||
# layers). Used as a fallback so the loader logic is still exercised when no trained
|
||||
# models are shipped (they are removed pending retraining and re-added over time).
|
||||
_SYNTHETIC_MODEL = {
|
||||
"input_size": 4,
|
||||
"input_size": 18,
|
||||
"output_size": 1,
|
||||
"input_mean": [[0.0], [0.0], [0.0], [0.0]],
|
||||
"input_std": [[1.0], [1.0], [1.0], [1.0]],
|
||||
"input_mean": [[0.0]] * 18,
|
||||
"input_std": [[1.0]] * 18,
|
||||
"layers": [
|
||||
{"dense_1_W": [[0.5, 0.5, 0.5, 0.5], [0.5, 0.5, 0.5, 0.5]], "dense_1_b": [[0.0], [0.0]], "activation": "sigmoid"},
|
||||
{"dense_1_W": [[0.5] * 18, [0.5] * 18], "dense_1_b": [[0.0], [0.0]], "activation": "sigmoid"},
|
||||
{"dense_2_W": [[2.0, 2.0]], "dense_2_b": [[-1.0]], "activation": "identity"},
|
||||
],
|
||||
}
|
||||
|
||||
MODEL_FILES = sorted(f for f in os.listdir(TORQUE_NN_MODEL_PATH) if f.endswith(".json"))
|
||||
MODEL_FILES = sorted(f for f in os.listdir(TORQUE_NN_MODEL_PATH) if f.endswith(".json")) if os.path.isdir(TORQUE_NN_MODEL_PATH) else []
|
||||
if MODEL_FILES:
|
||||
_MODEL_DIR = TORQUE_NN_MODEL_PATH
|
||||
_NAMES = MODEL_FILES
|
||||
|
||||
@@ -15,15 +15,9 @@ from iqpilot.common.params import Params
|
||||
from iqpilot.common.pid import PIDController
|
||||
from iqpilot.selfdrive.iqmodeld.config import ModelConstants
|
||||
from iqpilot.selfdrive.controls.lib.latcontrol_torque import NeuralNetworkFeedForward
|
||||
from iqpilot.selfdrive.controls.lib.latcontrol_torque import TORQUE_NN_MODEL_PATH
|
||||
from iqpilot.selfdrive.controls.lib.neural_network_feed_forward.tests.test_network import _MODEL_DIR, _NAMES
|
||||
|
||||
_REAL_MODEL = next((f for f in sorted(os.listdir(TORQUE_NN_MODEL_PATH))
|
||||
if f.endswith(".json") and f != "MOCK.json"), None)
|
||||
|
||||
# Models are shipped separately and re-added as retrained; with none present,
|
||||
# NNFF is a no-op (falls back to stock torque FF), so the assembly tests skip.
|
||||
pytestmark = pytest.mark.skipif(_REAL_MODEL is None,
|
||||
reason="no NNFF models present (nuked pending retraining)")
|
||||
_REAL_MODEL = next((f for f in _NAMES if f != "MOCK.json"), _NAMES[0])
|
||||
|
||||
|
||||
def _torque_fn():
|
||||
@@ -53,7 +47,7 @@ def _model_v2():
|
||||
|
||||
def _make_controller(model_file):
|
||||
Params().put_bool("NeuralNetworkFeedForward", True)
|
||||
path = os.path.join(TORQUE_NN_MODEL_PATH, model_file)
|
||||
path = os.path.join(_MODEL_DIR, model_file)
|
||||
cp = SimpleNamespace(steerActuatorDelay=0.15)
|
||||
cp_iq = SimpleNamespace(iqLateralNet=SimpleNamespace(
|
||||
model=SimpleNamespace(path=path, name=os.path.splitext(model_file)[0])))
|
||||
@@ -84,7 +78,10 @@ class TestControllerWiring:
|
||||
def test_mock_model_reports_absent(self):
|
||||
nnff = _make_controller("MOCK.json")
|
||||
assert nnff.has_nn_model is False
|
||||
assert nnff.model.input_size >= 2 # MOCK still loads as a valid net
|
||||
if "MOCK.json" in _NAMES:
|
||||
assert nnff.model.input_size >= 2
|
||||
else:
|
||||
assert nnff.model is None
|
||||
|
||||
def test_update_returns_finite_torque(self):
|
||||
nnff = _make_controller(_REAL_MODEL)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
from types import SimpleNamespace
|
||||
|
||||
from iqpilot.cereal import custom
|
||||
from iqpilot.selfdrive.controls.lib.longcontrol import LongCtrlState, long_control_state_trans
|
||||
from iqpilot.selfdrive.controls.lib.longcontrol import LongControl, LongCtrlState, long_control_state_trans
|
||||
|
||||
|
||||
class TestLongControlStateTransition:
|
||||
@@ -41,3 +43,30 @@ def test_engage():
|
||||
next_state = long_control_state_trans(CP_IQ, active, current_state,
|
||||
should_stop=False, brake_pressed=False, cruise_standstill=False)
|
||||
assert next_state == LongCtrlState.pid
|
||||
|
||||
|
||||
def test_gas_override_preserves_negative_accel_command():
|
||||
pid_calls = []
|
||||
control = object.__new__(LongControl)
|
||||
control.CP = SimpleNamespace(stopAccel=-0.55)
|
||||
control.CP_IQ = SimpleNamespace(enableGasInterceptor=False)
|
||||
control.long_control_state = LongCtrlState.pid
|
||||
control.pid = SimpleNamespace(
|
||||
update=lambda error, **kwargs: pid_calls.append((error, kwargs)) or -0.5,
|
||||
reset=lambda: None,
|
||||
)
|
||||
control.last_output_accel = -0.4
|
||||
control.stopping_decel_rate = 1.0
|
||||
control.smooth = SimpleNamespace(enabled=False, update=lambda: None, reset=lambda: None)
|
||||
car_state = SimpleNamespace(
|
||||
vEgo=15.0,
|
||||
aEgo=0.0,
|
||||
brakePressed=False,
|
||||
standstill=False,
|
||||
cruiseState=SimpleNamespace(standstill=False),
|
||||
)
|
||||
|
||||
output = control.update(True, car_state, -0.5, False, (-3.5, 2.0), gas_override=True)
|
||||
|
||||
assert output == -0.5
|
||||
assert pid_calls == [(-0.5, {"speed": 15.0, "feedforward": -0.5, "freeze_integrator": True})]
|
||||
|
||||
@@ -11,6 +11,7 @@ MODELS_DIR = MODELD_DIR / 'models'
|
||||
BASEDIR = MODELD_DIR.parents[2]
|
||||
METADATA_SCRIPT = MODELD_DIR / 'get_model_metadata.py'
|
||||
PYPROJECT = BASEDIR / 'pyproject.toml'
|
||||
TINYGRAD_REVISION_FILE = BASEDIR / 'artifacts/package_sources/tinygrad/.iqpilot-revision'
|
||||
|
||||
MODEL_NAMES = ['dmonitoring_model']
|
||||
|
||||
@@ -30,9 +31,16 @@ def _file_sha256(path: Path) -> str:
|
||||
@functools.lru_cache(maxsize=1)
|
||||
def _tinygrad_revision() -> str:
|
||||
match = re.search(r'"tinygrad @ git\+https://[^@]+@([0-9a-f]{40})"', PYPROJECT.read_text())
|
||||
if match is None:
|
||||
raise RuntimeError("missing pinned tinygrad revision")
|
||||
return match.group(1)
|
||||
if match is not None:
|
||||
return match.group(1)
|
||||
|
||||
try:
|
||||
revision = TINYGRAD_REVISION_FILE.read_text().strip()
|
||||
except OSError as e:
|
||||
raise RuntimeError("missing pinned tinygrad revision") from e
|
||||
if re.fullmatch(r'[0-9a-f]{40}', revision) is None:
|
||||
raise RuntimeError("invalid pinned tinygrad revision")
|
||||
return revision
|
||||
|
||||
|
||||
CHECK_PATH = MODELS_DIR / 'prebuilt_check.json'
|
||||
|
||||
@@ -49,3 +49,17 @@ def test_source_checkout_is_not_packaged_prebuilt(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(prebuilt_models, 'CHECK_PATH', check_path)
|
||||
|
||||
assert not prebuilt_models.packaged_prebuilt_matches('dmonitoring_model')
|
||||
|
||||
|
||||
def test_vendored_tinygrad_revision(tmp_path, monkeypatch):
|
||||
revision = '0123456789abcdef0123456789abcdef01234567'
|
||||
pyproject = tmp_path / 'pyproject.toml'
|
||||
revision_file = tmp_path / '.iqpilot-revision'
|
||||
pyproject.write_text('dependencies = ["tinygrad"]\n')
|
||||
revision_file.write_text(f'{revision}\n')
|
||||
monkeypatch.setattr(prebuilt_models, 'PYPROJECT', pyproject)
|
||||
monkeypatch.setattr(prebuilt_models, 'TINYGRAD_REVISION_FILE', revision_file)
|
||||
prebuilt_models._tinygrad_revision.cache_clear()
|
||||
|
||||
assert prebuilt_models._tinygrad_revision() == revision
|
||||
prebuilt_models._tinygrad_revision.cache_clear()
|
||||
|
||||
@@ -12,7 +12,7 @@ from msgq.visionipc import VisionIpcClient
|
||||
|
||||
from iqpilot.common.params import Params
|
||||
from iqpilot.common.issue_debug import log_issue_limited
|
||||
from iqpilot.common.realtime import config_realtime_process, lock_memory, Priority, Ratekeeper, DT_CTRL
|
||||
from iqpilot.common.realtime import config_background_thread, config_realtime_process, lock_memory, Priority, Ratekeeper, DT_CTRL
|
||||
from iqpilot.common.swaglog import cloudlog
|
||||
from iqpilot.common.gps import get_gps_location_service
|
||||
|
||||
@@ -755,6 +755,7 @@ class SelfdriveD(GapButtonActions):
|
||||
)
|
||||
|
||||
def params_thread(self, evt):
|
||||
config_background_thread()
|
||||
while not evt.is_set():
|
||||
self.is_metric = self.params.get_bool("IsMetric")
|
||||
self.is_ldw_enabled = self.params.get_bool("IsLdwEnabled")
|
||||
|
||||
@@ -98,7 +98,7 @@ class ChangelogWidget(Widget):
|
||||
return
|
||||
self._last_load = now
|
||||
|
||||
paths = [os.path.join(BASEDIR, "docs", "CHANGELOG.md")]
|
||||
paths = [os.path.join(BASEDIR, "iqpilot", "docs", "CHANGELOG.md")]
|
||||
content = ""
|
||||
for p in paths:
|
||||
try:
|
||||
@@ -110,7 +110,7 @@ class ChangelogWidget(Widget):
|
||||
pass
|
||||
|
||||
if not content:
|
||||
content = "No changelog found.\n\nAdd docs/CHANGELOG.md."
|
||||
content = "No changelog found.\n\nAdd iqpilot/docs/CHANGELOG.md."
|
||||
|
||||
ordered = self._reorder_sections_newest_first(content)
|
||||
self._latest_text = self._build_latest_text(ordered)
|
||||
|
||||
@@ -60,11 +60,6 @@ sound_list: dict[int, tuple[str, int | None, float]] = {
|
||||
|
||||
**sound_list_iq,
|
||||
}
|
||||
if HARDWARE.get_device_type() in ("tizi", "tici"):
|
||||
sound_list.update({
|
||||
AudibleAlert.engage: ("engage.wav", 1, MAX_VOLUME),
|
||||
AudibleAlert.disengage: ("disengage.wav", 1, MAX_VOLUME),
|
||||
})
|
||||
|
||||
def check_selfdrive_timeout_alert(sm):
|
||||
ss_missing = time.monotonic() - sm.recv_time['selfdriveState']
|
||||
|
||||
@@ -18,8 +18,8 @@ def run(args, **kwargs):
|
||||
|
||||
|
||||
def update_release(directory, name, version, agnos_version, release_notes):
|
||||
(directory / "docs").mkdir(parents=True, exist_ok=True)
|
||||
with open(directory / "docs" / "CHANGELOG.md", "w") as f:
|
||||
(directory / "iqpilot" / "docs").mkdir(parents=True, exist_ok=True)
|
||||
with open(directory / "iqpilot" / "docs" / "CHANGELOG.md", "w") as f:
|
||||
f.write(release_notes)
|
||||
|
||||
(directory / "iqpilot" / "common").mkdir(parents=True, exist_ok=True)
|
||||
|
||||
@@ -94,7 +94,7 @@ def cleanup_stale_overlay() -> None:
|
||||
|
||||
def parse_release_notes(basedir: str) -> bytes:
|
||||
try:
|
||||
with open(os.path.join(basedir, "docs", "CHANGELOG.md"), "rb") as f:
|
||||
with open(os.path.join(basedir, "iqpilot", "docs", "CHANGELOG.md"), "rb") as f:
|
||||
r = f.read().split(b'\n\n', 1)[0] # Slice latest release notes
|
||||
try:
|
||||
return bytes(parse_markdown(r.decode("utf-8")), encoding="utf-8")
|
||||
@@ -462,7 +462,7 @@ def prepare_environment() -> bool:
|
||||
subprocess.check_output(cmd, cwd=cwd, stderr=subprocess.STDOUT, encoding="utf8", env=env)
|
||||
|
||||
try:
|
||||
env_sync = os.path.join(BASEDIR, "scripts", "iqpilot", "env_sync.sh")
|
||||
env_sync = os.path.join(BASEDIR, "artifacts", "runtime", "env_sync.sh")
|
||||
if os.path.exists(env_sync):
|
||||
cloudlog.info("update prep: syncing python env")
|
||||
_run(["bash", env_sync], BASEDIR)
|
||||
|
||||
@@ -33,7 +33,7 @@ def get_version(path: str = BASEDIR) -> str:
|
||||
|
||||
|
||||
def get_release_notes(path: str = BASEDIR) -> str:
|
||||
with open(os.path.join(path, "docs", "CHANGELOG.md")) as f:
|
||||
with open(os.path.join(path, "iqpilot", "docs", "CHANGELOG.md")) as f:
|
||||
return f.read().split('\n\n', 1)[0]
|
||||
|
||||
|
||||
|
||||
@@ -167,11 +167,11 @@ function launch {
|
||||
fi
|
||||
fi
|
||||
|
||||
# Python env + proprietary runtime sync. Lives in scripts/iqpilot/env_sync.sh so updated.py
|
||||
# Python env + proprietary runtime sync. Lives in artifacts/runtime/env_sync.sh so updated.py
|
||||
# can run the identical steps at update-apply time (offroad, stack idle); by the
|
||||
# time this runs at boot it is normally a warm no-op. Real work still lands here
|
||||
# for local dev edits or a failed apply-time prep, under the boot spinner as before.
|
||||
source "$DIR/scripts/iqpilot/env_sync.sh"
|
||||
source "$DIR/artifacts/runtime/env_sync.sh"
|
||||
sync_python_env || return 1
|
||||
export PATH="$DIR/.venv/bin:$PATH"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user