diff --git a/artifacts/iqpilot_hephaestusd_private/manifest.json b/artifacts/iqpilot_hephaestusd_private/manifest.json index d130454..8893405 100644 --- a/artifacts/iqpilot_hephaestusd_private/manifest.json +++ b/artifacts/iqpilot_hephaestusd_private/manifest.json @@ -16,27 +16,27 @@ }, "python/iqpilot_private/konn3kt/backups/archive_codec.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "3153fede975ec92281e8b33acf9dfd6305a24696f4b877df651f3742a67f368e", + "sha256": "8f9c7215f23878cf3ca3a07f013850f7e889a9e10deb4c1ec8bdabae488723e6", "size": 135536 }, "python/iqpilot_private/konn3kt/backups/backup_keys.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "37d32ea795dddce22b47ad2bdec838d360894b325719f48bab6d1be8427d3026", + "sha256": "c0d031c33712c71abcad3f9e10aa8e987ee801e20407a98344295e008657aab9", "size": 67664 }, "python/iqpilot_private/konn3kt/backups/backup_orchestrator.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "c71f7680e32cee7117409c399e915ad3740120c76a3e74af843d7f04644f0d08", + "sha256": "e049af92c953da53db2728f23484d8d691c9834d4130e3b6caa19c3ae69ce86d", "size": 204624 }, "python/iqpilot_private/konn3kt/backups/cbc_vault.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "71d52c82a254f0a66bc78dd947623747131a8883579f73fa61915d17bd2f4787", + "sha256": "a73a6a7ba5ac0a87d114db02e895921f0c452e9a8c6bd622116d94c347216ef1", "size": 69752 }, "python/iqpilot_private/konn3kt/backups/imahelper.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "1163d7ffafaa9179812c65362c3b99d47bd880747731009bf7d81cdef872f2d0", + "sha256": "692bde7a464bcef05c8b684224cc8fd6a6c05d226775ed3e81b6a02c748e11c5", "size": 203072 }, "python/iqpilot_private/konn3kt/hephaestus/__init__.py": { @@ -46,67 +46,67 @@ }, "python/iqpilot_private/konn3kt/hephaestus/_vendor/localapi_runtime.zip": { "mode": 420, - "sha256": "a6f2e86d5f44caabab7070263d9cc17c9222365e8f1ef04a1a6d27db0d2c2e88", + "sha256": "832067fea89470fc6224abc8b49c2624e0278e0027ea4e0bb93f939e03938230", "size": 2100238 }, "python/iqpilot_private/konn3kt/hephaestus/ble_auth.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "fbe4f442f7914a0238b7e78bfebe7b99f19e517122bfa5b2467c46ed73df1f05", + "sha256": "92b5f941d9198bdd12915996216014d4bbc9b13c1b2435c20b9a2811661b23e3", "size": 268064 }, "python/iqpilot_private/konn3kt/hephaestus/ble_gatt.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "3c4a6df8c4458fbefefe8761aaf99732b5f62bcb4bb4a5b1068b5f42b0fc9da7", + "sha256": "4a71f1c7f88fdbd51707812370e733d30b22c0c46a2f22ce32d1757debc14cff", "size": 340584 }, "python/iqpilot_private/konn3kt/hephaestus/ble_rpc_dispatch.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "79a9ec735831f904ae635d6628695fe7a985430a0ee81e7d7e58842f7588d61e", + "sha256": "25d6899e8ebb8c0c5d813d522033d115502d9b622882c0e59f276406702d9e57", "size": 68048 }, "python/iqpilot_private/konn3kt/hephaestus/ble_transportd.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "a93df625aca20374031343cbbbef4f8c2a819d69680205f9ac5c92a3841c24d9", + "sha256": "abee9f335c9ddabaa85f341cb33aaf5eebc433b2397b71c921667329728808bc", "size": 335728 }, "python/iqpilot_private/konn3kt/hephaestus/bt_gamepad.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "116dbd9cd287c4bb55672233b66601d2af9e023be03b78d6aec39d8c2a4eef04", + "sha256": "b5900c92a037f7ac88199b515f91692c0f86c45981ca3c929b6cbeb6ad6002a0", "size": 271680 }, "python/iqpilot_private/konn3kt/hephaestus/cloud_routes.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "c9d3e1cfdd36e30b6546e43a9cf51c2608a08210ac97d818bbbf098b6cc0a50f", + "sha256": "d8ebf16a39d29f9932fd1277bd0d552b60a748b0bad6d5c6314cfe5e80859ce2", "size": 134408 }, "python/iqpilot_private/konn3kt/hephaestus/hephaestusd.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "b3f2772b58d09c27042e4e0f9147a6ff45bcd6d198e32a6993bc9ca411110e6a", + "sha256": "6f50c91b87b5e37033b2f7a9db22f01aba9bf5e31733b6e753a23c211ae71492", "size": 3514416 }, "python/iqpilot_private/konn3kt/hephaestus/kwp2000.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "d37822e6fc68f07b22145fb7aaac87795af585221dc148d4ef2477580509dda6", + "sha256": "63eb11f7251748dab6ad9ba7483ace77b0709f0a3f59492d5a9f2b50bfd9e1ad", "size": 136448 }, "python/iqpilot_private/konn3kt/hephaestus/manage_hephaestusd.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "8c3c93cce17f873983c70396fe194c705ae19bc180ec6c4658183777a6d3fa03", + "sha256": "88d2df85126983f2036badc3fac85ee25d79119c95bbe983030c6ea756da111b", "size": 68136 }, "python/iqpilot_private/konn3kt/hephaestus/motd.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "1ac1dcdc3983907a0e653b9769c1bf32e46ad5e4302b7993805a8e1f02958f47", + "sha256": "f0aa1d1e50f73a27fff17a40c16affafbfdd56239da484ac04315e55a7018e0e", "size": 67840 }, "python/iqpilot_private/konn3kt/hephaestus/tp20.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "f81235f79eb78c77a3811e3676b5c76c49e09ca20c9cf3c01e5aa4640ef3de6c", + "sha256": "5e4f675dbc70a3cd21156727f430fec31ecee99f28af3873fea89fb185dba39d", "size": 135648 }, "python/iqpilot_private/konn3kt/hephaestus/vw_pq_flasher.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "fd1683c047a47b54c17581e749d8448c664f4f84549e6129ff0c50f9e335f324", + "sha256": "6f9d47e0d6c4156335fcfd6562022dbfad2dd40c860fac20288be43823195443", "size": 269568 }, "python/iqpilot_private/konn3kt/uploaderd/__init__.py": { @@ -116,7 +116,7 @@ }, "python/iqpilot_private/konn3kt/uploaderd/iquploaderd.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "515f4e9a3865c8c5b34926005471df7328d2061034d8d490ad6c6556e4754fad", + "sha256": "995b9bcfa8544066a4b71565e834bedc4c1c3dd6b54e14765ef2365d32ccfe05", "size": 204184 }, "runtime": { @@ -148,23 +148,23 @@ } }, "signatures": { - "python/iqpilot_private/konn3kt/backups/archive_codec.cpython-312-aarch64-linux-gnu.so": "szqc9yDkYsxkYPyEfqBdz1B/T8WcrjvKjja+ORcUqAXVr4kPz5MQu2oT5HyJJ02NnR2QQ+OcVWgIR85aUg/VBA==", - "python/iqpilot_private/konn3kt/backups/backup_keys.cpython-312-aarch64-linux-gnu.so": "S+fnijAxAphfMnzAB/zXpi8tPX2GGZUecpPwhfdO1eNnzuFyqPiV6Q6q7vSr3dD86lG3BPTfJZCFRmGwc0rpBg==", - "python/iqpilot_private/konn3kt/backups/backup_orchestrator.cpython-312-aarch64-linux-gnu.so": "4xbYBIqUjczGMGWoz2P2PCCh+NGrPOKnWGluwPStk+oJHzZlVBnpj389tSqzJJzOyAJo2hA1GYeuMkfG8ETcCQ==", - "python/iqpilot_private/konn3kt/backups/cbc_vault.cpython-312-aarch64-linux-gnu.so": "VdS8oqeVMuNiLyrU9REZ4YV84XLSV8MyaKTTWDk20lYGJpQU4wBRLwla6Tq8WrwlaRgZmdX9H1msMwV0WVFHBQ==", - "python/iqpilot_private/konn3kt/backups/imahelper.cpython-312-aarch64-linux-gnu.so": "btwzW4V9KItwXYbRVjA8oYfI1y0xhvNfFseIuxO5o4uVsZ2h3W5WWoeZ3m+h1GvjcT/Ucdhn6lC3XbJxxfWgDQ==", - "python/iqpilot_private/konn3kt/hephaestus/ble_auth.cpython-312-aarch64-linux-gnu.so": "1andY86F9L840fIgJekSJQSvpRDZMr4JbNYZn40K/9dcs5F/dQ6s5IyiZwpS2+4W/hDCZiVqCz05f5o96+E+DQ==", - "python/iqpilot_private/konn3kt/hephaestus/ble_gatt.cpython-312-aarch64-linux-gnu.so": "JcJPlG9hSIWbcR8038As7VDvYVJNBg6L9qMr0ElBtHSvewFqcJ5tK4/swIo3IJS4DZpLjCwtIMmu+DqGQsnGCg==", - "python/iqpilot_private/konn3kt/hephaestus/ble_rpc_dispatch.cpython-312-aarch64-linux-gnu.so": "KuA+FLmbERkD5+C+Bl9G+GNGHPEbbc79onDNkUTMtZNr7YxTIx7Py71K0WQkP0qa5sgxr17/hF7kQszTBtzFAg==", - "python/iqpilot_private/konn3kt/hephaestus/ble_transportd.cpython-312-aarch64-linux-gnu.so": "O2p0H5siPJtTC0x72el2IEyoFSa/N+wvL9/G+XMgurZI6DQqqQrs+igpYvFFI1U2UO6lJwhxZxb2RbKaIhT8Bw==", - "python/iqpilot_private/konn3kt/hephaestus/bt_gamepad.cpython-312-aarch64-linux-gnu.so": "XVgvLfvS1KtjzGCYXLanTWE392+DBZGQxP41cTvUiyzf+MXUo9jRjV8xXVpVTmCjN6sqFhJccIcYdUh2cTp1BA==", - "python/iqpilot_private/konn3kt/hephaestus/cloud_routes.cpython-312-aarch64-linux-gnu.so": "iAlR196MOtgXdBLyOUhk19M2PAT1HjBQRlbEmuLrtKFCeHQC124ewsjClYVq/Hy6N+ksqzhSMeAL2hU6NcfTCQ==", - "python/iqpilot_private/konn3kt/hephaestus/hephaestusd.cpython-312-aarch64-linux-gnu.so": "ymo9xAJEpoER5GLSWNLsOSxnZZ+Rwe0GUVTsxLGX7/tuLUNMPq0Og/yQ8D5EpTgaPGV3wPUFLsLBiWv//OXZDA==", - "python/iqpilot_private/konn3kt/hephaestus/kwp2000.cpython-312-aarch64-linux-gnu.so": "PUPoFMxOzzmgaIFa0aTaKZDN81v2qTLj6j4jZkXnGlHXKfGbVpBLBYq8ytujJvamGevvVa5cssEA3XbMLFq8CQ==", - "python/iqpilot_private/konn3kt/hephaestus/manage_hephaestusd.cpython-312-aarch64-linux-gnu.so": "JGyDxUcUXvCd8lwNaLscpIo9vKTNRvtKd9roHI+kLa9OImJfk1XFAn7qY/LFEfqcpga0vRcucZLqa5T1YB/gDw==", - "python/iqpilot_private/konn3kt/hephaestus/motd.cpython-312-aarch64-linux-gnu.so": "9Kb9lnsLYhTCC7ctxVYvwO2iODIW0Z6NJ7+R+6BvIBV3ejL4yc8YVxjde0skgdjN5SvqlvRO1uG/ZE6aqK3VCQ==", - "python/iqpilot_private/konn3kt/hephaestus/tp20.cpython-312-aarch64-linux-gnu.so": "8u8bDBQ7SxYTWX+cEMeAH0DQ+hoZDfjYyOzU+sBzrtZylUVZyzlRjohciDDQXF2bpxnuNQUWb4GgE41Y60hlCg==", - "python/iqpilot_private/konn3kt/hephaestus/vw_pq_flasher.cpython-312-aarch64-linux-gnu.so": "8PyCivu4UmKF+biAg5aTRFRf6pSM6jt65/n0lrXgo4Ftpk4mNd623b/K/jPf+6wjgC8Sbqp40wNFwel0RUifAg==", - "python/iqpilot_private/konn3kt/uploaderd/iquploaderd.cpython-312-aarch64-linux-gnu.so": "GpPbShzcrAK4tP9pRg+SJh0WZ8Me0mxEVEL6ED7v/tK3Az3KTDf4jU5a3Bhg/Q/IrWxqNlBg/RPdOv2RYMBPDA==" + "python/iqpilot_private/konn3kt/backups/archive_codec.cpython-312-aarch64-linux-gnu.so": "UehTRkDLBq77ERDm+ZSjxDU3+5EpJUOIzs5zk7Fz8Aru6yQX9ytRexns4dGse8BlIveGuHpWq+L+GvjG0Hf4Bw==", + "python/iqpilot_private/konn3kt/backups/backup_keys.cpython-312-aarch64-linux-gnu.so": "uddHEDnsMjWbMeWotUzZES/3hyLuPmZM1ENCkcTxMYXzM0g0YfbyOJlzq2FuSL4Zg2Hl+PyM/nmnEYbi88NIBg==", + "python/iqpilot_private/konn3kt/backups/backup_orchestrator.cpython-312-aarch64-linux-gnu.so": "2gPFBBZeMfvlnGtQkP6JMI/8c6uanTylvVtZ+1cifaK/ixsGDyfw051gv28uorxjDvRHbgGab/q2n3QYZj8EBA==", + "python/iqpilot_private/konn3kt/backups/cbc_vault.cpython-312-aarch64-linux-gnu.so": "KwOoTQlcNJA//GwfMeS8e1yw9agzaJDa/oUXXhiEFyrdEgZurmLbV0slgxUR+hC/LLrrzqqsw1BjQcYuqVXdCw==", + "python/iqpilot_private/konn3kt/backups/imahelper.cpython-312-aarch64-linux-gnu.so": "BbNS1vTfoizdCnZE3j/2kbY84uXDcGk0WgQ+nmBtySNBBJgT/5HspuY/AOxHukgVyjh7vm7BCnBuJO6/Gm30AQ==", + "python/iqpilot_private/konn3kt/hephaestus/ble_auth.cpython-312-aarch64-linux-gnu.so": "HU6uqhzgAx6mA9ScihdhYvmknQ9kZbI2p4a/ViB4BLo1OTZnfhFecQQ3rnvXNLGOyfbacqooz+s+JRuSOqEmDw==", + "python/iqpilot_private/konn3kt/hephaestus/ble_gatt.cpython-312-aarch64-linux-gnu.so": "Nw/QTfb9gk1QgTWKvacfS4BlKZ3DuWJKf5ll/H4Hb8YEaXmYz1xU0klwcybjHPs4twA5qsYUnjmzL110llD+Cw==", + "python/iqpilot_private/konn3kt/hephaestus/ble_rpc_dispatch.cpython-312-aarch64-linux-gnu.so": "WE552SVLgy0vmwvrJv54kW4bDyjB9bKUhMnGa+OI/L7WZT/ReWm3H2NbT0TzWZEGbzFHKr4I01Zmi+MHJGVrAQ==", + "python/iqpilot_private/konn3kt/hephaestus/ble_transportd.cpython-312-aarch64-linux-gnu.so": "N9u9KO1e4Xc9su7MndJ6MfyDMY1eV89xbIy6Qo5F5eg0xqfl8QGyYcUU6btIOFdrpRdpWxXTukff9FbU0c+RBg==", + "python/iqpilot_private/konn3kt/hephaestus/bt_gamepad.cpython-312-aarch64-linux-gnu.so": "t9HmTDU8a0a3rhm9rxzbUaYalAmjASZRbgCku8rg6AxQJohJo3eMVmH7dy7A6vtFvhYvvD9Ywi9kKeUaPTvPCQ==", + "python/iqpilot_private/konn3kt/hephaestus/cloud_routes.cpython-312-aarch64-linux-gnu.so": "Oq2wyp4UTAQg/Q16pgCJ9+C/4zi4ljCOHJRcnYXhUk997Tq/5LuBHBstfxrq9ZLubF2ntLLw5UhePtehjLliDg==", + "python/iqpilot_private/konn3kt/hephaestus/hephaestusd.cpython-312-aarch64-linux-gnu.so": "n2X6vqTFDy3dGiTiI9kWfAYySl0srw30k5aDqN/YWTzZomQabwZ1ETmUC6TIG3Wag074XNEJgrZhiguN1wgeAg==", + "python/iqpilot_private/konn3kt/hephaestus/kwp2000.cpython-312-aarch64-linux-gnu.so": "ami2SR9/GUXkFRDB5hN/JrJO4rz2piQNtEYJFAsvssLmcqzVPHehRIy61gctjKr5kBLOfUGJjpNU3ceswOUWBg==", + "python/iqpilot_private/konn3kt/hephaestus/manage_hephaestusd.cpython-312-aarch64-linux-gnu.so": "wCeURfEwJlXuy7FYiJ3ZWUJZUp8ehKehKqWH/nNyo+GlSlC8YhAGNvQxwZ9FH0agOsSQVHMExnL4ofLvJOytAA==", + "python/iqpilot_private/konn3kt/hephaestus/motd.cpython-312-aarch64-linux-gnu.so": "+G2me3BkbbjwwtVfjGz/ePsXQwNde7Y9bLELSRk8tDxLdGHWkFCU9i8ba8vue7uqfMTnRq5opCDFdIXvY7CwDg==", + "python/iqpilot_private/konn3kt/hephaestus/tp20.cpython-312-aarch64-linux-gnu.so": "lh63nHd0YApA9e9+C8SnRd+DILlprzpzt2PR8S6x8VSMQAzAySS9xuJ8Jw76JMpIItzW030n5/wazi4i/gK+Aw==", + "python/iqpilot_private/konn3kt/hephaestus/vw_pq_flasher.cpython-312-aarch64-linux-gnu.so": "3fYQP73XdXlWREMsM+P7D9EUSAwrLuih17DqmbDfQDa0S0TKbXcWJgRMbeOHRUDMZ04sUDrli82OfAkz6vlyBQ==", + "python/iqpilot_private/konn3kt/uploaderd/iquploaderd.cpython-312-aarch64-linux-gnu.so": "UtM9t4Db3LX6RfiMkADMI7Skre5FtPvjPB2xNuJofd4fVtrLo7r4YYcSOmq7jo4+UviYp4N3CPiGGoOc6WHzAA==" } } diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/archive_codec.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/archive_codec.cpython-312-aarch64-linux-gnu.so index bdbb6bb..16b05ce 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/archive_codec.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/archive_codec.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/backup_keys.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/backup_keys.cpython-312-aarch64-linux-gnu.so index 95f2d55..b2d2795 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/backup_keys.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/backup_keys.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/backup_orchestrator.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/backup_orchestrator.cpython-312-aarch64-linux-gnu.so index 77e2780..a1bd81e 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/backup_orchestrator.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/backup_orchestrator.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/cbc_vault.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/cbc_vault.cpython-312-aarch64-linux-gnu.so index c262e77..10c4e03 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/cbc_vault.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/cbc_vault.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/imahelper.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/imahelper.cpython-312-aarch64-linux-gnu.so index 3f7c40f..bcec6ab 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/imahelper.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/imahelper.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/_vendor/localapi_runtime.zip b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/_vendor/localapi_runtime.zip index e61630f..0aa10c3 100644 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/_vendor/localapi_runtime.zip and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/_vendor/localapi_runtime.zip differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_auth.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_auth.cpython-312-aarch64-linux-gnu.so index 09d843e..56b5782 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_auth.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_auth.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_gatt.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_gatt.cpython-312-aarch64-linux-gnu.so index bb4705a..01ed395 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_gatt.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_gatt.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_rpc_dispatch.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_rpc_dispatch.cpython-312-aarch64-linux-gnu.so index e7089fe..562b1d4 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_rpc_dispatch.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_rpc_dispatch.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_transportd.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_transportd.cpython-312-aarch64-linux-gnu.so index 6a5090a..7887598 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_transportd.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_transportd.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/bt_gamepad.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/bt_gamepad.cpython-312-aarch64-linux-gnu.so index 19fb360..b0033e4 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/bt_gamepad.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/bt_gamepad.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/cloud_routes.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/cloud_routes.cpython-312-aarch64-linux-gnu.so index 1105c12..38ee1f1 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/cloud_routes.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/cloud_routes.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/hephaestusd.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/hephaestusd.cpython-312-aarch64-linux-gnu.so index fe144a9..f535d73 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/hephaestusd.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/hephaestusd.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/kwp2000.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/kwp2000.cpython-312-aarch64-linux-gnu.so index 330cab1..edde5ac 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/kwp2000.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/kwp2000.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/manage_hephaestusd.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/manage_hephaestusd.cpython-312-aarch64-linux-gnu.so index 348228a..0ace478 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/manage_hephaestusd.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/manage_hephaestusd.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/motd.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/motd.cpython-312-aarch64-linux-gnu.so index fd6666b..1dcb7f7 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/motd.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/motd.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/tp20.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/tp20.cpython-312-aarch64-linux-gnu.so index 45a0a6c..1052a8f 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/tp20.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/tp20.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/vw_pq_flasher.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/vw_pq_flasher.cpython-312-aarch64-linux-gnu.so index 4fa7f65..2238d6a 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/vw_pq_flasher.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/vw_pq_flasher.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/uploaderd/iquploaderd.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/uploaderd/iquploaderd.cpython-312-aarch64-linux-gnu.so index b4edcb8..2d81282 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/uploaderd/iquploaderd.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/uploaderd/iquploaderd.cpython-312-aarch64-linux-gnu.so differ diff --git a/iqdbc_repo/conftest.py b/iqdbc_repo/conftest.py index 4b01283..da290ac 100644 --- a/iqdbc_repo/conftest.py +++ b/iqdbc_repo/conftest.py @@ -4,6 +4,59 @@ collect_ignore_glob = [ "iqdbc/safety/tests/misra/cppcheck/", ] +# --- host test harness ------------------------------------------------------- +# tesla/volkswagen carstate+carcontroller import the closed-source ALC / odometer +# runtime via import_verified_module(), which gates on a rootfs integrity manifest +# that only exists on-device. Off-device (host CI / dev), install minimal stubs so +# the whole car interface set is importable and test_car_interfaces can collect and +# run. On-device the manifest is present and these stubs are never installed, so the +# real verified modules are used. +import os as _os + +if not _os.path.exists("/usr/libexec/iqpilot/runtime_integrity.json"): + import sys as _sys + import types as _types + + def _stub_module(name, attrs): + mod = _types.ModuleType(name) + for key, value in attrs.items(): + setattr(mod, key, value) + _sys.modules[name] = mod + + _noop = lambda *args, **kwargs: None # noqa: E731 + + class _VehicleOdometerStoreStub: + def __init__(self, *args, **kwargs): + pass + + def record(self, km): + return km + + _stub_module("iqpilot_private.konn3kt.iqlvbs.vehicle_state", + {"VehicleOdometerStore": _VehicleOdometerStoreStub}) + _stub_module("iqpilot_private.konn3kt.iqlvbs.alc", { + "angle_lateral_control_enabled": lambda *a, **k: False, + "update_vw_alc": _noop, + "append_private_apd": _noop, + "update_mqb_carstate_alc_state": _noop, + "update_mlb_carstate_alc_state": _noop, + "update_pq_carstate_alc_state": _noop, + }) + _stub_module("iqpilot_private.konn3kt.iqlvbs.iqlvbs_commander", {}) + _stub_module("iqpilot_private.konn3kt.hephaestus.vw_pq_flasher", {}) + + try: + from openpilot.system.proprietary_runtime import _verified_import as _vi + _real_import_verified_module = _vi.import_verified_module + + def _import_verified_module(bundle, module): + return _sys.modules.get(module) or _real_import_verified_module(bundle, module) + + _vi.import_verified_module = _import_verified_module + except Exception: + pass +# --- end host test harness --------------------------------------------------- + _ABSTRACT_BASES = frozenset(("CarSafetyTest", "AolSafetyTestBase", "SafetyTest", "SafetyTestBase")) def _method_from_base(cls, method_name): diff --git a/iqdbc_repo/iqdbc/car/chrysler/carstate.py b/iqdbc_repo/iqdbc/car/chrysler/carstate.py index 70d4448..a0bb499 100644 --- a/iqdbc_repo/iqdbc/car/chrysler/carstate.py +++ b/iqdbc_repo/iqdbc/car/chrysler/carstate.py @@ -4,8 +4,8 @@ from iqdbc.car.chrysler.values import DBC, STEER_THRESHOLD, RAM_CARS from iqdbc.car.common.conversions import Conversions as CV from iqdbc.car.interfaces import CarStateBase -from iqdbc.iqpilot.car.chrysler.carstate_ext import CarStateExt from iqdbc.iqpilot.car.chrysler.aol import AolCarState +from iqdbc.iqpilot.car.chrysler.carstate_ext import CarStateExt ButtonType = structs.CarState.ButtonEvent.Type @@ -114,7 +114,10 @@ class CarState(CarStateBase, AolCarState, CarStateExt): @staticmethod def get_can_parsers(CP, CP_IQ): + pt_messages: list = [] + cam_messages: list = [] + AolCarState.get_parser(CP, pt_messages, cam_messages) return { - Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], [], 0), - Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], [], 2), + Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], pt_messages, 0), + Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], cam_messages, 2), } diff --git a/iqdbc_repo/iqdbc/car/chrysler/fingerprints.py b/iqdbc_repo/iqdbc/car/chrysler/fingerprints.py index ccfa863..838eeed 100644 --- a/iqdbc_repo/iqdbc/car/chrysler/fingerprints.py +++ b/iqdbc_repo/iqdbc/car/chrysler/fingerprints.py @@ -1,10 +1,10 @@ """ AUTO-FORMATTED USING iqdbc/car/debug/format_fingerprints.py, EDIT STRUCTURE THERE.""" from iqdbc.car.structs import CarParams from iqdbc.car.chrysler.values import CAR - from iqdbc.iqpilot.car.fingerprints_ext import merge_fw_versions from iqdbc.iqpilot.car.chrysler.fingerprints_ext import FW_VERSIONS_EXT + Ecu = CarParams.Ecu FW_VERSIONS = { @@ -789,4 +789,6 @@ FW_VERSIONS = { }, } + + FW_VERSIONS = merge_fw_versions(FW_VERSIONS, FW_VERSIONS_EXT) diff --git a/iqdbc_repo/iqdbc/car/chrysler/interface.py b/iqdbc_repo/iqdbc/car/chrysler/interface.py index cde33e3..828120d 100755 --- a/iqdbc_repo/iqdbc/car/chrysler/interface.py +++ b/iqdbc_repo/iqdbc/car/chrysler/interface.py @@ -100,9 +100,10 @@ class CarInterface(CarInterfaceBase): stock_cp.wheelbase = 3.79 stock_cp.steerRatio = 19. + # LKAS heartbeat on bus 0 (msg 0x4FF) means the camera is on the ADAS bus and + # IQ.Pilot can steer down to a standstill. if 0x4FF in fingerprint[0]: ret.flags |= ChryslerFlagsIQ.NO_MIN_STEERING_SPEED.value stock_cp.minSteerSpeed = 0. - return ret diff --git a/iqdbc_repo/iqdbc/car/ford/carstate.py b/iqdbc_repo/iqdbc/car/ford/carstate.py index ee4bdec..7080d2e 100644 --- a/iqdbc_repo/iqdbc/car/ford/carstate.py +++ b/iqdbc_repo/iqdbc/car/ford/carstate.py @@ -5,17 +5,14 @@ from iqdbc.car.ford.fordcan import CanBus from iqdbc.car.ford.values import DBC, CarControllerParams, FordFlags from iqdbc.car.interfaces import CarStateBase -from iqdbc.iqpilot.car.ford.aol import AolCarState - ButtonType = structs.CarState.ButtonEvent.Type GearShifter = structs.CarState.GearShifter TransmissionType = structs.CarParams.TransmissionType -class CarState(CarStateBase, AolCarState): +class CarState(CarStateBase): def __init__(self, CP, CP_IQ): CarStateBase.__init__(self, CP, CP_IQ) - AolCarState.__init__(self, CP, CP_IQ) can_define = CANDefine(DBC[CP.carFingerprint][Bus.pt]) if CP.transmissionType == TransmissionType.automatic: self.shifter_values = can_define.dv["PowertrainData_10"]["TrnRng_D_Rq"] @@ -112,8 +109,6 @@ class CarState(CarStateBase, AolCarState): self.acc_tja_status_stock_values = cp_cam.vl["ACCDATA_3"] self.lkas_status_stock_values = cp_cam.vl["IPMA_Data"] - AolCarState.update_aol(self, ret, can_parsers) - ret.buttonEvents = [ *create_button_events(self.distance_button, prev_distance_button, {1: ButtonType.gapAdjustCruise}), *create_button_events(self.lc_button, prev_lc_button, {1: ButtonType.lkas}), diff --git a/iqdbc_repo/iqdbc/car/gm/fingerprints.py b/iqdbc_repo/iqdbc/car/gm/fingerprints.py index 37d8c57..734415b 100644 --- a/iqdbc_repo/iqdbc/car/gm/fingerprints.py +++ b/iqdbc_repo/iqdbc/car/gm/fingerprints.py @@ -1,7 +1,6 @@ # ruff: noqa: E501 """ AUTO-FORMATTED USING iqdbc/car/debug/format_fingerprints.py, EDIT STRUCTURE THERE.""" from iqdbc.car.gm.values import CAR - from iqdbc.iqpilot.car.fingerprints_ext import merge_fingerprints from iqdbc.iqpilot.car.gm.fingerprints_ext import FINGERPRINTS_EXT @@ -54,6 +53,9 @@ FINGERPRINTS = { }], CAR.CHEVROLET_SILVERADO: [{ 190: 6, 193: 8, 197: 8, 201: 8, 208: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 8, 288: 5, 289: 8, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 413: 8, 451: 8, 452: 8, 453: 6, 455: 7, 460: 5, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 528: 5, 532: 6, 534: 2, 560: 8, 562: 8, 563: 5, 565: 5, 587: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 761: 7, 789: 5, 800: 6, 801: 8, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 869: 4, 880: 6, 977: 8, 1001: 8, 1011: 6, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1271: 8, 1280: 4, 1296: 4, 1300: 8, 1611: 8, 1930: 7 + }, + { + 190: 6, 193: 8, 197: 8, 201: 8, 208: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 3, 288: 5, 289: 8, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 413: 8, 451: 8, 452: 8, 453: 6, 455: 7, 460: 5, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 528: 5, 532: 6, 534: 2, 560: 8, 562: 8, 563: 5, 565: 5, 587: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 761: 7, 789: 5, 800: 6, 801: 8, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 869: 4, 880: 6, 977: 8, 1001: 8, 1011: 6, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1271: 8, 1280: 4, 1296: 4, 1300: 8, 1611: 8, 1930: 7 }], CAR.CHEVROLET_EQUINOX: [{ 190: 6, 193: 8, 197: 8, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 8, 288: 5, 289: 8, 298: 8, 304: 1, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 413: 8, 451: 8, 452: 8, 453: 6, 455: 7, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 510: 8, 528: 5, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 587: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 789: 5, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 869: 4, 880: 6, 977: 8, 1001: 8, 1011: 6, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1271: 8, 1280: 4, 1296: 4, 1300: 8, 1611: 8, 1930: 7 @@ -78,4 +80,5 @@ FINGERPRINTS = { FW_VERSIONS: dict[str, dict[tuple, list[bytes]]] = { } + FINGERPRINTS = merge_fingerprints(FINGERPRINTS, FINGERPRINTS_EXT) diff --git a/iqdbc_repo/iqdbc/car/gm/interface.py b/iqdbc_repo/iqdbc/car/gm/interface.py index 68c2d56..c377f16 100755 --- a/iqdbc_repo/iqdbc/car/gm/interface.py +++ b/iqdbc_repo/iqdbc/car/gm/interface.py @@ -16,7 +16,7 @@ from iqdbc.iqpilot.car.gm.values_ext import GMFlagsIQ, GMSafetyFlagsIQ TransmissionType = structs.CarParams.TransmissionType NetworkLocation = structs.CarParams.NetworkLocation -# iqpilot-specific torque parameters for Bolt cars that actually use the d parameter +# Bolt Non-ACC uses the 4th (d) tune parameter; stock tunes zero it out. NON_LINEAR_TORQUE_PARAMS_IQ = { CAR.CHEVROLET_BOLT_NON_ACC: [2.24, 1.1, 0.28, -0.07], CAR.CHEVROLET_BOLT_NON_ACC_1ST_GEN: [1.8, 1.1, 0.3, -0.045], @@ -241,11 +241,10 @@ class CarInterface(CarInterfaceBase, CarInterfaceExt): CAR.CHEVROLET_BOLT_NON_ACC_2ND_GEN, CAR.CHEVROLET_TRAILBLAZER_NON_ACC_2ND_GEN): stock_cp.steerActuatorDelay = 0.2 CarInterfaceBase.configure_torque_tune(candidate, stock_cp.lateralTuning) - elif candidate in (CAR.CHEVROLET_EQUINOX_NON_ACC_3RD_GEN, ): CarInterfaceBase.configure_torque_tune(candidate, stock_cp.lateralTuning) - # NON_ACC vehicles should use camera car speed thresholds + # Non-ACC cars steer/long via the forward camera and pcmCruise, not the ASCM. if ret.flags & GMFlagsIQ.NON_ACC: stock_cp.dashcamOnly = False stock_cp.alphaLongitudinalAvailable = False @@ -254,13 +253,13 @@ class CarInterface(CarInterfaceBase, CarInterfaceExt): stock_cp.pcmCruise = True stock_cp.safetyConfigs[0].safetyParam |= GMSafetyFlags.HW_CAM.value ret.iqSafetyFlags |= GMSafetyFlagsIQ.NON_ACC - stock_cp.minEnableSpeed = 24 * CV.MPH_TO_MS # 24 mph - stock_cp.minSteerSpeed = 3.0 # ~6 mph + stock_cp.minEnableSpeed = 24 * CV.MPH_TO_MS + stock_cp.minSteerSpeed = 3.0 - # dashcamOnly platforms: untested platforms, need user validations + # Untested Non-ACC platforms ship dashcam-only pending user validation. if candidate in (CAR.CHEVROLET_BOLT_NON_ACC_2ND_GEN, CAR.CHEVROLET_EQUINOX_NON_ACC_3RD_GEN, - CAR.CHEVROLET_SUBURBAN_NON_ACC_11TH_GEN, CAR.CADILLAC_CT6_NON_ACC_1ST_GEN, CAR.CHEVROLET_TRAILBLAZER_NON_ACC_2ND_GEN, - CAR.CADILLAC_XT5_NON_ACC_1ST_GEN): + CAR.CHEVROLET_SUBURBAN_NON_ACC_11TH_GEN, CAR.CADILLAC_CT6_NON_ACC_1ST_GEN, + CAR.CHEVROLET_TRAILBLAZER_NON_ACC_2ND_GEN, CAR.CADILLAC_XT5_NON_ACC_1ST_GEN): stock_cp.dashcamOnly = True return ret diff --git a/iqdbc_repo/iqdbc/car/gm/values.py b/iqdbc_repo/iqdbc/car/gm/values.py index 369083b..e1244dc 100644 --- a/iqdbc_repo/iqdbc/car/gm/values.py +++ b/iqdbc_repo/iqdbc/car/gm/values.py @@ -4,9 +4,8 @@ from enum import Enum, IntFlag from iqdbc.car import Bus, PlatformConfig, DbcDict, Platforms, CarSpecs from iqdbc.car.structs import CarParams from iqdbc.car.docs_definitions import CarDocs, CarFootnote, CarHarness, CarParts, Column, SupportType -from iqdbc.car.fw_query_definitions import FwQueryConfig, Request, StdQueries - from iqdbc.iqpilot.car.gm.values_ext import GMFlagsIQ +from iqdbc.car.fw_query_definitions import FwQueryConfig, Request, StdQueries Ecu = CarParams.Ecu @@ -88,13 +87,6 @@ class GMCarDocs(CarDocs): self.car_parts = CarParts.common([CarHarness.obd_ii]) -@dataclass -class GMNonAccCarDocs(GMCarDocs): - package: str = "No Adaptive Cruise Control (Non-ACC)" - support_type: SupportType = SupportType.COMMUNITY - support_link: str = "community" - - @dataclass(frozen=True, kw_only=True) class GMCarSpecs(CarSpecs): tireStiffnessFactor: float = 0.444 # not optimized yet @@ -123,6 +115,13 @@ class GMSDGMPlatformConfig(GMPlatformConfig): self.car_docs = [] +@dataclass +class GMNonAccCarDocs(GMCarDocs): + package: str = "No Adaptive Cruise Control (Non-ACC)" + support_type: SupportType = SupportType.COMMUNITY + support_link: str = "community" + + @dataclass class GMNonSccPlatformConfig(GMPlatformConfig): def init(self): @@ -209,13 +208,7 @@ class CAR(Platforms): GMCarSpecs(mass=2490, wheelbase=2.94, steerRatio=17.3, centerToFrontRatio=0.5, tireStiffnessFactor=1.0), ) - # port extensions - # Separate car def is required when there is no ASCM - # (for now) unless there is a way to detect it when it has been unplugged... - # CHEVROLET_VOLT_CC = GMNonSccPlatformConfig( - # [GMNonAccCarDocs("Chevrolet Volt LT 2017-18")], - # CHEVROLET_VOLT.specs, - # ) + # IQ.Pilot Non-ACC camera-harness ports (no factory adaptive cruise). CHEVROLET_BOLT_NON_ACC = GMNonSccPlatformConfig( [GMNonAccCarDocs("Chevrolet Bolt EV Non-ACC 2017")], CHEVROLET_BOLT_EUV.specs, @@ -333,7 +326,7 @@ FW_QUERY_CONFIG = FwQueryConfig( # TODO: detect most of these sets live EV_CAR = {CAR.CHEVROLET_VOLT, CAR.CHEVROLET_VOLT_2019, CAR.CHEVROLET_BOLT_EUV, - # port extensions, Non-ACC + # Non-ACC EV ports CAR.CHEVROLET_BOLT_NON_ACC, CAR.CHEVROLET_BOLT_NON_ACC_1ST_GEN, CAR.CHEVROLET_BOLT_NON_ACC_2ND_GEN} # We're integrated at the camera with VOACC on these cars (instead of ASCM w/ OBD-II harness) diff --git a/iqdbc_repo/iqdbc/car/nissan/carstate.py b/iqdbc_repo/iqdbc/car/nissan/carstate.py index 517c314..ce8c252 100644 --- a/iqdbc_repo/iqdbc/car/nissan/carstate.py +++ b/iqdbc_repo/iqdbc/car/nissan/carstate.py @@ -5,6 +5,7 @@ from iqdbc.car import Bus, create_button_events, structs from iqdbc.car.common.conversions import Conversions as CV from iqdbc.car.interfaces import CarStateBase from iqdbc.car.nissan.values import CAR, DBC, CarControllerParams + from iqdbc.iqpilot.car.nissan.carstate_ext import CarStateExt ButtonType = structs.CarState.ButtonEvent.Type diff --git a/iqdbc_repo/iqdbc/car/rivian/interface.py b/iqdbc_repo/iqdbc/car/rivian/interface.py index 2730e80..dbc6ef1 100644 --- a/iqdbc_repo/iqdbc/car/rivian/interface.py +++ b/iqdbc_repo/iqdbc/car/rivian/interface.py @@ -39,6 +39,8 @@ 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: + # Longitudinal harness upgrade advertises msg 0x31a on bus 5; when present it + # unlocks radar, blind-spot and openpilot longitudinal on Rivian. if 0x31a in fingerprint[5]: ret.flags |= RivianFlagsIQ.LONGITUDINAL_HARNESS_UPGRADE.value stock_cp.radarUnavailable = False diff --git a/iqdbc_repo/iqdbc/car/torque_data/substitute.toml b/iqdbc_repo/iqdbc/car/torque_data/substitute.toml index 6ac4533..75cc15f 100644 --- a/iqdbc_repo/iqdbc/car/torque_data/substitute.toml +++ b/iqdbc_repo/iqdbc/car/torque_data/substitute.toml @@ -99,3 +99,14 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] "SUBARU_FORESTER_PREGLOBAL" = "SUBARU_IMPREZA" "SUBARU_LEGACY_PREGLOBAL" = "SUBARU_IMPREZA" "SUBARU_ASCENT" = "SUBARU_FORESTER" + +# IQ.Pilot GM Non-ACC ports borrow their base platform's lateral tune +"CHEVROLET_BOLT_NON_ACC" = "CHEVROLET_BOLT_EUV" +"CHEVROLET_BOLT_NON_ACC_1ST_GEN" = "CHEVROLET_BOLT_EUV" +"CHEVROLET_BOLT_NON_ACC_2ND_GEN" = "CHEVROLET_BOLT_EUV" +"CHEVROLET_EQUINOX_NON_ACC_3RD_GEN" = "CHEVROLET_EQUINOX" +"CHEVROLET_SUBURBAN_NON_ACC_11TH_GEN" = "CHEVROLET_SILVERADO" +"CADILLAC_CT6_NON_ACC_1ST_GEN" = "CHEVROLET_VOLT" +"CHEVROLET_TRAILBLAZER_NON_ACC_2ND_GEN" = "CHEVROLET_TRAILBLAZER" +"CHEVROLET_MALIBU_NON_ACC_9TH_GEN" = "CHEVROLET_VOLT" +"CADILLAC_XT5_NON_ACC_1ST_GEN" = "CADILLAC_XT4" diff --git a/iqdbc_repo/iqdbc/car/volkswagen/interface.py b/iqdbc_repo/iqdbc/car/volkswagen/interface.py index 637f1b1..85a4a9b 100644 --- a/iqdbc_repo/iqdbc/car/volkswagen/interface.py +++ b/iqdbc_repo/iqdbc/car/volkswagen/interface.py @@ -171,7 +171,7 @@ class CarInterface(CarInterfaceBase): ret.steerLimitTimer = 0.4 if ret.flags & VolkswagenFlags.PQ: ret.steerActuatorDelay = 0.2 - ret.longitudinalTuning.kfDEPRECATED = 1.2 + ret.longitudinalTuning.kf = 1.2 ret.longitudinalTuning.kpBP = [0.] ret.longitudinalTuning.kpV = [.45] ret.longitudinalTuning.kiBP = [0.] diff --git a/iqdbc_repo/iqdbc/car/volkswagen/tests/test_stopping.py b/iqdbc_repo/iqdbc/car/volkswagen/tests/test_stopping.py index 1c21653..9a07a21 100644 --- a/iqdbc_repo/iqdbc/car/volkswagen/tests/test_stopping.py +++ b/iqdbc_repo/iqdbc/car/volkswagen/tests/test_stopping.py @@ -1,5 +1,6 @@ import pytest +from iqdbc.car.volkswagen.interface import CarInterface from iqdbc.car.volkswagen.values import ( CAR, PASSAT_B7_STOP_ACCEL, PASSAT_B7_STOPPING_SPEED, PQ_STOPPING_SPEED, VolkswagenFlags, apply_pq_stopping_accel, get_longitudinal_stopping_speed_override, @@ -20,3 +21,13 @@ def test_passat_b7_stop_accel_is_exact(): assert apply_pq_stopping_accel(CAR.VOLKSWAGEN_PASSAT_B7, -0.2, True) == PASSAT_B7_STOP_ACCEL == -0.55 assert apply_pq_stopping_accel(CAR.VOLKSWAGEN_PASSAT_B7, -0.2, False) == -0.2 assert apply_pq_stopping_accel(CAR.VOLKSWAGEN_JETTA_MK6, -0.2, True) == -0.2 + + +@pytest.mark.parametrize("candidate", [ + CAR.VOLKSWAGEN_JETTA_MK6, + CAR.VOLKSWAGEN_PASSAT_NMS, +]) +def test_pq_longitudinal_feedforward_uses_active_schema_field(candidate): + fingerprint = {bus: {} for bus in range(8)} + cp = CarInterface.get_params(candidate, fingerprint, [], alpha_long=True, is_release=False, docs=False) + assert cp.longitudinalTuning.kf == pytest.approx(1.2) diff --git a/iqdbc_repo/iqdbc/iqpilot/car/chrysler/__init__.py b/iqdbc_repo/iqdbc/iqpilot/car/chrysler/__init__.py index 297dca9..e69de29 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/chrysler/__init__.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/chrysler/__init__.py @@ -1,3 +0,0 @@ -""" -Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos -""" diff --git a/iqdbc_repo/iqdbc/iqpilot/car/chrysler/aol.py b/iqdbc_repo/iqdbc/iqpilot/car/chrysler/aol.py index 262546a..6af6f4c 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/chrysler/aol.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/chrysler/aol.py @@ -1,21 +1,23 @@ """ Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos -""" +Always-on-Lateral adapter for Chrysler. CarState reads the LKAS toggle button +(and the forwarded LKAS heartbeat); CarController tracks the AOL state and, when +AOL is available, drives the LKAS_DISABLED bit the dash reads from the heartbeat. +""" from enum import StrEnum from collections import namedtuple from iqdbc.car import Bus, structs from iqdbc.car.chrysler.values import RAM_CARS - from iqdbc.iqpilot.aol_base import AolCarStateBase from iqdbc.can.parser import CANParser -AolDataIQ = namedtuple("AolDataIQ", - ["enable_aol", "paused", "lkas_disabled"]) - +AolDataIQ = namedtuple("AolDataIQ", ["enable_aol", "paused", "lkas_disabled"]) ButtonType = structs.CarState.ButtonEvent.Type +_HEARTBIT_FIELDS = ("LKAS_DISABLED", "AUTO_HIGH_BEAM", "FORWARD_1", "FORWARD_2", "FORWARD_3") + class AolCarController: def __init__(self): @@ -23,28 +25,18 @@ class AolCarController: @staticmethod def create_lkas_heartbit(packer, lkas_heartbit, aol): - # LKAS_HEARTBIT (0x2D9) LKAS heartbeat - values = {s: lkas_heartbit[s] for s in [ - "LKAS_DISABLED", - "AUTO_HIGH_BEAM", - "FORWARD_1", - "FORWARD_2", - "FORWARD_3", - ]} - + values = {name: lkas_heartbit[name] for name in _HEARTBIT_FIELDS} if aol.enable_aol: values["LKAS_DISABLED"] = 1 if aol.lkas_disabled else 0 - return packer.make_can_msg("LKAS_HEARTBIT", 0, values) @staticmethod def aol_status_update(CC: structs.CarControl, CC_IQ: structs.IQCarControl, CS) -> AolDataIQ: enable_aol = CC_IQ.aol.available paused = CC_IQ.aol.enabled and not CC.latActive - + # A tap of the LKAS button flips the driver's "LKAS disabled" preference. if any(be.type == ButtonType.lkas and be.pressed for be in CS.out.buttonEvents): CS.lkas_disabled = not CS.lkas_disabled - return AolDataIQ(enable_aol, paused, CS.lkas_disabled) def update(self, CC: structs.CarControl, CC_IQ: structs.IQCarControl, CS) -> None: @@ -55,35 +47,27 @@ class AolCarState(AolCarStateBase): def __init__(self, CP: structs.CarParams, CP_IQ: structs.IQCarParams): super().__init__(CP, CP_IQ) self.lkas_heartbit = 0 - self.init_lkas_disabled = False self.lkas_disabled = False @staticmethod def get_parser(CP, pt_messages, cam_messages) -> None: if CP.carFingerprint in RAM_CARS: - pt_messages += [ - ("Center_Stack_2", 1), - ] + pt_messages.append(("Center_Stack_2", 1)) else: pt_messages.append(("TRACTION_BUTTON", 1)) cam_messages.append(("LKAS_HEARTBIT", 1)) - def get_lkas_button(self, cp, cp_cam): + def _read_lkas_button(self, cp, cp_cam) -> int: if self.CP.carFingerprint in RAM_CARS: - lkas_button = cp.vl["Center_Stack_2"]["LKAS_Button"] - else: - lkas_button = cp.vl["TRACTION_BUTTON"]["TOGGLE_LKAS"] - self.lkas_heartbit = cp_cam.vl["LKAS_HEARTBIT"] - if not self.init_lkas_disabled: - self.lkas_disabled = cp_cam.vl["LKAS_HEARTBIT"]["LKAS_DISABLED"] - self.init_lkas_disabled = True + return cp.vl["Center_Stack_2"]["LKAS_Button"] - return lkas_button + self.lkas_heartbit = cp_cam.vl["LKAS_HEARTBIT"] + if not self.init_lkas_disabled: + self.lkas_disabled = cp_cam.vl["LKAS_HEARTBIT"]["LKAS_DISABLED"] + self.init_lkas_disabled = True + return cp.vl["TRACTION_BUTTON"]["TOGGLE_LKAS"] def update_aol(self, ret: structs.CarState, can_parsers: dict[StrEnum, CANParser]) -> None: - cp = can_parsers[Bus.pt] - cp_cam = can_parsers[Bus.cam] - self.prev_lkas_button = self.lkas_button - self.lkas_button = self.get_lkas_button(cp, cp_cam) + self.lkas_button = self._read_lkas_button(can_parsers[Bus.pt], can_parsers[Bus.cam]) diff --git a/iqdbc_repo/iqdbc/iqpilot/car/chrysler/carcontroller_ext.py b/iqdbc_repo/iqdbc/iqpilot/car/chrysler/carcontroller_ext.py index fdeb0a8..7e88389 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/chrysler/carcontroller_ext.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/chrysler/carcontroller_ext.py @@ -1,5 +1,8 @@ """ Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos + +Chrysler low-speed steering gate: overrides the stock LKAS control bit when the +no-min-steering-speed option is set, and holds the RAM DT engagement window. """ from iqdbc.car import structs from iqdbc.car.interfaces import CarStateBase @@ -16,8 +19,9 @@ class CarControllerExt: def get_lkas_control_bit(self, CS: CarStateBase, CC: structs.CarControl, lkas_control_bit: bool) -> bool: if self.CP_IQ.flags & ChryslerFlagsIQ.NO_MIN_STEERING_SPEED: - lkas_control_bit = CC.latActive - elif self.CP.carFingerprint in RAM_DT: + return CC.latActive + + if self.CP.carFingerprint in RAM_DT: if self.CP.minEnableSpeed <= CS.out.vEgo <= self.CP.minEnableSpeed + 0.5: lkas_control_bit = True if self.CP.minEnableSpeed >= 14.5 and CS.out.gearShifter != GearShifter.drive: diff --git a/iqdbc_repo/iqdbc/iqpilot/car/chrysler/carstate_ext.py b/iqdbc_repo/iqdbc/iqpilot/car/chrysler/carstate_ext.py index 67cf260..1be0839 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/chrysler/carstate_ext.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/chrysler/carstate_ext.py @@ -1,13 +1,13 @@ - """ Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos -""" +Chrysler cruise-button reader: emits edge ButtonEvents for the ACC steering-wheel +buttons so IQ.Pilot can react to accel/decel/cancel/resume. +""" from enum import StrEnum from iqdbc.car import Bus, structs from iqdbc.can.parser import CANParser -from iqdbc.car.chrysler.values import RAM_HD from iqdbc.iqpilot.car.chrysler.values_ext import BUTTONS @@ -15,23 +15,18 @@ class CarStateExt: def __init__(self, CP, CP_IQ): self.CP = CP self.CP_IQ = CP_IQ - - self.button_events = [] + self.button_events: list = [] self.button_states = {button.event_type: False for button in BUTTONS} - def update(self, ret: structs.CarState, ret_iq: structs.IQCarState, can_parsers: dict[StrEnum, CANParser]): + def update(self, ret: structs.CarState, ret_iq: structs.IQCarState, can_parsers: dict[StrEnum, CANParser]) -> None: cp = can_parsers[Bus.pt] - - button_events = [] + events = [] for button in BUTTONS: - state = (cp.vl[button.can_addr][button.can_msg] in button.values) - if self.button_states[button.event_type] != state: + pressed = cp.vl[button.can_addr][button.can_msg] in button.values + if pressed != self.button_states[button.event_type]: event = structs.CarState.ButtonEvent.new_message() event.type = button.event_type - event.pressed = state - button_events.append(event) - self.button_states[button.event_type] = state - self.button_events = button_events - - if self.CP.carFingerprint in RAM_HD: - ret.steeringAngleDeg = cp.vl["STEERING"]["STEERING_ANGLE"] + event.pressed = pressed + events.append(event) + self.button_states[button.event_type] = pressed + self.button_events = events diff --git a/iqdbc_repo/iqdbc/iqpilot/car/chrysler/values_ext.py b/iqdbc_repo/iqdbc/iqpilot/car/chrysler/values_ext.py index 7b966ee..caee733 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/chrysler/values_ext.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/chrysler/values_ext.py @@ -1,7 +1,9 @@ """ Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos -""" +IQ.Pilot Chrysler extension flags + the cruise-button table read by the AOL +cruise-button reader. +""" from collections import namedtuple from enum import IntFlag @@ -20,5 +22,3 @@ BUTTONS = [ class ChryslerFlagsIQ(IntFlag): NO_MIN_STEERING_SPEED = 1 - - diff --git a/iqdbc_repo/iqdbc/iqpilot/car/ford/__init__.py b/iqdbc_repo/iqdbc/iqpilot/car/ford/__init__.py deleted file mode 100644 index 297dca9..0000000 --- a/iqdbc_repo/iqdbc/iqpilot/car/ford/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -""" -Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos -""" diff --git a/iqdbc_repo/iqdbc/iqpilot/car/ford/aol.py b/iqdbc_repo/iqdbc/iqpilot/car/ford/aol.py deleted file mode 100644 index 510c9e0..0000000 --- a/iqdbc_repo/iqdbc/iqpilot/car/ford/aol.py +++ /dev/null @@ -1,21 +0,0 @@ -""" -Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos -""" - -from enum import StrEnum - -from iqdbc.car import Bus,structs - -from iqdbc.iqpilot.aol_base import AolCarStateBase -from iqdbc.can.parser import CANParser - - -class AolCarState(AolCarStateBase): - def __init__(self, CP: structs.CarParams, CP_IQ: structs.IQCarParams): - super().__init__(CP, CP_IQ) - - def update_aol(self, ret: structs.CarState, can_parsers: dict[StrEnum, CANParser]) -> None: - cp = can_parsers[Bus.pt] - - self.prev_lkas_button = self.lkas_button - self.lkas_button = cp.vl["Steering_Data_FD1"]["TjaButtnOnOffPress"] diff --git a/iqdbc_repo/iqdbc/iqpilot/car/gm/__init__.py b/iqdbc_repo/iqdbc/iqpilot/car/gm/__init__.py index 297dca9..e69de29 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/gm/__init__.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/gm/__init__.py @@ -1,3 +0,0 @@ -""" -Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos -""" diff --git a/iqdbc_repo/iqdbc/iqpilot/car/gm/carstate_ext.py b/iqdbc_repo/iqdbc/iqpilot/car/gm/carstate_ext.py index 4ebe9a1..2bfb846 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/gm/carstate_ext.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/gm/carstate_ext.py @@ -1,5 +1,8 @@ """ Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos + +Non-ACC GM carState: these cars have no adaptive cruise, so cruise engage/set +speed come from the stock (non-adaptive) ECM cruise message. """ from enum import StrEnum @@ -15,9 +18,9 @@ class CarStateExt: self.CP_IQ = CP_IQ def update(self, ret: structs.CarState, can_parsers: dict[StrEnum, CANParser]) -> None: + if not self.CP_IQ.flags & GMFlagsIQ.NON_ACC: + return pt_cp = can_parsers[Bus.pt] - - if self.CP_IQ.flags & GMFlagsIQ.NON_ACC: - ret.cruiseState.enabled = pt_cp.vl["ECMCruiseControl"]["CruiseActive"] != 0 - ret.cruiseState.speed = pt_cp.vl["ECMCruiseControl"]["CruiseSetSpeed"] * CV.KPH_TO_MS - ret.accFaulted = False + ret.cruiseState.enabled = pt_cp.vl["ECMCruiseControl"]["CruiseActive"] != 0 + ret.cruiseState.speed = pt_cp.vl["ECMCruiseControl"]["CruiseSetSpeed"] * CV.KPH_TO_MS + ret.accFaulted = False diff --git a/iqdbc_repo/iqdbc/iqpilot/car/gm/interface_ext.py b/iqdbc_repo/iqdbc/iqpilot/car/gm/interface_ext.py index 2c1bea1..2491266 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/gm/interface_ext.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/gm/interface_ext.py @@ -1,18 +1,19 @@ """ Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos + +GM torque-space feed-forward for the IQ.Pilot lateral extension: a sigmoid+linear +lat-accel -> torque curve for the tuned platforms, else the linear default. """ -import os from math import exp from iqdbc.car import structs -from iqdbc.car.common.basedir import BASEDIR from iqdbc.car.gm.interface import CAR -from iqdbc.iqpilot.car.interfaces import LatControlInputs, NanoFFModel, TorqueFromLateralAccelCallbackTypeTorqueSpace +from iqdbc.iqpilot.car.interfaces import LatControlInputs, TorqueFromLateralAccelCallbackTypeTorqueSpace -NON_LINEAR_TORQUE_PARAMS = { +_NON_LINEAR_TORQUE_PARAMS = { CAR.CHEVROLET_BOLT_EUV: [2.6531724862969748, 1.0, 0.1919764879840985, 0.009054123646805178], CAR.GMC_ACADIA: [4.78003305, 1.0, 0.3122, 0.05591772], - CAR.CHEVROLET_SILVERADO: [3.29974374, 1.0, 0.25571356, 0.0465122] + CAR.CHEVROLET_SILVERADO: [3.29974374, 1.0, 0.25571356, 0.0465122], } @@ -20,39 +21,23 @@ class CarInterfaceExt: def __init__(self, CP: structs.CarParams, CI_Base): self.CP = CP self.CI_Base = CI_Base - self.neural_ff_model = None - def torque_from_lateral_accel_siglin(self, latcontrol_inputs: LatControlInputs, torque_params: structs.CarParams.LateralTorqueTuning, + @staticmethod + def _centered_sigmoid(val: float) -> float: + # sigmoid shifted to pass through the origin; branch keeps exp() from overflowing + if val >= 0: + return 1.0 / (1.0 + exp(-val)) - 0.5 + z = exp(val) + return z / (1.0 + z) - 0.5 + + def torque_from_lateral_accel_siglin(self, latcontrol_inputs: LatControlInputs, + torque_params: structs.CarParams.LateralTorqueTuning, gravity_adjusted: bool) -> float: - def sig(val): - # https://timvieira.github.io/blog/post/2014/02/11/exp-normalize-trick - if val >= 0: - return 1 / (1 + exp(-val)) - 0.5 - else: - z = exp(val) - return z / (1 + z) - 0.5 - - # The "lat_accel vs torque" relationship is assumed to be the sum of "sigmoid + linear" curves - # An important thing to consider is that the slope at 0 should be > 0 (ideally >1) - # This has big effect on the stability about 0 (noise when going straight) - # ToDo: To generalize to other GMs, explore tanh function as the nonlinear - non_linear_torque_params = NON_LINEAR_TORQUE_PARAMS.get(self.CP.carFingerprint) - assert non_linear_torque_params, "The params are not defined" - a, b, c, _ = non_linear_torque_params - steer_torque = (sig(latcontrol_inputs.lateral_acceleration * a) * b) + (latcontrol_inputs.lateral_acceleration * c) - return float(steer_torque) - - def torque_from_lateral_accel_neural(self, latcontrol_inputs: LatControlInputs, orque_params: structs.CarParams.LateralTorqueTuning, - gravity_adjusted: bool) -> float: - inputs = list(latcontrol_inputs) - if gravity_adjusted: - inputs[0] += inputs[1] - return float(self.neural_ff_model.predict(inputs)) + a, b, c, _ = _NON_LINEAR_TORQUE_PARAMS[self.CP.carFingerprint] + lat_accel = latcontrol_inputs.lateral_acceleration + return float(self._centered_sigmoid(lat_accel * a) * b + lat_accel * c) def torque_from_lateral_accel_in_torque_space(self) -> TorqueFromLateralAccelCallbackTypeTorqueSpace: - if self.CP.carFingerprint == CAR.CHEVROLET_BOLT_EUV: - return self.torque_from_lateral_accel_neural - elif self.CP.carFingerprint in NON_LINEAR_TORQUE_PARAMS: + if self.CP.carFingerprint in _NON_LINEAR_TORQUE_PARAMS: return self.torque_from_lateral_accel_siglin - else: - return self.CI_Base.torque_from_lateral_accel_linear_in_torque_space + return self.CI_Base.torque_from_lateral_accel_linear_in_torque_space diff --git a/iqdbc_repo/iqdbc/iqpilot/car/gm/values_ext.py b/iqdbc_repo/iqdbc/iqpilot/car/gm/values_ext.py index ddbce1a..b52d293 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/gm/values_ext.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/gm/values_ext.py @@ -1,7 +1,8 @@ """ Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos -""" +IQ.Pilot GM extension flags for the non-adaptive-cruise (Non-ACC) camera-harness port. +""" from enum import IntFlag @@ -11,5 +12,3 @@ class GMFlagsIQ(IntFlag): class GMSafetyFlagsIQ: NON_ACC = 1 - - diff --git a/iqdbc_repo/iqdbc/iqpilot/car/interfaces.py b/iqdbc_repo/iqdbc/iqpilot/car/interfaces.py index c19f68a..c0bf1f6 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/interfaces.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/interfaces.py @@ -96,16 +96,17 @@ def _initialize_coop_steering(CP: structs.CarParams, CP_IQ: structs.IQCarParams, def _initialize_stop_and_go(CP: structs.CarParams, CP_IQ: structs.IQCarParams, params_dict: dict[str, str]) -> None: - if CP.brand == 'subaru' and not CP.flags & (SubaruFlags.GLOBAL_GEN2 | SubaruFlags.HYBRID): - stop_and_go = int(params_dict.get("SubaruStopAndGo", 0)) == 1 - stop_and_go_manual_parking_brake = int(params_dict.get("SubaruStopAndGoManualParkingBrake", 0)) == 1 + # Subaru stop-and-go; unsupported on gen2-global and hybrid platforms. + if CP.brand != 'subaru' or CP.flags & (SubaruFlags.GLOBAL_GEN2 | SubaruFlags.HYBRID): + return - if stop_and_go: - CP_IQ.flags |= SubaruFlagsIQ.STOP_AND_GO.value - if stop_and_go_manual_parking_brake: - CP_IQ.flags |= SubaruFlagsIQ.STOP_AND_GO_MANUAL_PARKING_BRAKE.value - if stop_and_go or stop_and_go_manual_parking_brake: - CP_IQ.safetyParam |= SubaruSafetyFlagsIQ.STOP_AND_GO + if int(params_dict.get("SubaruStopAndGo", 0)) == 1: + CP_IQ.flags |= SubaruFlagsIQ.STOP_AND_GO.value + if int(params_dict.get("SubaruStopAndGoManualParkingBrake", 0)) == 1: + CP_IQ.flags |= SubaruFlagsIQ.STOP_AND_GO_MANUAL_PARKING_BRAKE.value + + if CP_IQ.flags & (SubaruFlagsIQ.STOP_AND_GO | SubaruFlagsIQ.STOP_AND_GO_MANUAL_PARKING_BRAKE): + CP_IQ.iqSafetyFlags |= SubaruSafetyFlagsIQ.STOP_AND_GO def _initialize_toyota(CP: structs.CarParams, CP_IQ: structs.IQCarParams, params_dict: dict[str, str]) -> None: diff --git a/iqdbc_repo/iqdbc/iqpilot/car/mazda/__init__.py b/iqdbc_repo/iqdbc/iqpilot/car/mazda/__init__.py deleted file mode 100644 index 297dca9..0000000 --- a/iqdbc_repo/iqdbc/iqpilot/car/mazda/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -""" -Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos -""" diff --git a/iqdbc_repo/iqdbc/iqpilot/car/nissan/__init__.py b/iqdbc_repo/iqdbc/iqpilot/car/nissan/__init__.py index 297dca9..e69de29 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/nissan/__init__.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/nissan/__init__.py @@ -1,3 +0,0 @@ -""" -Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos -""" diff --git a/iqdbc_repo/iqdbc/iqpilot/car/nissan/carstate_ext.py b/iqdbc_repo/iqdbc/iqpilot/car/nissan/carstate_ext.py index e28f9e4..73f0c76 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/nissan/carstate_ext.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/nissan/carstate_ext.py @@ -1,7 +1,8 @@ """ Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos -""" +Nissan cruise-button reader: emits edge ButtonEvents for the RES/SET buttons. +""" from enum import StrEnum from iqdbc.car import Bus, structs @@ -13,20 +14,18 @@ class CarStateExt: def __init__(self, CP, CP_IQ): self.CP = CP self.CP_IQ = CP_IQ - - self.button_events = [] + self.button_events: list = [] self.button_states = {button.event_type: False for button in BUTTONS} - def update(self, ret: structs.CarState, ret_iq: structs.IQCarState, can_parsers: dict[StrEnum, CANParser]): + def update(self, ret: structs.CarState, ret_iq: structs.IQCarState, can_parsers: dict[StrEnum, CANParser]) -> None: cp = can_parsers[Bus.pt] - - button_events = [] + events = [] for button in BUTTONS: - state = (cp.vl[button.can_addr][button.can_msg] in button.values) - if self.button_states[button.event_type] != state: + pressed = cp.vl[button.can_addr][button.can_msg] in button.values + if pressed != self.button_states[button.event_type]: event = structs.CarState.ButtonEvent.new_message() event.type = button.event_type - event.pressed = state - button_events.append(event) - self.button_states[button.event_type] = state - self.button_events = button_events + event.pressed = pressed + events.append(event) + self.button_states[button.event_type] = pressed + self.button_events = events diff --git a/iqdbc_repo/iqdbc/iqpilot/car/nissan/values.py b/iqdbc_repo/iqdbc/iqpilot/car/nissan/values.py index 2c2e333..d1cbe20 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/nissan/values.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/nissan/values.py @@ -1,8 +1,10 @@ """ Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos -""" +IQ.Pilot Nissan extension: safety flag + cruise-button table. +""" from collections import namedtuple + from iqdbc.car import structs @@ -11,12 +13,9 @@ class NissanSafetyFlagsIQ: LEAF = 1 - - ButtonType = structs.CarState.ButtonEvent.Type Button = namedtuple('Button', ['event_type', 'can_addr', 'can_msg', 'values']) - BUTTONS = [ Button(ButtonType.accelCruise, "CRUISE_THROTTLE", "RES_BUTTON", [1]), Button(ButtonType.decelCruise, "CRUISE_THROTTLE", "SET_BUTTON", [1]), diff --git a/iqdbc_repo/iqdbc/iqpilot/car/rivian/__init__.py b/iqdbc_repo/iqdbc/iqpilot/car/rivian/__init__.py index 297dca9..e69de29 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/rivian/__init__.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/rivian/__init__.py @@ -1,3 +0,0 @@ -""" -Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos -""" diff --git a/iqdbc_repo/iqdbc/iqpilot/car/rivian/aol.py b/iqdbc_repo/iqdbc/iqpilot/car/rivian/aol.py index f28c0c2..3c92c9a 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/rivian/aol.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/rivian/aol.py @@ -1,33 +1,30 @@ """ Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos + +Always-on-Lateral output adapter for Rivian: derives the per-frame lateral-active +and lane-keep icon state the LKAS command needs from the shared AOL state. """ from collections import namedtuple from iqdbc.car import structs from iqdbc.car.interfaces import CarStateBase -MAX_STEERING_ANGLE = 90.0 +# Rivian EPAS rejects large-angle torque, so lateral is dropped past this bound. +_MAX_STEERING_ANGLE = 90.0 -AolDataIQ = namedtuple("AolDataIQ", - ["lka_icon_states", "lat_active"]) +AolDataIQ = namedtuple("AolDataIQ", ["lka_icon_states", "lat_active"]) class AolCarController: def __init__(self): self.aol = AolDataIQ(False, False) - self.lka_icon_states = False - self.lat_active = False - - def aol_status_update(self, CC: structs.CarControl, CC_IQ: structs.IQCarControl, CS: CarStateBase) -> AolDataIQ: - if CC_IQ.aol.available: - self.lka_icon_states = self.lat_active - self.lat_active = CC.latActive and abs(CS.out.steeringAngleDeg) < MAX_STEERING_ANGLE - else: - self.lka_icon_states = CC.enabled - self.lat_active = CC.latActive - - return AolDataIQ(self.lka_icon_states, self.lat_active) - def update(self, CC: structs.CarControl, CC_IQ: structs.IQCarControl, CS: CarStateBase) -> None: - self.aol = self.aol_status_update(CC, CC_IQ, CS) + prev_active = self.aol.lat_active + if CC_IQ.aol.available: + lat_active = CC.latActive and abs(CS.out.steeringAngleDeg) < _MAX_STEERING_ANGLE + lka_icon = prev_active + else: + lat_active = CC.latActive + lka_icon = CC.enabled + self.aol = AolDataIQ(lka_icon, lat_active) diff --git a/iqdbc_repo/iqdbc/iqpilot/car/rivian/carstate_ext.py b/iqdbc_repo/iqdbc/iqpilot/car/rivian/carstate_ext.py index 051ed13..f638afc 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/rivian/carstate_ext.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/rivian/carstate_ext.py @@ -1,5 +1,9 @@ """ Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos + +Rivian longitudinal-harness-upgrade carState reader: with the upgrade harness the +right steering-wheel controls and the drive stalk drive the openpilot set speed, +and the harness exposes blind-spot indicators. Only active behind the upgrade flag. """ import math from enum import StrEnum @@ -12,8 +16,10 @@ from iqdbc.iqpilot.car.rivian.values import RivianFlagsIQ ButtonType = structs.CarState.ButtonEvent.Type -MAX_SET_SPEED = 85 * CV.MPH_TO_MS -MIN_SET_SPEED = 20 * CV.MPH_TO_MS +_SET_SPEED_MAX = 85 * CV.MPH_TO_MS +_SET_SPEED_MIN = 20 * CV.MPH_TO_MS +_LONG_PRESS_FRAMES = 66 +_STALK_HOLD_FRAMES = 50 class CarStateExt: @@ -29,57 +35,57 @@ class CarStateExt: self.decrease_counter = 0 self.stalk_down_counter = 0 + def _apply_set_speed_buttons(self, ret: structs.CarState, cp_park, cp_adas) -> None: + was_increasing = self.increase_button + was_decreasing = self.decrease_button + + self.increase_button = cp_park.vl["WheelButtons"]["RightButton_RightClick"] == 2 + self.decrease_button = cp_park.vl["WheelButtons"]["RightButton_LeftClick"] == 2 + self.increase_counter = self.increase_counter + 1 if self.increase_button else 0 + self.decrease_counter = self.decrease_counter + 1 if self.decrease_button else 0 + + metric = cp_adas.vl["Cluster"]["Cluster_Unit"] == 0 + conversion = CV.KPH_TO_MS if metric else CV.MPH_TO_MS + step = 10.0 if metric else 5.0 + shown = self.set_speed * (CV.MS_TO_KPH if metric else CV.MS_TO_MPH) + + # A held button steps to the next round multiple; a tap nudges by one unit. + if self.increase_button: + if self.increase_counter % _LONG_PRESS_FRAMES == 0: + self.set_speed = math.ceil((shown + 1) / step) * step * conversion + elif not was_increasing: + self.set_speed += conversion + if self.decrease_button: + if self.decrease_counter % _LONG_PRESS_FRAMES == 0: + self.set_speed = math.floor((shown - 1) / step) * step * conversion + elif not was_decreasing: + self.set_speed -= conversion + def update_longitudinal_upgrade(self, ret: structs.CarState, can_parsers: dict[StrEnum, CANParser]) -> None: cp_park = can_parsers[Bus.alt] cp_adas = can_parsers[Bus.adas] cp = can_parsers[Bus.pt] - prev_increase_button = self.increase_button - prev_decrease_button = self.decrease_button - if self.CP.openpilotLongitudinalControl: - # distance scroll wheel right_scroll = cp_park.vl["WheelButtons"]["RightButton_Scroll"] if right_scroll != 255: if self.distance_button != right_scroll: ret.buttonEvents = [structs.CarState.ButtonEvent(pressed=False, type=ButtonType.gapAdjustCruise)] self.distance_button = right_scroll - # button logic for set-speed - self.increase_button = cp_park.vl["WheelButtons"]["RightButton_RightClick"] == 2 - self.decrease_button = cp_park.vl["WheelButtons"]["RightButton_LeftClick"] == 2 - - self.increase_counter = self.increase_counter + 1 if self.increase_button else 0 - self.decrease_counter = self.decrease_counter + 1 if self.decrease_button else 0 - - metric = cp_adas.vl["Cluster"]["Cluster_Unit"] == 0 - conversion = CV.KPH_TO_MS if metric else CV.MPH_TO_MS - long_press_step = 10.0 if metric else 5.0 - set_speed_converted = self.set_speed * (CV.MS_TO_KPH if metric else CV.MS_TO_MPH) - - if self.increase_button: - if self.increase_counter % 66 == 0: - self.set_speed = (int(math.ceil((set_speed_converted + 1) / long_press_step)) * long_press_step) * conversion - elif not prev_increase_button: - self.set_speed += conversion - - if self.decrease_button: - if self.decrease_counter % 66 == 0: - self.set_speed = (int(math.floor((set_speed_converted - 1) / long_press_step)) * long_press_step) * conversion - elif not prev_decrease_button: - self.set_speed -= conversion + self._apply_set_speed_buttons(ret, cp_park, cp_adas) if not ret.cruiseState.enabled: self.set_speed = ret.vEgoCluster - # VDM_UserAdasRequest: 0=IDLE, 1=UP_1, 2=UP_2, 3=DOWN_1, 4=DOWN_2 + # Drive stalk held down (VDM_UserAdasRequest 3/4) for ~0.5s snaps set speed + # up to the current speed, matching stock Rivian ACC (it never lowers it). stalk_down = int(cp.vl["VDM_AdasSts"]["VDM_UserAdasRequest"]) in (3, 4) self.stalk_down_counter = self.stalk_down_counter + 1 if stalk_down else 0 - if self.stalk_down_counter == 50: - # Mimic Rivian ACC: holding stalk 0.5s sets speed to current speed (never decreases) + if self.stalk_down_counter == _STALK_HOLD_FRAMES: self.set_speed = max(self.set_speed, ret.vEgoCluster) - self.set_speed = max(MIN_SET_SPEED, min(self.set_speed, MAX_SET_SPEED)) + self.set_speed = max(_SET_SPEED_MIN, min(self.set_speed, _SET_SPEED_MAX)) ret.cruiseState.speed = self.set_speed if self.CP.enableBsm: @@ -92,9 +98,7 @@ class CarStateExt: @staticmethod def get_parser(CP, CP_IQ) -> dict[StrEnum, CANParser]: - messages = {} - + messages: dict[StrEnum, CANParser] = {} if CP_IQ.flags & RivianFlagsIQ.LONGITUDINAL_HARNESS_UPGRADE: messages[Bus.alt] = CANParser(DBC[CP.carFingerprint][Bus.alt], [], 5) - return messages diff --git a/iqdbc_repo/iqdbc/iqpilot/car/rivian/values.py b/iqdbc_repo/iqdbc/iqpilot/car/rivian/values.py index c165a17..0cbd701 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/rivian/values.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/rivian/values.py @@ -1,10 +1,10 @@ """ Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos + +IQ.Pilot Rivian extension flags. """ from enum import IntFlag class RivianFlagsIQ(IntFlag): LONGITUDINAL_HARNESS_UPGRADE = 1 - - diff --git a/iqdbc_repo/iqdbc/iqpilot/car/subaru/__init__.py b/iqdbc_repo/iqdbc/iqpilot/car/subaru/__init__.py index 297dca9..e69de29 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/subaru/__init__.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/subaru/__init__.py @@ -1,3 +0,0 @@ -""" -Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos -""" diff --git a/iqdbc_repo/iqdbc/iqpilot/car/subaru/aol.py b/iqdbc_repo/iqdbc/iqpilot/car/subaru/aol.py index 523d06f..9e0938e 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/subaru/aol.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/subaru/aol.py @@ -1,45 +1,36 @@ """ Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos + +Always-on-Lateral input adapter for Subaru: turns the dashboard LKAS button into +a carState lkas ButtonEvent so the shared AOL state machine can toggle lateral. """ - from enum import StrEnum -from iqdbc.car import Bus, structs +from iqdbc.car import Bus, structs from iqdbc.car.subaru.values import SubaruFlags from iqdbc.iqpilot.aol_base import AolCarStateBase from iqdbc.can.parser import CANParser -ButtonType = structs.CarState.ButtonEvent.Type +_LKAS = structs.CarState.ButtonEvent.Type.lkas + +# ES_LKAS_State/LKAS_Dash_State: 0 = neutral, 1 = LKAS shown on, 2 = LKAS shown off +_DASH_ON = 1 +_DASH_OFF = 2 class AolCarState(AolCarStateBase): - def __init__(self, CP: structs.CarParams, CP_IQ: structs.IQCarParams): - super().__init__(CP, CP_IQ) - - @staticmethod - def create_lkas_button_events(cur_btn: int, prev_btn: int, - buttons_dict: dict[int, structs.CarState.ButtonEvent.Type]) -> list[structs.CarState.ButtonEvent]: - events: list[structs.CarState.ButtonEvent] = [] - - if cur_btn == prev_btn: - return events - - state_changes = [ - {"pressed": prev_btn != cur_btn and cur_btn != 2 and not (prev_btn == 2 and cur_btn == 1)}, - {"pressed": prev_btn != cur_btn and cur_btn == 2 and cur_btn != 1}, - ] - - for change in state_changes: - if change["pressed"]: - events.append(structs.CarState.ButtonEvent(pressed=change["pressed"], - type=buttons_dict.get(cur_btn, ButtonType.unknown))) - return events - def update_aol(self, ret: structs.CarState, can_parsers: dict[StrEnum, CANParser]) -> None: - cp_cam = can_parsers[Bus.cam] + if self.CP.flags & SubaruFlags.PREGLOBAL: + return self.prev_lkas_button = self.lkas_button - if not self.CP.flags & SubaruFlags.PREGLOBAL: - self.lkas_button = cp_cam.vl["ES_LKAS_State"]["LKAS_Dash_State"] + self.lkas_button = can_parsers[Bus.cam].vl["ES_LKAS_State"]["LKAS_Dash_State"] - ret.buttonEvents = self.create_lkas_button_events(self.lkas_button, self.prev_lkas_button, {1: ButtonType.lkas}) + if self._is_toggle_edge(): + ret.buttonEvents = [*ret.buttonEvents, structs.CarState.ButtonEvent(type=_LKAS, pressed=True)] + + def _is_toggle_edge(self) -> bool: + # every dash-state change is a deliberate press except the off->on rebound (2 -> 1) + if self.lkas_button == self.prev_lkas_button: + return False + return not (self.prev_lkas_button == _DASH_OFF and self.lkas_button == _DASH_ON) diff --git a/iqdbc_repo/iqdbc/iqpilot/car/subaru/stop_and_go.py b/iqdbc_repo/iqdbc/iqpilot/car/subaru/stop_and_go.py index a696c22..15357c4 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/subaru/stop_and_go.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/subaru/stop_and_go.py @@ -1,7 +1,11 @@ """ Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos -""" +IQ.Pilot Subaru stop-and-go: nudges the ACC out of a standstill it would +otherwise hold. Two variants gated by user flags — an electronic-parking-brake +resume pulse (distance/lead triggered) and a manual-parking-brake hold-timer +resume. Both work by spoofing the camera-bus throttle/brake frames. +""" import copy from enum import StrEnum @@ -14,93 +18,64 @@ from iqdbc.iqpilot.car.subaru import subarucan_ext from iqdbc.iqpilot.car.subaru.values_ext import SubaruFlagsIQ from iqdbc.can.parser import CANParser -_SNG_ACC_MIN_DIST = 3 -_SNG_ACC_MAX_DIST = 4.5 +# EPB resume fires only while the lead is pulling away within this gap band (m). +_RESUME_GAP_MIN = 3.0 +_RESUME_GAP_MAX = 4.5 +_EPB_PULSE_FRAMES = 15 class SnGCarController: def __init__(self, CP: structs.CarParams, CP_IQ: structs.IQCarParams): self.CP = CP self.CP_IQ = CP_IQ - self.enabled = CP_IQ.flags & (SubaruFlagsIQ.STOP_AND_GO | SubaruFlagsIQ.STOP_AND_GO_MANUAL_PARKING_BRAKE) - self.manual_parking_brake = CP_IQ.flags & SubaruFlagsIQ.STOP_AND_GO_MANUAL_PARKING_BRAKE + self.enabled = bool(CP_IQ.flags & (SubaruFlagsIQ.STOP_AND_GO | SubaruFlagsIQ.STOP_AND_GO_MANUAL_PARKING_BRAKE)) + self.manual_parking_brake = bool(CP_IQ.flags & SubaruFlagsIQ.STOP_AND_GO_MANUAL_PARKING_BRAKE) - self.last_standstill_frame = 0 - self.epb_resume_frames_remaining = -1 - self.prev_close_distance = 0.0 + self.standstill_since = 0 + self._pulse_left = 0 + self.prev_gap = 0.0 - def update_epb_resume_sequence(self, should_resume: bool) -> bool: + def _epb_pulse(self, trigger: bool) -> bool: + # A trigger arms a fixed-length resume pulse; the pulse then plays out frame by frame. if self.manual_parking_brake: return False + if trigger: + self._pulse_left = _EPB_PULSE_FRAMES + if self._pulse_left > 0: + self._pulse_left -= 1 + return True + return False - if should_resume: - self.epb_resume_frames_remaining = 15 - - send_resume = self.epb_resume_frames_remaining > 0 - if self.epb_resume_frames_remaining > 0: - self.epb_resume_frames_remaining -= 1 - - return send_resume - - def update_stop_and_go(self, CC: structs.CarControl, CS: CarStateBase, frame: int) -> bool: - """ - Manages stop-and-go functionality for adaptive cruise control (ACC). - - Args: - CC: Car control data - CS: Car state data - frame: Current frame number - - Returns: - bool: True if resume command should be sent, False otherwise - """ - + def _want_resume(self, CC: structs.CarControl, CS: CarStateBase, frame: int) -> bool: if not CC.enabled or not CC.hudControl.leadVisible: return False - close_distance = CS.es_distance_msg["Close_Distance"] - in_standstill = CS.out.standstill + gap = CS.es_distance_msg["Close_Distance"] + standing = CS.out.standstill + if not standing: + self.standstill_since = frame - if not in_standstill: - self.last_standstill_frame = frame + hold_arm, hold_reset = (0.75, 0.8) if self.CP.flags & SubaruFlags.PREGLOBAL else (0.5, 0.55) + held_for = (frame - self.standstill_since) * DT_CTRL + held_long_enough = held_for > hold_arm + if held_for >= hold_reset: + self.standstill_since = frame - # Check if we've been in standstill long enough - mpb_standstill_timers = (0.75, 0.8) if self.CP.flags & SubaruFlags.PREGLOBAL else (0.5, 0.55) - standstill_duration = (frame - self.last_standstill_frame) * DT_CTRL - in_standstill_hold = standstill_duration > mpb_standstill_timers[0] - if (frame - self.last_standstill_frame) * DT_CTRL >= mpb_standstill_timers[1]: - self.last_standstill_frame = frame - - # Car state distance-based conditions (EPB only) - in_resume_distance = _SNG_ACC_MIN_DIST < close_distance < _SNG_ACC_MAX_DIST - distance_increasing = close_distance > self.prev_close_distance - distance_resume_allowed = in_resume_distance and distance_increasing + lead_pulling_away = _RESUME_GAP_MIN < gap < _RESUME_GAP_MAX and gap > self.prev_gap + self.prev_gap = gap if self.manual_parking_brake: - # Manual parking brake: Direct resume when the standstill hold threshold is reached to prevent ACC fault - send_resume = in_standstill_hold - else: - # EPB: Resume sequence with trigger on distance with lead car increasing - should_resume = CS.out.standstill and distance_resume_allowed - send_resume = self.update_epb_resume_sequence(should_resume) - - self.prev_close_distance = close_distance - - return send_resume + return held_long_enough + return self._epb_pulse(standing and lead_pulling_away) def create_stop_and_go(self, packer, CC: structs.CarControl, CS: CarStateBase, frame: int) -> list[CanData]: - can_sends = [] - if not self.enabled: - return can_sends - - send_resume = self.update_stop_and_go(CC, CS, frame) - - can_sends.append(subarucan_ext.create_throttle(packer, self.CP, CS.throttle_msg, send_resume and not self.manual_parking_brake)) + return [] + resume = self._want_resume(CC, CS, frame) + can_sends = [subarucan_ext.create_throttle(packer, self.CP, CS.throttle_msg, resume and not self.manual_parking_brake)] if frame % 2 == 0: - can_sends.append(subarucan_ext.create_brake_pedal(packer, self.CP, CS.brake_pedal_msg, send_resume and self.manual_parking_brake)) - + can_sends.append(subarucan_ext.create_brake_pedal(packer, self.CP, CS.brake_pedal_msg, resume and self.manual_parking_brake)) return can_sends @@ -108,14 +83,11 @@ class SnGCarState: def __init__(self, CP: structs.CarParams, CP_IQ: structs.IQCarParams): self.CP = CP self.CP_IQ = CP_IQ - self.brake_pedal_msg: dict[str, float] = {} self.throttle_msg: dict[str, float] = {} def update(self, ret: structs.CarState, can_parsers: dict[StrEnum, CANParser]) -> None: cp = can_parsers[Bus.pt] - self.brake_pedal_msg = copy.copy(cp.vl["Brake_Pedal"]) - if not self.CP.flags & SubaruFlags.HYBRID: self.throttle_msg = copy.copy(cp.vl["Throttle"]) diff --git a/iqdbc_repo/iqdbc/iqpilot/car/subaru/subarucan_ext.py b/iqdbc_repo/iqdbc/iqpilot/car/subaru/subarucan_ext.py index b6a710e..5fd8e16 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/subaru/subarucan_ext.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/subaru/subarucan_ext.py @@ -1,68 +1,41 @@ +""" +Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos + +Camera-bus message spoofers for Subaru stop-and-go: re-emit the stock Throttle +and Brake_Pedal frames, nudging a single field to trigger an ACC resume from a +standstill. Field sets mirror the DBC message layout. +""" from iqdbc.car.subaru.values import CanBus, SubaruFlags +_THROTTLE_FIELDS_PREGLOBAL = ("Throttle_Pedal", "Signal1", "Not_Full_Throttle", "Signal2", "Engine_RPM", + "Off_Throttle", "Signal3", "Throttle_Cruise", "Throttle_Combo", "Throttle_Body", + "Off_Throttle_2", "Signal4") +_THROTTLE_FIELDS_GLOBAL = ("CHECKSUM", "Signal1", "Engine_RPM", "Neutral", "Throttle_Pedal", "Throttle_Cruise", + "Throttle_Combo", "Signal3", "Off_Accel") +_BRAKE_FIELDS_PREGLOBAL = ("Speed", "Brake_Pedal", "Signal1") +_BRAKE_FIELDS_GLOBAL = ("CHECKSUM", "Signal1", "Speed", "Signal2", "Brake_Lights", "Signal3", "Brake_Pedal", "Signal4") -def create_counter(msg): + +def _next_counter(msg): return (msg["COUNTER"] + 1) % 0x10 def create_throttle(packer, CP, throttle_msg, send_resume): - if CP.flags & SubaruFlags.PREGLOBAL: - values = {s: throttle_msg[s] for s in [ - "Throttle_Pedal", - "Signal1", - "Not_Full_Throttle", - "Signal2", - "Engine_RPM", - "Off_Throttle", - "Signal3", - "Throttle_Cruise", - "Throttle_Combo", - "Throttle_Body", - "Off_Throttle_2", - "Signal4", - ]} - else: - values = {s: throttle_msg[s] for s in [ - "CHECKSUM", - "Signal1", - "Engine_RPM", - "Neutral", - "Throttle_Pedal", - "Throttle_Cruise", - "Throttle_Combo", - "Signal3", - "Off_Accel", - ]} - - values["COUNTER"] = create_counter(throttle_msg) - + preglobal = bool(CP.flags & SubaruFlags.PREGLOBAL) + fields = _THROTTLE_FIELDS_PREGLOBAL if preglobal else _THROTTLE_FIELDS_GLOBAL + values = {name: throttle_msg[name] for name in fields} + values["COUNTER"] = _next_counter(throttle_msg) if send_resume: values["Throttle_Pedal"] = 5 - return packer.make_can_msg("Throttle", CanBus.camera, values) def create_brake_pedal(packer, CP, brake_pedal_msg, send_resume): - if CP.flags & SubaruFlags.PREGLOBAL: - values = {s: brake_pedal_msg[s] for s in [ - "Speed", - "Brake_Pedal", - "Signal1", - ]} - else: - values = {s: brake_pedal_msg[s] for s in [ - "CHECKSUM", - "Signal1", - "Speed", - "Signal2", - "Brake_Lights", - "Signal3", - "Brake_Pedal", - "Signal4", - ]} - values["COUNTER"] = create_counter(brake_pedal_msg) - + preglobal = bool(CP.flags & SubaruFlags.PREGLOBAL) + fields = _BRAKE_FIELDS_PREGLOBAL if preglobal else _BRAKE_FIELDS_GLOBAL + values = {name: brake_pedal_msg[name] for name in fields} + if not preglobal: + values["COUNTER"] = _next_counter(brake_pedal_msg) if send_resume: - values["Speed"] = 1 if CP.flags & SubaruFlags.PREGLOBAL else 3 - + values["Speed"] = 1 if preglobal else 3 return packer.make_can_msg("Brake_Pedal", CanBus.camera, values) diff --git a/iqdbc_repo/iqdbc/iqpilot/car/subaru/values_ext.py b/iqdbc_repo/iqdbc/iqpilot/car/subaru/values_ext.py index a58d763..05552bf 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/subaru/values_ext.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/subaru/values_ext.py @@ -1,14 +1,16 @@ """ Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos + +IQ.Pilot Subaru extension flags. Selected in setup_interfaces() from the user's +stop-and-go params and consumed by the stop-and-go controller and panda safety. """ - from enum import IntFlag -class SubaruSafetyFlagsIQ: - STOP_AND_GO = 1 - - class SubaruFlagsIQ(IntFlag): STOP_AND_GO = 1 STOP_AND_GO_MANUAL_PARKING_BRAKE = 2 + + +class SubaruSafetyFlagsIQ: + STOP_AND_GO = 1 diff --git a/iqdbc_repo/iqdbc/safety/tests/test_gm.py b/iqdbc_repo/iqdbc/safety/tests/test_gm.py index 55b265a..705bd3f 100755 --- a/iqdbc_repo/iqdbc/safety/tests/test_gm.py +++ b/iqdbc_repo/iqdbc/safety/tests/test_gm.py @@ -7,7 +7,8 @@ from iqdbc.safety.tests.libsafety import libsafety_py import iqdbc.safety.tests.common as common from iqdbc.safety.tests.common import CANPackerSafety -from iqdbc.iqpilot.car.gm.values_ext import GMSafetyFlagsIQ +# GM_PARAM_IQ_NON_ACC in safety/modes/gm.h (IQ safety framework flag) +GM_PARAM_IQ_NON_ACC = 1 class Buttons: @@ -236,7 +237,7 @@ class TestGmCameraNonACCSafety(TestGmCameraSafety): self.packer = CANPackerSafety("gm_global_a_powertrain_generated") self.packer_chassis = CANPackerSafety("gm_global_a_chassis") self.safety = libsafety_py.libsafety - self.safety.set_current_safety_param_iq(GMSafetyFlagsIQ.NON_ACC) + self.safety.set_current_safety_param_iq(GM_PARAM_IQ_NON_ACC) self.safety.set_safety_hooks(CarParams.SafetyModel.gm, GMSafetyFlags.HW_CAM | self.EXTRA_SAFETY_PARAM) self.safety.init_tests() diff --git a/iqdbc_repo/iqdbc/safety/tests/test_nissan.py b/iqdbc_repo/iqdbc/safety/tests/test_nissan.py index 7685f6c..fe09fa0 100755 --- a/iqdbc_repo/iqdbc/safety/tests/test_nissan.py +++ b/iqdbc_repo/iqdbc/safety/tests/test_nissan.py @@ -2,8 +2,10 @@ import unittest from iqdbc.car.nissan.values import NissanSafetyFlags -from iqdbc.iqpilot.car.nissan.values import NissanSafetyFlagsIQ from iqdbc.car.structs import CarParams + +# NISSAN_PARAM_IQ_LEAF in safety/modes/nissan.h (IQ safety framework flag) +NISSAN_PARAM_IQ_LEAF = 1 from iqdbc.safety.tests.libsafety import libsafety_py import iqdbc.safety.tests.common as common from iqdbc.safety.tests.common import CANPackerSafety @@ -105,7 +107,7 @@ class TestNissanLeafSafety(TestNissanSafety): def setUp(self): self.packer = CANPackerSafety("nissan_leaf_2018_generated") self.safety = libsafety_py.libsafety - self.safety.set_current_safety_param_iq(NissanSafetyFlagsIQ.LEAF) + self.safety.set_current_safety_param_iq(NISSAN_PARAM_IQ_LEAF) self.safety.set_safety_hooks(CarParams.SafetyModel.nissan, 0) self.safety.init_tests() diff --git a/iqpilot/ui/layouts/settings/iq_panels.py b/iqpilot/ui/layouts/settings/iq_panels.py index fc6dfcb..4db8d54 100644 --- a/iqpilot/ui/layouts/settings/iq_panels.py +++ b/iqpilot/ui/layouts/settings/iq_panels.py @@ -872,10 +872,10 @@ class SteeringLayout(Widget): lambda v: f"{int(round(v * (CV.MPH_TO_KPH if ui_state.is_metric else 1)))}" f" {'km/h' if ui_state.is_metric else 'mph'}" ) - self._lagd_toggle = toggle_item(tr("Live Learning Steer Delay"), "", param="IQLiveSteerDelay") + self._steer_delay_toggle = toggle_item(tr("Self-Tuning Steer Delay"), "", param="IQLiveSteerDelay") self._delay_control = option_item( - tr("Adjust Software Delay"), "IQSoftwareSteerDelay", 5, 50, - tr("Adjust the fixed software delay added to steer actuator delay when Live Learning Steer Delay is turned off. The default software delay value is 0.2 s."), + tr("Manual Delay Offset"), "IQSoftwareSteerDelay", 5, 50, + tr("How much lead time to add on top of the car's own steering rack delay while self-tuning is off. Default is 0.2 s."), 1, None, True, "", style.BUTTON_ACTION_WIDTH, None, True, lambda v: f"{float(v):.2f}s" ) @@ -890,7 +890,7 @@ class SteeringLayout(Widget): self._lane_turn_desire_toggle, self._lane_turn_value_control, IQLineSeparator(40), - self._lagd_toggle, + self._steer_delay_toggle, self._delay_control, ] return items @@ -922,19 +922,20 @@ class SteeringLayout(Widget): live_delay = ui_state.params.get_bool("IQLiveSteerDelay") self._lane_turn_desire_toggle.action_item.set_state(turn_desire) self._lane_turn_value_control.set_visible(turn_desire) - self._lagd_toggle.action_item.set_state(live_delay) + self._steer_delay_toggle.action_item.set_state(live_delay) self._delay_control.set_visible(not live_delay) new_step = int(round(100 / CV.MPH_TO_KPH)) if ui_state.is_metric else 100 if self._lane_turn_value_control.action_item.value_change_step != new_step: self._lane_turn_value_control.action_item.value_change_step = new_step - lagd_desc = tr("Enable this for the car to learn and adapt its steering response time. Disable to use a fixed steering response time.") + delay_desc = tr("Let IQ.Pilot measure how long your steering takes to respond and keep that figure up to date. " + "Switch it off to pin the timing yourself.") if live_delay: - lagd_desc += f"
{tr('Live Steer Delay:')} {ui_state.sm['liveDelay'].lateralDelay:.3f} s" + delay_desc += f"
{tr('Measured:')} {ui_state.sm['liveDelay'].lateralDelay:.3f} s" elif ui_state.CP: sw = float(ui_state.params.get("IQSoftwareSteerDelay", "0.2")) cp = ui_state.CP.steerActuatorDelay - lagd_desc += f"
{tr('Actuator Delay:')} {cp:.2f} s + {tr('Software Delay:')} {sw:.2f} s = {tr('Total Delay:')} {cp + sw:.2f} s" - self._lagd_toggle.set_description(lagd_desc) + delay_desc += f"
{tr('Rack:')} {cp:.2f} s + {tr('Offset:')} {sw:.2f} s = {tr('Total:')} {cp + sw:.2f} s" + self._steer_delay_toggle.set_description(delay_desc) def _render(self, rect): if self._current_panel == PanelType.LANE_CHANGE: diff --git a/selfdrive/ui/mici/layouts/settings/models.py b/selfdrive/ui/mici/layouts/settings/models.py index a85a6f7..d6d1aba 100644 --- a/selfdrive/ui/mici/layouts/settings/models.py +++ b/selfdrive/ui/mici/layouts/settings/models.py @@ -121,16 +121,16 @@ class ModelsLayoutMici(NavScroller): self._clear.set_click_callback(self._confirm_clear_cache) self._clear.set_enabled(lambda: ui_state.is_offroad()) - self._lagd = BigParamControl("live learning steer delay", "IQLiveSteerDelay") - self._sw_delay = MappedParamToggle("software delay", "IQSoftwareSteerDelay", _DELAY_OPTIONS, _DELAY_VALUES) - self._sw_delay.set_visible(lambda: not self._lagd._checked) + self._steer_delay = BigParamControl("self-tuning steer delay", "IQLiveSteerDelay") + self._sw_delay = MappedParamToggle("manual delay offset", "IQSoftwareSteerDelay", _DELAY_OPTIONS, _DELAY_VALUES) + self._sw_delay.set_visible(lambda: not self._steer_delay._checked) self._lane_turn = BigParamControl("use lane turn desires", "IQLaneTurnDesire") self._lane_speed = MappedParamToggle("lane turn speed", "IQLaneTurnValue", _LANE_TURN_OPTIONS, _LANE_TURN_VALUES) self._lane_speed.set_visible(lambda: self._lane_turn._checked) self._main_items = [self._current, self._cancel, self._supercombo, self._vision, self._policy, self._redownload, self._refresh, self._clear, - self._lagd, self._sw_delay, self._lane_turn, self._lane_speed] + self._steer_delay, self._sw_delay, self._lane_turn, self._lane_speed] self._scroller.add_widgets(self._main_items) @property @@ -368,7 +368,7 @@ class ModelsLayoutMici(NavScroller): self._last_cache_t = now self._clear.set_value(f"{self._calculate_cache_size():.1f} MB") - self._update_lagd_subtext() + self._update_steer_delay_subtext() def _progress_target_bundle(self): try: @@ -445,21 +445,21 @@ class ModelsLayoutMici(NavScroller): return f"failed: {_display_model_name(bundle)}" return self._active_model_name() - def _update_lagd_subtext(self): - if self._lagd._checked: + def _update_steer_delay_subtext(self): + if self._steer_delay._checked: try: - self._lagd.set_value(f"live {ui_state.sm['liveDelay'].lateralDelay:.3f} s") + self._steer_delay.set_value(f"measured {ui_state.sm['liveDelay'].lateralDelay:.3f} s") except Exception: - self._lagd.set_value("") + self._steer_delay.set_value("") return try: sw = float(ui_state.params.get("IQSoftwareSteerDelay", return_default=True)) except (TypeError, ValueError): sw = 0.2 if ui_state.CP is not None: - self._lagd.set_value(f"total {ui_state.CP.steerActuatorDelay + sw:.2f} s") + self._steer_delay.set_value(f"total {ui_state.CP.steerActuatorDelay + sw:.2f} s") else: - self._lagd.set_value(f"+{sw:.2f} s software") + self._steer_delay.set_value(f"+{sw:.2f} s offset") def _active_model_name(self) -> str: if not self._has_active_bundle_param(): @@ -495,5 +495,5 @@ class ModelsLayoutMici(NavScroller): def show_event(self): super().show_event() - for w in (self._lagd, self._sw_delay, self._lane_turn, self._lane_speed): + for w in (self._steer_delay, self._sw_delay, self._lane_turn, self._lane_speed): w.refresh() diff --git a/system/loggerd/loggerd.h b/system/loggerd/loggerd.h index f4cf803..74cd043 100644 --- a/system/loggerd/loggerd.h +++ b/system/loggerd/loggerd.h @@ -43,7 +43,10 @@ struct EncoderSettings { } static EncoderSettings QcamEncoderSettings() { - int _qcam_bitrate = getenv("QCAM_BITRATE") ? atoi(getenv("QCAM_BITRATE")) : 3'200'000; + // Keep Konn3kt route uploads useful without turning each 60-second qcamera + // segment into a 26 MB file. This is still a substantial improvement over + // stock qcam, while CBR keeps storage and upload usage predictable. + int _qcam_bitrate = getenv("QCAM_BITRATE") ? atoi(getenv("QCAM_BITRATE")) : 2'400'000; return EncoderSettings{.encode_type = cereal::EncodeIndex::Type::QCAMERA_H264, .bitrate = _qcam_bitrate, .gop_size = 15}; } @@ -137,8 +140,8 @@ const EncoderInfo qcam_encoder_info = { .filename = "qcamera.ts", .cbr = true, // enforce the bitrate so upload size stays predictable (no VBR overshoot) .get_settings = [](int){return EncoderSettings::QcamEncoderSettings();}, - .frame_width = 1578, // 3x the stock 526x330, same road-cam aspect ratio - .frame_height = 990, + .frame_width = 1315, // 2.5x the stock 526x330, same road-cam aspect ratio + .frame_height = 825, .include_audio = Params().getBool("RecordAudio"), INIT_ENCODE_FUNCTIONS(QRoadEncode), }; diff --git a/system/manager/helpers.py b/system/manager/helpers.py index 43c0f23..23fb35b 100644 --- a/system/manager/helpers.py +++ b/system/manager/helpers.py @@ -11,7 +11,6 @@ import threading from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params -from openpilot.common.swaglog import cloudlog def unblock_stdout() -> None: # get a non-blocking stdout @@ -103,57 +102,3 @@ def save_bootlog(): t = threading.Thread(target=fn, args=(tmp, )) t.daemon = True t.start() - - -# REVERT ME! --------------------------------------------------------------- -# One-shot migration carrying values across the sunny -> IQ param key renames. -# Old keys are no longer registered in params_keys.h, so their values are read -# straight off disk, copied to the new IQ key, and the stale file removed. -# Delete this block (and its manager_init() call) once fielded devices have -# booted past it at least once. -_RENAMED_PARAMS = { - "QuietMode": "IQAlertSilence", - "SpeedLimitMode": "IQSpeedAssistMode", - "SpeedLimitPolicy": "IQSpeedAssistPolicy", - "SpeedLimitOffsetType": "IQSpeedAssistOffsetType", - "SpeedLimitValueOffset": "IQSpeedAssistValueOffset", - "LaneTurnDesire": "IQLaneTurnDesire", - "LaneTurnValue": "IQLaneTurnValue", - "BlinkerPauseLateralControl": "IQBlinkerPauseLateral", - "BlinkerMinLateralControlSpeed": "IQBlinkerMinLateralSpeed", - "DevUIInfo": "IQDevUIInfo", - "OffroadMode": "IQAlwaysOffroad", - "AutoLaneChangeTimer": "IQLaneChangeTimer", - "AutoLaneChangeBsmDelay": "IQLaneChangeBsmDelay", - "LagdToggle": "IQLiveSteerDelay", - "LagdToggleDelay": "IQSoftwareSteerDelay", - "LagdValueCache": "IQSteerDelayCache", -} - - -def migrate_renamed_params(params: Params | None = None) -> None: - """REVERT ME! carry stored values across the sunny->IQ key renames, then drop the old files. - - Copies at the file level: on-disk param values are raw bytes, so this preserves the exact - stored representation and sidesteps put()'s typed-value check for BOOL/INT/FLOAT keys. - """ - p = params if params is not None else Params() - for old, new in _RENAMED_PARAMS.items(): - try: - old_path = p.get_param_path(old) - if not os.path.isfile(old_path): - continue - new_path = p.get_param_path(new) - if not os.path.exists(new_path): - with open(old_path, "rb") as f: - value = f.read() - tmp = new_path + ".tmp" - with open(tmp, "wb") as f: - f.write(value) - f.flush() - os.fsync(f.fileno()) - os.rename(tmp, new_path) - os.remove(old_path) - except Exception: - cloudlog.exception(f"param rename migration failed for {old} -> {new}") -# END REVERT ME! ------------------------------------------------------------ diff --git a/system/manager/manager.py b/system/manager/manager.py index 57feb99..158fe8b 100755 --- a/system/manager/manager.py +++ b/system/manager/manager.py @@ -17,7 +17,7 @@ from openpilot.common.params import Params, ParamKeyFlag from openpilot.common.text_window import TextWindow from openpilot.system.hardware import HARDWARE from openpilot.system.loggerd.crash_recovery import recover_unclean_segments -from openpilot.system.manager.helpers import unblock_stdout, write_onroad_params, save_bootlog, heal_param_perms, migrate_renamed_params +from openpilot.system.manager.helpers import unblock_stdout, write_onroad_params, save_bootlog, heal_param_perms from openpilot.system.manager.process import ensure_running from openpilot.system.manager.process_config import managed_processes from openpilot.iqpilot.konn3kt.registration import register, UNREGISTERED_DONGLE_ID @@ -40,7 +40,6 @@ def manager_init() -> None: build_metadata = get_build_metadata() params = Params() - migrate_renamed_params(params) # REVERT ME! sunny->IQ param key migration (runs before defaults are filled) params.clear_all(ParamKeyFlag.CLEAR_ON_MANAGER_START) params.clear_all(ParamKeyFlag.CLEAR_ON_ONROAD_TRANSITION) params.clear_all(ParamKeyFlag.CLEAR_ON_OFFROAD_TRANSITION) diff --git a/system/ui/lib/wifi_manager.py b/system/ui/lib/wifi_manager.py index 0993f04..4fe310a 100644 --- a/system/ui/lib/wifi_manager.py +++ b/system/ui/lib/wifi_manager.py @@ -67,6 +67,9 @@ class MeteredType(IntEnum): NO = 2 +_WARNED_UNSUPPORTED_NETWORKS: set[tuple[int, int, int]] = set() + + def get_security_type(flags: int, wpa_flags: int, rsn_flags: int) -> SecurityType: wpa_props = wpa_flags | rsn_flags @@ -83,7 +86,10 @@ def get_security_type(flags: int, wpa_flags: int, rsn_flags: int) -> SecurityTyp # WPA2, WPA2+WPA3 mixed, or WPA — all handled via WPA key_mgmt (NM negotiates SAE if available) return SecurityType.WPA2 else: - cloudlog.warning(f"Unsupported network! flags: {flags}, wpa_flags: {wpa_flags}, rsn_flags: {rsn_flags}") + _key = (flags, wpa_flags, rsn_flags) + if _key not in _WARNED_UNSUPPORTED_NETWORKS: + _WARNED_UNSUPPORTED_NETWORKS.add(_key) + cloudlog.warning(f"Unsupported network! flags: {flags}, wpa_flags: {wpa_flags}, rsn_flags: {rsn_flags}") return SecurityType.UNSUPPORTED