diff --git a/README.md b/README.md index 4901a38..6380bdc 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,11 @@ * A modern comma, or clone device to run this software (Comma 3, 3x, 4, Konik A1/M, Mr.One C3, C3 Lite) * One of [the supported cars](https://gitlvb.teallvbs.xyz/IQ.Lvbs/IQ.Pilot/src/branch/release/iqdbc_repo/docs/CARS.md). * A [car harness](https://comma.ai/shop/products/car-harness) to connect to your car -#### Side Note: Volkswagen Group, and Tesla vehicles are currently the most compatible for use with IQ.Pilot, other manufacturers are supported at a minimum to the same level as stock openpilot, but are not a top priority while we are in beta. +#### Wondering if IQ.Pilot supports your car? IQ.Pilot supports every car [stock openpilot](https://gitlvb.teallvbs.xyz/IQ.Lvbs/IQ.Pilot/src/branch/release/iqdbc_repo/docs/CARS.md) supports! ## Installation #### Installing Via Installer URL: #### Enter the following into your device custom URL box to install IQ.Pilot: -`iqinc/release` +`installer.iqlvbs.com/release` #### Having Trouble? If your device is currently running AGNOS 13.1 or older, you should install latest stock openpilot, then install IQ.Pilot, or try one of the alternative methods listed below! @@ -27,11 +27,11 @@ #### Installing Via SSH: #### Once you are connected to your device via SSH, you can paste the following command below to install IQ.Pilot: -`cd .. && rm -rf openpilot && git clone https://github.com/iqinc/openpilot.git -b release && cd openpilot && sudo reboot` +`cd .. && rm -rf openpilot && git clone https://git.konn3kt.com/IQ.Lvbs/IQ.Pilot openpilot -b release && cd openpilot && sudo reboot` #### If you'd like to backup your previous installation as well, paste the following command below to install IQ.Pilot: -`cd .. && mv openpilot openpilot_backup_X && git clone https://github.com/iqinc/openpilot.git -b release && cd openpilot && sudo reboot` -#### Alternatively, you can use your existing fork's built in tools to switch your branch as well: -`git remote add iqpilot https://github.com/iqinc/openpilot.git && op switch iqpilot release` +`cd .. && mv openpilot openpilot_backup_X && git clone https://git.konn3kt.com/IQ.Lvbs/IQ.Pilot -b release && cd openpilot && sudo reboot` +#### Alternatively, you can use your existing fork's built in tools to switch your branch as well: +`git remote add iqpilot https://git.konn3kt.com/IQ.Lvbs/IQ.Pilot && op switch iqpilot release` --- diff --git a/artifacts/iqpilot_hephaestusd_private/manifest.json b/artifacts/iqpilot_hephaestusd_private/manifest.json index 51dccf0..92601e1 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": "70cbd719ded42c8fd7c841864ab88c334a2155be4a57c36df240233022a5e8d1", + "sha256": "2e02a71cab9b9609ba13dc1ec0d8e804802411f1796036d2316829fdf3781804", "size": 135536 }, "python/iqpilot_private/konn3kt/backups/backup_keys.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "b6a02ca7f2adb8788c960e931b97f9b9f40164944ad9d2a7824689beaabc53b9", + "sha256": "38d13fa715f5d04b8f4b3bb00dd1179bd0acfba6bccb8ed0ef188744be6ee48a", "size": 67664 }, "python/iqpilot_private/konn3kt/backups/backup_orchestrator.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "95187b8c5f81707a7fabbd9d1d8e281405ff382260ed43bef510c0089af95d13", + "sha256": "aeb2de2e8ec70238b4a5958d191eb9c674bcbdba68d5224f00339e0f6398834f", "size": 204624 }, "python/iqpilot_private/konn3kt/backups/cbc_vault.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "cd215251153edb32ff7a2d417ccc3e2921f3e669e98fa508cecb169b21e0bf4a", + "sha256": "28f5cb9010ef726b44cb3c386bdb892c1b6ad245dca5a14a530dfcb2f8975cb1", "size": 69752 }, "python/iqpilot_private/konn3kt/backups/imahelper.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "49736fa1e12f39114a40814f142750312ac5544416bbccc6014f1337c19dc606", + "sha256": "0f8d80604c2c124c59f7fbc62797d7ec19ab6f3ea7a239382ffa84a7ef67895f", "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": "8c1a71f4be436f09054bda32748c4eb094bf0e26832147d7e28ca19ce91e805f", + "sha256": "37c257acb58ab4eceb7908cd0694aeb228e5434a4110300fa8c9f38adb9bce8f", "size": 2100238 }, "python/iqpilot_private/konn3kt/hephaestus/ble_auth.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "0109732b5e45e846531048a649e4cd188d394aa5e64df3b36b6f4f26542dc155", + "sha256": "1e84c409cbbc2cb10d4ee120ef7a29e642add973d7fb1c788e90cf0e2c64bede", "size": 268064 }, "python/iqpilot_private/konn3kt/hephaestus/ble_gatt.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "237166f1c645447f1467f7081bc71dedb7d090076ad135f83dc189cd3a904802", + "sha256": "d3706d25e240417da3e9e6736afd4c237bff9885f1af58dc7f58232639acab21", "size": 340584 }, "python/iqpilot_private/konn3kt/hephaestus/ble_rpc_dispatch.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "4f493569b38e1e50e2fa6d752a30d495cb3fdf572daa94452e72db067674bc0f", + "sha256": "9dcc0237069538c4848291b42c15f53c6c574b0be15b943caec86ae419f15b1d", "size": 68048 }, "python/iqpilot_private/konn3kt/hephaestus/ble_transportd.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "bf42ea50717c7bac73bec9fd48874f43d963459f1a91cf9c92596018fbe4cd62", + "sha256": "65104577577030a91052822478be8e2ebfade9c148d01fe6dc1bb90aca269668", "size": 335728 }, "python/iqpilot_private/konn3kt/hephaestus/bt_gamepad.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "11cc3a7a1c21f40a0b6719ec1b97776ab786a5c75f31b43af173bc4452697ca7", + "sha256": "5b8c42a4b552225da64a2ee7415c4128f7b01c1949d37ada07d2f763ba35116e", "size": 271680 }, "python/iqpilot_private/konn3kt/hephaestus/cloud_routes.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "5098e97f036dffb92eca2fce847fcbe9bc13f9277a2ae39b42300cfe56e133df", + "sha256": "d561920e30cbc493c3b6e43778f6149285d9131103dfc1b41c965aa3ecb6f5af", "size": 134408 }, "python/iqpilot_private/konn3kt/hephaestus/hephaestusd.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "17605aaedb7b4324a4c2ea64c15c6a6f305f8d455060c7a280e2db228307a9e7", - "size": 3513840 + "sha256": "e7cbdb07e7fbf760313d430a1aa635ff20566fe4c974690b1e3c37dbbf83ceb3", + "size": 3514416 }, "python/iqpilot_private/konn3kt/hephaestus/kwp2000.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "45022394525e297bff8af3f17710bfe31f63c3526985211e4eb8924490f54600", + "sha256": "deca6bd519f1e9ffa21654eec9efd078ffeb0164b5a7920418da03015daef58b", "size": 136448 }, "python/iqpilot_private/konn3kt/hephaestus/manage_hephaestusd.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "f35fe3724a5a8f823b2ad42efc3a7bbeeba6d7f7fd61eda76596a296df51ca5a", + "sha256": "b6fa57cdd14e5be2afe62f7670a33bd857240aa326e0861783ac5c04fc279eea", "size": 68136 }, "python/iqpilot_private/konn3kt/hephaestus/motd.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "af53a0e6fef1bbb63cbdae857aeb7b2b4c93cfc290b3e27211a5df60af462a9d", + "sha256": "edc1708324a5822298dbf3d65436e5887c8b72da4ef6fab98dd237dccad6a94b", "size": 67840 }, "python/iqpilot_private/konn3kt/hephaestus/tp20.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "83f5129c7a2337e63ac79e4fd4cd430e96f9570bca6b5e6e3bc5224815030913", + "sha256": "57a1f5528041a28ccc77bb491b39af7e3013aece38aa8d1fbe19fa529cecc7b2", "size": 135648 }, "python/iqpilot_private/konn3kt/hephaestus/vw_pq_flasher.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "afb1b9cd772fe31c6845af195f6c62ef89aeef028cebc9ea7e25187ac108f90f", + "sha256": "3ea49eb20d190b9fd858c6c5bf102d474ddefb8b9e98e6e80fc7968c738b5bc2", "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": "4c4589a6419e9501ec5a86385a6991a54a72b290e9de855e5aa303c2fac59cb0", + "sha256": "07579fac8cc95845e8bd2125b898f8d28a6f65c73556671b56f5cdffece7ac09", "size": 204184 }, "runtime": { @@ -148,23 +148,23 @@ } }, "signatures": { - "python/iqpilot_private/konn3kt/backups/archive_codec.cpython-312-aarch64-linux-gnu.so": "fHETfdkKuvKTn8rv9E8G6c7xzCNGE2z4BV9YqbGN4Al5F+knIeiSh2EzKkjr8TVLMHmF1BpbYqO/Hk0Le9eqBw==", - "python/iqpilot_private/konn3kt/backups/backup_keys.cpython-312-aarch64-linux-gnu.so": "oXxKlxWYX8r6eFPfFWTUgUgykuIv4Fbn4LGdLzRQcO8gBNm6ZvF1+z5vlZ3A1eX/vdutp3nilP6PVz83kE+XDg==", - "python/iqpilot_private/konn3kt/backups/backup_orchestrator.cpython-312-aarch64-linux-gnu.so": "A2qyZYHlLEheJ7MKAWJ/t435DBRud3DDWXZZIAnS0KQthX2hSjxeYPPToQAaBOVso2yGj+02Jr6d5XjAjfGlDQ==", - "python/iqpilot_private/konn3kt/backups/cbc_vault.cpython-312-aarch64-linux-gnu.so": "yq0n30lKaAYI3uwYthCUY5w+DU52v80vQQdzdJ3HU/H4Yx//us+qoulgO4y5Lh6wIkcGyVxZM8qALf6tv/uICw==", - "python/iqpilot_private/konn3kt/backups/imahelper.cpython-312-aarch64-linux-gnu.so": "dc9Uj1Mtzs/JqAhXrRypKVXcOeDz+LhQkoC9i480cm9xTD4CwHi0uMb0R0ug3Zy/a/T6kEb1dfeLaRu8bifsAQ==", - "python/iqpilot_private/konn3kt/hephaestus/ble_auth.cpython-312-aarch64-linux-gnu.so": "f8rBsEG6oV0FWBwF1UN/wNZstXb+I1RHgznD+IuFXdsSKD1ucPSIfu+BYzxDi9/DpPfxRXVoHS4cOgN1CadmBw==", - "python/iqpilot_private/konn3kt/hephaestus/ble_gatt.cpython-312-aarch64-linux-gnu.so": "YFxsXCJUOlnws+cDf5MO8mkKSiOo27xUqo29lwZBP8y2+BPiiknCShaI4hC+ejzWd4+59smPaKUuUsXcdmPABQ==", - "python/iqpilot_private/konn3kt/hephaestus/ble_rpc_dispatch.cpython-312-aarch64-linux-gnu.so": "aC/O3UeBljXJ6QGSvJBULyPhSUmMOp6Y7pGtfXA1Nf5tw8qEAb/7kjiU6my5+f9w48fNAe1voSF1mO5eLCsLCg==", - "python/iqpilot_private/konn3kt/hephaestus/ble_transportd.cpython-312-aarch64-linux-gnu.so": "lubN92tDcIPYnpq7LLPsgqxq5qj715kBljkie2yURge7SGluI6bWyO616OIVHjdG0Wvq58/EsmvH2qKH6EbKAg==", - "python/iqpilot_private/konn3kt/hephaestus/bt_gamepad.cpython-312-aarch64-linux-gnu.so": "51hAcDuyXxQcnPQUQV58KcRnIggvBJSVyRA/EzO22WgX1kLXCkhGsYbJ9lMHZH3IVUXzOpP16qEoxcdykyK/Bw==", - "python/iqpilot_private/konn3kt/hephaestus/cloud_routes.cpython-312-aarch64-linux-gnu.so": "ExuQziX7rIwMiZGQjFTnr7Rw+LA4iluxeRPZ7zxnvdKo6qagECqmv5VdqxsevAYmH6KiwYDBH/Bjn4G4sLnQDg==", - "python/iqpilot_private/konn3kt/hephaestus/hephaestusd.cpython-312-aarch64-linux-gnu.so": "T1QHRSyUFUhXl0Mw0CSrG3oIbcCuInWNdX1mMuYHKNf3O+iaAVDB7fgYB6jl9C3jzeiD2LH6jgpgvWEUqF9WAA==", - "python/iqpilot_private/konn3kt/hephaestus/kwp2000.cpython-312-aarch64-linux-gnu.so": "YlDNaD3dT6JuYRT7P3UEnha+/W13//OtYrkoGa8KwpDFhZy7FAyQkZiENHjIQi+K3K+I7qd2phlwrWcPXvaWAg==", - "python/iqpilot_private/konn3kt/hephaestus/manage_hephaestusd.cpython-312-aarch64-linux-gnu.so": "PxuLDE5We4EsluPRWPZBt2E9nBJTsEX0You50iDdWgjQp8+gJT5ZWfX3wG8cHF8JzOL4xZdg11SjdXpOKsoODg==", - "python/iqpilot_private/konn3kt/hephaestus/motd.cpython-312-aarch64-linux-gnu.so": "Lsz5pL5pkh5n3aqJ+SQi4vixS2CTIG1Nou3+z8/OgnPq/8nF47NWuOgL2pT2ogeElgOqSHZgEVO4v4V/FQKHBg==", - "python/iqpilot_private/konn3kt/hephaestus/tp20.cpython-312-aarch64-linux-gnu.so": "hbCMagRzeN+JMb4Z/ZkiYo8WvA8ptT8r0NzwBlLRfY1LqkC1ZePGROG3Fq5RC9ylb1UotOmBcIVcOfiG3zDMCw==", - "python/iqpilot_private/konn3kt/hephaestus/vw_pq_flasher.cpython-312-aarch64-linux-gnu.so": "zxtsmguucERIWEZXJiNU16fWzGDcbOWgsDa4oB90G1kAP73CTY9cMjchHsIkNZ+bkQNBFNSMmBsTavo6NeOTCQ==", - "python/iqpilot_private/konn3kt/uploaderd/iquploaderd.cpython-312-aarch64-linux-gnu.so": "mInwiS+voFDcEVMHBmHY4W69OQ+Vhl0N6cdmsetpX2YMS8zKfkDJIWvP7AwwX2ZFGkKJ/V8Wc2NTObJAIUqDBA==" + "python/iqpilot_private/konn3kt/backups/archive_codec.cpython-312-aarch64-linux-gnu.so": "kMbERPxDWFOY9nlRI3TUHRCWmz9HUw+Y+LNT7YoA0m+kovLcUK7+9JKlggNrvEMnxZwxeJQgo1vApe42zEeaDA==", + "python/iqpilot_private/konn3kt/backups/backup_keys.cpython-312-aarch64-linux-gnu.so": "AsrsCTOTeh3yiMJfFc/soDYkWnRUyJ/xwhpIqYfK+RpPe9dNlNWcS7DOMotFNOhqd4FmaLqLK4IkRRzNYPpnCQ==", + "python/iqpilot_private/konn3kt/backups/backup_orchestrator.cpython-312-aarch64-linux-gnu.so": "L6J8e3PaiczBVYPncWdp0w2odCp9kJCZqEPYJkQb4vevXzTc9/5Z8CghPRhRJBdTkqIGhMUtz4ow4278PVhOBw==", + "python/iqpilot_private/konn3kt/backups/cbc_vault.cpython-312-aarch64-linux-gnu.so": "/3LrOQ6xtNfEb9UO5aBIGXKc4CIcn5MFTvDX6yziN0/fpk5UoZcyimG8Fs3lJn3/XFKxEN9iXQCb2IHrE9PyAQ==", + "python/iqpilot_private/konn3kt/backups/imahelper.cpython-312-aarch64-linux-gnu.so": "pjbxXEMGie5nE9RkTi0HZXCSODxluy/NtKNYE2BbFCh45TQHGLnb514BFiUSRzfX8HvlHOVFdyq50NUpQDghBw==", + "python/iqpilot_private/konn3kt/hephaestus/ble_auth.cpython-312-aarch64-linux-gnu.so": "eIgj34UctUOUNppp1SzsYQThvVXLSwco8K5Nj877cawc1G557rqjKtNANful4fRqzFQY25GBLj0kD09Uh1LRAg==", + "python/iqpilot_private/konn3kt/hephaestus/ble_gatt.cpython-312-aarch64-linux-gnu.so": "u2Vl/KgwccBFEZiI60gFG7yfHMpU3GZTrqVEOrc7ak28pvPGY4i5SxMxN0n5j88F+2M3DiVa2PXH0WquaipTCA==", + "python/iqpilot_private/konn3kt/hephaestus/ble_rpc_dispatch.cpython-312-aarch64-linux-gnu.so": "tBfufS3snKVFtpPxgbyMOLQGvqU+m0urlD/FAUe7q2ID0VDWLY7yb1/LIkdwdaMFq9jvhXfZN7VXp8Fg7XbJCw==", + "python/iqpilot_private/konn3kt/hephaestus/ble_transportd.cpython-312-aarch64-linux-gnu.so": "mVG3Ji6AjMyUMbvljZQziNfVi4sdGZer0Z1+V2imca5u+VNAqYeejxuH3qO0jvnJNCMEWy2G4LGmw/+Opl/XBA==", + "python/iqpilot_private/konn3kt/hephaestus/bt_gamepad.cpython-312-aarch64-linux-gnu.so": "E+LW1FntRDSVaQ9OLC927TnsrL7h17yuPg21yAigJKZuPGZdzgNRjBtw/tCeJ31VvaKnx24/oHiGXVBzhMxfCw==", + "python/iqpilot_private/konn3kt/hephaestus/cloud_routes.cpython-312-aarch64-linux-gnu.so": "r1LJu5eBd9HyVlc6ARvuwmstrr9EoOPYMC5Zo4uUX7/9wf1fIx8zeSY/lZVjZ+Xv9+4Jr5FcAUKn+0nO0KPrCA==", + "python/iqpilot_private/konn3kt/hephaestus/hephaestusd.cpython-312-aarch64-linux-gnu.so": "qL0x7nD5tDgZUBLdjzZxOwdaYNWUjE6HiQN9ZSt10KvrS1Yke+vKl+1YhdT0jC8WEbMRBttKAqW8ZDs5iWY6AA==", + "python/iqpilot_private/konn3kt/hephaestus/kwp2000.cpython-312-aarch64-linux-gnu.so": "OhcVaRn2lq3moVXMWL5oEudhVyka9hDjxEJ6WRuMfKf7o1TlbxVJZny8FqABCOCATD+/HmdjAuIMU31QIZOZCQ==", + "python/iqpilot_private/konn3kt/hephaestus/manage_hephaestusd.cpython-312-aarch64-linux-gnu.so": "8GcOxABlpN/fH0EMLA7JAWsnwH6/jaxqQ+BOLo8VZXfi7mXw08RcuP6aQyEJGRd2PMil4JNdesjywNB6fFFxDA==", + "python/iqpilot_private/konn3kt/hephaestus/motd.cpython-312-aarch64-linux-gnu.so": "uno8NAMvkEV0e9FxoyHNtQGjd3rIjcNboTcCrKdIHpoSN20VQBWz//jD7ksFkS/gKfnFDHqVZF/gPDoU11H6DA==", + "python/iqpilot_private/konn3kt/hephaestus/tp20.cpython-312-aarch64-linux-gnu.so": "1dOOCOC63YO+dP/b52CftTU4ZgnBeZd3J8Op3lrVVi4rVdoBtqtV0TlzPNDU1dOxIJM3NwUKYdJNucKNSRJaAg==", + "python/iqpilot_private/konn3kt/hephaestus/vw_pq_flasher.cpython-312-aarch64-linux-gnu.so": "De+rhzupAdghqffQpAPIBwIK2IuMMGTNzrTpLdDzv0DcNpBeL+NYaFBFTa1Q4Pvdt0jLkg+tAT+HO0QO4gDQCg==", + "python/iqpilot_private/konn3kt/uploaderd/iquploaderd.cpython-312-aarch64-linux-gnu.so": "WpnAv/vfP2yAg1IbyK9b9TD4VDMLDlPPkMHVOunJYi7Ua56+8hSgW6yJmYW6XuMUjoUjLiAbjYwt1GqJABj+Ag==" } } 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 2d46a09..2cee5b8 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 5975b7d..db6c005 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 58dd980..4030cb7 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 acc32ba..4f67428 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 3ad8f6a..be96d2a 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 36be043..8b4b8fe 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 4f71e7a..4659eae 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 728e283..53f37e3 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 6dbb83d..4dd20f1 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 f77b531..d03f0be 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 5ff1767..5675433 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 74339bb..20f19d3 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 ebea228..da97485 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 58ee26c..c605021 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 142b519..af418c8 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 72dab1a..ed2e44a 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 115223b..1613bb0 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 23d81b9..d9b9434 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 b2e8532..03e5ca3 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/common/filter_simple.py b/common/filter_simple.py index 212e1a8..30839f6 100644 --- a/common/filter_simple.py +++ b/common/filter_simple.py @@ -1,3 +1,8 @@ +from collections import deque + +import numpy as np + + class FirstOrderFilter: def __init__(self, x0, rc, dt, initialized=True): self.x = x0 @@ -32,3 +37,35 @@ class BounceFilter(FirstOrderFilter): self.velocity.x = 0.0 self.x += self.velocity.x return self.x + + +class MyMovingAverage: + def __init__(self, window_size, value=None): + self.window_size = window_size + if value is not None: + self.values = deque([value] * window_size, maxlen=window_size) + self.sum = value * window_size + self.result = value + else: + self.values = deque(maxlen=window_size) + self.sum = 0 + self.result = 0 + + def set(self, value): + self.values.clear() + self.values.append(value) + self.sum = value + self.result = value + return value + + def set_all(self, value): + self.values = deque([value] * self.window_size, maxlen=self.window_size) + self.sum = value * self.window_size + self.result = value + return value + + def process(self, value, median=False): + self.values.append(value) + self.sum = sum(self.values) + self.result = float(np.median(self.values)) if median else float(self.sum) / len(self.values) + return self.result diff --git a/common/params.h b/common/params.h index 8169063..cc362f0 100644 --- a/common/params.h +++ b/common/params.h @@ -63,6 +63,14 @@ public: inline bool getBool(const std::string &key, bool block = false) { return get(key, block) == "1"; } + inline int getInt(const std::string &key, bool block = false) { + std::string value = get(key, block); + return value.empty() ? 0 : std::stoi(value); + } + inline float getFloat(const std::string &key, bool block = false) { + std::string value = get(key, block); + return value.empty() ? 0.0F : std::stof(value); + } std::map readAll(); // helpers for writing values @@ -73,10 +81,24 @@ public: inline int putBool(const std::string &key, bool val) { return put(key.c_str(), val ? "1" : "0", 1); } + inline int putInt(const std::string &key, int val) { + const std::string value = std::to_string(val); + return put(key.c_str(), value.c_str(), value.size()); + } + inline int putFloat(const std::string &key, float val) { + const std::string value = std::to_string(val); + return put(key.c_str(), value.c_str(), value.size()); + } void putNonBlocking(const std::string &key, const std::string &val); inline void putBoolNonBlocking(const std::string &key, bool val) { putNonBlocking(key, val ? "1" : "0"); } + inline void putIntNonBlocking(const std::string &key, int val) { + putNonBlocking(key, std::to_string(val)); + } + inline void putFloatNonBlocking(const std::string &key, float val) { + putNonBlocking(key, std::to_string(val)); + } private: void asyncWriteThread(); diff --git a/common/params.py b/common/params.py index 2b7165a..2315220 100644 --- a/common/params.py +++ b/common/params.py @@ -64,6 +64,14 @@ except ImportError: except (FileNotFoundError, NotADirectoryError, IsADirectoryError): return False + def get_int(self, key, block: bool = False) -> int: + value = self.get(key, block=block) + return int(value) if value else 0 + + def get_float(self, key, block: bool = False) -> float: + value = self.get(key, block=block) + return float(value) if value else 0.0 + def put(self, key, dat): if isinstance(dat, str): dat = dat.encode("utf-8") @@ -80,12 +88,24 @@ except ImportError: def put_bool(self, key, val: bool): self.put(key, b"1" if val else b"0") + def put_int(self, key, val: int): + self.put(key, str(val)) + + def put_float(self, key, val: float): + self.put(key, str(val)) + def put_nonblocking(self, key, dat): self.put(key, dat) def put_bool_nonblocking(self, key, val: bool): self.put_bool(key, val) + def put_int_nonblocking(self, key, val: int): + self.put_int(key, val) + + def put_float_nonblocking(self, key, val: float): + self.put_float(key, val) + def remove(self, key): try: os.remove(self._p(key)) diff --git a/common/params_pyx.pyx b/common/params_pyx.pyx index 636ad44..ea761a1 100644 --- a/common/params_pyx.pyx +++ b/common/params_pyx.pyx @@ -33,11 +33,17 @@ cdef extern from "common/params.h": c_Params(string) except + nogil string get(string, bool) nogil bool getBool(string, bool) nogil + int getInt(string, bool) nogil + float getFloat(string, bool) nogil int remove(string) nogil int put(string, string) nogil void putNonBlocking(string, string) nogil void putBoolNonBlocking(string, bool) nogil int putBool(string, bool) nogil + int putInt(string, int) nogil + int putFloat(string, float) nogil + void putIntNonBlocking(string, int) nogil + void putFloatNonBlocking(string, float) nogil bool checkKey(string) nogil ParamKeyType getKeyType(string) nogil optional[string] getKeyDefaultValue(string) nogil @@ -136,6 +142,20 @@ cdef class Params: r = self.p.getBool(k, block) return r + def get_int(self, key, bool block=False): + cdef string k = self.check_key(key) + cdef int r + with nogil: + r = self.p.getInt(k, block) + return r + + def get_float(self, key, bool block=False): + cdef string k = self.check_key(key) + cdef float r + with nogil: + r = self.p.getFloat(k, block) + return r + def _put_cast(self, key, dat): cdef string k = self.check_key(key) cdef ParamKeyType t = self.p.getKeyType(k) @@ -158,6 +178,16 @@ cdef class Params: with nogil: self.p.putBool(k, val) + def put_int(self, key, int val): + cdef string k = self.check_key(key) + with nogil: + self.p.putInt(k, val) + + def put_float(self, key, float val): + cdef string k = self.check_key(key) + with nogil: + self.p.putFloat(k, val) + def put_nonblocking(self, key, dat): cdef string k = self.check_key(key) cdef string dat_bytes = self._put_cast(key, dat) @@ -169,6 +199,16 @@ cdef class Params: with nogil: self.p.putBoolNonBlocking(k, val) + def put_int_nonblocking(self, key, int val): + cdef string k = self.check_key(key) + with nogil: + self.p.putIntNonBlocking(k, val) + + def put_float_nonblocking(self, key, float val): + cdef string k = self.check_key(key) + with nogil: + self.p.putFloatNonBlocking(k, val) + def remove(self, key): cdef string k = self.check_key(key) with nogil: diff --git a/iqdbc_repo/credits/CREDITS.MD b/iqdbc_repo/credits/CREDITS.MD index e34e88f..c2909f6 100644 --- a/iqdbc_repo/credits/CREDITS.MD +++ b/iqdbc_repo/credits/CREDITS.MD @@ -6,63 +6,18 @@ It does not replace the repository-wide license files for IQ.Pilot itself or any ## Credits: -### Hyundai / Kia / Genesis (HKG) - Sunnypilot - -#### Contributors - -Full credit for the Hyundai / Kia / Genesis port, along with the HKG-specific tuning work used in this tree, belongs to: - -- Jason Wen -- James Vecellio-Grant -- sunnypilot - -#### Attribution - -This repository carries HKG-side tuning and port lineage that originated from, and/or is verbatim their work. They are the authors of the Sunnypilot-side HKG port and its tuning, and are accredited as such, IQ.Lvbs claims no copyright, credit, or authorship of the components listed below. - -#### Upstream License Notice - -The HKG work attributed above is acknowledged here under LICENSE notice: - -```text -MIT License - -Copyright (c) 2024 Jason Wen, James Vecellio-Grant, Sunnypilot, and a number of other contributors. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -``` - -#### Scope - -This licensing is limited to `iqdbc_repo/iqdbc/car/hyundai` and `iqdbc_repo/iqdbc/iqpilot/car/hyundai`. - ### Hyundai / Kia / Genesis (HKG) - carrotpilot #### Contributors -Full credit for the carrotpilot-side HKG tuning lineage carried in this tree belongs to: +Full credit for the Hyundai / Kia / Genesis port and its HKG-specific tuning belongs to: -- carrotpilot devs (ajoutam) +- carrotpilot +- ajouatom #### Attribution -This repository carries HKG-side tuning and port lineage that originated from, and/or is verbatim their work. They are the authors of the carrotpilot-side HKG tuning credited here, and are accredited as such, IQ.Lvbs claims no copyright, credit, or authorship of the components listed below. +This repository carries the carrotpilot HKG implementation from `ajouatom/openpilot`, imported from commit `b54d44efd514bc61f86f08b01c23a6c190885c07`. IQ.Lvbs claims no copyright, credit, or authorship over that implementation. #### Upstream License Notice @@ -80,7 +35,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #### Scope -This licensing is limited to `iqdbc_repo/iqdbc/car/hyundai` and `iqdbc_repo/iqdbc/iqpilot/car/hyundai`. +This licensing is limited to the Hyundai/Kia/Genesis car, DBC, and safety implementations and the supporting schema and compatibility changes required by that port. ### Honda diff --git a/iqdbc_repo/iqdbc/can/parser.py b/iqdbc_repo/iqdbc/can/parser.py index 929c8d6..ab21ce8 100644 --- a/iqdbc_repo/iqdbc/can/parser.py +++ b/iqdbc_repo/iqdbc/can/parser.py @@ -1,5 +1,6 @@ import math import numbers +import time from collections import defaultdict, deque from dataclasses import dataclass, field @@ -154,7 +155,7 @@ class CANParser: self.last_nonempty_nanos: int = 0 self._last_update_nanos: int = 0 - def _add_message(self, name_or_addr: str | int, freq: int | None = None) -> None: + def _add_message(self, name_or_addr: str | int, freq: int | None = None, ignore_counter: bool = False) -> None: if isinstance(name_or_addr, numbers.Number): msg = self.dbc.addr_to_msg.get(int(name_or_addr)) else: @@ -171,16 +172,15 @@ class CANParser: self.vl_all[msg.name] = self.vl_all[msg.address] self.ts_nanos[msg.address] = {s: 0 for s in signal_names} self.ts_nanos[msg.name] = self.ts_nanos[msg.address] - self.dat[msg.address] = b"" - self.dat[msg.name] = b"" - state = MessageState( address=msg.address, name=msg.name, size=msg.size, signals=list(msg.sigs.values()), ignore_alive=freq is not None and math.isnan(freq), + ignore_counter=ignore_counter, ) + state.first_seen_nanos = time.monotonic_ns() if freq is not None and freq > 0: state.frequency = freq else: diff --git a/iqdbc_repo/iqdbc/car/car.capnp b/iqdbc_repo/iqdbc/car/car.capnp index c427998..8bc3d70 100644 --- a/iqdbc_repo/iqdbc/car/car.capnp +++ b/iqdbc_repo/iqdbc/car/car.capnp @@ -238,6 +238,42 @@ struct CarState { fuelTankLevelL @63 :Float32; # raw fuel tank level in liters (konn3kt: VW PQ Kombi_1.Tankinhalt) batteryDetails @65 :BatteryDetails; + # carrotpilot HKG extension state + vCluRatio @68 :Float32; + logCarrot @69 :Text; + softHoldActive @70 :Int16; + activateCruise @71 :Int16; + latEnabled @72 :Bool; + pcmCruiseGap @73 :Int16; + speedLimit @74 :Float32; + speedLimitDistance @75 :Float32; + gearStep @76 :Int16; + tpms @77 :Tpms; + useLaneLineSpeed @78 :Float32; + leftLatDist @79 :Float32; + rightLatDist @80 :Float32; + leftLongDist @81 :Float32; + rightLongDist @82 :Float32; + carrotCruise @83 :Int16; + leftLaneLine @84 :Int16; + rightLaneLine @85 :Int16; + datetime @86 :UInt64; + leftRearLongDist @87 :Float32; + rightRearLongDist @88 :Float32; + leftRearLatDist @89 :Float32; + rightRearLatDist @90 :Float32; + trailerConnected @91 :Bool; + ureaGauge @92 :Float32; + evModeActive @93 :Bool; + evModeValid @94 :Bool; + + struct Tpms { + fl @0 :Float32; + fr @1 :Float32; + rl @2 :Float32; + rr @3 :Float32; + } + struct BatteryDetails { capacity @0 :Float32; charge @1 :Float32; @@ -302,13 +338,16 @@ struct CarState { setCruise @9; resumeCruise @10; gapAdjustCruise @11; + lfaButton @12; + paddleLeft @13; + paddleRight @14; } } # deprecated errorsDEPRECATED @0 :List(OnroadEventDEPRECATED.EventName); - gasDEPRECATED @3 :Float32; # this is user pedal only - brakeLightsDEPRECATED @19 :Bool; + gas @3 :Float32; # this is user pedal only + brakeLights @19 :Bool; steeringRateLimitedDEPRECATED @29 :Bool; canMonoTimesDEPRECATED @12: List(UInt64); canRcvTimeoutDEPRECATED @49 :Bool; @@ -346,6 +385,18 @@ struct RadarData @0x888ad6581cf0aacb { # some radars flag measurements VS estimates measured @6 :Bool; + + vLead @7 :Float32; # m/s + aLead @8 :Float32; # m/s^2 + jLead @9 :Float32; # m/s^3 + radarSource @10 :RadarSource; + + enum RadarSource { + frontRadar @0; + scc @1; + corner235 @2; + corner180 @3; + } } enum ErrorDEPRECATED { @@ -401,6 +452,8 @@ struct CarControl { brake @1: Float32; # [0.0, 1.0] torqueOutputCan @8: Float32; # value sent over can to the car speed @6: Float32; # m/s + jerk @9: Float32; # m/s^3 + aTarget @10: Float32; # m/s^2 enum LongControlState @0xe40f3a917d908282{ off @0; @@ -436,6 +489,12 @@ struct CarControl { leadFollowTime @11: Float32; leadDistance @12: Float32; driverUnresponsive @13: Bool; + activeCarrot @14: Int16; + leadRelSpeed @15: Float32; + leadDPath @16: Float32; + leadRadar @17: Int16; + modelDesire @18: Int16; + atcDistance @19: Float32; # not used with the dash, TODO: separate structs for dash UI and device UI audibleAlert @5: AudibleAlert; @@ -499,6 +558,7 @@ struct CarParams { enableBsm @56 :Bool; # blind spot monitoring flags @64 :UInt32; # flags for car specific quirks alphaLongitudinalAvailable @71 :Bool; + extFlags @79 :UInt32; # carrotpilot HKG extension flags minEnableSpeed @7 :Float32; minSteerSpeed @8 :Float32; @@ -595,7 +655,7 @@ struct CarParams { kpV @1 :List(Float32); kiBP @2 :List(Float32); kiV @3 :List(Float32); - kfDEPRECATED @6 :Float32; + kf @6 :Float32; deadzoneBPDEPRECATED @4 :List(Float32); deadzoneVDEPRECATED @5 :List(Float32); } @@ -768,11 +828,11 @@ struct CarParams { maxSteeringAngleDegDEPRECATED @54 :Float32; longitudinalActuatorDelayLowerBoundDEPRECATED @61 :Float32; stoppingControlDEPRECATED @31 :Bool; # Does the car allow full control even at lows speeds when stopping - radarTimeStepDEPRECATED @45: Float32 = 0.05; # time delta between radar updates, 20Hz is very standard + radarTimeStep @45: Float32 = 0.05; # time delta between radar updates, 20Hz is very standard enableDsuDEPRECATED @5 :Bool; # driving support unit - vEgoStartingDEPRECATED @59 :Float32; - startAccelDEPRECATED @32 :Float32; - startingStateDEPRECATED @70 :Bool; + vEgoStarting @59 :Float32; + startAccel @32 :Float32; + startingState @70 :Bool; vEgoStoppingDEPRECATED @29 :Float32; stoppingDecelRateDEPRECATED @52 :Float32; } diff --git a/iqdbc_repo/iqdbc/car/hyundai/carcontroller.py b/iqdbc_repo/iqdbc/car/hyundai/carcontroller.py index 862a79e..4368cbf 100644 --- a/iqdbc_repo/iqdbc/car/hyundai/carcontroller.py +++ b/iqdbc_repo/iqdbc/car/hyundai/carcontroller.py @@ -1,31 +1,47 @@ import numpy as np from iqdbc.can import CANPacker from iqdbc.car import Bus, DT_CTRL, make_tester_present_msg, structs -from iqdbc.car.lateral import apply_driver_steer_torque_limits, common_fault_avoidance +from iqdbc.car.lateral import apply_driver_steer_torque_limits, apply_std_steer_angle_limits, common_fault_avoidance from iqdbc.car.common.conversions import Conversions as CV from iqdbc.car.hyundai import hyundaicanfd, hyundaican +from iqdbc.car.hyundai.carstate import CarState from iqdbc.car.hyundai.hyundaicanfd import CanBus -from iqdbc.car.hyundai.values import HyundaiFlags, Buttons, CarControllerParams, CAR +from iqdbc.car.hyundai.values import HyundaiFlags, Buttons, CarControllerParams, CAR, CAN_GEARS, HyundaiExtFlags from iqdbc.car.interfaces import CarControllerBase - -from iqdbc.iqpilot.car.hyundai.escc import EsccCarController -from iqdbc.iqpilot.car.hyundai.longitudinal.controller import LongitudinalController -from iqdbc.iqpilot.car.hyundai.lead_data_ext import LeadDataCarController -from iqdbc.iqpilot.car.hyundai.aol import AolCarController +from iqdbc.car.vehicle_model import VehicleModel VisualAlert = structs.CarControl.HUDControl.VisualAlert LongCtrlState = structs.CarControl.Actuators.LongControlState + +from openpilot.common.params import Params + # EPS faults if you apply torque while the steering angle is above 90 degrees for more than 1 second # All slightly below EPS thresholds to avoid fault MAX_ANGLE = 85 MAX_ANGLE_FRAMES = 89 MAX_ANGLE_CONSECUTIVE_FRAMES = 2 +DRIVER_TORQUE_FILTER_TAU = 0.12 +PRE_OVERRIDE_PREDICTION_TIME = 0.15 +PRE_OVERRIDE_START_RATIO = 0.90 +PRE_OVERRIDE_FULL_RATIO = 1.05 +PRE_OVERRIDE_RAW_MIN_RATIO = 0.70 +PRE_OVERRIDE_FILTERED_MIN_RATIO = 0.65 +PRE_OVERRIDE_MIN_RATE_RATIO = 0.50 +PRE_OVERRIDE_CONFIRM_FRAMES = 2 +PRE_OVERRIDE_MAX_TORQUE_DELTA = -10.0 +LOW_SPEED_ANGLE_RATE_RAMP_SPEED = 15.0 * CV.KPH_TO_MS +MID_SPEED_ANGLE_RATE_LIMIT_SPEED = 40.0 * CV.KPH_TO_MS - -def _use_stock_lkas_request_path(CP) -> bool: - return CP.carFingerprint == CAR.HYUNDAI_PALISADE - +vibrate_intervals = [ + (0.0, 0.5), + (1.0, 1.5), + #(2.5, 3.0), + #(3.5, 4.0), + (5.0, 5.5), + (6.0, 6.5), + (7.5, 8.0), +] def process_hud_alert(enabled, fingerprint, hud_control): sys_warning = (hud_control.visualAlert in (VisualAlert.steerRequired, VisualAlert.ldw)) @@ -50,14 +66,75 @@ def process_hud_alert(enabled, fingerprint, hud_control): return sys_warning, sys_state, left_lane_warning, right_lane_warning +def rate_limit(x, x_last, lo, hi): + return float(np.clip(x, x_last + lo, x_last + hi)) -class CarController(CarControllerBase, EsccCarController, LeadDataCarController, LongitudinalController, AolCarController): - def __init__(self, dbc_names, CP, CP_IQ): - CarControllerBase.__init__(self, dbc_names, CP, CP_IQ) - EsccCarController.__init__(self, CP, CP_IQ) - AolCarController.__init__(self) - LeadDataCarController.__init__(self, CP) - LongitudinalController.__init__(self, CP, CP_IQ) +def apply_steer_angle_limits_physics(desired_sw_deg: float, + last_sw_deg: float, + v_ego: float, + steering_sw_deg: float, + lat_active: bool, + wheelbase_m: float, + steer_ratio: float, + steer_sw_max_deg: float, + model_v2=None) -> float: + max_lat_accel = 8.5 # m/s^2 + max_lat_jerk = 4.0 # m/s^3 + y_std_1s = 0.1 + if model_v2 is not None and len(model_v2.position.yStd) > 10: + model_y_std_1s = float(model_v2.position.yStd[10]) + if np.isfinite(model_y_std_1s) and model_y_std_1s >= 0.0: + y_std_1s = model_y_std_1s + max_sw_rate_deg_per_tick = float(np.interp(y_std_1s, [0.1, 0.2, 0.4], [2.0, 1.5, 0.8])) + v = max(float(v_ego), 1.0) + + target_sw = float(np.clip(desired_sw_deg, -steer_sw_max_deg, steer_sw_max_deg)) + if v_ego < MID_SPEED_ANGLE_RATE_LIMIT_SPEED: + # Keep low/mid-speed angle commands quieter without reducing LKAS_ANGLE_MAX_TORQUE. + # Allow the angle, but slow the arrival: 0~15 kph ramps 0.8->1.1 deg/tick, + # then 15~40 kph tapers 1.1->0.8 deg/tick. Above 40 kph, physics limits take over. + low_mid_speed_cap = float(np.interp(v_ego, + [0.0, LOW_SPEED_ANGLE_RATE_RAMP_SPEED, MID_SPEED_ANGLE_RATE_LIMIT_SPEED], + [0.8, 1.1, 0.8])) + max_sw_rate_deg_per_tick = min(max_sw_rate_deg_per_tick, low_mid_speed_cap) + + target_rw = target_sw / steer_ratio + last_rw = float(last_sw_deg) / steer_ratio + + # --- accel limit --- + rw_max_rad = np.arctan((max_lat_accel * wheelbase_m) / (v * v)) + rw_max = float(np.degrees(rw_max_rad)) + + # --- jerk -> rate limit --- + sec2 = 1.2 + max_drw_dt = (max_lat_jerk * wheelbase_m) / (v * v * sec2) # rad/s + max_drw_per_tick = max_drw_dt * DT_CTRL # rad/tick + max_drw_per_tick_deg = float(np.degrees(max_drw_per_tick)) + + err = abs(target_sw - last_sw_deg) + if err > 20.0: + max_sw_rate_deg_per_tick = min(max_sw_rate_deg_per_tick, 1.0) + + max_drw_per_tick_deg = min( + max_drw_per_tick_deg, + max_sw_rate_deg_per_tick / steer_ratio + ) + + # --- rate limit --- + cmd_rw = rate_limit(target_rw, last_rw, -max_drw_per_tick_deg, max_drw_per_tick_deg) + + # --- accel clip --- + cmd_rw = float(np.clip(cmd_rw, -rw_max, rw_max)) + + if not lat_active: + cmd_rw = float(steering_sw_deg) / steer_ratio + + cmd_sw = cmd_rw * steer_ratio + return float(np.clip(cmd_sw, -steer_sw_max_deg, steer_sw_max_deg)) + +class CarController(CarControllerBase): + def __init__(self, dbc_names, CP, CP_IQ=None): + super().__init__(dbc_names, CP, CP_IQ or structs.IQCarParams()) self.CAN = CanBus(CP) self.params = CarControllerParams(CP) self.packer = CANPacker(dbc_names[Bus.pt]) @@ -68,56 +145,302 @@ class CarController(CarControllerBase, EsccCarController, LeadDataCarController, self.car_fingerprint = CP.carFingerprint self.last_button_frame = 0 + self.hyundai_jerk = HyundaiJerk() + self.speedCameraHapticEndFrame = 0 + self.hapticFeedbackWhenSpeedCamera = 0 + self.max_angle_frames = MAX_ANGLE_FRAMES + self.blinking_signal = False # 1Hz + self.blinking_frame = int(1.0 / DT_CTRL) + self.soft_hold_mode = 2 + + self.activateCruise = 0 + self.button_wait = 12 + self.cruise_buttons_msg_values = None + self.cruise_buttons_msg_cnt = 0 + self.button_spamming_count = 0 + self.prev_clu_speed = 0 + self.button_spam1 = 8 + self.button_spam2 = 30 + self.button_spam3 = 1 + + self.apply_angle_last = 0 + self.lkas_max_torque = 0 + self.angle_max_torque = 250 + self.steering_pressed_prev = False + self.recovering_from_override = False + self.full_recovery_frames = 0 + self.repeated_override_count = 0 + self.override_latched = False + self.override_release_frames = 0 + self.driver_torque_filtered = 0.0 + self.driver_torque_filtered_prev = 0.0 + self.pre_override_frames = 0 + + self.lkas11_active = False + + self.canfd_debug = 0 + self.MainMode_ACC_trigger = 0 + self.LFA_trigger = 0 + + self.activeCarrot = 0 + self.camera_scc_params = Params().get_int("HyundaiCameraSCC") + self.is_ldws_car = Params().get_bool("IsLdwsCar") + self.enable_corner_radar = 0 + + self.steerDeltaUpOrg = self.steerDeltaUp = self.steerDeltaUpLC = self.params.STEER_DELTA_UP + self.steerDeltaDownOrg = self.steerDeltaDown = self.steerDeltaDownLC = self.params.STEER_DELTA_DOWN + def update(self, CC, CC_IQ, CS, now_nanos): - EsccCarController.update(self, CS) - LeadDataCarController.update(self, CC_IQ) - AolCarController.update(self, self.CP, CC, CC_IQ, self.frame) - if self.frame % 2 == 0: - LongitudinalController.update(self, CC, CS) + + if self.frame % 50 == 0: + params = Params() + self.max_angle_frames = params.get_int("MaxAngleFrames") + steerMax = params.get_int("CustomSteerMax") + steerDeltaUp = params.get_int("CustomSteerDeltaUp") + steerDeltaDown = params.get_int("CustomSteerDeltaDown") + steerDeltaUpLC = params.get_int("CustomSteerDeltaUpLC") + steerDeltaDownLC = params.get_int("CustomSteerDeltaDownLC") + if steerMax > 0: + self.params.STEER_MAX = steerMax + if steerDeltaUp > 0: + self.steerDeltaUp = steerDeltaUp + #self.params.ANGLE_TORQUE_UP_RATE = steerDeltaUp + else: + self.steerDeltaUp = self.steerDeltaUpOrg + if steerDeltaDown > 0: + self.steerDeltaDown = steerDeltaDown + #self.params.ANGLE_TORQUE_DOWN_RATE = steerDeltaDown + else: + self.steerDeltaDown = self.steerDeltaDownOrg + + if steerDeltaUpLC > 0: + self.steerDeltaUpLC = steerDeltaUpLC + else: + self.steerDeltaUpLC = self.steerDeltaUp + if steerDeltaDownLC > 0: + self.steerDeltaDownLC = steerDeltaDownLC + else: + self.steerDeltaDownLC = self.steerDeltaDown + + self.soft_hold_mode = 1 if params.get_int("AutoCruiseControl") > 1 else 2 + self.hapticFeedbackWhenSpeedCamera = int(params.get_int("HapticFeedbackWhenSpeedCamera")) + + self.button_spam1 = params.get_int("CruiseButtonTest1") + self.button_spam2 = params.get_int("CruiseButtonTest2") + self.button_spam3 = params.get_int("CruiseButtonTest3") + self.speed_from_pcm = params.get_int("SpeedFromPCM") + + self.canfd_debug = params.get_int("CanfdDebug") + self.camera_scc_params = params.get_int("HyundaiCameraSCC") + self.enable_corner_radar = params.get_int("EnableCornerRadar") actuators = CC.actuators hud_control = CC.hudControl + if hud_control.modelDesire in [3,4]: + self.params.STEER_DELTA_UP = self.steerDeltaUpLC + self.params.STEER_DELTA_DOWN = self.steerDeltaDownLC + else: + self.params.STEER_DELTA_UP = self.steerDeltaUp + self.params.STEER_DELTA_DOWN = self.steerDeltaDown + + angle_control = self.CP.flags & HyundaiFlags.ANGLE_CONTROL + # steering torque new_torque = int(round(actuators.torque * self.params.STEER_MAX)) apply_torque = apply_driver_steer_torque_limits(new_torque, self.apply_torque_last, CS.out.steeringTorque, self.params) # >90 degree steering fault prevention self.angle_limit_counter, apply_steer_req = common_fault_avoidance(abs(CS.out.steeringAngleDeg) >= MAX_ANGLE, CC.latActive, - self.angle_limit_counter, MAX_ANGLE_FRAMES, + self.angle_limit_counter, self.max_angle_frames, MAX_ANGLE_CONSECUTIVE_FRAMES) + #apply_angle = apply_std_steer_angle_limits(actuators.steeringAngleDeg, self.apply_angle_last, CS.out.vEgoRaw, + # CS.out.steeringAngleDeg, CC.latActive, self.params.ANGLE_LIMITS) + + apply_angle = apply_steer_angle_limits_physics( + actuators.steeringAngleDeg, + self.apply_angle_last, + CS.out.vEgoRaw, + CS.out.steeringAngleDeg, + CC.latActive, + self.CP.wheelbase, + self.CP.steerRatio, + self.params.ANGLE_LIMITS.STEER_ANGLE_MAX, + CS.modelV2, + ) + + + if angle_control: + apply_steer_req = CC.latActive + + angle_torque_cap = self.angle_max_torque + + steering_pressed_rising = CS.out.steeringPressed and not self.steering_pressed_prev + if steering_pressed_rising: + if 0 < self.full_recovery_frames < int(5.0 / DT_CTRL): + self.repeated_override_count = min(self.repeated_override_count + 1, 3) + self.full_recovery_frames = 0 + self.recovering_from_override = True + + torque_threshold = max(self.params.STEER_THRESHOLD, 1.0) + # Filter signed torque so alternating sensor noise cancels out before its + # magnitude is used for pre-override prediction. + driver_torque = float(CS.out.steeringTorque) + driver_torque_abs = abs(driver_torque) + if not CC.latActive: + self.driver_torque_filtered = driver_torque + self.driver_torque_filtered_prev = driver_torque + self.pre_override_frames = 0 + else: + torque_filter_alpha = DT_CTRL / (DRIVER_TORQUE_FILTER_TAU + DT_CTRL) + self.driver_torque_filtered_prev = self.driver_torque_filtered + self.driver_torque_filtered += torque_filter_alpha * (driver_torque - self.driver_torque_filtered) + + driver_torque_filtered_abs = abs(self.driver_torque_filtered) + driver_torque_filtered_prev_abs = abs(self.driver_torque_filtered_prev) + driver_torque_rate = max(0.0, (driver_torque_filtered_abs - driver_torque_filtered_prev_abs) / DT_CTRL) + torque_ratio = driver_torque_filtered_abs / torque_threshold + raw_torque_ratio = driver_torque_abs / torque_threshold + predicted_torque_ratio = ( + driver_torque_filtered_abs + driver_torque_rate * PRE_OVERRIDE_PREDICTION_TIME + ) / torque_threshold + pre_override_candidate = ( + CC.latActive and + not CS.out.steeringPressed and + raw_torque_ratio > PRE_OVERRIDE_RAW_MIN_RATIO and + torque_ratio > PRE_OVERRIDE_FILTERED_MIN_RATIO and + predicted_torque_ratio > PRE_OVERRIDE_START_RATIO and + driver_torque_rate > torque_threshold * PRE_OVERRIDE_MIN_RATE_RATIO + ) + self.pre_override_frames = self.pre_override_frames + 1 if pre_override_candidate else 0 + pre_override_yield = 0.0 + if self.pre_override_frames >= PRE_OVERRIDE_CONFIRM_FRAMES: + pre_override_yield = float(np.interp( + predicted_torque_ratio, + [PRE_OVERRIDE_START_RATIO, PRE_OVERRIDE_FULL_RATIO], + [0.0, 1.0], + )) + recovery_allowed = False + + if CS.out.steeringPressed: + # Start yielding immediately when driver override is confirmed. + self.override_latched = True + self.override_release_frames = 0 + torque_delta = -20.0 + elif pre_override_yield > 0.0: + # Start handing off gently before steeringPressed flips to avoid a sharp torque drop. + torque_delta = PRE_OVERRIDE_MAX_TORQUE_DELTA * pre_override_yield + elif self.lkas_max_torque >= self.angle_max_torque: + # Once fully recovered, hold full authority until the next driver override. + torque_delta = 0.0 + elif self.override_latched: + # Hold reduced authority until driver torque stays below 60% for 0.2 seconds. + self.override_release_frames = self.override_release_frames + 1 if torque_ratio < 0.6 else 0 + if self.override_release_frames >= int(0.2 / DT_CTRL): + self.override_latched = False + self.override_release_frames = 0 + recovery_allowed = True + else: + torque_delta = 0.0 + else: + recovery_allowed = True + + if recovery_allowed: + # Use one-second model uncertainty to set the base torque recovery time. + # Missing or invalid model data falls back to a moderate 1.5-second recovery. + y_std_1s = 0.2 + if CS.modelV2 is not None and len(CS.modelV2.position.yStd) > 10: + model_y_std_1s = float(CS.modelV2.position.yStd[10]) + if np.isfinite(model_y_std_1s) and model_y_std_1s >= 0.0: + y_std_1s = model_y_std_1s + + recovery_time = float(np.interp(y_std_1s, [0.1, 0.2, 0.3, 0.4], [0.5, 0.8, 1.5, 3.0])) + recovery_time = max(recovery_time, float(np.interp( + self.repeated_override_count, + [0, 1, 2, 3], + [0.1, 1.0, 2.0, 3.0], + ))) + base_rate_up = (self.angle_max_torque - self.params.ANGLE_MIN_TORQUE) * DT_CTRL / recovery_time + + # During recovery, taper the rate to zero. Only steeringPressed can reduce authority. + torque_delta = base_rate_up * float(np.interp(torque_ratio, [0.6, 0.8], [1.0, 0.0])) + self.lkas_max_torque = float(np.clip(self.lkas_max_torque + torque_delta, + self.params.ANGLE_MIN_TORQUE, angle_torque_cap)) + + if not CS.out.steeringPressed and self.recovering_from_override and self.lkas_max_torque >= self.angle_max_torque: + self.recovering_from_override = False + self.full_recovery_frames = 1 + elif not CS.out.steeringPressed and self.full_recovery_frames > 0: + self.full_recovery_frames += 1 + if self.full_recovery_frames >= int(5.0 / DT_CTRL): + self.full_recovery_frames = 0 + self.repeated_override_count = 0 + if not CC.latActive: apply_torque = 0 - if self.apply_torque_last > 0: - self.apply_torque_last = max(self.apply_torque_last - self.params.STEER_DELTA_DOWN, 0) - elif self.apply_torque_last < 0: - self.apply_torque_last = min(self.apply_torque_last + self.params.STEER_DELTA_DOWN, 0) - else: - self.apply_torque_last = apply_torque + self.lkas_max_torque = 0 + self.recovering_from_override = False + self.full_recovery_frames = 0 + self.repeated_override_count = 0 + self.override_latched = False + self.override_release_frames = 0 + self.driver_torque_filtered = 0.0 + self.driver_torque_filtered_prev = 0.0 + self.pre_override_frames = 0 - if not _use_stock_lkas_request_path(self.CP) and apply_torque == 0 and CC.latActive and CS.out.steeringPressed: - apply_steer_req = False + self.steering_pressed_prev = CS.out.steeringPressed if CC.latActive else False + + self.apply_angle_last = apply_angle # Hold torque with induced temporary fault when cutting the actuation bit - # FIXME: we don't use this with CAN FD? - torque_fault = False if _use_stock_lkas_request_path(self.CP) else (CC.latActive and not apply_steer_req) + torque_fault = CC.latActive and not apply_steer_req + + self.apply_torque_last = apply_torque # accel + longitudinal accel = float(np.clip(actuators.accel, CarControllerParams.ACCEL_MIN, CarControllerParams.ACCEL_MAX)) stopping = actuators.longControlState == LongCtrlState.stopping set_speed_in_units = hud_control.setSpeed * (CV.MS_TO_KPH if CS.is_metric else CV.MS_TO_MPH) + # HUD messages + sys_warning, sys_state, left_lane_warning, right_lane_warning = process_hud_alert(CC.enabled, self.car_fingerprint, + hud_control) + + active_speed_decel = hud_control.activeCarrot == 3 and self.activeCarrot != 3 # 3: Speed Decel + self.activeCarrot = hud_control.activeCarrot + if active_speed_decel and self.speedCameraHapticEndFrame < 0: # 과속카메라 감속시작 + self.speedCameraHapticEndFrame = self.frame + (8.0 / DT_CTRL) #8초간 켜줌. + elif not active_speed_decel: + self.speedCameraHapticEndFrame = -1 + + if 0 <= self.speedCameraHapticEndFrame - self.frame < int(8.0 / DT_CTRL) and self.hapticFeedbackWhenSpeedCamera > 0: + t = (self.frame - (self.speedCameraHapticEndFrame - int(8.0 / DT_CTRL))) * DT_CTRL + + for start, end in vibrate_intervals: + if start <= t < end: + left_lane_warning = right_lane_warning = self.hapticFeedbackWhenSpeedCamera + break + + if self.frame >= self.speedCameraHapticEndFrame: + self.speedCameraHapticEndFrame = -1 + + if self.frame % self.blinking_frame == 0: + self.blinking_signal = True + elif self.frame % self.blinking_frame == self.blinking_frame / 2: + self.blinking_signal = False + + + can_sends = [] # *** common hyundai stuff *** # tester present - w/ no response (keeps relevant ECU disabled) - if self.frame % 100 == 0 and not ((self.CP.flags & HyundaiFlags.CANFD_CAMERA_SCC) or self.ESCC.enabled) and \ - self.CP.openpilotLongitudinalControl: + if self.frame % 100 == 0 and not (self.CP.flags & HyundaiFlags.CANFD_CAMERA_SCC) and self.CP.openpilotLongitudinalControl: # for longitudinal control, either radar or ADAS driving ECU addr, bus = 0x7d0, self.CAN.ECAN if self.CP.flags & HyundaiFlags.CANFD else 0 - if self.CP.flags & HyundaiFlags.CANFD_LKA_STEERING.value: + if self.CP.flags & HyundaiFlags.CANFD_HDA2.value: addr, bus = 0x730, self.CAN.ECAN can_sends.append(make_tester_present_msg(addr, bus, suppress_response=True)) @@ -125,40 +448,135 @@ class CarController(CarControllerBase, EsccCarController, LeadDataCarController, if self.CP.flags & HyundaiFlags.ENABLE_BLINKERS: can_sends.append(make_tester_present_msg(0x7b1, self.CAN.ECAN, suppress_response=True)) - # *** CAN/CAN FD specific *** + camera_scc = self.CP.flags & HyundaiFlags.CAMERA_SCC + # CAN-FD platforms if self.CP.flags & HyundaiFlags.CANFD: - can_sends.extend(self.create_canfd_msgs(apply_steer_req, apply_torque, set_speed_in_units, accel, - stopping, hud_control, CS, CC)) + hda2 = self.CP.flags & HyundaiFlags.CANFD_HDA2 + hda2_long = hda2 and self.CP.openpilotLongitudinalControl + # steering control + if camera_scc: + can_sends.extend(hyundaicanfd.create_steering_messages_camera_scc(self.frame, self.packer, self.CP, self.CAN, CC, apply_steer_req, apply_torque, CS, apply_angle, self.lkas_max_torque, angle_control)) + else: + can_sends.extend(hyundaicanfd.create_steering_messages(self.packer, self.CP, self.CAN, CC.enabled, apply_steer_req, apply_torque, apply_angle, self.lkas_max_torque, angle_control)) + + # prevent LFA from activating on HDA2 by sending "no lane lines detected" to ADAS ECU + if self.frame % 5 == 0 and hda2 and not camera_scc: + can_sends.extend(hyundaicanfd.create_suppress_lfa(self.packer, self.CAN, CS)) + + # LFA and HDA icons + if self.frame % 5 == 0 and (not hda2 or hda2_long or camera_scc): + can_sends.extend(hyundaicanfd.create_lfahda_cluster(self.packer, CS, self.CAN, CC.longActive, CC.latActive)) + if not camera_scc: + can_sends.extend(hyundaicanfd.create_lfa_icon_non_camera_scc(self.packer, CS, self.CAN, CC)) + + # blinkers + if hda2 and self.CP.flags & HyundaiFlags.ENABLE_BLINKERS: + can_sends.extend(hyundaicanfd.create_spas_messages(self.packer, self.CAN, self.frame, CC.leftBlinker, CC.rightBlinker)) + + if self.camera_scc_params in [2, 3]: + self.canfd_toggle_adas(CC, CS) + if self.CP.openpilotLongitudinalControl: + self.hyundai_jerk.make_jerk(self.CP, CS, accel, actuators, hud_control) + self.hyundai_jerk.check_carrot_cruise(CC, CS, hud_control, stopping, accel, actuators.aTarget) + + if True: #not camera_scc: + can_sends.extend(hyundaicanfd.create_ccnc_messages(self.CP, self.packer, self.CAN, self.frame, CC, CS, hud_control, apply_angle, left_lane_warning, right_lane_warning, self.enable_corner_radar, stopping, self.canfd_debug)) + if hda2: + can_sends.extend(hyundaicanfd.create_adrv_messages(self.CP, self.packer, self.CAN, self.frame)) + else: + can_sends.extend(hyundaicanfd.create_fca_warning_light(self.CP, self.packer, self.CAN, self.frame)) + if self.frame % 2 == 0: + if self.CP.flags & HyundaiFlags.CAMERA_SCC.value: + msg = hyundaicanfd.create_acc_control_scc2(self.packer, self.CAN, CC.enabled, self.accel_last, accel, stopping, CC.cruiseControl.override, + set_speed_in_units, hud_control, self.hyundai_jerk, CS) + if msg is not None: + can_sends.append(msg) + can_sends.extend(hyundaicanfd.create_tcs_messages(self.packer, self.CAN, CS)) # for sorento SCC radar... + else: + can_sends.append(hyundaicanfd.create_acc_control(self.packer, self.CAN, CC.enabled, self.accel_last, accel, stopping, CC.cruiseControl.override, + set_speed_in_units, hud_control, self.hyundai_jerk.jerk_u, self.hyundai_jerk.jerk_l, CS)) + self.accel_last = accel + else: + # button presses + if self.camera_scc_params == 3: # camera scc but stock long + send_button = self.make_spam_button(CC, CS) + can_sends.extend(hyundaicanfd.forward_button_message(self.packer, self.CAN, self.frame, CS, send_button, self.MainMode_ACC_trigger, self.LFA_trigger)) + else: + can_sends.extend(self.create_button_messages(CC, CS, use_clu11=False)) else: - can_sends.extend(self.create_can_msgs(apply_steer_req, apply_torque, torque_fault, set_speed_in_units, accel, - stopping, hud_control, actuators, CS, CC)) + if CS.lkas11 is not None: + if self.lkas11_active: + can_sends.append(hyundaican.create_lkas11(self.packer, self.frame, self.CP, apply_torque, apply_steer_req, + torque_fault, CS.lkas11, sys_warning, sys_state, CC.enabled, + hud_control.leftLaneVisible, hud_control.rightLaneVisible, + left_lane_warning, right_lane_warning, self.is_ldws_car)) + self.lkas11_active = True + + if not self.CP.openpilotLongitudinalControl: + can_sends.extend(self.create_button_messages(CC, CS, use_clu11=True)) + if self.CP.carFingerprint in CAN_GEARS["send_mdps12"] and CS.mdps12 is not None: # send mdps12 to LKAS to prevent LKAS error + can_sends.append(hyundaican.create_mdps12(self.packer, self.frame, CS.mdps12)) + + casper_ev = self.CP.carFingerprint == CAR.HYUNDAI_CASPER_EV + if self.frame % 2 == 0 and self.CP.openpilotLongitudinalControl: + self.hyundai_jerk.make_jerk(self.CP, CS, accel, actuators, hud_control) + self.hyundai_jerk.check_carrot_cruise(CC, CS, hud_control, stopping, accel, actuators.aTarget) + #jerk = 3.0 if actuators.longControlState == LongCtrlState.pid else 1.0 + use_fca = self.CP.flags & HyundaiFlags.USE_FCA.value + if camera_scc: + + can_sends.extend(hyundaican.create_acc_commands_scc(self.packer, CC.enabled, accel, self.hyundai_jerk, int(self.frame / 2), + hud_control, set_speed_in_units, stopping, + CC.cruiseControl.override, casper_ev, CS, self.soft_hold_mode)) + else: + can_sends.extend(hyundaican.create_acc_commands(self.packer, CC.enabled, accel, self.hyundai_jerk, int(self.frame / 2), + hud_control, set_speed_in_units, stopping, + CC.cruiseControl.override, use_fca, self.CP, CS, self.soft_hold_mode)) + + + # 20 Hz LFA MFA message + if self.frame % 5 == 0 and self.CP.flags & HyundaiFlags.SEND_LFA.value: + can_sends.append(hyundaican.create_lfahda_mfc(self.packer, CC, self.blinking_signal)) + + # 5 Hz ACC options + if self.frame % 20 == 0 and self.CP.openpilotLongitudinalControl: + if camera_scc: + if CS.scc13 is not None: + if casper_ev: + #can_sends.append(hyundaican.create_acc_opt_copy(CS, self.packer)) + pass + pass + else: + can_sends.extend(hyundaican.create_acc_opt(self.packer, self.CP)) + + # 2 Hz front radar options + if self.frame % 50 == 0 and self.CP.openpilotLongitudinalControl and not camera_scc: + can_sends.append(hyundaican.create_frt_radar_opt(self.packer)) new_actuators = actuators.as_builder() new_actuators.torque = apply_torque / self.params.STEER_MAX - new_actuators.torqueOutputCan = apply_torque - new_actuators.accel = self.tuning.actual_accel + # torqueOutputCan reflects the steering authority value actually sent over CAN. + # Torque-control platforms send the signed torque command, while angle-control + # platforms send LKAS_ANGLE_MAX_TORQUE alongside the requested angle. + new_actuators.torqueOutputCan = self.lkas_max_torque if angle_control else apply_torque + new_actuators.steeringAngleDeg = float(apply_angle) + new_actuators.accel = accel self.frame += 1 return new_actuators, can_sends - def create_can_msgs(self, apply_steer_req, apply_torque, torque_fault, set_speed_in_units, accel, stopping, hud_control, actuators, CS, CC): + + def create_button_messages(self, CC: structs.CarControl, CS: CarState, use_clu11: bool): can_sends = [] + if CS.out.brakePressed or CS.out.brakeHoldActive: + return can_sends + if use_clu11: + if CS.clu11 is None: + return can_sends - # HUD messages - sys_warning, sys_state, left_lane_warning, right_lane_warning = process_hud_alert(CC.enabled, self.car_fingerprint, - hud_control) - - can_sends.append(hyundaican.create_lkas11(self.packer, self.frame, self.CP, apply_torque, apply_steer_req, - torque_fault, CS.lkas11, sys_warning, sys_state, CC.enabled, - hud_control.leftLaneVisible, hud_control.rightLaneVisible, - left_lane_warning, right_lane_warning, - self.lkas_icon)) - - # Button messages - if not self.CP.openpilotLongitudinalControl: if CC.cruiseControl.cancel: can_sends.append(hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.CANCEL, self.CP)) - elif CC.cruiseControl.resume: + elif False: #CC.cruiseControl.resume: # send resume at a max freq of 10Hz if (self.frame - self.last_button_frame) * DT_CTRL > 0.1: # send 25 messages at a time to increases the likelihood of resume being accepted @@ -166,81 +584,205 @@ class CarController(CarControllerBase, EsccCarController, LeadDataCarController, if (self.frame - self.last_button_frame) * DT_CTRL >= 0.15: self.last_button_frame = self.frame - if self.frame % 2 == 0 and self.CP.openpilotLongitudinalControl: - # TODO: unclear if this is needed - jerk = 3.0 if actuators.longControlState == LongCtrlState.pid else 1.0 - use_fca = self.CP.flags & HyundaiFlags.USE_FCA.value - can_sends.extend(hyundaican.create_acc_commands(self.packer, CC.enabled, accel, jerk, int(self.frame / 2), - self.lead_data, hud_control, set_speed_in_units, stopping, - CC.cruiseControl.override, use_fca, self.CP, - CS.main_cruise_enabled, self.tuning, self.ESCC)) + if self.last_button_frame != self.frame: + send_button = self.make_spam_button(CC, CS) + if send_button > 0: + can_sends.append(hyundaican.create_clu11_button(self.packer, self.frame, CS.clu11, send_button, self.CP)) - # 20 Hz LFA MFA message - if self.frame % 5 == 0 and self.CP.flags & HyundaiFlags.SEND_LFA.value: - can_sends.append(hyundaican.create_lfahda_mfc(self.packer, CC.enabled, self.lfa_icon)) - - # 5 Hz ACC options - if self.frame % 20 == 0 and self.CP.openpilotLongitudinalControl: - can_sends.extend(hyundaican.create_acc_opt(self.packer, self.CP, self.ESCC)) - - # 2 Hz front radar options - if self.frame % 50 == 0 and self.CP.openpilotLongitudinalControl and not self.ESCC.enabled: - can_sends.append(hyundaican.create_frt_radar_opt(self.packer)) - - return can_sends - - def create_canfd_msgs(self, apply_steer_req, apply_torque, set_speed_in_units, accel, stopping, hud_control, CS, CC): - can_sends = [] - - lka_steering = self.CP.flags & HyundaiFlags.CANFD_LKA_STEERING - lka_steering_long = lka_steering and self.CP.openpilotLongitudinalControl - - # steering control - can_sends.extend(hyundaicanfd.create_steering_messages(self.packer, self.CP, self.CAN, CC.enabled, apply_steer_req, apply_torque, self.lkas_icon)) - - # prevent LFA from activating on LKA steering cars by sending "no lane lines detected" to ADAS ECU - if self.frame % 5 == 0 and lka_steering: - can_sends.append(hyundaicanfd.create_suppress_lfa(self.packer, self.CAN, CS.lfa_block_msg, - self.CP.flags & HyundaiFlags.CANFD_LKA_STEERING_ALT)) - - # LFA and HDA icons - if self.frame % 5 == 0 and (not lka_steering or lka_steering_long): - can_sends.append(hyundaicanfd.create_lfahda_cluster(self.packer, self.CAN, CC.enabled, self.lfa_icon)) - - # blinkers - if lka_steering and self.CP.flags & HyundaiFlags.ENABLE_BLINKERS: - can_sends.extend(hyundaicanfd.create_spas_messages(self.packer, self.CAN, CC.leftBlinker, CC.rightBlinker)) - - if self.CP.openpilotLongitudinalControl: - if lka_steering: - can_sends.extend(hyundaicanfd.create_adrv_messages(self.packer, self.CAN, self.frame)) - else: - can_sends.extend(hyundaicanfd.create_fca_warning_light(self.packer, self.CAN, self.frame)) - if self.frame % 2 == 0: - can_sends.append(hyundaicanfd.create_acc_control(self.packer, self.CAN, CC.enabled, self.accel_last, accel, stopping, CC.cruiseControl.override, - set_speed_in_units, hud_control, self.lead_data, CS.main_cruise_enabled, self.tuning)) - self.accel_last = accel else: - # button presses + + # carrot.. 왜 alt_cruise_button는 값이 리스트일까?, 그리고 왜? 빈데이터가 들어오는것일까? + if CS.cruise_buttons_msg is not None and self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS: + try: + cruise_buttons_msg_values = {key: value[0] for key, value in CS.cruise_buttons_msg.items()} + except: # IndexError: + #print("IndexError....") + cruise_buttons_msg_values = None + self.cruise_buttons_msg_cnt += 1 + if cruise_buttons_msg_values is not None: + self.cruise_buttons_msg_values = cruise_buttons_msg_values + self.cruise_buttons_msg_cnt = 0 + if (self.frame - self.last_button_frame) * DT_CTRL > 0.25: # cruise cancel if CC.cruiseControl.cancel: - if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS: - can_sends.append(hyundaicanfd.create_acc_cancel(self.packer, self.CP, self.CAN, CS.cruise_info)) - self.last_button_frame = self.frame - else: - for _ in range(20): - can_sends.append(hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, CS.buttons_counter + 1, Buttons.CANCEL)) + if (self.frame - self.last_button_frame) * DT_CTRL > 0.1: + print("cruiseControl.cancel222222") + if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS: + #can_sends.append(hyundaicanfd.create_acc_cancel(self.packer, self.CP, self.CAN, CS.scc_control)) + if self.cruise_buttons_msg_values is not None: + can_sends.append(hyundaicanfd.alt_cruise_buttons(self.packer, self.CP, self.CAN, Buttons.CANCEL, self.cruise_buttons_msg_values, self.cruise_buttons_msg_cnt)) + + else: + for _ in range(20): + can_sends.append(hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, CS.buttons_counter+1, Buttons.CANCEL)) self.last_button_frame = self.frame # cruise standstill resume - elif CC.cruiseControl.resume: + elif False: #CC.cruiseControl.resume: if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS: # TODO: resume for alt button cars pass else: for _ in range(20): - can_sends.append(hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, CS.buttons_counter + 1, Buttons.RES_ACCEL)) + can_sends.append(hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, CS.buttons_counter+1, Buttons.RES_ACCEL)) self.last_button_frame = self.frame + ## button 스패밍을 안했을때... + if self.last_button_frame != self.frame: + dat = self.canfd_speed_control_pcm(CC, CS, self.cruise_buttons_msg_values) + if dat is not None: + for _ in range(self.button_spam3): + can_sends.append(dat) + self.cruise_buttons_msg_cnt += 1 + return can_sends + + def canfd_toggle_adas(self, CC, CS): + trigger_min = -200 + trigger_start = 6 + self.MainMode_ACC_trigger = max(trigger_min, self.MainMode_ACC_trigger - 1) + self.LFA_trigger = max(trigger_min, self.LFA_trigger - 1) + if self.MainMode_ACC_trigger == trigger_min and self.LFA_trigger == trigger_min: + if CC.enabled and not CS.MainMode_ACC and CS.out.vEgo > 3.: + self.MainMode_ACC_trigger = trigger_start + elif CC.latActive and CS.LFA_ICON == 0: + self.LFA_trigger = trigger_start + + def canfd_speed_control_pcm(self, CC, CS, cruise_buttons_msg_values): + + alt_buttons = True if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS else False + + if alt_buttons and cruise_buttons_msg_values is None: + return None + + send_button = self.make_spam_button(CC, CS) + if send_button > 0: + if alt_buttons: + return hyundaicanfd.alt_cruise_buttons(self.packer, self.CP, self.CAN, send_button, cruise_buttons_msg_values, self.cruise_buttons_msg_cnt) + else: + return hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, CS.buttons_counter+1, send_button) + + return None + + + def make_spam_button(self, CC, CS): + hud_control = CC.hudControl + set_speed_in_units = hud_control.setSpeed * (CV.MS_TO_KPH if CS.is_metric else CV.MS_TO_MPH) + target = int(set_speed_in_units+0.5) + current = int(CS.out.cruiseState.speed * (CV.MS_TO_KPH if CS.is_metric else CV.MS_TO_MPH) + 0.5) + v_ego_kph = CS.out.vEgo * CV.MS_TO_KPH + + send_button = 0 + activate_cruise = False + + if CC.enabled: + if not CS.out.cruiseState.enabled: + if (hud_control.leadVisible or v_ego_kph > 10.0) and self.activateCruise == 0: + send_button = Buttons.RES_ACCEL + self.activateCruise = 1 + activate_cruise = True + elif CC.cruiseControl.resume: + send_button = Buttons.RES_ACCEL + elif target < current and current>= 31 and self.speed_from_pcm != 1: + send_button = Buttons.SET_DECEL + elif target > current and current < 160 and self.speed_from_pcm != 1: + send_button = Buttons.RES_ACCEL + elif CS.out.activateCruise: #CC.cruiseControl.activate: + if (hud_control.leadVisible or v_ego_kph > 10.0) and self.activateCruise == 0: + self.activateCruise = 1 + send_button = Buttons.RES_ACCEL + activate_cruise = True + + if CS.out.brakePressed or CS.out.gasPressed: + self.activateCruise = 0 + + if send_button == 0: + self.button_spamming_count = 0 + self.prev_clu_speed = current + return 0 + + speed_diff = self.prev_clu_speed - current + spamming_max = self.button_spam1 + if CS.cruise_buttons[-1] != Buttons.NONE: + self.last_button_frame = self.frame + self.button_wait = self.button_spam2 + self.button_spamming_count = 0 + elif abs(self.button_spamming_count) >= spamming_max or abs(speed_diff) > 0: + self.last_button_frame = self.frame + self.button_wait = self.button_spam2 if abs(self.button_spamming_count) >= spamming_max else 7 + self.button_spamming_count = 0 + + self.prev_clu_speed = current + send_button_allowed = (self.frame - self.last_button_frame) > self.button_wait + #CC.debugTextCC = "{} speed_diff={:.1f},{:.0f}/{:.0f}, button={}, button_wait={}, count={}".format( + # send_button_allowed, speed_diff, target, current, send_button, self.button_wait, self.button_spamming_count) + + if send_button_allowed or activate_cruise or (CC.cruiseControl.resume and self.frame % 2 == 0): + self.button_spamming_count = self.button_spamming_count + 1 if send_button == Buttons.RES_ACCEL else self.button_spamming_count - 1 + return send_button + else: + self.button_spamming_count = 0 + return 0 + +from openpilot.common.filter_simple import MyMovingAverage +class HyundaiJerk: + def __init__(self): + self.params = Params() + self.jerk = 0.0 + self.jerk_u = self.jerk_l = 0.0 + self.cb_upper = self.cb_lower = 0.0 + self.jerk_u_min = 0.5 + self.carrot_cruise = 1 + self.carrot_cruise_accel = 0.0 + + def check_carrot_cruise(self, CC, CS, hud_control, stopping, accel, a_target): + carrot_cruise_decel = self.params.get_float("CarrotCruiseDecel") + carrot_cruise_atc_decel = self.params.get_float("CarrotCruiseAtcDecel") + if carrot_cruise_atc_decel >= 0 and 0 < hud_control.atcDistance < 500: + carrot_cruise_decel = max(carrot_cruise_decel, carrot_cruise_atc_decel) + self.carrot_cruise = 0 + if CS.out.carrotCruise > 0 and not CC.cruiseControl.override: + if CS.softHoldActive == 0 and not stopping: + if CS.out.vEgo > 10/3.6: + if carrot_cruise_decel < 0: + if (a_target > -0.1 or accel > -0.1): + self.carrot_cruise = 1 + self.carrot_cruise_accel = 0.0 + else: + self.carrot_cruise = 2 + carrot_cruise = min(accel, -carrot_cruise_decel * 0.01) + self.carrot_cruise_accel = max(carrot_cruise, self.carrot_cruise_accel - 1.0 * DT_CTRL) # 점진적으로 줄임. + if self.carrot_cruise == 0: + self.carrot_cruise_accel = CS.out.aEgo + + def make_jerk(self, CP, CS, accel, actuators, hud_control): + if actuators.longControlState == LongCtrlState.stopping: + self.jerk = self.jerk_u_min / 2 - CS.out.aEgo + else: + jerk = actuators.jerk if actuators.longControlState == LongCtrlState.pid else 0.0 + #a_error = actuators.aTarget - CS.out.aEgo + self.jerk = jerk# + a_error + + jerk_max_l = 5.0 + jerk_max_u = jerk_max_l + if actuators.longControlState == LongCtrlState.off: + self.jerk_u = jerk_max_u + self.jerk_l = jerk_max_l + self.cb_upper = self.cb_lower = 0.0 + else: + if CP.flags & HyundaiFlags.CANFD: + # Keep deceleration authority after the MPC jerk settles to zero. Stock SCC raises the + # lower jerk limit with the raw acceleration request instead of relying on jerk alone. + jerk_l_base = 1.2 + jerk_l_raw = np.clip(jerk_l_base + 2.0 * max(0.0, -accel - 2.8), jerk_l_base, jerk_max_l) + jerk_l_mpc = np.clip(-self.jerk * 4.0, jerk_l_base, jerk_max_l) + + self.jerk_u = min(max(self.jerk_u_min, self.jerk * 2.0), jerk_max_u) + self.jerk_l = max(jerk_l_raw, jerk_l_mpc) + self.cb_upper = self.cb_lower = 0.0 + else: + self.jerk_u = min(max(self.jerk_u_min, self.jerk * 2.0), jerk_max_u) + self.jerk_l = min(max(1.0, -self.jerk * 4.0), jerk_max_l) + self.cb_upper = np.clip(0.9 + accel * 0.2, 0, 1.2) + self.cb_lower = np.clip(0.8 + accel * 0.2, 0, 1.2) diff --git a/iqdbc_repo/iqdbc/car/hyundai/carstate.py b/iqdbc_repo/iqdbc/car/hyundai/carstate.py index 6b98f38..48eb597 100644 --- a/iqdbc_repo/iqdbc/car/hyundai/carstate.py +++ b/iqdbc_repo/iqdbc/car/hyundai/carstate.py @@ -1,47 +1,83 @@ from collections import deque import copy import math +import numpy as np +import ast from iqdbc.can import CANDefine, CANParser -from iqdbc.car import Bus, create_button_events, structs +from iqdbc.car import Bus, create_button_events, structs, DT_CTRL from iqdbc.car.common.conversions import Conversions as CV from iqdbc.car.hyundai.hyundaicanfd import CanBus -from iqdbc.car.hyundai.values import HyundaiFlags, CAR, DBC, Buttons, CarControllerParams +from iqdbc.car.hyundai.values import HyundaiFlags, CAR, DBC, Buttons, CarControllerParams, CAMERA_SCC_CAR, HyundaiExtFlags, \ + EV_MODE_ACTIVE_VALUES, EV_MODE_STATUS_ADDR, EV_MODE_STATUS_DLC, EV_MODE_STATUS_MSG, \ + EV_MODE_STATUS_SIGNAL from iqdbc.car.interfaces import CarStateBase -from iqdbc.iqpilot.car.hyundai.carstate_ext import CarStateExt -from iqdbc.iqpilot.car.hyundai.escc import EsccCarStateBase -from iqdbc.iqpilot.car.hyundai.aol import AolCarState -from iqdbc.iqpilot.car.hyundai.values import HyundaiFlagsIQ +from openpilot.common.params import Params + +from datetime import datetime +from zoneinfo import ZoneInfo + ButtonType = structs.CarState.ButtonEvent.Type PREV_BUTTON_SAMPLES = 8 CLUSTER_SAMPLE_RATE = 20 # frames -STANDSTILL_THRESHOLD = 12 * 0.03125 +STANDSTILL_THRESHOLD = 12 * 0.03125 * CV.KPH_TO_MS -# Cancel button can sometimes be ACC pause/resume button, main button can also enable on some cars -ENABLE_BUTTONS = (Buttons.RES_ACCEL, Buttons.SET_DECEL, Buttons.CANCEL) BUTTONS_DICT = {Buttons.RES_ACCEL: ButtonType.accelCruise, Buttons.SET_DECEL: ButtonType.decelCruise, - Buttons.GAP_DIST: ButtonType.gapAdjustCruise, Buttons.CANCEL: ButtonType.cancel} + Buttons.GAP_DIST: ButtonType.gapAdjustCruise, Buttons.CANCEL: ButtonType.cancel, Buttons.LFA_BUTTON: ButtonType.lfaButton} + +GearShifter = structs.CarState.GearShifter + +READY_COUNT_OK = 200 +TRAILER_DISCONNECT_GRACE_FRAMES = int(5.0 / DT_CTRL) +EV_MODE_STATUS_TIMEOUT_NS = 500_000_000 -class CarState(CarStateBase, EsccCarStateBase, AolCarState, CarStateExt): - def __init__(self, CP, CP_IQ): - CarStateBase.__init__(self, CP, CP_IQ) - EsccCarStateBase.__init__(self) - AolCarState.__init__(self, CP, CP_IQ) - CarStateExt.__init__(self, CP, CP_IQ) +def _get_ev_mode_state(cp: CANParser) -> tuple[bool, bool]: + timestamps = cp.ts_nanos.get(EV_MODE_STATUS_MSG) + if timestamps is None: + return False, False + + timestamp = timestamps.get(EV_MODE_STATUS_SIGNAL, 0) + dat = cp.dat.get(EV_MODE_STATUS_ADDR, b"") + # The update timestamp advances even when the whole ECAN bus is silent. + # last_nonempty_nanos would leave the final decoded state valid forever. + age = cp._last_update_nanos - timestamp + valid = timestamp > 0 and len(dat) == EV_MODE_STATUS_DLC and not cp.bus_timeout and 0 <= age <= EV_MODE_STATUS_TIMEOUT_NS + active = valid and int(cp.vl[EV_MODE_STATUS_MSG][EV_MODE_STATUS_SIGNAL]) in EV_MODE_ACTIVE_VALUES + return active, valid + + +NUMERIC_TO_TZ = { + 840: "America/New_York", # 미국 (US) → 동부 시간대 + 124: "America/Toronto", # 캐나다 (CA) → 동부 시간대 + 250: "Europe/Paris", # 프랑스 (FR) + 276: "Europe/Berlin", # 독일 (DE) + 826: "Europe/London", # 영국 (GB) + 392: "Asia/Tokyo", # 일본 (JP) + 156: "Asia/Shanghai", # 중국 (CN) + 410: "Asia/Seoul", # 한국 (KR) + 36: "Australia/Sydney", # 호주 (AU) + 356: "Asia/Kolkata", # 인도 (IN) +} + +class CarState(CarStateBase): + def __init__(self, CP, CP_IQ=None): + super().__init__(CP, CP_IQ or structs.IQCarParams()) can_define = CANDefine(DBC[CP.carFingerprint][Bus.pt]) self.cruise_buttons: deque = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES) self.main_buttons: deque = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES) - self.lda_button = 0 - self.gear_msg_canfd = "ACCELERATOR" if CP.flags & HyundaiFlags.EV else \ + self.gear_msg_canfd = "GEAR" if CP.extFlags & HyundaiExtFlags.CANFD_GEARS_69 else \ + "ACCELERATOR" if CP.flags & HyundaiFlags.EV else \ "GEAR_ALT" if CP.flags & HyundaiFlags.CANFD_ALT_GEARS else \ "GEAR_ALT_2" if CP.flags & HyundaiFlags.CANFD_ALT_GEARS_2 else \ "GEAR_SHIFTER" + + self.use_accelerator = self.gear_msg_canfd == "ACCELERATOR" if CP.flags & HyundaiFlags.CANFD: self.shifter_values = can_define.dv[self.gear_msg_canfd]["GEAR"] elif CP.flags & (HyundaiFlags.HYBRID | HyundaiFlags.EV): @@ -63,31 +99,210 @@ class CarState(CarStateBase, EsccCarStateBase, AolCarState, CarStateExt): self.is_metric = False self.buttons_counter = 0 - self.cruise_info = {} + # for generic CAN parsing + self.fca11 = None + self.scc11 = None + self.scc12 = None + self.scc13 = None + self.scc14 = None + self.lkas11 = None + self.clu11 = None + + # for CANFD parsing + self.scc_control = None + self.lfa = None + self.lfa_alt = None + self.lfahda_cluster = None + self.adrv_0x161 = None + self.adrv_0x200 = None + self.adrv_0x1ea = None + self.adrv_0x160 = None + self.ccnc_0x162 = None + self.hda_info_4a3 = None + self.tcs = None + self.mdps = None + self.steer_touch_2af = None + self.cruise_buttons_msg = None + self.cam_0x362 = None + self.cam_0x2a4 = None + self.manual_speed_limit_assist = None + self.accelerator = None + self.blinkers = None + self.blinkers_alt = None + self.doors_seatbelts = None + self.cruise_buttons_alt2 = None # On some cars, CLU15->CF_Clu_VehicleSpeed can oscillate faster than the dash updates. Sample at 5 Hz self.cluster_speed = 0 self.cluster_speed_counter = CLUSTER_SAMPLE_RATE self.params = CarControllerParams(CP) + self.op_params = Params() + + self.main_enabled = True if self.op_params.get_int("AutoEngage") == 2 else False + self.gear_shifter = GearShifter.drive # Gear_init for Nexo ?? unknown 21.02.23.LSW + + self.totalDistance = 0.0 + self.speedLimitDistance = 0 + self.pcmCruiseGap = 0 + + self.cruise_buttons_alt = True if self.CP.carFingerprint in (CAR.HYUNDAI_CASPER, CAR.HYUNDAI_CASPER_EV) else False + self.MainMode_ACC = False + self.ACCMode = 0 + self.LFA_ICON = 0 + self.paddle_button_prev = 0 + + self.lf_distance = 0 + self.rf_distance = 0 + self.lr_distance = 0 + self.rr_distance = 0 + #self.lf_lateral = 0 + #self.rf_lateral = 0 + + fingerprints_str = Params().get("FingerPrints") + try: + fingerprints = ast.literal_eval(fingerprints_str) if fingerprints_str else {i: {} for i in range(8)} + except (SyntaxError, ValueError): + fingerprints = {i: {} for i in range(8)} + #print("fingerprints =", fingerprints) + ecu_disabled = False + if self.CP.openpilotLongitudinalControl and not (self.CP.flags & HyundaiFlags.CANFD_CAMERA_SCC): + ecu_disabled = True + + + self.HAS_LFA_BUTTON = True if 913 in fingerprints[0] else False + self.CRUISE_BUTTON_ALT = True if 1007 in fingerprints[0] else False + + cam_bus = CanBus(CP).CAM + pt_bus = CanBus(CP).ECAN + alt_bus = CanBus(CP).ACAN + self.GEAR = True if 69 in fingerprints[pt_bus] else False + self.GEAR_ALT = True if 64 in fingerprints[pt_bus] else False + self.TPMS = True if 0x3a0 in fingerprints[pt_bus] else False + self.LOCAL_TIME = True if 1264 in fingerprints[pt_bus] else False + + self.cp_bsm = None + self.time_zone = "UTC" + + self.cp = None + self.cp_cam = None + self.cp_alt = None + self.controls_ready_count = 0 + + # trailer detection + self.trailer_connected = False + self.trailer_timeout_cnt = 0 + self.trailer_connected_prev = False + self.trailer_status = None + + def monitor_fingerprint(self, can_parsers, canfd): + if self.controls_ready_count <= READY_COUNT_OK: + if Params().get_bool("ControlsReady"): + self.controls_ready_count += 1 + + self.cp = can_parsers[Bus.pt] + self.cp_cam = can_parsers[Bus.cam] + self.cp_alt = can_parsers[Bus.alt] if Bus.alt in can_parsers else None + + def add_if_seen(parser, name, ignore_counter = False): + msg = parser.dbc.name_to_msg.get(name) + if not msg: + print(f"{name} not in DBC") + return + if msg.address not in parser.seen_addresses: + return + if msg.address in parser.addresses: + return + parser._add_message(name, ignore_counter = ignore_counter) # ← 이름으로 등록 + + def add_and_cache(parser, name: str, attr: str, ignore_counter: bool = False): + add_if_seen(parser, name, ignore_counter) + if name in parser.vl: # 등록 성공했을 때만 + setattr(self, attr, parser.vl[name]) + return True + return False + + if self.controls_ready_count == 50: + self.cp.controls_ready = self.cp_cam.controls_ready = True + if self.cp_alt is not None: + self.cp_alt.controls_ready = True + elif self.controls_ready_count == 100: + self.cp.enable_capture = self.cp_cam.enable_capture = False + if self.cp_alt is not None: + self.cp_alt.enable_capture = False + elif self.controls_ready_count == 101: + print("cp_cam.seen_addresses =", self.cp_cam.seen_addresses) + elif self.controls_ready_count == 102: + print("cp.seen_addresses =", self.cp.seen_addresses) + elif self.controls_ready_count == 103: + if self.cp_alt is not None: + print("cp_alt.seen_addresses =", self.cp_alt.seen_addresses) + else: + print("cp_alt.seen_addresses = None") + if not canfd: + if self.controls_ready_count == 104: + if not add_and_cache(self.cp_cam, "FCA11", "fca11"): + add_and_cache(self.cp, "FCA11", "fca11") + add_and_cache(self.cp_cam, "LKAS11", "lkas11") + add_and_cache(self.cp, "CLU11", "clu11") + elif self.controls_ready_count == 105: + cp_cruise = self.cp_cam if self.CP.flags & HyundaiFlags.CAMERA_SCC else self.cp + scc_messages_expected = not self.CP.openpilotLongitudinalControl or self.CP.flags & HyundaiFlags.CAMERA_SCC + if scc_messages_expected: + add_and_cache(cp_cruise, "SCC11", "scc11") + add_and_cache(cp_cruise, "SCC12", "scc12") + add_and_cache(cp_cruise, "SCC13", "scc13") + add_and_cache(cp_cruise, "SCC14", "scc14") + else: # canfd + if self.controls_ready_count == 120: + cp_cruise = self.cp_cam if self.CP.flags & HyundaiFlags.CANFD_CAMERA_SCC else self.cp + add_and_cache(cp_cruise, "SCC_CONTROL", "scc_control") + elif self.controls_ready_count == 121: + add_and_cache(self.cp, "TCS", "tcs") + add_and_cache(self.cp, "MDPS", "mdps") + add_and_cache(self.cp_cam, "LFA", "lfa") + add_and_cache(self.cp_cam, "LFA_ALT", "lfa_alt") + add_and_cache(self.cp_cam, "LFAHDA_CLUSTER", "lfahda_cluster") + elif self.controls_ready_count == 122: + add_and_cache(self.cp_cam, "ADRV_0x161", "adrv_0x161") + add_and_cache(self.cp_cam, "ADRV_0x200", "adrv_0x200") + add_and_cache(self.cp_cam, "ADRV_0x1ea", "adrv_0x1ea") + add_and_cache(self.cp_cam, "ADRV_0x160", "adrv_0x160") + add_and_cache(self.cp_cam, "CCNC_0x162", "ccnc_0x162") + elif self.controls_ready_count == 123: + add_and_cache(self.cp, "HDA_INFO_4A3", "hda_info_4a3") + add_and_cache(self.cp, "STEER_TOUCH_2AF", "steer_touch_2af") + elif self.controls_ready_count == 124: + add_and_cache(self.cp, self.cruise_btns_msg_canfd, "cruise_buttons_msg") + if not add_and_cache(self.cp_cam, "CAM_0x362", "cam_0x362") and self.cp_alt is not None: + add_and_cache(self.cp_alt, "CAM_0x362", "cam_0x362") + if not add_and_cache(self.cp_alt, "CAM_0x2a4", "cam_0x2a4") and self.cp_cam is not None: + add_and_cache(self.cp_cam, "CAM_0x2a4", "cam_0x2a4") + elif self.controls_ready_count == 125: + add_and_cache(self.cp, "MANUAL_SPEED_LIMIT_ASSIST", "manual_speed_limit_assist", ignore_counter = True) + if self.gear_msg_canfd == "ACCELERATOR": + add_and_cache(self.cp, "ACCELERATOR", "accelerator", ignore_counter = True) + add_and_cache(self.cp, "BLINKERS", "blinkers") + add_and_cache(self.cp, "BLINKERS_ALT", "blinkers_alt") + add_and_cache(self.cp, "DOORS_SEATBELTS", "doors_seatbelts") + elif self.controls_ready_count == 126: + add_and_cache(self.cp, "CRUISE_BUTTONS_ALT2", "cruise_buttons_alt2", ignore_counter = True) + add_and_cache(self.cp, "TRAILER_STATUS", "trailer_status", ignore_counter = True) + + - self.steer_fault_counter = 0 - def recent_button_interaction(self) -> bool: - # On some newer model years, the CANCEL button acts as a pause/resume button based on the PCM state - # To avoid re-engaging when openpilot cancels, check user engagement intention via buttons - # Main button also can trigger an engagement on these cars - return any(btn in ENABLE_BUTTONS for btn in self.cruise_buttons) or any(self.main_buttons) def update(self, can_parsers) -> tuple[structs.CarState, structs.IQCarState]: + self.monitor_fingerprint(can_parsers, self.CP.flags & HyundaiFlags.CANFD) cp = can_parsers[Bus.pt] cp_cam = can_parsers[Bus.cam] + cp_alt = can_parsers[Bus.alt] if Bus.alt in can_parsers else None if self.CP.flags & HyundaiFlags.CANFD: - return self.update_canfd(can_parsers) + return self.update_canfd(can_parsers), self.out_iq ret = structs.CarState() - ret_iq = structs.IQCarState() cp_cruise = cp_cam if self.CP.flags & HyundaiFlags.CAMERA_SCC else cp self.is_metric = cp.vl["CLU11"]["CF_Clu_SPEED_UNIT"] == 0 speed_conv = CV.KPH_TO_MS if self.is_metric else CV.MPH_TO_MS @@ -97,13 +312,18 @@ class CarState(CarStateBase, EsccCarStateBase, AolCarState, CarStateExt): ret.seatbeltUnlatched = cp.vl["CGW1"]["CF_Gway_DrvSeatBeltSw"] == 0 - self.parse_wheel_speeds(ret, + if cp.ts_nanos["EMS21"]["SCR_UREA_LEVEL"] > 0: + ret.ureaGauge = float(np.clip(cp.vl["EMS21"]["SCR_UREA_LEVEL"] / 100.0, 0.0, 1.0)) + + ret.wheelSpeeds = self.get_wheel_speeds( cp.vl["WHL_SPD11"]["WHL_SPD_FL"], cp.vl["WHL_SPD11"]["WHL_SPD_FR"], cp.vl["WHL_SPD11"]["WHL_SPD_RL"], cp.vl["WHL_SPD11"]["WHL_SPD_RR"], ) - ret.standstill = cp.vl["WHL_SPD11"]["WHL_SPD_FL"] <= STANDSTILL_THRESHOLD and cp.vl["WHL_SPD11"]["WHL_SPD_RR"] <= STANDSTILL_THRESHOLD + ret.vEgoRaw = (ret.wheelSpeeds.fl + ret.wheelSpeeds.fr + ret.wheelSpeeds.rl + ret.wheelSpeeds.rr) / 4. + ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw) + ret.standstill = ret.wheelSpeeds.fl <= STANDSTILL_THRESHOLD and ret.wheelSpeeds.rr <= STANDSTILL_THRESHOLD self.cluster_speed_counter += 1 if self.cluster_speed_counter > CLUSTER_SAMPLE_RATE: @@ -116,73 +336,109 @@ class CarState(CarStateBase, EsccCarStateBase, AolCarState, CarStateExt): if not self.is_metric and self.CP.carFingerprint not in (CAR.KIA_SORENTO,): self.cluster_speed = math.floor(self.cluster_speed * CV.KPH_TO_MPH + CV.KPH_TO_MPH) - ret.vEgoCluster = self.cluster_speed * speed_conv + #ret.vEgoCluster = self.cluster_speed * speed_conv ret.steeringAngleDeg = cp.vl["SAS11"]["SAS_Angle"] ret.steeringRateDeg = cp.vl["SAS11"]["SAS_Speed"] + ret.yawRate = cp.vl["ESP12"]["YAW_RATE"] ret.leftBlinker, ret.rightBlinker = self.update_blinker_from_lamp( 50, cp.vl["CGW1"]["CF_Gway_TurnSigLh"], cp.vl["CGW1"]["CF_Gway_TurnSigRh"]) ret.steeringTorque = cp.vl["MDPS12"]["CR_Mdps_StrColTq"] ret.steeringTorqueEps = cp.vl["MDPS12"]["CR_Mdps_OutTq"] ret.steeringPressed = self.update_steering_pressed(abs(ret.steeringTorque) > self.params.STEER_THRESHOLD, 5) - steer_fault_raw = cp.vl["MDPS12"]["CF_Mdps_ToiUnavail"] != 0 or cp.vl["MDPS12"]["CF_Mdps_ToiFlt"] != 0 - self.steer_fault_counter = self.steer_fault_counter + 1 if steer_fault_raw else 0 - ret.steerFaultTemporary = self.steer_fault_counter > 5 + ret.steerFaultTemporary = cp.vl["MDPS12"]["CF_Mdps_ToiUnavail"] != 0 or cp.vl["MDPS12"]["CF_Mdps_ToiFlt"] != 0 # cruise state if self.CP.openpilotLongitudinalControl: # These are not used for engage/disengage since openpilot keeps track of state using the buttons - ret.cruiseState.available = cp.vl["TCS13"]["ACCEnable"] == 0 + ret.cruiseState.available = self.main_enabled and self.controls_ready_count >= READY_COUNT_OK #cp.vl["TCS13"]["ACCEnable"] == 0 ret.cruiseState.enabled = cp.vl["TCS13"]["ACC_REQ"] == 1 ret.cruiseState.standstill = False ret.cruiseState.nonAdaptive = False - elif not self.CP_IQ.flags & HyundaiFlagsIQ.NON_SCC: - ret.cruiseState.available = cp_cruise.vl["SCC11"]["MainMode_ACC"] == 1 + elif not self.CP.flags & HyundaiFlags.CC_ONLY_CAR: + self.main_enabled = ret.cruiseState.available = cp_cruise.vl["SCC11"]["MainMode_ACC"] == 1 ret.cruiseState.enabled = cp_cruise.vl["SCC12"]["ACCMode"] != 0 ret.cruiseState.standstill = cp_cruise.vl["SCC11"]["SCCInfoDisplay"] == 4. ret.cruiseState.nonAdaptive = cp_cruise.vl["SCC11"]["SCCInfoDisplay"] == 2. # Shows 'Cruise Control' on dash ret.cruiseState.speed = cp_cruise.vl["SCC11"]["VSetDis"] * speed_conv + ret.pcmCruiseGap = cp_cruise.vl["SCC11"]["TauGapSet"] + # TODO: Find brake pressure ret.brake = 0 - ret.brakePressed = cp.vl["TCS13"]["DriverOverride"] == 2 # 2 includes regen braking by user on HEV/EV - ret.brakeHoldActive = cp.vl["TCS15"]["AVH_LAMP"] == 2 # 0 OFF, 1 ERROR, 2 ACTIVE, 3 READY - ret.parkingBrake = cp.vl["TCS13"]["PBRAKE_ACT"] == 1 - ret.espDisabled = cp.vl["TCS11"]["TCS_PAS"] == 1 - ret.espActive = cp.vl["TCS11"]["ABS_ACT"] == 1 - ret.accFaulted = cp.vl["TCS13"]["ACCEnable"] != 0 # 0 ACC CONTROL ENABLED, 1-3 ACC CONTROL DISABLED + if not self.CP.flags & HyundaiFlags.CC_ONLY_CAR: + ret.brakePressed = cp.vl["TCS13"]["DriverOverride"] == 2 # 2 includes regen braking by user on HEV/EV + ret.brakeHoldActive = cp.vl["TCS15"]["AVH_LAMP"] == 2 # 0 OFF, 1 ERROR, 2 ACTIVE, 3 READY + ret.parkingBrake = cp.vl["TCS13"]["PBRAKE_ACT"] == 1 + ret.espDisabled = cp.vl["TCS11"]["TCS_PAS"] == 1 + ret.espActive = cp.vl["TCS11"]["ABS_ACT"] == 1 + ret.accFaulted = cp.vl["TCS13"]["ACCEnable"] != 0 # 0 ACC CONTROL ENABLED, 1-3 ACC CONTROL DISABLED + ret.brakeLights = bool(cp.vl["TCS13"]["BrakeLight"] or ret.brakePressed) if self.CP.flags & (HyundaiFlags.HYBRID | HyundaiFlags.EV | HyundaiFlags.FCEV): if self.CP.flags & HyundaiFlags.FCEV: - ret.gasPressed = cp.vl["FCEV_ACCELERATOR"]["ACCELERATOR_PEDAL"] > 0 + ret.gas = cp.vl["FCEV_ACCELERATOR"]["ACCELERATOR_PEDAL"] / 254. elif self.CP.flags & HyundaiFlags.HYBRID: - ret.gasPressed = cp.vl["E_EMS11"]["CR_Vcu_AccPedDep_Pos"] > 0 + ret.gas = cp.vl["E_EMS11"]["CR_Vcu_AccPedDep_Pos"] / 254. else: - ret.gasPressed = cp.vl["E_EMS11"]["Accel_Pedal_Pos"] > 0 + ret.gas = cp.vl["E_EMS11"]["Accel_Pedal_Pos"] / 254. + ret.gasPressed = ret.gas > 0 else: + ret.gas = cp.vl["EMS12"]["PV_AV_CAN"] / 100. ret.gasPressed = bool(cp.vl["EMS16"]["CF_Ems_AclAct"]) # Gear Selection via Cluster - For those Kia/Hyundai which are not fully discovered, we can use the Cluster Indicator for Gear Selection, # as this seems to be standard over all cars, but is not the preferred method. if self.CP.flags & (HyundaiFlags.HYBRID | HyundaiFlags.EV): gear = cp.vl["ELECT_GEAR"]["Elect_Gear_Shifter"] + ret.gearStep = cp.vl["ELECT_GEAR"]["Elect_Gear_Step"] + if self.CP.carFingerprint == CAR.HYUNDAI_CASPER_EV: + ret.gearStep = 0 elif self.CP.flags & HyundaiFlags.FCEV: gear = cp.vl["EMS20"]["HYDROGEN_GEAR_SHIFTER"] elif self.CP.flags & HyundaiFlags.CLUSTER_GEARS: gear = cp.vl["CLU15"]["CF_Clu_Gear"] + if self.CP.carFingerprint == CAR.KIA_K7: + ret.gearStep = cp.vl["LVR11"]["CF_Lvr_GearInf"] elif self.CP.flags & HyundaiFlags.TCU_GEARS: gear = cp.vl["TCU12"]["CUR_GR"] else: gear = cp.vl["LVR12"]["CF_Lvr_Gear"] + ret.gearStep = cp.vl["LVR11"]["CF_Lvr_GearInf"] - ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(gear)) + if not self.CP.carFingerprint in (CAR.HYUNDAI_NEXO): + ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(gear)) + else: + gear = cp.vl["ELECT_GEAR"]["Elect_Gear_Shifter"] + gear_disp = cp.vl["ELECT_GEAR"] - if (not self.CP.openpilotLongitudinalControl or self.CP.flags & HyundaiFlags.CAMERA_SCC) and not self.CP_IQ.flags & HyundaiFlagsIQ.NON_SCC: + gear_shifter = GearShifter.unknown + + if gear == 1546: # Thank you for Neokii # fix PolorBear 22.06.05 + gear_shifter = GearShifter.drive + elif gear == 2314: + gear_shifter = GearShifter.neutral + elif gear == 2569: + gear_shifter = GearShifter.park + elif gear == 2566: + gear_shifter = GearShifter.reverse + + if gear_shifter != GearShifter.unknown and self.gear_shifter != gear_shifter: + self.gear_shifter = gear_shifter + + ret.gearShifter = self.gear_shifter + + if not self.CP.flags & HyundaiFlags.CC_ONLY_CAR and (not self.CP.openpilotLongitudinalControl or self.CP.flags & HyundaiFlags.CAMERA_SCC): aeb_src = "FCA11" if self.CP.flags & HyundaiFlags.USE_FCA.value else "SCC12" aeb_sig = "FCA_CmdAct" if self.CP.flags & HyundaiFlags.USE_FCA.value else "AEB_CmdAct" aeb_warning = cp_cruise.vl[aeb_src]["CF_VSM_Warn"] != 0 scc_warning = cp_cruise.vl["SCC12"]["TakeOverReq"] == 1 # sometimes only SCC system shows an FCW aeb_braking = cp_cruise.vl[aeb_src]["CF_VSM_DecCmdAct"] != 0 or cp_cruise.vl[aeb_src][aeb_sig] != 0 + if self.CP.carFingerprint == CAR.HYUNDAI_CASPER_EV and aeb_src == "FCA11": + fca_fault = cp_cruise.vl["FCA11"]["FCA_Failinfo"] != 0 or cp_cruise.vl["FCA11"]["FCA_Status"] == 3 + if fca_fault: + aeb_warning = False + aeb_braking = False ret.stockFcw = (aeb_warning or scc_warning) and not aeb_braking ret.stockAeb = aeb_warning and aeb_braking @@ -190,157 +446,393 @@ class CarState(CarStateBase, EsccCarStateBase, AolCarState, CarStateExt): ret.leftBlindspot = cp.vl["LCA11"]["CF_Lca_IndLeft"] != 0 ret.rightBlindspot = cp.vl["LCA11"]["CF_Lca_IndRight"] != 0 - # save the entire LKAS11 and CLU11 - self.lkas11 = copy.copy(cp_cam.vl["LKAS11"]) - self.clu11 = copy.copy(cp.vl["CLU11"]) self.steer_state = cp.vl["MDPS12"]["CF_Mdps_ToiActive"] # 0 NOT ACTIVE, 1 ACTIVE prev_cruise_buttons = self.cruise_buttons[-1] + #self.cruise_buttons.extend(cp.vl_all["CLU11"]["CF_Clu_CruiseSwState"]) + #carrot {{ + #if self.CRUISE_BUTTON_ALT and cp.vl["CRUISE_BUTTON_ALT"]["SET_ME_1"] == 1: + # self.cruise_buttons_alt = True + + cruise_button = [Buttons.NONE] + if self.cruise_buttons_alt: + lfa_button = cp.vl["CRUISE_BUTTON_LFA"]["CruiseSwLfa"] + cruise_button = [Buttons.LFA_BUTTON] if lfa_button > 0 else [cp.vl["CRUISE_BUTTON_ALT"]["CruiseSwState"]] + elif self.HAS_LFA_BUTTON and cp.vl["BCM_PO_11"]["LFA_Pressed"] == 1: # for K5 + cruise_button = [Buttons.LFA_BUTTON] + else: + cruise_button = cp.vl_all["CLU11"]["CF_Clu_CruiseSwState"] + self.cruise_buttons.extend(cruise_button) + # }} carrot prev_main_buttons = self.main_buttons[-1] - prev_lda_button = self.lda_button - self.cruise_buttons.extend(cp.vl_all["CLU11"]["CF_Clu_CruiseSwState"]) - self.main_buttons.extend(cp.vl_all["CLU11"]["CF_Clu_CruiseSwMain"]) - if self.CP.flags & HyundaiFlags.HAS_LDA_BUTTON: - self.lda_button = cp.vl["BCM_PO_11"]["LDA_BTN"] + #self.cruise_buttons.extend(cp.vl_all["CLU11"]["CF_Clu_CruiseSwState"]) + if self.cruise_buttons_alt: + self.main_buttons.extend(cp.vl_all["CRUISE_BUTTON_ALT"]["CruiseSwMain"]) + else: + self.main_buttons.extend(cp.vl_all["CLU11"]["CF_Clu_CruiseSwMain"]) + self.mdps12 = copy.copy(cp.vl["MDPS12"]) ret.buttonEvents = [*create_button_events(self.cruise_buttons[-1], prev_cruise_buttons, BUTTONS_DICT), - *create_button_events(self.main_buttons[-1], prev_main_buttons, {1: ButtonType.mainCruise}), - *create_button_events(self.lda_button, prev_lda_button, {1: ButtonType.lkas})] + *create_button_events(self.main_buttons[-1], prev_main_buttons, {1: ButtonType.mainCruise})] - if self.CP.openpilotLongitudinalControl: - ret.cruiseState.available = self.get_main_cruise(ret) - CarStateExt.update(self, ret, ret_iq, can_parsers, speed_conv) + if not self.CP.flags & HyundaiFlags.CC_ONLY_CAR: + tpms_unit = cp.vl["TPMS11"]["UNIT"] * 0.725 if int(cp.vl["TPMS11"]["UNIT"]) > 0 else 1. + ret.tpms.fl = tpms_unit * cp.vl["TPMS11"]["PRESSURE_FL"] + ret.tpms.fr = tpms_unit * cp.vl["TPMS11"]["PRESSURE_FR"] + ret.tpms.rl = tpms_unit * cp.vl["TPMS11"]["PRESSURE_RL"] + ret.tpms.rr = tpms_unit * cp.vl["TPMS11"]["PRESSURE_RR"] - ret.blockPcmEnable = not self.recent_button_interaction() + cluSpeed = cp.vl["CLU11"]["CF_Clu_Vanz"] + decimal = cp.vl["CLU11"]["CF_Clu_VanzDecimal"] + if 0. < decimal < 0.5: + cluSpeed += decimal - # low speed steer alert hysteresis logic (only for cars with steer cut off above 10 m/s) - if ret.vEgo < (self.CP.minSteerSpeed + 2.) and self.CP.minSteerSpeed > 10.: - self.low_speed_alert = True - if ret.vEgo > (self.CP.minSteerSpeed + 4.): - self.low_speed_alert = False - ret.lowSpeedAlert = self.low_speed_alert + ret.vEgoCluster = cluSpeed * speed_conv + vEgoClu, aEgoClu = self.update_clu_speed_kf(ret.vEgoCluster) + ret.vCluRatio = (ret.vEgo / vEgoClu) if (vEgoClu > 3. and ret.vEgo > 3.) else 1.0 - return ret, ret_iq + if self.CP.extFlags & HyundaiExtFlags.NAVI_CLUSTER.value: + speedLimit = cp.vl["Navi_HU"]["SpeedLim_Nav_Clu"] + speedLimitCam = cp.vl["Navi_HU"]["SpeedLim_Nav_Cam"] + ret.speedLimit = speedLimit if speedLimit < 255 and speedLimitCam == 1 else 0 + speed_limit_cam = speedLimitCam == 1 + else: + ret.speedLimit = 0 + ret.speedLimitDistance = 0 + speed_limit_cam = False - def update_canfd(self, can_parsers) -> tuple[structs.CarState, structs.IQCarState]: + self.update_speed_limit(ret, speed_limit_cam) + + if prev_main_buttons == 0 and self.main_buttons[-1] != 0: + self.main_enabled = not self.main_enabled + + return ret, self.out_iq + + def update_speed_limit(self, ret, speed_limit_cam): + self.totalDistance += ret.vEgo * DT_CTRL + if ret.speedLimit > 0 and not ret.gasPressed and speed_limit_cam: + if self.speedLimitDistance <= self.totalDistance: + self.speedLimitDistance = self.totalDistance + ret.speedLimit * 6 + self.speedLimitDistance = max(self.totalDistance + 1, self.speedLimitDistance) + else: + self.speedLimitDistance = self.totalDistance + ret.speedLimitDistance = self.speedLimitDistance - self.totalDistance + + def update_canfd(self, can_parsers) -> structs.CarState: cp = can_parsers[Bus.pt] cp_cam = can_parsers[Bus.cam] + cp_alt = can_parsers[Bus.alt] if Bus.alt in can_parsers else None ret = structs.CarState() - ret_iq = structs.IQCarState() + + if self.CP.extFlags & HyundaiExtFlags.EV_MODE_STATUS_230: + ret.evModeActive, ret.evModeValid = _get_ev_mode_state(cp) self.is_metric = cp.vl["CRUISE_BUTTONS_ALT"]["DISTANCE_UNIT"] != 1 speed_factor = CV.KPH_TO_MS if self.is_metric else CV.MPH_TO_MS if self.CP.flags & (HyundaiFlags.EV | HyundaiFlags.HYBRID): - ret.gasPressed = cp.vl[self.accelerator_msg_canfd]["ACCELERATOR_PEDAL"] > 1e-5 + offset = 255. if self.CP.flags & HyundaiFlags.EV else 1023. + ret.gas = cp.vl[self.accelerator_msg_canfd]["ACCELERATOR_PEDAL"] / offset if not self.use_accelerator else 0 if self.accelerator is None else self.accelerator["ACCELERATOR_PEDAL"] / offset + ret.gasPressed = ret.gas > 1e-5 else: - ret.gasPressed = bool(cp.vl[self.accelerator_msg_canfd]["ACCELERATOR_PEDAL_PRESSED"]) + ret.gasPressed = bool(cp.vl[self.accelerator_msg_canfd]["ACCELERATOR_PEDAL_PRESSED"]) if not self.use_accelerator else False if self.accelerator is None else bool(self.accelerator["ACCELERATOR_PEDAL_PRESSED"]) ret.brakePressed = cp.vl["TCS"]["DriverBraking"] == 1 + #print(cp.vl["TCS"], cp.vl_all["TCS"]["DriverBraking"][-10:]) - ret.doorOpen = cp.vl["DOORS_SEATBELTS"]["DRIVER_DOOR"] == 1 - ret.seatbeltUnlatched = cp.vl["DOORS_SEATBELTS"]["DRIVER_SEATBELT"] == 0 + if self.doors_seatbelts is not None: + ret.doorOpen = self.doors_seatbelts["DRIVER_DOOR"] == 1 + ret.seatbeltUnlatched = self.doors_seatbelts["DRIVER_SEATBELT"] == 0 - gear = cp.vl[self.gear_msg_canfd]["GEAR"] + gear = cp.vl[self.gear_msg_canfd]["GEAR"] if not self.use_accelerator else 0 if self.accelerator is None else self.accelerator["GEAR"] ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(gear)) + if self.TPMS: + tpms_unit = cp.vl["TPMS"]["UNIT"] * 0.725 if int(cp.vl["TPMS"]["UNIT"]) > 0 else 1. + ret.tpms.fl = tpms_unit * cp.vl["TPMS"]["PRESSURE_FL"] + ret.tpms.fr = tpms_unit * cp.vl["TPMS"]["PRESSURE_FR"] + ret.tpms.rl = tpms_unit * cp.vl["TPMS"]["PRESSURE_RL"] + ret.tpms.rr = tpms_unit * cp.vl["TPMS"]["PRESSURE_RR"] + # TODO: figure out positions - self.parse_wheel_speeds(ret, - cp.vl["WHEEL_SPEEDS"]["WHL_SpdFLVal"], - cp.vl["WHEEL_SPEEDS"]["WHL_SpdFRVal"], - cp.vl["WHEEL_SPEEDS"]["WHL_SpdRLVal"], - cp.vl["WHEEL_SPEEDS"]["WHL_SpdRRVal"], + ret.wheelSpeeds = self.get_wheel_speeds( + cp.vl["WHEEL_SPEEDS"]["WHEEL_SPEED_1"], + cp.vl["WHEEL_SPEEDS"]["WHEEL_SPEED_2"], + cp.vl["WHEEL_SPEEDS"]["WHEEL_SPEED_3"], + cp.vl["WHEEL_SPEEDS"]["WHEEL_SPEED_4"], ) - ret.standstill = cp.vl["WHEEL_SPEEDS"]["WHL_SpdFLVal"] <= STANDSTILL_THRESHOLD and cp.vl["WHEEL_SPEEDS"]["WHL_SpdFRVal"] <= STANDSTILL_THRESHOLD and \ - cp.vl["WHEEL_SPEEDS"]["WHL_SpdRLVal"] <= STANDSTILL_THRESHOLD and cp.vl["WHEEL_SPEEDS"]["WHL_SpdRRVal"] <= STANDSTILL_THRESHOLD + ret.vEgoRaw = (ret.wheelSpeeds.fl + ret.wheelSpeeds.fr + ret.wheelSpeeds.rl + ret.wheelSpeeds.rr) / 4. + ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw) + ret.standstill = ret.wheelSpeeds.fl <= STANDSTILL_THRESHOLD and ret.wheelSpeeds.rr <= STANDSTILL_THRESHOLD + + ret.brakeLights = ret.brakePressed or cp.vl["TCS"]["BrakeLight"] == 1 or ret.aEgo < -0.5 ret.steeringRateDeg = cp.vl["STEERING_SENSORS"]["STEERING_RATE"] - ret.steeringAngleDeg = cp.vl["STEERING_SENSORS"]["STEERING_ANGLE"] + + # steering angle deg값이 이상함. mdps값이 더 신뢰가 가는듯.. torque steering 차량도 확인해야함. + #ret.steeringAngleDeg = cp.vl["STEERING_SENSORS"]["STEERING_ANGLE"] * -1 + #ret.steeringAngleDeg = cp.vl["MDPS"]["STEERING_ANGLE"] * -1 + if self.CP.flags & HyundaiFlags.ANGLE_CONTROL: + ret.steeringAngleDeg = cp.vl["MDPS"]["STEERING_ANGLE_2"] * -1 + else: + ret.steeringAngleDeg = cp.vl["STEERING_SENSORS"]["STEERING_ANGLE"] * -1 + + trailer_signal = self.trailer_status is not None and self.trailer_status["TRAILER_CONNECTED"] != 0 + if trailer_signal: + # Rising edge is immediate so trailer-specific behavior is preserved. + self.trailer_timeout_cnt = 0 + self.trailer_connected = True + elif self.trailer_connected: + # During ignition-off, the trailer bit can clear before the cluster shuts down. + # Keep suppression active through that transient, while still detecting a real + # disconnect after 5 seconds at the 100 Hz CarState update rate. + self.trailer_timeout_cnt += 1 + if self.trailer_timeout_cnt > TRAILER_DISCONNECT_GRACE_FRAMES: + self.trailer_connected = False + else: + self.trailer_timeout_cnt = 0 + + ret.trailerConnected = self.trailer_connected + + if self.trailer_connected != self.trailer_connected_prev: + print(f"[TRAILER_DEBUG] connected={self.trailer_connected} timeout={self.trailer_timeout_cnt}") + self.trailer_connected_prev = self.trailer_connected + ret.steeringTorque = cp.vl["MDPS"]["STEERING_COL_TORQUE"] ret.steeringTorqueEps = cp.vl["MDPS"]["STEERING_OUT_TORQUE"] ret.steeringPressed = self.update_steering_pressed(abs(ret.steeringTorque) > self.params.STEER_THRESHOLD, 5) - steer_fault_raw = cp.vl["MDPS"]["LKA_FAULT"] != 0 - self.steer_fault_counter = self.steer_fault_counter + 1 if steer_fault_raw else 0 - ret.steerFaultTemporary = self.steer_fault_counter > 5 + ret.steerFaultTemporary = cp.vl["MDPS"]["LKA_FAULT"] != 0 or cp.vl["MDPS"]["LFA2_FAULT"] != 0 + #ret.steerFaultTemporary = False + + blinkers_info = self.blinkers if self.blinkers is not None else self.blinkers_alt if self.blinkers_alt is not None else None + if blinkers_info is not None: + left_blinker_lamp = blinkers_info["LEFT_LAMP"] or blinkers_info["LEFT_LAMP_ALT"] + right_blinker_lamp = blinkers_info["RIGHT_LAMP"] or blinkers_info["RIGHT_LAMP_ALT"] + ret.leftBlinker, ret.rightBlinker = self.update_blinker_from_lamp(50, left_blinker_lamp, right_blinker_lamp) - # TODO: alt signal usage may be described by cp.vl['BLINKERS']['USE_ALT_LAMP'] - left_blinker_sig, right_blinker_sig = "LEFT_LAMP", "RIGHT_LAMP" - if self.CP.carFingerprint == CAR.HYUNDAI_KONA_EV_2ND_GEN: - left_blinker_sig, right_blinker_sig = "LEFT_LAMP_ALT", "RIGHT_LAMP_ALT" - ret.leftBlinker, ret.rightBlinker = self.update_blinker_from_lamp(50, cp.vl["BLINKERS"][left_blinker_sig], - cp.vl["BLINKERS"][right_blinker_sig]) if self.CP.enableBsm: - ret.leftBlindspot = cp.vl["BLINDSPOTS_REAR_CORNERS"]["FL_INDICATOR"] != 0 - ret.rightBlindspot = cp.vl["BLINDSPOTS_REAR_CORNERS"]["FR_INDICATOR"] != 0 + if self.cp_bsm is None: + if 442 in cp.seen_addresses: + self.cp_bsm = cp + print("######## BSM in ECAN") + elif 442 in cp_cam.seen_addresses: + self.cp_bsm = cp_cam + print("######## BSM in CAM") + else: + bsm_info = self.cp_bsm.vl["BLINDSPOTS_REAR_CORNERS"] + ret.leftBlindspot = (bsm_info["FL_INDICATOR"] + bsm_info["INDICATOR_LEFT_TWO"] + bsm_info["INDICATOR_LEFT_FOUR"]) > 0 + ret.rightBlindspot = (bsm_info["FR_INDICATOR"] + bsm_info["INDICATOR_RIGHT_TWO"] + bsm_info["INDICATOR_RIGHT_FOUR"]) > 0 # cruise state + if self.cruise_buttons_alt2 is not None: + cruise_button = self.cruise_buttons_alt2["CRUISE_BUTTONS"] + else: + cruise_button = cp.vl[self.cruise_btns_msg_canfd]["CRUISE_BUTTONS"] + if cruise_button in [Buttons.RES_ACCEL, Buttons.SET_DECEL] and self.CP.openpilotLongitudinalControl: + self.main_enabled = True # CAN FD cars enable on main button press, set available if no TCS faults preventing engagement - ret.cruiseState.available = cp.vl["TCS"]["ACCEnable"] == 0 + ret.cruiseState.available = self.main_enabled and self.controls_ready_count >= READY_COUNT_OK #cp.vl["TCS"]["ACCEnable"] == 0 + if self.CP.flags & HyundaiFlags.CAMERA_SCC.value: + self.MainMode_ACC = cp_cam.vl["SCC_CONTROL"]["MainMode_ACC"] == 1 + self.ACCMode = cp_cam.vl["SCC_CONTROL"]["ACCMode"] + self.LFA_ICON = cp_cam.vl["LFAHDA_CLUSTER"]["HDA_LFA_SymSta"] + if self.CP.openpilotLongitudinalControl: # These are not used for engage/disengage since openpilot keeps track of state using the buttons ret.cruiseState.enabled = cp.vl["TCS"]["ACC_REQ"] == 1 ret.cruiseState.standstill = False + if self.MainMode_ACC or self.main_enabled: + self.main_enabled = True else: cp_cruise_info = cp_cam if self.CP.flags & HyundaiFlags.CANFD_CAMERA_SCC else cp ret.cruiseState.enabled = cp_cruise_info.vl["SCC_CONTROL"]["ACCMode"] in (1, 2) - ret.cruiseState.standstill = cp_cruise_info.vl["SCC_CONTROL"]["CRUISE_STANDSTILL"] == 1 + if cp_cruise_info.vl["SCC_CONTROL"]["MainMode_ACC"] == 1: # carrot + ret.cruiseState.available = self.main_enabled = True + ret.pcmCruiseGap = int(np.clip(cp_cruise_info.vl["SCC_CONTROL"]["DISTANCE_SETTING"], 1, 4)) + ret.cruiseState.standstill = cp_cruise_info.vl["SCC_CONTROL"]["InfoDisplay"] >= 4 ret.cruiseState.speed = cp_cruise_info.vl["SCC_CONTROL"]["VSetDis"] * speed_factor - self.cruise_info = copy.copy(cp_cruise_info.vl["SCC_CONTROL"]) + ret.brakeHoldActive = cp.vl["ESP_STATUS"]["AUTO_HOLD"] == 1 and cp_cruise_info.vl["SCC_CONTROL"]["ACCMode"] not in (1, 2) + + speed_limit_cam = False + corner = False + corner_infos = [info for info in (self.adrv_0x1ea, self.ccnc_0x162) if info is not None] + if corner_infos: + def corner_max(signal): + return max(info[signal] for info in corner_infos) + + ret.leftLongDist = self.lf_distance = corner_max("LF_DETECT_DISTANCE") + ret.rightLongDist = self.rf_distance = corner_max("RF_DETECT_DISTANCE") + self.lr_distance = corner_max("LR_DETECT_DISTANCE") + self.rr_distance = corner_max("RR_DETECT_DISTANCE") + ret.leftLatDist = corner_max("LF_DETECT_LATERAL") + ret.rightLatDist = corner_max("RF_DETECT_LATERAL") + ret.leftRearLongDist = self.lr_distance + ret.rightRearLongDist = self.rr_distance + ret.leftRearLatDist = corner_max("LR_DETECT_LATERAL") + ret.rightRearLatDist = corner_max("RR_DETECT_LATERAL") + corner = True + if corner: + raw_corner_radar_enabled = ( + self.op_params.get_int("EnableCornerRadar") > 0 and + bool(self.CP.extFlags & (HyundaiExtFlags.CORNER_RADAR_OBJECTS_235.value | + HyundaiExtFlags.CORNER_RADAR_OBJECTS_180.value)) + ) + left_front_block = (not raw_corner_radar_enabled) and 0 < ret.leftLongDist < 7.0 + right_front_block = (not raw_corner_radar_enabled) and 0 < ret.rightLongDist < 7.0 + rear_block_dist = 5.0 if raw_corner_radar_enabled else 7.0 + left_rear_block = 0 < self.lr_distance < rear_block_dist + right_rear_block = 0 < self.rr_distance < rear_block_dist + left_block = left_front_block or left_rear_block + right_block = right_front_block or right_rear_block + if left_block: + ret.leftBlindspot = True + if right_block: + ret.rightBlindspot = True + + if self.hda_info_4a3 is not None: + speedLimit = self.hda_info_4a3["SPEED_LIMIT"] + if not self.is_metric: + speedLimit *= CV.MPH_TO_KPH + ret.speedLimit = speedLimit if speedLimit < 255 else 0 + if int(self.hda_info_4a3["MapSource"]) == 2: + speed_limit_cam = True + + if self.time_zone == "UTC": + country_code = int(self.hda_info_4a3["CountryCode"]) + self.time_zone = ZoneInfo(NUMERIC_TO_TZ.get(country_code, "UTC")) + + ret.gearStep = cp.vl["GEAR"]["GEAR_STEP"] if self.GEAR else 0 + if 1 <= ret.gearStep <= 8 and ret.gearShifter == GearShifter.unknown: + ret.gearShifter = GearShifter.drive + ret.gearStep = cp.vl["GEAR_ALT"]["GEAR_STEP"] if self.GEAR_ALT else ret.gearStep + + lane_info = self.cam_0x2a4 if self.cam_0x2a4 is not None else self.cam_0x362 + + if lane_info is not None: + left_lane_prob = lane_info["LEFT_LANE_PROB"] + right_lane_prob = lane_info["RIGHT_LANE_PROB"] + left_lane_type = lane_info["LEFT_LANE_TYPE"] # 0: dashed, 1: solid, 2: undecided, 3: road edge, 4: DLM Inner Solid, 5: DLM InnerDashed, 6:DLM Inner Undecided, 7: Botts Dots, 8: Barrier + right_lane_type = lane_info["RIGHT_LANE_TYPE"] + left_lane_color = lane_info["LEFT_LANE_COLOR"] # 0: none, 1: white, 2: yellow, 3: blue + right_lane_color = lane_info["RIGHT_LANE_COLOR"] + left_lane_info = left_lane_color * 10 + left_lane_type + right_lane_info = right_lane_color * 10 + right_lane_type + ret.leftLaneLine = left_lane_info + ret.rightLaneLine = right_lane_info # Manual Speed Limit Assist is a feature that replaces non-adaptive cruise control on EV CAN FD platforms. # It limits the vehicle speed, overridable by pressing the accelerator past a certain point. # The car will brake, but does not respect positive acceleration commands in this mode # TODO: find this message on ICE & HYBRID cars + cruise control signals (if exists) if self.CP.flags & HyundaiFlags.EV: - ret.cruiseState.nonAdaptive = cp.vl["MANUAL_SPEED_LIMIT_ASSIST"]["MSLA_ENABLED"] == 1 + if self.manual_speed_limit_assist is not None: + #ret.cruiseState.nonAdaptive = cp.vl["MANUAL_SPEED_LIMIT_ASSIST"]["MSLA_ENABLED"] == 1 + ret.cruiseState.nonAdaptive = self.manual_speed_limit_assist["MSLA_ENABLED"] == 1 + + if self.LOCAL_TIME and self.time_zone != "UTC": + lt = cp.vl["LOCAL_TIME"] + y, m, d, H, M, S = int(lt["YEAR"]) + 2000, int(lt["MONTH"]), int(lt["DATE"]), int(lt["HOURS"]), int(lt["MINUTES"]), int(lt["SECONDS"]) + try: + dt_local = datetime(y, m, d, H, M, S, tzinfo=self.time_zone) + ret.datetime = int(dt_local.timestamp() * 1000) + except: + #print(f"Error parsing local time: {y}-{m}-{d} {H}:{M}:{S} in {self.time_zone}") + pass prev_cruise_buttons = self.cruise_buttons[-1] + #self.cruise_buttons.extend(cp.vl_all[self.cruise_btns_msg_canfd]["CRUISE_BUTTONS"]) + #carrot {{ + + if self.cruise_buttons_alt2 is not None: + if int(self.cruise_buttons_alt2.get("LFA_BTN", 0)) == 1: + cruise_button = [Buttons.LFA_BUTTON] + else: + v = int(self.cruise_buttons_alt2.get("CRUISE_BUTTONS", 0)) + cruise_button = [v if v < 5 else Buttons.NONE] + elif cp.vl[self.cruise_btns_msg_canfd]["LFA_BTN"]: + cruise_button = [Buttons.LFA_BUTTON] + else: + cruise_button = cp.vl_all[self.cruise_btns_msg_canfd]["CRUISE_BUTTONS"] + + self.cruise_buttons.extend(cruise_button) + # }} carrot + + + #if self.cruise_btns_msg_canfd in cp.vl: + # self.cruise_buttons_msg = copy.copy(cp.vl[self.cruise_btns_msg_canfd]) + """ + if self.cruise_btns_msg_canfd in cp.vl: #carrot + if not cp.vl[self.cruise_btns_msg_canfd]["CRUISE_BUTTONS"]: + pass + #print("empty cruise btns...") + else: + self.cruise_buttons_msg = copy.copy(cp.vl[self.cruise_btns_msg_canfd]) + """ prev_main_buttons = self.main_buttons[-1] - prev_lda_button = self.lda_button - self.cruise_buttons.extend(cp.vl_all[self.cruise_btns_msg_canfd]["CRUISE_BUTTONS"]) - self.main_buttons.extend(cp.vl_all[self.cruise_btns_msg_canfd]["ADAPTIVE_CRUISE_MAIN_BTN"]) - self.lda_button = cp.vl[self.cruise_btns_msg_canfd]["LDA_BTN"] + #self.cruise_buttons.extend(cp.vl_all[self.cruise_btns_msg_canfd]["CRUISE_BUTTONS"]) + if self.cruise_buttons_alt2 is not None: + self.main_buttons.extend([1 if int(self.cruise_buttons_alt2.get("CRUISE_BUTTONS", 0)) == 8 else 0]) + else: + adaptive_main = cp.vl_all[self.cruise_btns_msg_canfd]["ADAPTIVE_CRUISE_MAIN_BTN"] + normal_main = cp.vl_all[self.cruise_btns_msg_canfd]["NORMAL_CRUISE_MAIN_BTN"] + self.main_buttons.extend(int(adaptive or normal) for adaptive, normal in zip(adaptive_main, normal_main, strict=True)) + if self.main_buttons[-1] != prev_main_buttons and not self.main_buttons[-1]: # and self.CP.openpilotLongitudinalControl: #carrot + self.main_enabled = not self.main_enabled + print("main_enabled = {}".format(self.main_enabled)) self.buttons_counter = cp.vl[self.cruise_btns_msg_canfd]["COUNTER"] ret.accFaulted = cp.vl["TCS"]["ACCEnable"] != 0 # 0 ACC CONTROL ENABLED, 1-3 ACC CONTROL DISABLED - if self.CP.flags & HyundaiFlags.CANFD_LKA_STEERING: - self.lfa_block_msg = copy.copy(cp_cam.vl["CAM_0x362"] if self.CP.flags & HyundaiFlags.CANFD_LKA_STEERING_ALT - else cp_cam.vl["CAM_0x2a4"]) + speed_conv = CV.KPH_TO_MS # if self.is_metric else CV.MPH_TO_MS + cluSpeed = cp.vl["CRUISE_BUTTONS_ALT"]["CLU_SPEED"] + ret.vEgoCluster = cluSpeed * speed_conv # MPH단위에서도 KPH로 나오는듯.. + vEgoClu, aEgoClu = self.update_clu_speed_kf(ret.vEgoCluster) + ret.vCluRatio = (ret.vEgo / vEgoClu) if (vEgoClu > 3. and ret.vEgo > 3.) else 1.0 - AolCarState.update_aol_canfd(self, ret, can_parsers) + self.update_speed_limit(ret, speed_limit_cam) + + paddle_button = self.paddle_button_prev + if self.cruise_btns_msg_canfd == "CRUISE_BUTTONS": + paddle_button = 1 if cp.vl["CRUISE_BUTTONS"]["LEFT_PADDLE"] == 1 else 2 if cp.vl["CRUISE_BUTTONS"]["RIGHT_PADDLE"] == 1 else 0 + elif self.gear_msg_canfd == "GEAR": + paddle_button = 1 if cp.vl["GEAR"]["LEFT_PADDLE"] == 1 else 2 if cp.vl["GEAR"]["RIGHT_PADDLE"] == 1 else 0 ret.buttonEvents = [*create_button_events(self.cruise_buttons[-1], prev_cruise_buttons, BUTTONS_DICT), - *create_button_events(self.main_buttons[-1], prev_main_buttons, {1: ButtonType.mainCruise}), - *create_button_events(self.lda_button, prev_lda_button, {1: ButtonType.lkas})] + *create_button_events(paddle_button, self.paddle_button_prev, {1: ButtonType.paddleLeft, 2: ButtonType.paddleRight}), + *create_button_events(self.main_buttons[-1], prev_main_buttons, {1: ButtonType.mainCruise})] - if self.CP.openpilotLongitudinalControl: - ret.cruiseState.available = self.get_main_cruise(ret) + self.paddle_button_prev = paddle_button - CarStateExt.update_canfd_ext(self, ret, ret_iq, can_parsers, speed_factor) + return ret - ret.blockPcmEnable = not self.recent_button_interaction() - - return ret, ret_iq - - def get_can_parsers_canfd(self, CP): + def get_can_parsers_canfd(self, CP, CP_IQ=None): msgs = [] if not (CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS): # TODO: this can be removed once we add dynamic support to vl_all msgs += [ - # this message is 50Hz but the ECU frequently stops transmitting for ~0.5s - ("CRUISE_BUTTONS", 1) + ("CRUISE_BUTTONS", 50) ] + + CAN = CanBus(CP) + pt_parser = CANParser(DBC[CP.carFingerprint][Bus.pt], msgs, CAN.ECAN) + if CP.extFlags & HyundaiExtFlags.EV_MODE_STATUS_230: + # Display-only while the signal is fleet-validated: checksum and freshness + # gate the value without making a counter/alive fault disable controls. + pt_parser._add_message(EV_MODE_STATUS_MSG, math.nan, ignore_counter=True) + return { - Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], msgs, CanBus(CP).ECAN), - Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], [], CanBus(CP).CAM), + Bus.pt: pt_parser, + Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], [], CAN.CAM), + Bus.alt: CANParser(DBC[CP.carFingerprint][Bus.pt], [], CAN.ACAN), } - def get_can_parsers(self, CP, CP_IQ): + def get_can_parsers(self, CP, CP_IQ=None): if CP.flags & HyundaiFlags.CANFD: return self.get_can_parsers_canfd(CP) return { - Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], [], 0), + # EMS21 carries SCR_UREA_LEVEL on diesel platforms. NaN frequency makes + # it optional, so gasoline/EV platforms do not fail CAN validity. + Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], [("EMS21", math.nan)], 0), Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], [], 2), } diff --git a/iqdbc_repo/iqdbc/car/hyundai/fingerprints.py b/iqdbc_repo/iqdbc/car/hyundai/fingerprints.py index b518a49..6024002 100644 --- a/iqdbc_repo/iqdbc/car/hyundai/fingerprints.py +++ b/iqdbc_repo/iqdbc/car/hyundai/fingerprints.py @@ -1,10 +1,6 @@ -""" AUTO-FORMATTED USING iqdbc/car/debug/format_fingerprints.py, EDIT STRUCTURE THERE.""" from iqdbc.car.structs import CarParams from iqdbc.car.hyundai.values import CAR -from iqdbc.iqpilot.car.fingerprints_ext import merge_fw_versions -from iqdbc.iqpilot.car.hyundai.fingerprints_ext import FW_VERSIONS_EXT - Ecu = CarParams.Ecu # The existence of SCC or RDR in the fwdRadar FW usually determines the radar's function, @@ -12,6 +8,14 @@ Ecu = CarParams.Ecu FW_VERSIONS = { + CAR.HYUNDAI_AZERA_7TH_GEN: { + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00GN7_ RDR ----- 1.00 1.03 99110-N1000 ', + ], + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00GN7 MFC AT KOR LHD 1.00 1.03 99211-N1000 230322', + ], + }, CAR.HYUNDAI_AZERA_6TH_GEN: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00IG__ SCC F-CU- 1.00 1.00 99110-G8100 ', @@ -21,7 +25,6 @@ FW_VERSIONS = { ], (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00IG MFC AT MES LHD 1.00 1.04 99211-G8100 200511', - b'\xf1\x00IG MFC AT MES LHD 1.00 1.05 99211-G8100 210409', ], }, CAR.HYUNDAI_AZERA_HEV_6TH_GEN: { @@ -55,20 +58,13 @@ FW_VERSIONS = { ], (Ecu.eps, 0x7d4, None): [ b'\xf1\x00AE MDPS C 1.00 1.03 56310/G2300 4AEHC103', - b'\xf1\x00AE MDPS C 1.00 1.03 56310G2300\x00 4AEHC103', - b'\xf1\x00AE MDPS C 1.00 1.04 56310G2550\x00 4AEHC104', - b'\xf1\x00AE MDPS C 1.00 1.05 56310/G2500 4AEHC105', b'\xf1\x00AE MDPS C 1.00 1.05 56310/G2501 4AEHC105', b'\xf1\x00AE MDPS C 1.00 1.07 56310/G2301 4AEHC107', b'\xf1\x00AE MDPS C 1.00 1.07 56310/G2501 4AEHC107', - b'\xf1\x00AE MDPS C 1.00 1.07 56310/G2551 4AEHC107', ], (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00AEH MFC AT EUR LHD 1.00 1.00 95740-G2400 180222', b'\xf1\x00AEH MFC AT EUR LHD 1.00 1.00 95740-G7200 160418', - b'\xf1\x00AEH MFC AT EUR RHD 1.00 1.00 95740-G2200 161014', - b'\xf1\x00AEH MFC AT EUR RHD 1.00 1.00 95740-G2400 180222', - b'\xf1\x00AEH MFC AT USA LHD 1.00 1.00 95740-G2300 170703', b'\xf1\x00AEH MFC AT USA LHD 1.00 1.00 95740-G2400 180222', ], }, @@ -78,13 +74,11 @@ FW_VERSIONS = { b'\xf1\x00AEhe SCC H-CUP 1.01 1.01 96400-G2100 ', ], (Ecu.eps, 0x7d4, None): [ - b'\xf1\x00AE MDPS C 1.00 1.07 56310/G2201 4AEHC107', b'\xf1\x00AE MDPS C 1.00 1.07 56310/G2501 4AEHC107', b'\xf1\x00AE MDPS C 1.00 1.07 56310/G2551 4AEHC107', ], (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00AEP MFC AT AUS RHD 1.00 1.00 95740-G2400 180222', - b'\xf1\x00AEP MFC AT EUR LHD 1.00 1.00 95740-G2400 180222', b'\xf1\x00AEP MFC AT USA LHD 1.00 1.00 95740-G2400 180222', ], }, @@ -154,12 +148,10 @@ FW_VERSIONS = { CAR.HYUNDAI_IONIQ_HEV_2022: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00AEhe SCC F-CUP 1.00 1.00 99110-G2600 ', - b'\xf1\x00AEhe SCC F-CUP 1.00 1.02 99110-G2100 ', b'\xf1\x00AEhe SCC FHCUP 1.00 1.00 99110-G2600 ', b'\xf1\x00AEhe SCC FHCUP 1.00 1.02 99110-G2100 ', ], (Ecu.eps, 0x7d4, None): [ - b'\xf1\x00AE MDPS C 1.00 1.01 56310-XX000 4APHC101', b'\xf1\x00AE MDPS C 1.00 1.01 56310/G2510 4APHC101', b'\xf1\x00AE MDPS C 1.00 1.01 56310G2510\x00 4APHC101', ], @@ -173,7 +165,6 @@ FW_VERSIONS = { b'\xf1\x00DN8_ SCC F-CU- 1.00 1.00 99110-L0000 ', b'\xf1\x00DN8_ SCC F-CUP 1.00 1.00 99110-L0000 ', b'\xf1\x00DN8_ SCC F-CUP 1.00 1.02 99110-L1000 ', - b'\xf1\x00DN8_ SCC FHCU- 1.00 1.00 99110-L0000 ', b'\xf1\x00DN8_ SCC FHCUP 1.00 1.00 99110-L0000 ', b'\xf1\x00DN8_ SCC FHCUP 1.00 1.01 99110-L1000 ', b'\xf1\x00DN8_ SCC FHCUP 1.00 1.02 99110-L1000 ', @@ -232,6 +223,15 @@ FW_VERSIONS = { b'\xf1\x00LFF LKAS AT USA LHD 1.01 1.02 95740-C1000 E52', ], }, + CAR.HYUNDAI_SONATA_2024: { + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00DN8_ RDR ----- 1.00 1.00 99110-L1800 ', + ], + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00DN8 MFC AT KOR LHD 1.00 1.01 99211-L1800 230512', + b'\xf1\x00DN8 MFC AT USA LHD 1.00 1.01 99211-L1800 230512', + ], + }, CAR.HYUNDAI_TUCSON: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00TL__ FCA F-CUP 1.00 1.01 99110-D3500 ', @@ -293,7 +293,6 @@ FW_VERSIONS = { b'\xf1\x00TM ESC \x04 101 \x08\x04 58910-S2GA0', b'\xf1\x00TM ESC \x04 102!\x04\x05 58910-S2GA0', b'\xf1\x00TM ESC \x04 103"\x07\x08 58910-S2GA0', - b'\xf1\x00TM ESC \x1b 102 \x08\x08 58910-S1DA0', b'\xf1\x00TM ESC \x1e 102 \x08\x08 58910-S1DA0', b'\xf1\x00TM ESC 103!\x030 58910-S1MA0', ], @@ -301,7 +300,6 @@ FW_VERSIONS = { b'\xf1\x00TM MDPS C 1.00 1.01 56310-S1AB0 4TSDC101', b'\xf1\x00TM MDPS C 1.00 1.01 56310-S1EB0 4TSDC101', b'\xf1\x00TM MDPS C 1.00 1.02 56370-S2AA0 0B19', - b'\xf1\x00TM MDPS R 1.00 1.05 57700-S1500 4TSDP105', ], (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00TM MFC AT EUR LHD 1.00 1.03 99211-S1500 210224', @@ -367,7 +365,6 @@ FW_VERSIONS = { }, CAR.KIA_STINGER: { (Ecu.fwdRadar, 0x7d0, None): [ - b'\xf1\x00CK__ SCC FHCUP 1.00 1.02 96400-J5000 ', b'\xf1\x00CK__ SCC F_CUP 1.00 1.01 96400-J5000 ', b'\xf1\x00CK__ SCC F_CUP 1.00 1.01 96400-J5100 ', b'\xf1\x00CK__ SCC F_CUP 1.00 1.02 96400-J5100 ', @@ -383,7 +380,6 @@ FW_VERSIONS = { ], (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00CK MFC AT EUR LHD 1.00 1.03 95740-J5000 170822', - b'\xf1\x00CK MFC AT KOR LHD 1.00 1.04 95740-J5000 180504', b'\xf1\x00CK MFC AT USA LHD 1.00 1.03 95740-J5000 170822', b'\xf1\x00CK MFC AT USA LHD 1.00 1.04 95740-J5000 180504', ], @@ -400,7 +396,6 @@ FW_VERSIONS = { b'\xf1\x00CK MDPS R 1.00 5.03 57700-J5320 4C2VL503', b'\xf1\x00CK MDPS R 1.00 5.03 57700-J5380 4C2VR503', b'\xf1\x00CK MDPS R 1.00 5.03 57700-J5520 4C4VL503', - b'\xf1\x00CK MDPS R 1.00 5.04 57700-J5320 4C2VL504', b'\xf1\x00CK MDPS R 1.00 5.04 57700-J5520 4C4VL504', ], (Ecu.fwdCamera, 0x7c4, None): [ @@ -442,7 +437,6 @@ FW_VERSIONS = { b'\xf1\x00LX ESC \x0b 104 \x10\x13 58910-S8330', b'\xf1\x00LX ESC \x0b 104 \x10\x16 58910-S8360', b'\xf1\x00ON ESC \x01 101\x19\t\x08 58910-S9360', - b'\xf1\x00ON ESC \x01 103$\x04\x08 58910-S9360', b'\xf1\x00ON ESC \x0b 100\x18\x12\x18 58910-S9360', b'\xf1\x00ON ESC \x0b 101\x19\t\x05 58910-S9320', b'\xf1\x00ON ESC \x0b 101\x19\t\x08 58910-S9360', @@ -648,6 +642,14 @@ FW_VERSIONS = { b'\xf1\x00DL3HMFC AT KOR LHD 1.00 1.04 99210-L2000 210527', ], }, + CAR.KIA_K5_DL3_24_HEV: { # (DL3) + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00DL3HMFC AT KOR LHD 1.00 1.02 99210-L2500 230911' + ], + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00DL3_ RDR ----- 1.00 1.01 99110-L2500 ', + ], + }, CAR.HYUNDAI_KONA_EV: { (Ecu.abs, 0x7d1, None): [ b'\xf1\x00OS IEB \x01 212 \x11\x13 58520-K4000', @@ -703,7 +705,6 @@ FW_VERSIONS = { b'\xf1\x00OSP MDPS C 1.00 1.02 56310-K4271 4OEPC102', b'\xf1\x00OSP MDPS C 1.00 1.02 56310/K4271 4OEPC102', b'\xf1\x00OSP MDPS C 1.00 1.02 56310/K4970 4OEPC102', - b'\xf1\x00OSP MDPS C 1.00 1.02 56310/K4971 4OEPC102', b'\xf1\x00OSP MDPS C 1.00 1.02 56310K4260\x00 4OEPC102', b'\xf1\x00OSP MDPS C 1.00 1.02 56310K4261\x00 4OEPC102', b'\xf1\x00OSP MDPS C 1.00 1.02 56310K4971\x00 4OEPC102', @@ -720,6 +721,14 @@ FW_VERSIONS = { b'\xf1\x00SX2EMFC AT KOR LHD 1.00 1.00 99211-BF000 230410', ], }, + CAR.HYUNDAI_KONA_HEV_2ND_GEN: { + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00SX2HMFC AT EUR RHD 1.00 1.04 99211-BE000 231010', + ], + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00SX2_ RDR ----- 1.00 1.02 99110-BE500 ', + ], + }, CAR.KIA_NIRO_EV: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00DEev SCC F-CUP 1.00 1.00 99110-Q4000 ', @@ -737,14 +746,11 @@ FW_VERSIONS = { b'\xf1\x00DE MDPS C 1.00 1.04 56310Q4100\x00 4DEEC104', b'\xf1\x00DE MDPS C 1.00 1.05 56310Q4000\x00 4DEEC105', b'\xf1\x00DE MDPS C 1.00 1.05 56310Q4100\x00 4DEEC105', - b'\xf1\x00DE MDPS C 1.00 1.05 56310Q4150\x00 4DEEC105', - b'\xf1\x00DE MDPS C 1.00 1.05 56310Q4200\x00 4DEEC105', ], (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00DEE MFC AT EUR LHD 1.00 1.00 99211-Q4000 191211', b'\xf1\x00DEE MFC AT EUR LHD 1.00 1.00 99211-Q4100 200706', b'\xf1\x00DEE MFC AT EUR LHD 1.00 1.03 95740-Q4000 180821', - b'\xf1\x00DEE MFC AT EUR RHD 1.00 1.00 99211-Q4000 191211', b'\xf1\x00DEE MFC AT KOR LHD 1.00 1.02 95740-Q4000 180705', b'\xf1\x00DEE MFC AT KOR LHD 1.00 1.03 95740-Q4000 180821', b'\xf1\x00DEE MFC AT USA LHD 1.00 1.00 99211-Q4000 191211', @@ -756,13 +762,9 @@ FW_VERSIONS = { CAR.KIA_NIRO_EV_2ND_GEN: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00SG2_ RDR ----- 1.00 1.01 99110-AT000 ', - b'\xf1\x00SG__ RDR ----- 1.00 1.00 99110-AT200 ', ], (Ecu.fwdCamera, 0x7c4, None): [ - b'\xf1\x00SG2EMFC AT EUR LHD 1.00 1.00 99211-AT200 240315', b'\xf1\x00SG2EMFC AT EUR LHD 1.01 1.09 99211-AT000 220801', - b'\xf1\x00SG2EMFC AT USA LHD 1.00 1.00 99211-AT100 230216', - b'\xf1\x00SG2EMFC AT USA LHD 1.00 1.00 99211-AT200 240401', b'\xf1\x00SG2EMFC AT USA LHD 1.01 1.09 99211-AT000 220801', ], }, @@ -866,11 +868,9 @@ FW_VERSIONS = { CAR.KIA_OPTIMA_H_G4_FL: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00JFhe SCC FHCUP 1.00 1.01 99110-A8500 ', - b'\xf1\x00JFhe SCC FHCUP 1.00 1.03 99110-A8500 ', ], (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00JFH MFC AT KOR LHD 1.00 1.01 95895-A8200 180323', - b'\xf1\x00JFH MFC AT KOR LHD 1.00 1.04 95895-A8200 181217', ], }, CAR.HYUNDAI_ELANTRA: { @@ -930,7 +930,6 @@ FW_VERSIONS = { b'\xf1\x00CN7 MFC AT USA LHD 1.00 1.06 99210-AA000 220111', b'\xf1\x00CN7 MFC AT USA LHD 1.00 1.07 99210-AA000 220426', b'\xf1\x00CN7 MFC AT USA LHD 1.00 1.08 99210-AA000 220728', - b'\xf1\x00CN7 MFC AT USA LHD 1.00 1.09 99210-AA000 221108', ], (Ecu.abs, 0x7d1, None): [ b'\xf1\x00CN ESC \t 101 \x10\x03 58910-AB800', @@ -998,7 +997,6 @@ FW_VERSIONS = { }, CAR.KIA_SORENTO: { (Ecu.fwdCamera, 0x7c4, None): [ - b'\xf1\x00UMP LKAS AT AUS RHD 1.00 1.00 96400-C6550 S30', b'\xf1\x00UMP LKAS AT KOR LHD 1.00 1.00 95740-C5550 S30', b'\xf1\x00UMP LKAS AT USA LHD 1.00 1.00 95740-C6550 d00', b'\xf1\x00UMP LKAS AT USA LHD 1.01 1.01 95740-C6550 d01', @@ -1032,6 +1030,14 @@ FW_VERSIONS = { b'\xf1\x00CV1 MFC AT USA LHD 1.00 1.06 99210-CV000 220328', ], }, + CAR.KIA_EV6_PE: { # (CV1) + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00CV__ RDR ----- 1.00 1.01 99110-CV500 ', + ], + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00CV MFC AT KOR LHD 1.00 1.01 99210-CV500 240405', + ], + }, CAR.HYUNDAI_IONIQ_5: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00NE1_ RDR ----- 1.00 1.00 99110-GI000 ', @@ -1042,7 +1048,6 @@ FW_VERSIONS = { b'\xf1\x00NE1 MFC AT EUR LHD 1.00 1.00 99211-GI100 230915', b'\xf1\x00NE1 MFC AT EUR LHD 1.00 1.01 99211-GI010 211007', b'\xf1\x00NE1 MFC AT EUR LHD 1.00 1.01 99211-GI100 240110', - b'\xf1\x00NE1 MFC AT EUR LHD 1.00 1.02 99211-GI010 211206', b'\xf1\x00NE1 MFC AT EUR LHD 1.00 1.03 99211-GI010 220401', b'\xf1\x00NE1 MFC AT EUR LHD 1.00 1.06 99211-GI000 210813', b'\xf1\x00NE1 MFC AT EUR LHD 1.00 1.06 99211-GI010 230110', @@ -1056,13 +1061,29 @@ FW_VERSIONS = { b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.00 99211-GI020 230719', b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.00 99211-GI100 230915', b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.01 99211-GI010 211007', - b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.01 99211-GI100 240110', b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.02 99211-GI010 211206', b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.03 99211-GI010 220401', b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.05 99211-GI010 220614', b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.06 99211-GI010 230110', ], }, + CAR.HYUNDAI_IONIQ_5_PE: { # (NE1) + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00NE__ RDR ----- 1.00 1.00 99110-GI500 ', + ], + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00NE MFC AT KOR LHD 1.00 1.02 99211-GI500 240221', + ], + }, + CAR.HYUNDAI_IONIQ_5_N: { + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00NE1N RDR ----- 1.00 1.00 99110-NI000 ', + ], + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00NE1NMFC AT KOR LHD 1.00 1.04 99211-NI000 231219', + b'\xf1\x00NE1NMFC AT USA LHD 1.00 1.04 99211-NI000 231219', + ], + }, CAR.HYUNDAI_IONIQ_6: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00CE__ RDR ----- 1.00 1.01 99110-KL000 ', @@ -1076,9 +1097,16 @@ FW_VERSIONS = { b'\xf1\x00CE MFC AT USA LHD 1.00 1.06 99211-KL000 230915', ], }, + CAR.HYUNDAI_IONIQ_9: { + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00MEev RDR ----- 1.00 1.00 99110-GO000 ', + ], + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00ME MFC AT KOR LHD 1.00 1.00 99211-GO000 241007', + ], + }, CAR.HYUNDAI_TUCSON_4TH_GEN: { (Ecu.fwdCamera, 0x7c4, None): [ - b'\xf1\x00NX4 FR_CMR AT CAN LHD 1.00 1.00 99211-N9220 14K', b'\xf1\x00NX4 FR_CMR AT CAN LHD 1.00 1.00 99211-N9260 14Y', b'\xf1\x00NX4 FR_CMR AT CAN LHD 1.00 1.01 99211-N9100 14A', b'\xf1\x00NX4 FR_CMR AT EUR LHD 1.00 1.00 99211-N9220 14K', @@ -1090,14 +1118,12 @@ FW_VERSIONS = { b'\xf1\x00NX4 FR_CMR AT USA LHD 1.00 1.00 99211-N9260 14Y', b'\xf1\x00NX4 FR_CMR AT USA LHD 1.00 1.01 99211-N9100 14A', b'\xf1\x00NX4 FR_CMR AT USA LHD 1.00 1.01 99211-N9240 14T', - b'\xf1\x00NX4 FR_CMR AT EUR LHD 1.00 1.00 99211-N9240 14Q', ], (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00NX4__ 1.00 1.00 99110-N9100 ', b'\xf1\x00NX4__ 1.00 1.01 99110-N9000 ', b'\xf1\x00NX4__ 1.00 1.02 99110-N9000 ', b'\xf1\x00NX4__ 1.01 1.00 99110-N9100 ', - b'\xf1\x00NX4__ 1.01 1.02 99110-N9000 ', ], }, CAR.HYUNDAI_SANTA_CRUZ_1ST_GEN: { @@ -1115,13 +1141,11 @@ FW_VERSIONS = { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00NQ5 FR_CMR AT AUS RHD 1.00 1.00 99211-P1040 663', b'\xf1\x00NQ5 FR_CMR AT EUR LHD 1.00 1.00 99211-P1040 663', - b'\xf1\x00NQ5 FR_CMR AT GEN LHD 1.00 1.00 99211-P1040 663', b'\xf1\x00NQ5 FR_CMR AT GEN LHD 1.00 1.00 99211-P1060 665', b'\xf1\x00NQ5 FR_CMR AT USA LHD 1.00 1.00 99211-P1030 662', b'\xf1\x00NQ5 FR_CMR AT USA LHD 1.00 1.00 99211-P1040 663', b'\xf1\x00NQ5 FR_CMR AT USA LHD 1.00 1.00 99211-P1060 665', b'\xf1\x00NQ5 FR_CMR AT USA LHD 1.00 1.00 99211-P1070 690', - b'\xf1\x00NQ5 FR_CMR AT USA LHD 1.00 1.01 99211-P1060 680', ], (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00NQ5__ 1.00 1.02 99110-P1000 ', @@ -1134,14 +1158,11 @@ FW_VERSIONS = { CAR.GENESIS_GV70_1ST_GEN: { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00JK1 MFC AT CAN LHD 1.00 1.02 99211-IY000 230627', - b'\xf1\x00JK1 MFC AT CAN LHD 1.00 1.04 99211-AR100 210204', b'\xf1\x00JK1 MFC AT USA LHD 1.00 1.01 99211-AR200 220125', b'\xf1\x00JK1 MFC AT USA LHD 1.00 1.01 99211-AR300 220125', - b'\xf1\x00JK1 MFC AT USA LHD 1.00 1.02 99211-IY000 230627', b'\xf1\x00JK1 MFC AT USA LHD 1.00 1.04 99211-AR000 210204', ], (Ecu.fwdRadar, 0x7d0, None): [ - b'\xf1\x00JK1_ SCC ----- 1.00 1.02 99110-AR100 ', b'\xf1\x00JK1_ SCC FHCUP 1.00 1.00 99110-AR200 ', b'\xf1\x00JK1_ SCC FHCUP 1.00 1.00 99110-AR300 ', b'\xf1\x00JK1_ SCC FHCUP 1.00 1.00 99110-IY000 ', @@ -1158,6 +1179,24 @@ FW_VERSIONS = { b'\xf1\x00JKev SCC ----- 1.00 1.01 99110-DS000 ', ], }, + + CAR.HYUNDAI_NEXO_1ST_GEN: { + (Ecu.abs, 0x7d1, None): [ + b'\xf1\x00FE IEB \x01 312 \x11\x13 58520-M5000', + ], + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00FE MFC AT KOR LHD 1.00 1.00 99211-M5100 201218', + b'\xf1\x00FE MFC AT KOR LHD 1.00 1.02 99211-M5100 220405', + ], + (Ecu.eps, 0x7d4, None): [ + b'\xf1\x00FE MDPS C 1.00 1.05 56340-M5000 9903', + b'\xf1\x00FE MDPS C 1.00 1.06 56340-M5000 1625', + ], + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00FE__ SCC FHCUP 1.00 1.05 99110-M5000 ', + ], + }, + CAR.GENESIS_GV60_EV_1ST_GEN: { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00JW1 MFC AT AUS RHD 1.00 1.03 99211-CU100 221118', @@ -1189,7 +1228,6 @@ FW_VERSIONS = { b'\xf1\x00MQ4HMFC AT KOR LHD 1.00 1.12 99210-P2000 230331', b'\xf1\x00MQ4HMFC AT USA LHD 1.00 1.10 99210-P2000 210406', b'\xf1\x00MQ4HMFC AT USA LHD 1.00 1.11 99210-P2000 211217', - b'\xf1\x00MQ4HMFC AT USA LHD 1.00 1.12 99210-P2000 230331', ], (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00MQhe SCC FHCUP 1.00 1.04 99110-P4000 ', @@ -1250,40 +1288,15 @@ FW_VERSIONS = { b'\xf1\x00US4_ RDR ----- 1.00 1.00 99110-CG000 ', ], }, - CAR.HYUNDAI_NEXO_1ST_GEN: { - (Ecu.abs, 0x7d1, None): [ - b'\xf1\x00FE IEB \x01 312 \x11\x13 58520-M5000', + CAR.KIA_EV9: { # (MV) + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00MV__ RDR ----- 1.00 1.02 99110-DO700 ', + b'\xf1\x00MV__ RDR ----- 1.00 1.02 99110-DO000 ' ], (Ecu.fwdCamera, 0x7c4, None): [ - b'\xf1\x00FE MFC AT KOR LHD 1.00 1.00 99211-M5100 201218', - ], - (Ecu.eps, 0x7d4, None): [ - b'\xf1\x00FE MDPS C 1.00 1.05 56340-M5000 9903', - ], - (Ecu.fwdRadar, 0x7d0, None): [ - b'\xf1\x00FE__ SCC FHCUP 1.00 1.05 99110-M5000 ', - ], - }, - CAR.HYUNDAI_KONA_2022: { - (Ecu.fwdCamera, 0x7c4, None): [ - b'\xf1\x00OSP LKA AT CND LHD 1.00 1.04 99211-J9200 904', - b'\xf1\x00OSP LKA AT USA LHD 1.00 1.04 99211-J9200 904', - ], - (Ecu.eps, 0x7d4, None): [ - b'\xf1\x00OSP MDPS C 1.00 1.04 56310/J9290 4OPCC104', - b'\xf1\x00OSP MDPS C 1.00 1.04 56310/J9291 4OPCC104', - b'\xf1\x00OSP MDPS C 1.00 1.04 56310J9291\x00 4OPCC104', - ], - (Ecu.fwdRadar, 0x7d0, None): [ - b'\xf1\x00YB__ FCA ----- 1.00 1.01 99110-J9000 \x00\x00\x00', - ], - (Ecu.transmission, 0x7e1, None): [ - b'\xf1\x00HT6WA280BLHT6VA650A1COS4N20NS1\x00\x00\x00\x00\x00\x00\x15\xf5\x87~', - b'\xf1\x00T01960BL T01E60A1 DOS2T16X4XE60NS4N\x90\xe6\xcb', - b'\xf1\x00T01G00BL T01I00A1 DOS2T16X2XI00NS0\x8c`\xff\xe7', - b'\xf1\x00T01G00BL T01I00A1 DOS2T16X4XI00NS0\x99L\xeeq', + b'\xf1\x00MV MFC AT KOR LHD 1.00 1.01 99211-DO000 230419', + b'\xf1\x00MV MFC AT USA LHD 1.00 1.02 99211-DO000 230616', + b'\xf1\x00MV MFC AT EUR LHD 1.00 1.02 99211-DO000 230616', ], }, } - -FW_VERSIONS = merge_fw_versions(FW_VERSIONS, FW_VERSIONS_EXT) diff --git a/iqdbc_repo/iqdbc/car/hyundai/hyundaican.py b/iqdbc_repo/iqdbc/car/hyundai/hyundaican.py index 2267e0c..f021118 100644 --- a/iqdbc_repo/iqdbc/car/hyundai/hyundaican.py +++ b/iqdbc_repo/iqdbc/car/hyundai/hyundaican.py @@ -1,21 +1,33 @@ +import copy import crcmod from iqdbc.car.hyundai.values import CAR, HyundaiFlags -from iqdbc.iqpilot.car.hyundai.escc import EnhancedSmartCruiseControl -from iqdbc.iqpilot.car.hyundai.lead_data_ext import CanLeadData - hyundai_checksum = crcmod.mkCrcFun(0x11D, initCrc=0xFD, rev=False, xorOut=0xdf) +def suppress_casper_ev_fca11_fault(values): + # CASPER EV can report transient FCA faults during camera-SCC handoff. + # Keep the copied FCA11 frame non-faulting without changing other cars. + fca_fault = values["FCA_Failinfo"] != 0 or values["FCA_Status"] == 3 + values["FCA_Failinfo"] = 0 -def _use_stock_scc_surrogates(CP) -> bool: - return CP.carFingerprint == CAR.HYUNDAI_PALISADE + if fca_fault: + values["FCA_Status"] = 2 + values["CF_VSM_Prefill"] = 0 + values["CF_VSM_HBACmd"] = 0 + values["CF_VSM_Warn"] = 0 + values["CF_VSM_BeltCmd"] = 0 + values["CR_VSM_DecCmd"] = 0 + values["FCA_CmdAct"] = 0 + values["FCA_StopReq"] = 0 + values["CF_VSM_DecCmdAct"] = 0 + return values def create_lkas11(packer, frame, CP, apply_torque, steer_req, torque_fault, lkas11, sys_warning, sys_state, enabled, left_lane, right_lane, - left_lane_depart, right_lane_depart, - lkas_icon): + left_lane_depart, right_lane_depart, is_ldws_car): + values = {s: lkas11[s] for s in [ "CF_Lkas_LdwsActivemode", "CF_Lkas_LdwsSysState", @@ -34,7 +46,7 @@ def create_lkas11(packer, frame, CP, apply_torque, steer_req, "CF_Lkas_LdwsOpt_USM", ]} values["CF_Lkas_LdwsSysState"] = sys_state - values["CF_Lkas_SysWarning"] = 3 if sys_warning else 0 + values["CF_Lkas_SysWarning"] = 0 # 3 if sys_warning else 0 values["CF_Lkas_LdwsLHWarning"] = left_lane_depart values["CF_Lkas_LdwsRHWarning"] = right_lane_depart values["CR_Lkas_StrToqReq"] = apply_torque @@ -42,16 +54,10 @@ def create_lkas11(packer, frame, CP, apply_torque, steer_req, values["CF_Lkas_ToiFlt"] = torque_fault # seems to allow actuation on CR_Lkas_StrToqReq values["CF_Lkas_MsgCount"] = frame % 0x10 - if CP.carFingerprint in (CAR.HYUNDAI_SONATA, CAR.HYUNDAI_PALISADE, CAR.KIA_NIRO_EV, CAR.KIA_NIRO_HEV_2021, CAR.KIA_NIRO_PHEV_2022, CAR.HYUNDAI_SANTA_FE, - CAR.HYUNDAI_IONIQ_EV_2020, CAR.HYUNDAI_IONIQ_PHEV, CAR.KIA_SELTOS, CAR.HYUNDAI_ELANTRA_2021, CAR.GENESIS_G70_2020, - CAR.HYUNDAI_ELANTRA_HEV_2021, CAR.HYUNDAI_SONATA_HYBRID, CAR.HYUNDAI_KONA_EV, CAR.HYUNDAI_KONA_HEV, CAR.HYUNDAI_KONA_EV_2022, - CAR.HYUNDAI_SANTA_FE_2022, CAR.KIA_K5_2021, CAR.HYUNDAI_IONIQ_HEV_2022, CAR.HYUNDAI_SANTA_FE_HEV_2022, - CAR.HYUNDAI_SANTA_FE_PHEV_2022, CAR.KIA_STINGER_2022, CAR.KIA_K5_HEV_2020, CAR.KIA_CEED, - CAR.HYUNDAI_AZERA_6TH_GEN, CAR.HYUNDAI_AZERA_HEV_6TH_GEN, CAR.HYUNDAI_CUSTIN_1ST_GEN, CAR.HYUNDAI_KONA_2022, - CAR.KIA_CEED_PHEV_2022_NON_SCC, CAR.HYUNDAI_KONA_EV_NON_SCC, CAR.HYUNDAI_ELANTRA_2022_NON_SCC, - CAR.GENESIS_G70_2021_NON_SCC, CAR.KIA_SELTOS_2023_NON_SCC, CAR.HYUNDAI_BAYON_1ST_GEN_NON_SCC): + + if CP.flags & HyundaiFlags.SEND_LFA.value or CP.carFingerprint in (CAR.HYUNDAI_SANTA_FE): values["CF_Lkas_LdwsActivemode"] = int(left_lane) + (int(right_lane) << 1) - values["CF_Lkas_LdwsOpt_USM"] = 2 + values["CF_Lkas_LdwsOpt_USM"] = 0 if CP.carFingerprint in (CAR.KIA_RAY_EV) else 2 # FcwOpt_USM 5 = Orange blinking car + lanes # FcwOpt_USM 4 = Orange car + lanes @@ -59,16 +65,16 @@ def create_lkas11(packer, frame, CP, apply_torque, steer_req, # FcwOpt_USM 2 = Green car + lanes # FcwOpt_USM 1 = White car + lanes # FcwOpt_USM 0 = No car + lanes - values["CF_Lkas_FcwOpt_USM"] = lkas_icon + values["CF_Lkas_FcwOpt_USM"] = 2 if enabled else 1 # SysWarning 4 = keep hands on wheel # SysWarning 5 = keep hands on wheel (red) # SysWarning 6 = keep hands on wheel (red) + beep # Note: the warning is hidden while the blinkers are on - values["CF_Lkas_SysWarning"] = 4 if sys_warning else 0 + values["CF_Lkas_SysWarning"] = 0 #4 if sys_warning else 0 # Likely cars lacking the ability to show individual lane lines in the dash - elif CP.carFingerprint in (CAR.KIA_OPTIMA_G4, CAR.KIA_OPTIMA_G4_FL, CAR.HYUNDAI_KONA_NON_SCC): + elif CP.carFingerprint in (CAR.KIA_OPTIMA_G4, CAR.KIA_OPTIMA_G4_FL): # SysWarning 4 = keep hands on wheel + beep values["CF_Lkas_SysWarning"] = 4 if sys_warning else 0 @@ -76,7 +82,7 @@ def create_lkas11(packer, frame, CP, apply_torque, steer_req, # SysState 1-2 = white car + lanes # SysState 3 = green car + lanes, green steering wheel # SysState 4 = green car + lanes - values["CF_Lkas_LdwsSysState"] = lkas_icon + values["CF_Lkas_LdwsSysState"] = 3 if enabled else 1 values["CF_Lkas_LdwsOpt_USM"] = 2 # non-2 changes above SysState definition # these have no effect @@ -88,6 +94,11 @@ def create_lkas11(packer, frame, CP, apply_torque, steer_req, # Genesis and Optima fault when forwarding while engaged values["CF_Lkas_LdwsActivemode"] = 2 + if is_ldws_car: + values["CF_Lkas_LdwsOpt_USM"] = 3 + + values["CF_Lkas_Chksum"] = 0 + dat = packer.make_can_msg("LKAS11", 0, values)[1] if CP.flags & HyundaiFlags.CHECKSUM_CRC8: @@ -128,152 +139,265 @@ def create_clu11(packer, frame, clu11, button, CP): return packer.make_can_msg("CLU11", bus, values) -def create_lfahda_mfc(packer, enabled, lfa_icon): +def create_lfahda_mfc(packer, CC, blinking_signal): + activeCarrot = CC.hudControl.activeCarrot values = { - "LFA_Icon_State": lfa_icon, + "LFA_Icon_State": 2 if CC.latActive else 1 if CC.enabled else 0, + #"HDA_Active": 1 if activeCarrot >= 2 else 0, + #"HDA_Icon_State": 2 if activeCarrot == 3 and blinking_signal else 2 if activeCarrot >= 2 else 0, + "HDA_Icon_State": 0 if activeCarrot == 3 and blinking_signal else 2 if activeCarrot >= 1 else 0, + "HDA_VSetReq": 0, #set_speed_in_units if activeCarrot >= 2 else 0, + "HDA_USM" : 2, + "HDA_Icon_Wheel" : 1 if CC.latActive else 0, + #"HDA_Chime" : 1 if CC.latActive else 0, # comment for K9 chime, } return packer.make_can_msg("LFAHDA_MFC", 0, values) +def create_acc_commands_scc(packer, enabled, accel, jerk, idx, hud_control, set_speed, stopping, long_override, suppress_casper_ev_fca, CS, soft_hold_mode): + from iqdbc.car.hyundai.carcontroller import HyundaiJerk + cruise_available = CS.out.cruiseState.available + if CS.paddle_button_prev > 0: + cruise_available = False + soft_hold_active = CS.softHoldActive + soft_hold_info = soft_hold_active > 1 and enabled + #soft_hold_mode = 2 ## some cars can't enable while braking + long_enabled = enabled or (soft_hold_active > 0 and soft_hold_mode == 2) + stop_req = 1 if stopping or (soft_hold_active > 0 and soft_hold_mode == 2) else 0 + d = hud_control.leadDistance + objGap = 0 if d == 0 else 2 if d < 25 else 3 if d < 40 else 4 if d < 70 else 5 + objGap2 = 0 if objGap == 0 else 2 if hud_control.leadRelSpeed < -0.2 else 1 + + if long_enabled: + if jerk.carrot_cruise == 1: + long_enabled = False + accel = -0.5 + elif jerk.carrot_cruise == 2: + accel = jerk.carrot_cruise_accel + + if long_enabled: + scc12_acc_mode = 2 if long_override else 1 + scc14_acc_mode = 2 if long_override else 1 + if CS.out.brakeHoldActive: + scc12_acc_mode = 0 + scc14_acc_mode = 4 + elif CS.out.brakePressed: + scc12_acc_mode = 1 + scc14_acc_mode = 1 + else: + scc12_acc_mode = 0 + scc14_acc_mode = 4 + + warning_front = False -def create_acc_commands(packer, enabled, accel, upper_jerk, idx, lead_data: CanLeadData, - hud_control, set_speed, stopping, long_override, use_fca, CP, - main_cruise_enabled, tuning, ESCC: EnhancedSmartCruiseControl | None = None): commands = [] + if CS.scc11 is not None: + values = copy.copy(CS.scc11) + values["MainMode_ACC"] = 1 if cruise_available else 0 + values["TauGapSet"] = hud_control.leadDistanceBars + values["VSetDis"] = set_speed if enabled else 0 + values["AliveCounterACC"] = idx % 0x10 + values["SCCInfoDisplay"] = 3 if warning_front else 4 if soft_hold_info else 0 if enabled else 0 #2: 크루즈 선택, 3: 전방상황주의, 4: 출발준비 + values["ObjValid"] = 1 if hud_control.leadVisible else 0 + values["ACC_ObjStatus"] = 1 if hud_control.leadVisible else 0 + values["ACC_ObjLatPos"] = 0 + values["ACC_ObjRelSpd"] = hud_control.leadRelSpeed + values["ACC_ObjDist"] = int(hud_control.leadDistance) + values["DriverAlertDisplay"] = 0 + commands.append(packer.make_can_msg("SCC11", 0, values)) - def get_scc11_values(): - values = { - "MainMode_ACC": 1 if main_cruise_enabled else 0, - "TauGapSet": hud_control.leadDistanceBars, - "VSetDis": set_speed if enabled else 0, - "AliveCounterACC": idx % 0x10, - "ObjValid": int(lead_data.lead_visible), # close lead makes controls tighter - "ACC_ObjStatus": int(lead_data.lead_visible), # close lead makes controls tighter - "ACC_ObjLatPos": 0, - "ACC_ObjRelSpd": lead_data.lead_rel_speed, - "ACC_ObjDist": int(lead_data.lead_distance), # close lead makes controls tighter - } - if _use_stock_scc_surrogates(CP): - values["ObjValid"] = 1 - values["ACC_ObjStatus"] = 1 - values["ACC_ObjDist"] = 1 - return values + if CS.scc12 is not None: + values = copy.copy(CS.scc12) + values["ACCMode"] = scc12_acc_mode #2 if enabled and long_override else 1 if long_enabled else 0 + values["StopReq"] = stop_req + values["aReqRaw"] = accel + values["aReqValue"] = accel + values["ACCFailInfo"] = 0 - def get_scc12_values(): - scc12_values = { - "ACCMode": 2 if enabled and long_override else 1 if enabled else 0, - "StopReq": 1 if tuning.stopping else 0, - "aReqRaw": tuning.desired_accel, - "aReqValue": tuning.actual_accel, # stock ramps up and down respecting jerk limit until it reaches aReqRaw - "CR_VSM_Alive": idx % 0xF, - } + #values["DESIRED_DIST"] = CS.out.vEgo * 1.0 + 4.0 # TF: 1.0 + STOPDISTANCE 4.0 m로 가정함. - # show AEB disabled indicator on dash with SCC12 if not sending FCA messages. - # these signals also prevent a TCS fault on non-FCA cars with alpha longitudinal - if not use_fca: - scc12_values["CF_VSM_ConfMode"] = 1 - scc12_values["AEB_Status"] = 1 # AEB disabled - - # Since we have ESCC available, we can update SCC12 with ESCC values. - if ESCC and ESCC.enabled: - ESCC.update_scc12(scc12_values) - - return scc12_values - - def calculate_scc12_checksum(values): + values["CR_VSM_ChkSum"] = 0 + values["CR_VSM_Alive"] = idx % 0xF scc12_dat = packer.make_can_msg("SCC12", 0, values)[1] values["CR_VSM_ChkSum"] = 0x10 - sum(sum(divmod(i, 16)) for i in scc12_dat) % 0x10 - return values - def get_scc14_values(): - values = { - "ComfortBandUpper": tuning.comfort_band_upper, # stock usually is 0 but sometimes uses higher values - "ComfortBandLower": tuning.comfort_band_lower, # stock usually is 0 but sometimes uses higher values - "JerkUpperLimit": tuning.jerk_upper, # stock usually is 1.0 but sometimes uses higher values - "JerkLowerLimit": tuning.jerk_lower, # stock usually is 0.5 but sometimes uses higher values - "ACCMode": 2 if enabled and long_override else 1 if enabled else 4, # stock will always be 4 instead of 0 after first disengage - "ObjGap": lead_data.object_gap, # 5: >30, m, 4: 25-30 m, 3: 20-25 m, 2: < 20 m, 0: no lead - } - if not _use_stock_scc_surrogates(CP): - values["ObjDistStat"] = lead_data.object_rel_gap - return values + commands.append(packer.make_can_msg("SCC12", 0, values)) - def get_fca11_values(): - return { + if CS.scc14 is not None: + values = copy.copy(CS.scc14) + values["ComfortBandUpper"] = jerk.cb_upper + values["ComfortBandLower"] = jerk.cb_lower + values["JerkUpperLimit"] = jerk.jerk_u + values["JerkLowerLimit"] = jerk.jerk_l if long_enabled else 0 # for KONA test + values["ACCMode"] = scc14_acc_mode #2 if enabled and long_override else 1 if long_enabled else 4 # stock will always be 4 instead of 0 after first disengage + values["ObjGap"] = objGap #2 if hud_control.leadVisible else 0 # 5: >30, m, 4: 25-30 m, 3: 20-25 m, 2: < 20 m, 0: no lead + values["ObjDistStat"] = objGap2 + commands.append(packer.make_can_msg("SCC14", 0, values)) + + if CS.fca11 is not None and suppress_casper_ev_fca: # CASPER_EV의 경우 FCA11에서 fail이 간헐적 발생함.. 그냥막자.. 원인불명.. + values = suppress_casper_ev_fca11_fault(copy.copy(CS.fca11)) + fca11_dat = packer.make_can_msg("FCA11", 0, values)[1] + values["CR_FCA_ChkSum"] = hyundai_checksum(fca11_dat[:7]) + commands.append(packer.make_can_msg("FCA11", 0, values)) + # Only send FCA11 on cars where it exists on the bus + if False: #use_fca: + # note that some vehicles most likely have an alternate checksum/counter definition + # https://github.com/commaai/iqdbc/commit/9ddcdb22c4929baf310295e832668e6e7fcfa602 + fca11_values = { "CR_FCA_Alive": idx % 0xF, "PAINT1_Status": 1, "FCA_DrvSetStatus": 1, - "FCA_Status": 1, + "FCA_Status": 1, # AEB disabled } - - def calculate_fca11_checksum(values): - fca11_dat = packer.make_can_msg("FCA11", 0, values)[1] - values["CR_FCA_ChkSum"] = hyundai_checksum(fca11_dat[:7]) - return values - - scc11_values = get_scc11_values() - commands.append(packer.make_can_msg("SCC11", 0, scc11_values)) - - scc12_values = get_scc12_values() - scc12_values = calculate_scc12_checksum(scc12_values) - commands.append(packer.make_can_msg("SCC12", 0, scc12_values)) - - scc14_values = get_scc14_values() - commands.append(packer.make_can_msg("SCC14", 0, scc14_values)) - - # Only send FCA11 on cars where it exists on the bus - # On Camera SCC cars, FCA11 is not disabled, so we forward stock FCA11 back to the car forward hooks - # If we don't use ESCC since ESCC does not block FCA11 from stock radar - if use_fca and not ((CP.flags & HyundaiFlags.CAMERA_SCC) or (ESCC and ESCC.enabled)): - # note that some vehicles most likely have an alternate checksum/counter definition - # https://github.com/commaai/iqdbc/commit/9ddcdb22c4929baf310295e832668e6e7fcfa602 - fca11_values = get_fca11_values() - fca11_values = calculate_fca11_checksum(fca11_values) + fca11_dat = packer.make_can_msg("FCA11", 0, fca11_values)[1] + fca11_values["CR_FCA_ChkSum"] = hyundai_checksum(fca11_dat[:7]) commands.append(packer.make_can_msg("FCA11", 0, fca11_values)) return commands +def create_acc_opt_copy(CS, packer): + values = copy.copy(CS.scc13) + if values["NEW_SIGNAL_1"] == 255: + values["NEW_SIGNAL_1"] = 218 + values["NEW_SIGNAL_2"] = 0 + return packer.make_can_msg("SCC13", 0, CS.scc13) -def create_acc_opt(packer, CP, ESCC: EnhancedSmartCruiseControl | None = None): - """ - Creates SCC13 and FCA12. If ESCC is enabled, it will only create SCC13 since ESCC does not block FCA12. - :param packer: - :param ESCC: - :return: - """ +def create_acc_commands(packer, enabled, accel, jerk, idx, hud_control, set_speed, stopping, long_override, use_fca, CP, CS, soft_hold_mode): + from iqdbc.car.hyundai.carcontroller import HyundaiJerk + cruise_available = CS.out.cruiseState.available + soft_hold_active = CS.softHoldActive + soft_hold_info = soft_hold_active > 1 and enabled + #soft_hold_mode = 2 ## some cars can't enable while braking + long_enabled = enabled or (soft_hold_active > 0 and soft_hold_mode == 2) + stop_req = 1 if stopping or (soft_hold_active > 0 and soft_hold_mode == 2) else 0 + d = hud_control.leadDistance + objGap = 0 if d == 0 else 2 if d < 25 else 3 if d < 40 else 4 if d < 70 else 5 + objGap2 = 0 if objGap == 0 else 2 if hud_control.leadRelSpeed < -0.2 else 1 - def get_scc13_values(): - return { - "SCCDrvModeRValue": 2, - "SCC_Equip": 1, - "Lead_Veh_Dep_Alert_USM": 2, - } + if long_enabled: + scc12_acc_mode = 2 if long_override else 1 + scc14_acc_mode = 2 if long_override else 1 + if CS.out.brakeHoldActive: + scc12_acc_mode = 0 + scc14_acc_mode = 4 + elif CS.out.brakePressed: + scc12_acc_mode = 1 + scc14_acc_mode = 1 + else: + scc12_acc_mode = 0 + scc14_acc_mode = 4 - def get_fca12_values(): - return { - "FCA_DrvSetState": 2, - "FCA_USM": 1, # AEB disabled - } + warning_front = False commands = [] - scc13_values = get_scc13_values() - commands.append(packer.make_can_msg("SCC13", 0, scc13_values)) + scc11_values = { + "MainMode_ACC": 1 if cruise_available else 0, + "TauGapSet": hud_control.leadDistanceBars, + "VSetDis": set_speed if enabled else 0, + "AliveCounterACC": idx % 0x10, + "SCCInfoDisplay": 3 if warning_front else 4 if soft_hold_info else 0 if enabled else 0, + "ObjValid": 1 if hud_control.leadVisible else 0, # close lead makes controls tighter + "ACC_ObjStatus": 1 if hud_control.leadVisible else 0, # close lead makes controls tighter + "ACC_ObjLatPos": 0, + "ACC_ObjRelSpd": hud_control.leadRelSpeed, + "ACC_ObjDist": int(hud_control.leadDistance), # close lead makes controls tighter + "DriverAlertDisplay": 0, + } + commands.append(packer.make_can_msg("SCC11", 0, scc11_values)) - # If ESCC is available and enabled, we skip FCA12, since ESCC does not block FCA12 - if ESCC and ESCC.enabled: - return commands + scc12_values = { + "ACCMode": scc12_acc_mode, + "StopReq": stop_req, + "aReqRaw": 0 if stop_req > 0 else accel, + "aReqValue": accel, # stock ramps up and down respecting jerk limit until it reaches aReqRaw + #"DESIRED_DIST": CS.out.vEgo * 1.0 + 4.0, + "CR_VSM_Alive": idx % 0xF, + } + + # show AEB disabled indicator on dash with SCC12 if not sending FCA messages. + # these signals also prevent a TCS fault on non-FCA cars with alpha longitudinal + if not use_fca: + scc12_values["CF_VSM_ConfMode"] = 1 + scc12_values["AEB_Status"] = 1 # AEB disabled + + scc12_dat = packer.make_can_msg("SCC12", 0, scc12_values)[1] + scc12_values["CR_VSM_ChkSum"] = 0x10 - sum(sum(divmod(i, 16)) for i in scc12_dat) % 0x10 + + commands.append(packer.make_can_msg("SCC12", 0, scc12_values)) + + scc14_values = { + "ComfortBandUpper": jerk.cb_upper, # stock usually is 0 but sometimes uses higher values + "ComfortBandLower": jerk.cb_lower, # stock usually is 0 but sometimes uses higher values + "JerkUpperLimit": jerk.jerk_u, # stock usually is 1.0 but sometimes uses higher values + "JerkLowerLimit": jerk.jerk_l, # stock usually is 0.5 but sometimes uses higher values + "ACCMode": scc14_acc_mode, # if enabled and long_override else 1 if enabled else 4, # stock will always be 4 instead of 0 after first disengage + "ObjGap": objGap, #2 if hud_control.leadVisible else 0, # 5: >30, m, 4: 25-30 m, 3: 20-25 m, 2: < 20 m, 0: no lead + "ObjDistStat": objGap2, + } + commands.append(packer.make_can_msg("SCC14", 0, scc14_values)) + + # Only send FCA11 on cars where it exists on the bus + # On Camera SCC cars, FCA11 is not disabled, so we forward stock FCA11 back to the car forward hooks + if use_fca and not (CP.flags & HyundaiFlags.CAMERA_SCC): + # note that some vehicles most likely have an alternate checksum/counter definition + # https://github.com/commaai/iqdbc/commit/9ddcdb22c4929baf310295e832668e6e7fcfa602 + fca11_values = { + "CR_FCA_Alive": idx % 0xF, + "PAINT1_Status": 1, + "FCA_DrvSetStatus": 1, + "FCA_Status": 1, # AEB disabled + } + fca11_dat = packer.make_can_msg("FCA11", 0, fca11_values)[1] + fca11_values["CR_FCA_ChkSum"] = hyundai_checksum(fca11_dat[:7]) + commands.append(packer.make_can_msg("FCA11", 0, fca11_values)) + + return commands + +def create_acc_opt(packer, CP): + commands = [] + + scc13_values = { + "SCCDrvModeRValue": 2, + "SCC_Equip": 1, + "Lead_Veh_Dep_Alert_USM": 2, + } + commands.append(packer.make_can_msg("SCC13", 0, scc13_values)) # TODO: this needs to be detected and conditionally sent on unsupported long cars # On Camera SCC cars, FCA12 is not disabled, so we forward stock FCA12 back to the car forward hooks if not (CP.flags & HyundaiFlags.CAMERA_SCC): - fca12_values = get_fca12_values() + fca12_values = { + "FCA_DrvSetState": 2, + "FCA_USM": 1, # AEB disabled + } commands.append(packer.make_can_msg("FCA12", 0, fca12_values)) return commands - def create_frt_radar_opt(packer): frt_radar11_values = { "CF_FCA_Equip_Front_Radar": 1, } return packer.make_can_msg("FRT_RADAR11", 0, frt_radar11_values) + +def create_clu11_button(packer, frame, clu11, button, CP): + values = clu11.copy() + values["CF_Clu_CruiseSwState"] = button + #values["CF_Clu_AliveCnt1"] = frame % 0x10 + values["CF_Clu_AliveCnt1"] = (values["CF_Clu_AliveCnt1"] + 1) % 0x10 + # send buttons to camera on camera-scc based cars + bus = 2 if CP.flags & HyundaiFlags.CAMERA_SCC else 0 + return packer.make_can_msg("CLU11", bus, values) + +def create_mdps12(packer, frame, mdps12): + values = mdps12 + values["CF_Mdps_ToiActive"] = 0 + values["CF_Mdps_ToiUnavail"] = 1 + values["CF_Mdps_MsgCount2"] = frame % 0x100 + values["CF_Mdps_Chksum2"] = 0 + + dat = packer.make_can_msg("MDPS12", 2, values)[1] + checksum = sum(dat) % 256 + values["CF_Mdps_Chksum2"] = checksum + + return packer.make_can_msg("MDPS12", 2, values) diff --git a/iqdbc_repo/iqdbc/car/hyundai/hyundaicanfd.py b/iqdbc_repo/iqdbc/car/hyundai/hyundaicanfd.py index bc8c103..3d210f0 100644 --- a/iqdbc_repo/iqdbc/car/hyundai/hyundaicanfd.py +++ b/iqdbc_repo/iqdbc/car/hyundai/hyundaicanfd.py @@ -2,22 +2,42 @@ import copy import numpy as np from iqdbc.car import CanBusBase from iqdbc.car.crc import CRC16_XMODEM -from iqdbc.car.hyundai.values import HyundaiFlags -from iqdbc.iqpilot.car.hyundai.lead_data_ext import CanFdLeadData +from iqdbc.car.hyundai.values import HyundaiFlags, HyundaiExtFlags +from openpilot.common.params import Params +from iqdbc.car.common.conversions import Conversions as CV +from cereal import log +LaneChangeState = log.LaneChangeState +LaneChangeDirection = log.LaneChangeDirection +TurnDirection = log.Desire + + +def hyundai_crc8(data: bytes) -> int: + poly = 0x2F + crc = 0xFF + + for byte in data: + crc ^= byte + for _ in range(8): + if crc & 0x80: + crc = ((crc << 1) ^ poly) & 0xFF + else: + crc = (crc << 1) & 0xFF + + return crc ^ 0xFF class CanBus(CanBusBase): def __init__(self, CP, fingerprint=None, lka_steering=None) -> None: super().__init__(CP, fingerprint) if lka_steering is None: - lka_steering = CP.flags & HyundaiFlags.CANFD_LKA_STEERING.value if CP is not None else False + lka_steering = CP.flags & HyundaiFlags.CANFD_HDA2.value if CP is not None else False # On the CAN-FD platforms, the LKAS camera is on both A-CAN and E-CAN. LKA steering cars # have a different harness than the LFA steering variants in order to split # a different bus, since the steering is done by different ECUs. self._a, self._e = 1, 0 - if lka_steering: + if lka_steering and Params().get_int("HyundaiCameraSCC") == 0: #배선개조는 무조건 Bus0가 ECAN임. self._a, self._e = 0, 1 self._a += self.offset @@ -36,50 +56,190 @@ class CanBus(CanBusBase): def CAM(self): return self._cam +# CAN LIST (CAM) - 롱컨개조시... ADAS + CAM +# 160: ADRV_0x160 +# 1da: ADRV_0x1da +# 1ea: ADRV_0x1ea +# 200: ADRV_0x200 +# 345: ADRV_0x345 +# 1fa: CLUSTER_SPEED_LIMIT +# 12a: LFA +# 1e0: LFAHDA_CLUSTER +# 11a: +# 1b5: +# 1a0: SCC_CONTROL -def create_steering_messages(packer, CP, CAN, enabled, lat_active, apply_torque, lkas_icon): - common_values = { - "LKA_MODE": 2, - "LKA_ICON": lkas_icon, - "TORQUE_REQUEST": apply_torque, - "LKA_ASSIST": 0, - "STEER_REQ": 1 if lat_active else 0, - "STEER_MODE": 0, - "HAS_LANE_SAFETY": 0, # hide LKAS settings - "NEW_SIGNAL_2": 0, - "DAMP_FACTOR": 100, # can potentially tuned for better perf [3, 200] - } +# CAN LIST (ACAN) +# 160: ADRV_0x160 +# 51: ADRV_0x51 +# 180: CAM_0x180 +# ... +# 185: CAM_0x185 +# 1b6: CAM_0x1b6 +# ... +# 1b9: CAM_0x1b9 +# 1fb: CAM_0x1fb +# 2a2 - 2a4 +# 2bb - 2be +# LKAS +# 201 - 2a0 - lkas_values = copy.copy(common_values) - lkas_values["LKA_AVAILABLE"] = 0 - lfa_values = copy.copy(common_values) - lfa_values["NEW_SIGNAL_1"] = 0 + +def create_steering_messages_camera_scc(frame, packer, CP, CAN, CC, lat_active, apply_steer, CS, apply_angle, max_torque, angle_control): + + emergency_steering = False + if CS.adrv_0x161 is not None: + values = CS.adrv_0x161 + emergency_steering = values["ALERTS_1"] in [11, 12, 13, 14, 15, 21, 22, 23, 24, 25, 26] + ret = [] - if CP.flags & HyundaiFlags.CANFD_LKA_STEERING: - lkas_msg = "LKAS_ALT" if CP.flags & HyundaiFlags.CANFD_LKA_STEERING_ALT else "LKAS" - if CP.openpilotLongitudinalControl: - ret.append(packer.make_can_msg("LFA", CAN.ECAN, lfa_values)) - ret.append(packer.make_can_msg(lkas_msg, CAN.ACAN, lkas_values)) - else: - ret.append(packer.make_can_msg("LFA", CAN.ECAN, lfa_values)) + if CS.mdps is not None: + values = copy.copy(CS.mdps) + #rx_counter = values.pop("COUNTER", None) + if angle_control: + if CS.lfa_alt is not None: + values["LFA2_ACTIVE"] = CS.lfa_alt["LKAS_ANGLE_ACTIVE"] + else: + if CS.lfa is not None: + values["LKA_ACTIVE"] = 1 if CS.lfa["STEER_REQ"] == 1 else 0 + + if frame % 1000 < 40: + values["STEERING_COL_TORQUE"] += 220 + #ret.append(packer.make_can_msg("MDPS", CAN.CAM, values, rx_counter = rx_counter)) + ret.append(packer.make_can_msg("MDPS", CAN.CAM, values)) + + if frame % 10 == 0: + if CS.steer_touch_2af is not None: + values = copy.copy(CS.steer_touch_2af) + if frame % 1000 < 40: + values["TOUCH_DETECT"] = 3 + values["TOUCH1"] = 50 + values["TOUCH2"] = 50 + values["CHECKSUM_"] = 0 + dat = packer.make_can_msg("STEER_TOUCH_2AF", 0, values)[1] + values["CHECKSUM_"] = hyundai_crc8(dat[1:8]) + + ret.append(packer.make_can_msg("STEER_TOUCH_2AF", CAN.CAM, values)) + + if angle_control: + if CS.lfa_alt is not None: + values = copy.copy(CS.lfa_alt) + rx_counter = values.pop("COUNTER", None) + if emergency_steering: + pass + else: + #values = {} #CS.lfa_alt + values["LKAS_ANGLE_ACTIVE"] = 2 if CC.latActive else 1 + values["LKAS_ANGLE_CMD"] = -apply_angle + values["LKAS_ANGLE_MAX_TORQUE"] = max_torque if CC.latActive else 0 + ret.append(packer.make_can_msg("LFA_ALT", CAN.ECAN, values, rx_counter = rx_counter)) + + if CS.lfa is not None: + values = copy.copy(CS.lfa) + rx_counter = values.pop("COUNTER", None) + if not emergency_steering: + values["LKA_MODE"] = 0 + values["LKA_ICON"] = 2 if CC.latActive else 1 + values["TORQUE_REQUEST"] = -1024 # apply_steer, + values["VALUE63"] = 0 # LKA_ASSIST + values["STEER_REQ"] = 0 # 1 if lat_active else 0, + values["HAS_LANE_SAFETY"] = 0 # hide LKAS settings + values["LKA_ACTIVE"] = 3 if CC.latActive else 0 # this changes sometimes, 3 seems to indicate engaged + values["VALUE64"] = 0 #STEER_MODE, NEW_SIGNAL_2 + values["LKAS_ANGLE_CMD"] = -25.6 #-apply_angle, + values["LKAS_ANGLE_ACTIVE"] = 0 #2 if lat_active else 1, + values["LKAS_ANGLE_MAX_TORQUE"] = 0 #max_torque if lat_active else 0, + values["NEW_SIGNAL_1"] = 10 + ret.append(packer.make_can_msg("LFA", CAN.ECAN, values, rx_counter = rx_counter)) + + elif CS.lfa is not None: + values = {} + values["LKA_MODE"] = 2 + values["LKA_ICON"] = 2 if lat_active else 1 + values["TORQUE_REQUEST"] = apply_steer + values["STEER_REQ"] = 1 if lat_active else 0 + values["VALUE64"] = 0 # STEER_MODE, NEW_SIGNAL_2 + values["HAS_LANE_SAFETY"] = 0 + values["LKA_ACTIVE"] = 0 # NEW_SIGNAL_1 + + values["DampingGain"] = 0 if lat_active else 100 + #values["VALUE63"] = 0 + + #values["VALUE82_SET256"] = 0 + + ret.append(packer.make_can_msg("LFA", CAN.ECAN, values)) return ret +def create_steering_messages(packer, CP, CAN, enabled, lat_active, apply_steer, apply_angle, max_torque, angle_control): -def create_suppress_lfa(packer, CAN, lfa_block_msg, lka_steering_alt): - suppress_msg = "CAM_0x362" if lka_steering_alt else "CAM_0x2a4" - msg_bytes = 32 if lka_steering_alt else 24 + ret = [] + if angle_control: + values = { + "LKA_MODE": 0, + "LKA_ICON": 2 if enabled else 1, + "TORQUE_REQUEST": 0, # apply_steer, + "VALUE63": 0, # LKA_ASSIST + "STEER_REQ": 0, # 1 if lat_active else 0, + "HAS_LANE_SAFETY": 0, # hide LKAS settings + "LKA_ACTIVE": 3 if lat_active else 0, # this changes sometimes, 3 seems to indicate engaged + "VALUE64": 0, #STEER_MODE, NEW_SIGNAL_2 + "LKAS_ANGLE_CMD": -apply_angle, + "LKAS_ANGLE_ACTIVE": 2 if lat_active else 1, + "LKAS_ANGLE_MAX_TORQUE": max_torque if lat_active else 0, - values = {f"BYTE{i}": lfa_block_msg[f"BYTE{i}"] for i in range(3, msg_bytes) if i != 7} + # test for EV6PE + "NEW_SIGNAL_1": 10, #2, + "DampingGain": 9, + "VALUE231": 146, + "VALUE239": 1, + "VALUE247": 255, + "VALUE255": 255, + } + else: + values = { + "LKA_MODE": 2, + "LKA_ICON": 2 if enabled else 1, + "TORQUE_REQUEST": apply_steer, + "DampingGain": 100, #3 if enabled else 100, + "STEER_REQ": 1 if lat_active else 0, + #"STEER_MODE": 0, + "HAS_LANE_SAFETY": 0, # hide LKAS settings + "VALUE63": 0, + "VALUE64": 100, + } + + if CP.flags & HyundaiFlags.CANFD_HDA2: + lkas_msg = "LKAS_ALT" if CP.flags & HyundaiFlags.CANFD_HDA2_ALT_STEERING else "LKAS" + if CP.openpilotLongitudinalControl: + ret.append(packer.make_can_msg("LFA", CAN.ECAN, values)) + if not (CP.flags & HyundaiFlags.CAMERA_SCC.value): + ret.append(packer.make_can_msg(lkas_msg, CAN.ACAN, values)) + else: + ret.append(packer.make_can_msg("LFA", CAN.ECAN, values)) + + return ret + +def create_suppress_lfa(packer, CAN, CS): + if CS.cam_0x362 is not None: + suppress_msg = "CAM_0x362" + lfa_block_msg = CS.cam_0x362 + elif CS.cam_0x2a4 is not None: + suppress_msg = "CAM_0x2a4" + lfa_block_msg = CS.cam_0x2a4 + else: + return [] + + #values = {f"BYTE{i}": lfa_block_msg[f"BYTE{i}"] for i in range(3, msg_bytes) if i != 7} + values = copy.copy(lfa_block_msg) values["COUNTER"] = lfa_block_msg["COUNTER"] values["SET_ME_0"] = 0 values["SET_ME_0_2"] = 0 values["LEFT_LANE_LINE"] = 0 values["RIGHT_LANE_LINE"] = 0 - return packer.make_can_msg(suppress_msg, CAN.ACAN, values) - + return [packer.make_can_msg(suppress_msg, CAN.ACAN, values)] def create_buttons(packer, CP, CAN, cnt, btn): values = { @@ -88,14 +248,12 @@ def create_buttons(packer, CP, CAN, cnt, btn): "CRUISE_BUTTONS": btn, } - bus = CAN.ECAN if CP.flags & HyundaiFlags.CANFD_LKA_STEERING else CAN.CAM + #bus = CAN.ECAN if CP.flags & HyundaiFlags.CANFD_HDA2 else CAN.CAM + bus = CAN.ECAN return packer.make_can_msg("CRUISE_BUTTONS", bus, values) - def create_acc_cancel(packer, CP, CAN, cruise_info_copy): - # CAN FD camera-based SCC requires additional signals to be preserved - # verbatim from the previous SCC_CONTROL frame to avoid checksum or - # state validation faults. Classic CAN SCC only validates a subset. + # TODO: why do we copy different values here? if CP.flags & HyundaiFlags.CANFD_CAMERA_SCC.value: values = {s: cruise_info_copy[s] for s in [ "COUNTER", @@ -124,49 +282,169 @@ def create_acc_cancel(packer, CP, CAN, cruise_info_copy): }) return packer.make_can_msg("SCC_CONTROL", CAN.ECAN, values) - -def create_lfahda_cluster(packer, CAN, enabled, lfa_icon): - values = { - "HDA_ICON": 1 if enabled else 0, - "LFA_ICON": lfa_icon, - } - return packer.make_can_msg("LFAHDA_CLUSTER", CAN.ECAN, values) +def create_lfahda_cluster(packer, CS, CAN, long_active, lat_active): -def create_acc_control(packer, CAN, enabled, accel_last, accel, stopping, gas_override, set_speed, hud_control, - lead_data: CanFdLeadData, main_cruise_enabled, tuning): + if CS.lfahda_cluster is not None: + values = copy.copy(CS.lfahda_cluster) + rx_counter = values.pop("COUNTER", None) + else: + return [] + values = {} + rx_counter = None + values["LFA_OptUsmSta"] = 2 + values["HDA_OptUsmSta"] = 2 + values["HDA_CntrlModSta"] = 2 if long_active else 0 + values["HDA_LFA_SymSta"] = 2 if lat_active else 0 + return [packer.make_can_msg("LFAHDA_CLUSTER", CAN.ECAN, values, rx_counter=rx_counter)] + +def create_lfa_icon_non_camera_scc(packer, CS, CAN, CC): + ret = [] + if CS.adrv_0x161 is not None: + values = copy.copy(CS.adrv_0x161) + rx_counter = values.pop("COUNTER", None) + + lat_active = CC.latActive + lat_enabled = CS.out.latEnabled + + values["LFA_ICON"] = 2 if lat_active else 1 if lat_enabled else 0 + values["LKA_ICON"] = 4 if lat_active else 3 if lat_enabled else 0 + + if values["ALERTS_2"] in [1, 2, 5, 6, 10, 21, 22]: + values["ALERTS_2"] = 0 + values["DAW_ICON"] = 0 + + if values["ALERTS_1"] == 0: + values["SOUNDS_1"] = 0 + values["SOUNDS_2"] = 0 + values["SOUNDS_4"] = 0 + + if values["ALERTS_3"] in [3, 4, 11, 12, 13, 14, 17, 19, 26, 7, 8, 9, 10]: + values["ALERTS_3"] = 0 + values["SOUNDS_3"] = 0 + + if values["ALERTS_5"] in [1, 2, 3, 4, 5]: + values["ALERTS_5"] = 0 + + ret.append(packer.make_can_msg("ADRV_0x161", CAN.ECAN, values, rx_counter=rx_counter)) + return ret + +def create_acc_control_scc2(packer, CAN, enabled, accel_last, accel, stopping, gas_override, set_speed, hud_control, hyundai_jerk, CS): + + if CS.scc_control is None: + return None + enabled = (enabled or CS.softHoldActive > 0) and CS.paddle_button_prev == 0 + + acc_mode = 0 if not enabled else (2 if gas_override else 1) + + if hyundai_jerk.carrot_cruise == 1: + acc_mode = 4 if enabled else 0 + enabled = False + accel = accel_last = 0.5 + + elif hyundai_jerk.carrot_cruise == 2: + accel = accel_last = hyundai_jerk.carrot_cruise_accel + + jerk_u = hyundai_jerk.jerk_u + jerk_l = hyundai_jerk.jerk_l jerk = 5 jn = jerk / 50 if not enabled or gas_override: a_val, a_raw = 0, 0 else: - a_raw = accel # noqa: F841 - a_val = np.clip(accel, accel_last - jn, accel_last + jn) # noqa: F841 + a_raw = accel + a_val = accel #np.clip(accel, accel_last - jn, accel_last + jn) + + values = copy.copy(CS.scc_control) + rx_counter = values.pop("COUNTER", None) + values["ACCMode"] = acc_mode + values["MainMode_ACC"] = 1 + values["StopReq"] = 1 if stopping or CS.softHoldActive > 0 else 0 # 1: Stop control is required, 2: Not used, 3: Error Indicator + values["aReqValue"] = a_val + values["aReqRaw"] = a_raw + values["VSetDis"] = set_speed + #values["JerkLowerLimit"] = jerk if enabled else 1 + #values["JerkUpperLimit"] = 3.0 + values["JerkLowerLimit"] = jerk_l if enabled else 1 + values["JerkUpperLimit"] = 2.0 if stopping or CS.softHoldActive else jerk_u + values["DISTANCE_SETTING"] = hud_control.leadDistanceBars # + 5 + #values["DISTANCE_SETTING"] = hud_control.leadDistanceBars + 5 + + #values["ACC_ObjDist"] = 1 + #values["ObjValid"] = 0 + #values["OBJ_STATUS"] = 2 + #values["NSCCOper"] = 1 if enabled else 0 # 0: off, 1: Ready, 2: Act, 3: Error Indicator + #values["NSCCOnOff"] = 2 # 0: Default, 1: Off, 2: On, 3: Invalid + #values["SET_ME_3"] = 0x3 # objRelsped와 충돌 + #values["ACC_ObjLatPos"] = - hud_control.leadDPath + values["DriveMode"] = 0 # 0: Default, 1: Comfort Mode, 2:Normal mode, 3:Dynamic mode, reserved + + hud_lead_info = 0 + if hud_control.leadVisible: + hud_lead_info = 1 if values["ACC_ObjRelSpd"] > 0 else 2 + values["HUD_LEAD_INFO"] = hud_lead_info #1: in-path object detected(uncontrollable), 2: controllable long, 3: controllable long & lat, ... reserved + + values["DriverAlert"] = 0 # 1: SCC Disengaged, 2: No SCC Engage condition, 3: SCC Disenganed when the vehicle stops + + values["TARGET_DISTANCE"] = CS.out.vEgo * 1.0 + 4.0 + + soft_hold_info = 1 if CS.softHoldActive > 1 and enabled else 0 + + # 이거안하면 정지중 뒤로 밀리는 현상 발생하는듯.. (신호정지중에 뒤로 밀리는 경험함.. 시험해봐야) + if values["InfoDisplay"] != 5: #5: Front Car Departure Notice + values["InfoDisplay"] = 4 if stopping and CS.out.aEgo > -0.3 else 0 # 1: SCC Mode, 2: Convention Cruise Mode, 3: Object disappered at low speed, 4: Available to resume acceleration control, 5: Front vehicle departure notice, 6: Reserved, 7: Invalid + + values["TakeOverReq"] = 0 # 1: Takeover request, 2: Not used, 3: Error indicator , 이것이 켜지면 가속을 안하는듯함. + #values["NEW_SIGNAL_4"] = 9 if hud_control.leadVisible else 0 + # AccelLimitBandUpper, Lower + values["SysFailState"] = 0 # 1: Performance degredation, 2: system temporairy unavailble, 3: SCC Service required , 눈이 묻어 레이더오류시... 2가 됨. 이때 가속을 안함... + + values["AccelLimitBandUpper"] = 0.0 # 이값이 1.26일때 가속을 안하는 증상이 보임.. + values["AccelLimitBandLower"] = 0.0 + + values["ZEROS_7"] = 1 + + return packer.make_can_msg("SCC_CONTROL", CAN.ECAN, values) + +def create_acc_control(packer, CAN, enabled, accel_last, accel, stopping, gas_override, set_speed, hud_control, jerk_u, jerk_l, CS): + + enabled = enabled or CS.softHoldActive > 0 + jerk = 5 + jn = jerk / 50 + if not enabled or gas_override: + a_val, a_raw = 0, 0 + else: + a_raw = accel + a_val = np.clip(accel, accel_last - jn, accel_last + jn) values = { "ACCMode": 0 if not enabled else (2 if gas_override else 1), - "MainMode_ACC": 1 if main_cruise_enabled else 0, - "StopReq": 1 if tuning.stopping else 0, - "aReqValue": tuning.actual_accel, - "aReqRaw": tuning.actual_accel, + "MainMode_ACC": 1, + "StopReq": 1 if stopping or CS.softHoldActive > 0 else 0, + "aReqValue": a_val, + "aReqRaw": a_raw, "VSetDis": set_speed, - "JerkLowerLimit": tuning.jerk_lower, - "JerkUpperLimit": tuning.jerk_upper, + #"JerkLowerLimit": jerk if enabled else 1, + #"JerkUpperLimit": 3.0, + "JerkLowerLimit": jerk_l if enabled else 1, + "JerkUpperLimit": jerk_u, - "ACC_ObjDist": int(lead_data.lead_distance), - "ACC_ObjRelSpd": lead_data.lead_rel_speed, - "ObjValid": int(not lead_data.lead_visible), - "SCC_ObjSta": 0 if not (enabled and lead_data.lead_visible) else (1 if gas_override else 2), - "SET_ME_2": 0x4, - "SET_ME_3": 0x3, - "SET_ME_TMP_64": 0x64, - "DISTANCE_SETTING": hud_control.leadDistanceBars, + "ACC_ObjDist": 1, + #"ObjValid": 0, + #"OBJ_STATUS": 2, + "NSCCOper": 0, + "NSCCOnOff": 2, + "DriveMode": 0, + #"SET_ME_3": 0x3, + "ACC_ObjLatPos": 0x64, + "DISTANCE_SETTING": hud_control.leadDistanceBars, # + 5, + "InfoDisplay": 4 if stopping and CS.out.cruiseState.standstill else 0, } return packer.make_can_msg("SCC_CONTROL", CAN.ECAN, values) -def create_spas_messages(packer, CAN, left_blink, right_blink): +def create_spas_messages(packer, CAN, frame, left_blink, right_blink): ret = [] values = { @@ -186,8 +464,10 @@ def create_spas_messages(packer, CAN, left_blink, right_blink): return ret -def create_fca_warning_light(packer, CAN, frame): +def create_fca_warning_light(CP, packer, CAN, frame): ret = [] + if CP.flags & HyundaiFlags.CAMERA_SCC.value: + return ret if frame % 2 == 0: values = { @@ -196,53 +476,100 @@ def create_fca_warning_light(packer, CAN, frame): 'SET_ME_FF': 0xff, 'SET_ME_FC': 0xfc, 'SET_ME_9': 0x9, + #'DATA102': 1, } ret.append(packer.make_can_msg("ADRV_0x160", CAN.ECAN, values)) return ret +def create_tcs_messages(packer, CAN, CS): + ret = [] + if CS.tcs is not None: + values = copy.copy(CS.tcs) + #rx_counter = values.pop("COUNTER", None) + values["DriverBraking"] = 0 + values["NEW_SIGNAL_20"] = 0 + values["NEW_SIGNAL_11"] = 0 + values["DriverBrakingLowSens"] = 0 + #values["NEW_SIGNAL_1"] = 0 # accel과 관련.. 옆두부 꺼지는것과 관련? 확인필요 + #values["ACC_REQ"] = 1 # 옆두부 꺼지는것과 관련? 확인필요.. 항상 켜지게함.. + values["NEW_SIGNAL_1"] = 0 if values["ACC_REQ"] == 1 else 1 # 옆두부.. + #ret.append(packer.make_can_msg("TCS", CAN.CAM, values, rx_counter = rx_counter)) + ret.append(packer.make_can_msg("TCS", CAN.CAM, values)) + return ret -def create_adrv_messages(packer, CAN, frame): +def forward_button_message(packer, CAN, frame, CS, cruise_button, MainMode_ACC_trigger, LFA_trigger): + ret = [] + if frame % 2 == 0: + if CS.cruise_buttons_msg is not None: + values = copy.copy(CS.cruise_buttons_msg) + # A held MAIN is reported on this bit and switches some clusters to LIMIT mode. + values["NORMAL_CRUISE_MAIN_BTN"] = 0 + #rx_counter = values.pop("COUNTER", None) + cruise_button_driver = values["CRUISE_BUTTONS"] + if cruise_button_driver == 0: + values["CRUISE_BUTTONS"] = cruise_button + if MainMode_ACC_trigger > 0: + #values["ADAPTIVE_CRUISE_MAIN_BTN"] = 1 + pass + elif LFA_trigger > 0: + values["LFA_BTN"] = 1 + + #ret.append(packer.make_can_msg(CS.cruise_btns_msg_canfd, CAN.CAM, values, rx_counter = rx_counter)) + ret.append(packer.make_can_msg(CS.cruise_btns_msg_canfd, CAN.CAM, values)) + return ret + +def create_adrv_messages(CP, packer, CAN, frame): # messages needed to car happy after disabling # the ADAS Driving ECU to do longitudinal control ret = [] - values = { - } - ret.append(packer.make_can_msg("ADRV_0x51", CAN.ACAN, values)) + if not CP.flags & HyundaiFlags.CAMERA_SCC.value: + values = {} - ret.extend(create_fca_warning_light(packer, CAN, frame)) + ret.extend(create_fca_warning_light(CP, packer, CAN, frame)) + if frame % 5 == 0: + values = { + #'HDA_MODE1': 0x8, + 'HDA_MODE2': 0x1, + #'SET_ME_1C': 0x1c, + 'SET_ME_FF': 0xff, + #'SET_ME_TMP_F': 0xf, + #'SET_ME_TMP_F_2': 0xf, + #'DATA26': 1, #1 + #'DATA32': 5, #5 + } + ret.append(packer.make_can_msg("ADRV_0x1ea", CAN.ECAN, values)) - if frame % 5 == 0: - values = { - 'SET_ME_1C': 0x1c, - 'SET_ME_FF': 0xff, - 'SET_ME_TMP_F': 0xf, - 'SET_ME_TMP_F_2': 0xf, - } - ret.append(packer.make_can_msg("ADRV_0x1ea", CAN.ECAN, values)) + values = { + 'SET_ME_E1': 0xe1, + #'SET_ME_3A': 0x3a, + 'TauGapSet' : 1, + 'NEW_SIGNAL_2': 3, + } + ret.append(packer.make_can_msg("ADRV_0x200", CAN.ECAN, values)) - values = { - 'SET_ME_E1': 0xe1, - 'SET_ME_3A': 0x3a, - } - ret.append(packer.make_can_msg("ADRV_0x200", CAN.ECAN, values)) + if frame % 20 == 0: + values = { + 'SET_ME_15': 0x15, + } + ret.append(packer.make_can_msg("ADRV_0x345", CAN.ECAN, values)) - if frame % 20 == 0: - values = { - 'SET_ME_15': 0x15, - } - ret.append(packer.make_can_msg("ADRV_0x345", CAN.ECAN, values)) - - if frame % 100 == 0: - values = { - 'SET_ME_22': 0x22, - 'SET_ME_41': 0x41, - } - ret.append(packer.make_can_msg("ADRV_0x1da", CAN.ECAN, values)) + if frame % 100 == 0: + values = { + 'SET_ME_22': 0x22, + 'SET_ME_41': 0x41, + } + ret.append(packer.make_can_msg("ADRV_0x1da", CAN.ECAN, values)) return ret +## carrot +def alt_cruise_buttons(packer, CP, CAN, buttons, cruise_btns_msg, cnt): + cruise_btns_msg["CRUISE_BUTTONS"] = buttons + cruise_btns_msg["COUNTER"] = (cruise_btns_msg["COUNTER"] + 1 + cnt) % 256 + bus = CAN.ECAN if CP.flags & HyundaiFlags.CANFD_HDA2 else CAN.CAM + return packer.make_can_msg("CRUISE_BUTTONS_ALT", bus, cruise_btns_msg) def hkg_can_fd_checksum(address: int, sig, d: bytearray) -> int: crc = 0 @@ -259,3 +586,348 @@ def hkg_can_fd_checksum(address: int, sig, d: bytearray) -> int: elif len(d) == 32: crc ^= 0x9F5B return crc + + + + +def _clip_int(x, lo, hi): + return lo if x < lo else hi if x > hi else int(x) + +def _get_desire_and_lane_changing(md): + desire = 0 + lane_changing = 0 + if md is not None: + desire = md.meta.desire.raw + ds = md.meta.desireState + if len(ds) > 4: + if ds[1] > 0.9: lane_changing = 1 + if ds[2] > 0.9: lane_changing = 2 + if ds[3] > 0.9: lane_changing = 3 + if ds[4] > 0.9: lane_changing = 4 + return desire, lane_changing + +def _apply_lane_desire(values, desire): + #values['LANE_CHANGING'] = 0 + + if desire == 1: # 좌회전 + values['LANE_CHANGING'] = 1 + values["LANELINE_CURVATURE"] = 15 + values["LANELINE_CURVATURE_DIRECTION"] = 0 + + elif desire == 2: # 우회전 + values['LANE_CHANGING'] = 2 + values["LANELINE_CURVATURE"] = 15 + values["LANELINE_CURVATURE_DIRECTION"] = 1 + + elif desire == 3: # 좌차선변경 + values['LANE_CHANGING'] = 3 + + elif desire == 4: # 우차선변경 + values['LANE_CHANGING'] = 4 + +def _apply_radar_blink(values, radar_pairs, frame, *, + disp_dist=30.0, min_dist=14.0, + max_interval=100, t=1.0): + """ + 거리 > min_dist 일 때만 깜빡임. + 거리 멀수록 interval 커짐(느리게). + """ + for det_key, dist_key in radar_pairs: + dist = values[dist_key] + if dist <= min_dist: + continue + + d = min(dist, disp_dist) + interval = int((1 + (max_interval - 1) * (d / disp_dist)) * t) + interval = _clip_int(interval, 1, max_interval) + + blink = (frame // interval) & 1 + values[det_key] = 2 - blink + values[dist_key] = min_dist + +def _suppress_trailer_mode_warning(values, CS): + # Logs from IONIQ 9 show ALERTS_5=6 is the periodic + # "driver assistance limited in trailer mode" popup. + if CS.trailer_connected and values.get("ALERTS_5") == 6: + values["ALERTS_5"] = 0 + +def _make_ccnc_values(values, CS, lat_active, frame, hud_control, + lane_line=True, corner_radar=True, + desire=0, + blink_pairs=None, + blink_t=1.0): + if lane_line: + curvature = round(CS.out.steeringAngleDeg / 3) + mag = min(abs(curvature), 15) + curv = mag + (-1 if curvature < 0 else 0) + direction = 1 if curvature < 0 else 0 + values["LANELINE_CURVATURE"] = curv if lat_active else 0 + values["LANELINE_CURVATURE_DIRECTION"] = direction if lat_active else 0 + if desire: + _apply_lane_desire(values, desire) + + if corner_radar: + radar_all = [ + ('LF_DETECT', 'LF_DETECT_DISTANCE'), + ('RF_DETECT', 'RF_DETECT_DISTANCE'), + ('LR_DETECT', 'LR_DETECT_DISTANCE'), + ('RR_DETECT', 'RR_DETECT_DISTANCE'), + ] + for det_key, dist_key in radar_all: + if values[det_key] >= 4 and values[dist_key] != 0: + values[det_key] = 1 + + if blink_pairs: + _apply_radar_blink(values, blink_pairs, frame, t=blink_t) + +def create_ccnc_messages(CP, packer, CAN, frame, CC, CS, hud_control, + disp_angle, left_lane_warning, right_lane_warning, + enable_corner_radar, stopping, canfd_debug): + ret = [] + + md = CS.modelV2 + if not hasattr(create_ccnc_messages, '_lane_line_check') or frame % 100 == 0: + create_ccnc_messages._lane_line_check = Params().get_int("LaneLineCheck") + lane_line_check = create_ccnc_messages._lane_line_check + desire, lane_changing = _get_desire_and_lane_changing(md) + + if CP.flags & HyundaiFlags.CAMERA_SCC.value: + HDA_CntrlModSta = 0 + HDA_LFA_SymSta = 0 + if CS.lfahda_cluster is not None: + HDA_CntrlModSta = CS.lfahda_cluster["HDA_CntrlModSta"] + HDA_LFA_SymSta = CS.lfahda_cluster["HDA_LFA_SymSta"] + + if frame % 2 == 0: + #if CS.adrv_0x160 is not None: + # values = copy.copy(CS.adrv_0x160) + # ret.append(packer.make_can_msg("ADRV_0x160", CAN.ECAN, values)) + + if CS.cruise_buttons_msg is not None: + values = copy.copy(CS.cruise_buttons_msg) + # Keep the physical long press on ECAN for CarState, but don't forward it to CAM. + values["NORMAL_CRUISE_MAIN_BTN"] = 0 + + if HDA_LFA_SymSta == 0 and 0 < frame % 200 < 12: + values["LFA_BTN"] = 1 + + if CC.enabled: + if not CS.MainMode_ACC: + if 10 < frame % 200 <= 16 and CS.out.vEgo > 3.: + values["ADAPTIVE_CRUISE_MAIN_BTN"] = 1 + elif CS.ACCMode in [0, 4]: + if 10 < frame % 200 <= 16 and CS.out.vEgo > 3.: + values["CRUISE_BUTTONS"] = 2 + elif CS.scc_control is not None and CS.scc_control["InfoDisplay"] == 4: + if 10 < frame % 30 <= 16 and not stopping: + values["CRUISE_BUTTONS"] = 2 + else: + if CS.adrv_0x1ea is not None and CS.adrv_0x1ea["HDA_MODE2"] == 0: # if corner radar is disabled, send main btn + if 10 < frame % 1000 <= 16 and CS.out.vEgo > 3: + values["ADAPTIVE_CRUISE_MAIN_BTN"] = 1 + + ret.append(packer.make_can_msg(CS.cruise_btns_msg_canfd, CAN.CAM, values)) + + # --- 0x161/0x200/0x1ea/0x162 (frame%5) --- + if frame % 5 == 0: + lat_active = CC.latActive + + if CS.adrv_0x161 is not None: + main_enabled = CS.out.cruiseState.available + cruise_enabled = CC.enabled + lat_enabled = CS.out.latEnabled + nav_active = hud_control.activeCarrot > 1 + + # hdpuse carrot + hdp_use = int(Params().get("HDPuse")) + hdp_active = False + if hdp_use == 1: + hdp_active = cruise_enabled and nav_active + elif hdp_use == 2: + hdp_active = cruise_enabled + # hdpuse carrot + + values = copy.copy(CS.adrv_0x161) + rx_counter = values.pop("COUNTER", None) + values["SETSPEED"] = (6 if hdp_active else 3 if cruise_enabled else 1) if main_enabled else 0 + values["SETSPEED_HUD"] = (5 if hdp_active else 3 if cruise_enabled else 1) if main_enabled else 0 + + set_speed_in_units = hud_control.setSpeed * (CV.MS_TO_KPH if CS.is_metric else CV.MS_TO_MPH) + values["vSetDis"] = int(set_speed_in_units + 0.5) + + values["DISTANCE"] = 4 if hdp_active else hud_control.leadDistanceBars + values["DISTANCE_LEAD"] = 2 if cruise_enabled and hud_control.leadVisible else 1 if main_enabled and hud_control.leadVisible else 0 + values["DISTANCE_CAR"] = 3 if hdp_active else 2 if cruise_enabled else 1 if main_enabled else 0 + values["DISTANCE_SPACING"] = 5 if hdp_active else 1 if cruise_enabled else 0 + + values["TARGET"] = 1 if hud_control.leadVisible and cruise_enabled else 0 + values["TARGET_DISTANCE"] = int(hud_control.leadDistance) + + values["BACKGROUND"] = 6 if CS.paddle_button_prev > 0 else 1 if cruise_enabled else 3 if lat_active else 7 + values["CENTERLINE"] = 1 if HDA_CntrlModSta > 0 else 0 + values["CAR_CIRCLE"] = 2 if hdp_active else 1 if cruise_enabled else 0 + + values["NAV_ICON"] = 2 if nav_active and cruise_enabled else 1 if main_enabled and nav_active else 0 + values["HDA_ICON"] = 5 if hdp_active else 2 if cruise_enabled else 1 if main_enabled else 0 + values["LFA_ICON"] = 5 if hdp_active else 2 if lat_active else 1 if lat_enabled else 0 + values["LKA_ICON"] = 4 if lat_active else 3 if lat_enabled else 0 + values["FCA_ALT_ICON"] = 0 + + if values["ALERTS_2"] in [1, 2, 5, 6, 10, 21, 22]: + values["ALERTS_2"] = 0 + values["DAW_ICON"] = 0 + + if values["ALERTS_1"] == 0: # alerts가 있으면 사운드도 같이 나옴 + values["SOUNDS_1"] = 0 + values["SOUNDS_2"] = 0 + values["SOUNDS_4"] = 0 + + if values["ALERTS_3"] in [3, 4, 11, 12, 13, 14, 17, 19, 20, 26, 27, 28, 7, 8, 9, 10]: # hide gap distance msg.(11,12,13,14), lanechange(19,20,27, 28) + values["ALERTS_3"] = 0 + values["SOUNDS_3"] = 0 + + if values["ALERTS_5"] in [1, 2, 3, 4, 5]: + values["ALERTS_5"] = 0 + + if values["ALERTS_5"] in [11] and CS.softHoldActive == 0: + values["ALERTS_5"] = 0 + + # curvature 표시(0x161쪽 기존 로직 유지) + _suppress_trailer_mode_warning(values, CS) + + curvature = round(CS.out.steeringAngleDeg / 3) + values["LANELINE_CURVATURE"] = (min(abs(curvature), 15) + (-1 if curvature < 0 else 0)) if lat_active else 0 + values["LANELINE_CURVATURE_DIRECTION"] = 1 if curvature < 0 and lat_active else 0 + + trailer_lane_change_blocked = CS.trailer_connected + if trailer_lane_change_blocked: + values["LANELINE_LEFT"] = 2 if hud_control.leftLaneVisible else 0 + values["LANELINE_RIGHT"] = 2 if hud_control.rightLaneVisible else 0 + else: + lane_color = 6 if md is not None and md.meta.laneChangeAvailableLeft else 2 + if lane_line_check >= 1: + lane_line_warn_left = CS.out.leftLaneLine % 10 not in (0, 5) + else: + lane_line_warn_left = CS.out.leftLaneLine // 10 == 2 + lane_color = 4 if lane_line_warn_left or CS.out.leftBlindspot else lane_color + if hud_control.leftLaneDepart: + values["LANELINE_LEFT"] = 4 if (frame // 50) % 2 == 0 else 1 + else: + values["LANELINE_LEFT"] = lane_color if hud_control.leftLaneVisible else 0 + + lane_color = 6 if md is not None and md.meta.laneChangeAvailableRight else 2 + if lane_line_check >= 1: + lane_line_warn_right = CS.out.rightLaneLine % 10 not in (0, 5) + else: + lane_line_warn_right = CS.out.rightLaneLine // 10 == 2 + lane_color = 4 if lane_line_warn_right or CS.out.rightBlindspot else lane_color + if hud_control.rightLaneDepart: + values["LANELINE_RIGHT"] = 4 if (frame // 50) % 2 == 0 else 1 + else: + values["LANELINE_RIGHT"] = lane_color if hud_control.rightLaneVisible else 0 + + values["LCA_LEFT_ARROW"] = 2 if CS.out.leftBlinker else 0 + values["LCA_RIGHT_ARROW"] = 2 if CS.out.rightBlinker else 0 + + if trailer_lane_change_blocked: + values["LCA_LEFT_ICON"] = 1 if lat_active else 0 + values["LCA_RIGHT_ICON"] = 1 if lat_active else 0 + else: + values["LCA_LEFT_ICON"] = (1 if CS.out.leftBlindspot else 2) if lat_active else 0 + values["LCA_RIGHT_ICON"] = (1 if CS.out.rightBlindspot else 2) if lat_active else 0 + + values["LANE_LEFT"] = 0 if trailer_lane_change_blocked else 1 if desire in (1, 3) else 0 + values["LANE_RIGHT"] = 0 if trailer_lane_change_blocked else 1 if desire in (2, 4) else 0 + + ret.append(packer.make_can_msg("ADRV_0x161", CAN.ECAN, values, rx_counter = rx_counter)) + + if CS.adrv_0x200 is not None: + values = copy.copy(CS.adrv_0x200) + rx_counter = values.pop("COUNTER", None) + values["TauGapSet"] = hud_control.leadDistanceBars + ret.append(packer.make_can_msg("ADRV_0x200", CAN.ECAN, values, rx_counter = rx_counter)) + + if CS.adrv_0x1ea is not None: + values = copy.copy(CS.adrv_0x1ea) + rx_counter = values.pop("COUNTER", None) + # blinker hold + values['LEFT_BLINK_HOLD'] = 1 if lane_changing == 3 else 0 + values['RIGHT_BLINK_HOLD'] = 1 if lane_changing == 4 else 0 + + _make_ccnc_values( + values, CS, lat_active, frame, hud_control, + lane_line=True, + corner_radar=True, + desire=desire, + # 기존대로 LR/RR만 깜빡임 + blink_pairs=[('LR_DETECT', 'LR_DETECT_DISTANCE'), + ('RR_DETECT', 'RR_DETECT_DISTANCE')], + blink_t=1.0 + ) + + ret.append(packer.make_can_msg("ADRV_0x1ea", CAN.ECAN, values, rx_counter = rx_counter)) + + if CS.ccnc_0x162 is not None: + values = copy.copy(CS.ccnc_0x162) + + if hud_control.leadDistance > 0: + values["FF_DISTANCE"] = hud_control.leadDistance + ff_type = 3 if hud_control.leadRadar == 1 else 13 + values["FF_DETECT"] = ff_type if hud_control.leadRelSpeed > -0.1 else ff_type + 1 + + _make_ccnc_values( + values, CS, lat_active, frame, hud_control, + lane_line=False, + corner_radar=True, + desire=0, + # 필요하면 162도 깜빡임 적용(원래 코드처럼 LR/RR만) + blink_pairs=[('LR_DETECT', 'LR_DETECT_DISTANCE'), + ('RR_DETECT', 'RR_DETECT_DISTANCE')], + blink_t=1.0 + ) + + if (left_lane_warning and not CS.out.leftBlinker) or (right_lane_warning and not CS.out.rightBlinker): + values["VIBRATE"] = 1 + + if canfd_debug > 0: + values["FAULT_LSS"] = 0 + values["FAULT_DAS"] = 0 + + ret.append(packer.make_can_msg("CCNC_0x162", CAN.ECAN, values)) + + # --- NEW_MSG_4B9 (corner radar keep-alive?) --- + if enable_corner_radar > 0: + if HDA_CntrlModSta == 0: + if frame % 500 in [10, 20, 30]: + values = { + 'BYTE_1': 0, + 'BYTE_2': 0, + 'BYTE_3': 0x80, + 'BYTE_4': 0x8A, + 'BYTE_5': 0x32, + 'BYTE_6': 0x30, + 'BYTE_7': 0x01, + 'BYTE_8': 0x00, + } + ret.append(packer.make_can_msg("NEW_MSG_4B9", CAN.CAM, values)) + elif frame % 500 in [40, 50, 60]: + values = { + 'BYTE_1': 0xff, + 'BYTE_2': 0xff, + 'BYTE_3': 0xff, + 'BYTE_4': 0xff, + 'BYTE_5': 0xff, + 'BYTE_6': 0xff, + 'BYTE_7': 0xff, + 'BYTE_8': 0xff, + } + ret.append(packer.make_can_msg("NEW_MSG_4B9", CAN.CAM, values)) + + if False: # canfd_debug > 1 and frame % 20 == 0: + if CS.hda_info_4a3 is not None: + values = copy.copy(CS.hda_info_4a3) + values["LinkClass"] = 1 + values["SPEED_LIMIT"] = 100 + ret.append(packer.make_can_msg("HDA_INFO_4A3", CAN.CAM, values)) + + return ret diff --git a/iqdbc_repo/iqdbc/car/hyundai/interface.py b/iqdbc_repo/iqdbc/car/hyundai/interface.py index da5b783..fcab212 100644 --- a/iqdbc_repo/iqdbc/car/hyundai/interface.py +++ b/iqdbc_repo/iqdbc/car/hyundai/interface.py @@ -1,8 +1,10 @@ -from iqdbc.car import Bus, get_safety_config, structs, uds +from iqdbc.car import Bus, get_safety_config, structs from iqdbc.car.hyundai.hyundaicanfd import CanBus -from iqdbc.car.hyundai.values import HyundaiFlags, CAR, DBC, \ +from iqdbc.car.hyundai.values import HyundaiFlags, CAR, DBC, CANFD_RADAR_SCC_CAR, \ CANFD_UNSUPPORTED_LONGITUDINAL_CAR, \ - UNSUPPORTED_LONGITUDINAL_CAR, HyundaiSafetyFlags + UNSUPPORTED_LONGITUDINAL_CAR, HyundaiSafetyFlags, HyundaiExtFlags, \ + CANFD_HYBRID_STATUS_ADDR, CANFD_HYBRID_STATUS_DLC, \ + EV_MODE_STATUS_ADDR, EV_MODE_STATUS_DLC from iqdbc.car.hyundai.radar_interface import RADAR_START_ADDR from iqdbc.car.interfaces import CarInterfaceBase from iqdbc.car.disable_ecu import disable_ecu @@ -10,9 +12,7 @@ from iqdbc.car.hyundai.carcontroller import CarController from iqdbc.car.hyundai.carstate import CarState from iqdbc.car.hyundai.radar_interface import RadarInterface -from iqdbc.iqpilot.car.hyundai.escc import ESCC_MSG -from iqdbc.iqpilot.car.hyundai.longitudinal.helpers import get_longitudinal_tune -from iqdbc.iqpilot.car.hyundai.values import HyundaiFlagsIQ, HyundaiSafetyFlagsIQ +from openpilot.common.params import Params ButtonType = structs.CarState.ButtonEvent.Type Ecu = structs.CarParams.Ecu @@ -20,67 +20,125 @@ Ecu = structs.CarParams.Ecu # Cancel button can sometimes be ACC pause/resume button, main button can also enable on some cars ENABLE_BUTTONS = (ButtonType.accelCruise, ButtonType.decelCruise, ButtonType.cancel, ButtonType.mainCruise) +SteerControlType = structs.CarParams.SteerControlType + class CarInterface(CarInterfaceBase): CarState = CarState CarController = CarController RadarInterface = RadarInterface - DRIVABLE_GEARS = (structs.CarState.GearShifter.sport, structs.CarState.GearShifter.manumatic) - @staticmethod def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, alpha_long, is_release, docs) -> structs.CarParams: + + params = Params() + camera_scc = params.get_int("HyundaiCameraSCC") + if camera_scc > 0: + ret.flags |= HyundaiFlags.CAMERA_SCC.value + print("$$$CAMERA_SCC toggled...") + ret.brand = "hyundai" - # "LKA steering" if LKAS or LKAS_ALT messages are seen coming from the camera. - # Generally means our LKAS message is forwarded to another ECU (commonly ADAS ECU) - # that finally retransmits our steering command in LFA or LFA_ALT to the MDPS. - # "LFA steering" if camera directly sends LFA to the MDPS - cam_can = CanBus(None, fingerprint).CAM - lka_steering = 0x50 in fingerprint[cam_can] or 0x110 in fingerprint[cam_can] - CAN = CanBus(None, fingerprint, lka_steering) + if candidate == CAR.KIA_SORENTO: + ret.extFlags |= HyundaiExtFlags.RADAR_GROUP4.value + + cam_can = CanBus(None, fingerprint).CAM if camera_scc == 0 else 1 + hda2 = False #0x50 in fingerprint[cam_can] or 0x110 in fingerprint[cam_can] + hda2 = hda2 or params.get_int("CanfdHDA2") > 0 + CAN = CanBus(None, fingerprint, hda2) if ret.flags & HyundaiFlags.CANFD: # Shared configuration for CAN-FD cars - ret.alphaLongitudinalAvailable = candidate not in CANFD_UNSUPPORTED_LONGITUDINAL_CAR - if lka_steering and Ecu.adas not in [fw.ecu for fw in car_fw]: - # this needs to be figured out for cars without an ADAS ECU - ret.alphaLongitudinalAvailable = False + ret.alphaLongitudinalAvailable = True #candidate not in (CANFD_UNSUPPORTED_LONGITUDINAL_CAR | CANFD_RADAR_SCC_CAR) + #ret.enableBsm = 0x1e5 in fingerprint[CAN.ECAN] + ret.enableBsm = 0x1ba in fingerprint[CAN.ECAN] # BLINDSPOTS_REAR_CORNERS 0x1ba(442) - ret.enableBsm = 0x1e5 in fingerprint[CAN.ECAN] - - # Check if the car is hybrid. Only HEV/PHEV cars have 0xFA on E-CAN. - if 0xFA in fingerprint[CAN.ECAN]: + if 0x105 in fingerprint[CAN.ECAN]: ret.flags |= HyundaiFlags.HYBRID.value - if lka_steering: - # detect LKA steering - ret.flags |= HyundaiFlags.CANFD_LKA_STEERING.value - if 0x110 in fingerprint[CAN.CAM]: - ret.flags |= HyundaiFlags.CANFD_LKA_STEERING_ALT.value + # Keep drivetrain/safety classification unchanged: this capability is display-only and requires both exact ECAN frames. + has_ev_mode_status = fingerprint[CAN.ECAN].get(CANFD_HYBRID_STATUS_ADDR) == CANFD_HYBRID_STATUS_DLC and \ + fingerprint[CAN.ECAN].get(EV_MODE_STATUS_ADDR) == EV_MODE_STATUS_DLC + if has_ev_mode_status: + ret.extFlags |= HyundaiExtFlags.EV_MODE_STATUS_230.value + + if 203 in fingerprint[CAN.CAM]: # LFA_ALT + print("##### Anglecontrol detected (LFA_ALT)") + ret.flags |= HyundaiFlags.ANGLE_CONTROL.value + + print("ACAN=", fingerprint[CAN.ACAN]) + + if 0x210 in fingerprint[CAN.ACAN]: + print("##### Radar Group 1 detected (0x210)") + ret.extFlags |= HyundaiExtFlags.RADAR_GROUP1.value + elif 0x400 in fingerprint[CAN.ACAN] and 0x41D in fingerprint[CAN.ACAN]: + print("##### Radar Group 3 detected (0x400-0x41D)") + ret.extFlags |= HyundaiExtFlags.RADAR_GROUP3.value + if all(fingerprint[CAN.ACAN].get(addr) == 32 for addr in range(0x235, 0x249)): + ret.extFlags |= HyundaiExtFlags.CORNER_RADAR_OBJECTS_235.value + print("##### Corner radar objects 0x235 group detected") + if all(fingerprint[CAN.ACAN].get(addr) == 32 for addr in range(0x180, 0x185)): + ret.extFlags |= HyundaiExtFlags.CORNER_RADAR_OBJECTS_180.value + print("##### Corner radar objects 0x180 group detected") + if all(fingerprint[CAN.ACAN].get(addr) == 32 for addr in tuple(range(0x430, 0x438)) + tuple(range(0x440, 0x448))): + ret.extFlags |= HyundaiExtFlags.CORNER_RADAR_OBJECTS_430.value + print("##### Corner radar objects 0x430/0x440 group detected") + + # detect HDA2 with ADAS Driving ECU + if hda2: + print("$$$CANFD HDA2") + ret.flags |= HyundaiFlags.CANFD_HDA2.value + if camera_scc > 0: + if 0x110 in fingerprint[CAN.ACAN]: + ret.flags |= HyundaiFlags.CANFD_HDA2_ALT_STEERING.value + print("$$$CANFD ALT_STEERING1") + else: + if 0x110 in fingerprint[CAN.CAM]: # 0x110(272): LKAS_ALT + ret.flags |= HyundaiFlags.CANFD_HDA2_ALT_STEERING.value + print("$$$CANFD ALT_STEERING1") + ## carrot_todo: sorento: + if 0x2a4 not in fingerprint[CAN.CAM]: # 0x2a4(676): CAM_0x2a4 + ret.flags |= HyundaiFlags.CANFD_HDA2_ALT_STEERING.value + print("$$$CANFD ALT_STEERING2") + + ## carrot: canival 4th, no 0x1cf + if 0x1cf not in fingerprint[CAN.ECAN]: # 0x1cf(463): CRUISE_BUTTONS + ret.flags |= HyundaiFlags.CANFD_ALT_BUTTONS.value + print("$$$CANFD ALT_BUTTONS") else: - # no LKA steering + # non-HDA2 + print("$$$CANFD non HDA2") if 0x1cf not in fingerprint[CAN.ECAN]: ret.flags |= HyundaiFlags.CANFD_ALT_BUTTONS.value - if not ret.flags & HyundaiFlags.RADAR_SCC: - ret.flags |= HyundaiFlags.CANFD_CAMERA_SCC.value - - # Some LKA steering cars have alternative messages for gear checks + print("$$$CANFD ALT_BUTTONS") + #if not ret.flags & HyundaiFlags.RADAR_SCC: + # ret.flags |= HyundaiFlags.CANFD_CAMERA_SCC.value + # print("$$$CANFD CAMERA_SCC") + # Some HDA2 cars have alternative messages for gear checks # ICE cars do not have 0x130; GEARS message on 0x40 or 0x70 instead - if 0x130 not in fingerprint[CAN.ECAN]: - if 0x40 not in fingerprint[CAN.ECAN]: - ret.flags |= HyundaiFlags.CANFD_ALT_GEARS_2.value - else: - ret.flags |= HyundaiFlags.CANFD_ALT_GEARS.value + if 0x40 in fingerprint[CAN.ECAN]: # 0x40(64): GEAR_ALT + ret.flags |= HyundaiFlags.CANFD_ALT_GEARS.value + print("$$$CANFD ALT_GEARS") + elif 69 in fingerprint[CAN.ECAN]: # Special case + ret.extFlags |= HyundaiExtFlags.CANFD_GEARS_69.value + print("$$$CANFD GEARS_69") + elif 112 in fingerprint[CAN.ECAN]: # carrot: eGV70 + ret.flags |= HyundaiFlags.CANFD_ALT_GEARS_2.value + print("$$$CANFD ALT_GEARS_2") + elif 0x130 in fingerprint[CAN.ECAN]: # 0x130(304): GEAR_SHIFTER + print("$$$CANFD GEAR_SHIFTER present") + else: + ret.extFlags |= HyundaiExtFlags.CANFD_GEARS_NONE.value + print("$$$CANFD GEARS_NONE") cfgs = [get_safety_config(structs.CarParams.SafetyModel.hyundaiCanfd), ] if CAN.ECAN >= 4: cfgs.insert(0, get_safety_config(structs.CarParams.SafetyModel.noOutput)) ret.safetyConfigs = cfgs - if ret.flags & HyundaiFlags.CANFD_LKA_STEERING: + if ret.flags & HyundaiFlags.CANFD_HDA2: ret.safetyConfigs[-1].safetyParam |= HyundaiSafetyFlags.CANFD_LKA_STEERING.value - if ret.flags & HyundaiFlags.CANFD_LKA_STEERING_ALT: + if ret.flags & HyundaiFlags.CANFD_HDA2_ALT_STEERING: ret.safetyConfigs[-1].safetyParam |= HyundaiSafetyFlags.CANFD_LKA_STEERING_ALT.value if ret.flags & HyundaiFlags.CANFD_ALT_BUTTONS: ret.safetyConfigs[-1].safetyParam |= HyundaiSafetyFlags.CANFD_ALT_BUTTONS.value @@ -89,53 +147,93 @@ class CarInterface(CarInterfaceBase): else: # Shared configuration for non CAN-FD cars - ret.alphaLongitudinalAvailable = candidate not in UNSUPPORTED_LONGITUDINAL_CAR + ret.alphaLongitudinalAvailable = True #candidate not in (UNSUPPORTED_LONGITUDINAL_CAR | CAMERA_SCC_CAR) ret.enableBsm = 0x58b in fingerprint[0] + print(f"$$$ enableBsm = {ret.enableBsm}") # Send LFA message on cars with HDA if 0x485 in fingerprint[2]: ret.flags |= HyundaiFlags.SEND_LFA.value + print("$$$SEND_LFA") # These cars use the FCA11 message for the AEB and FCW signals, all others use SCC12 if 0x38d in fingerprint[0] or 0x38d in fingerprint[2]: ret.flags |= HyundaiFlags.USE_FCA.value + print("$$$USE_FCA") if ret.flags & HyundaiFlags.LEGACY: # these cars require a special panda safety mode due to missing counters and checksums in the messages ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.hyundaiLegacy)] + print("$$$Legacy Safety Model") else: ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.hyundai, 0)] if ret.flags & HyundaiFlags.CAMERA_SCC: ret.safetyConfigs[0].safetyParam |= HyundaiSafetyFlags.CAMERA_SCC.value - - # These cars have the LFA button on the steering wheel - if 0x391 in fingerprint[0]: - ret.flags |= HyundaiFlags.HAS_LDA_BUTTON.value + print("$$$CAMERA_SCC") # Common lateral control setup ret.centerToFront = ret.wheelbase * 0.4 ret.steerActuatorDelay = 0.1 ret.steerLimitTimer = 0.4 - CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) + if ret.flags & HyundaiFlags.ANGLE_CONTROL: + ret.steerControlType = SteerControlType.angle + else: + CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) if ret.flags & HyundaiFlags.ALT_LIMITS: ret.safetyConfigs[-1].safetyParam |= HyundaiSafetyFlags.ALT_LIMITS.value - if ret.flags & HyundaiFlags.ALT_LIMITS_2: - ret.safetyConfigs[-1].safetyParam |= HyundaiSafetyFlags.ALT_LIMITS_2.value - - # see https://github.com/commaai/iqdbc/pull/1137/ - ret.dashcamOnly = True - # Common longitudinal control setup ret.radarUnavailable = RADAR_START_ADDR not in fingerprint[1] or Bus.radar not in DBC[ret.carFingerprint] ret.openpilotLongitudinalControl = alpha_long and ret.alphaLongitudinalAvailable + + # carrot, if camera_scc enabled, enable openpilotLongitudinalControl + enable_radar_tracks = params.get_int("EnableRadarTracks") + if ret.flags & HyundaiFlags.CAMERA_SCC.value or enable_radar_tracks > 0 or enable_radar_tracks == -2: + ret.radarUnavailable = False + ret.openpilotLongitudinalControl = True if camera_scc < 3 else False + print(f"$$$OenpilotLongitudinalControl = True, CAMERA_SCC({ret.flags & HyundaiFlags.CAMERA_SCC.value}) or RadarTracks{enable_radar_tracks}") + else: + print(f"$$$OenpilotLongitudinalControl = {alpha_long}") + + #ret.radarUnavailable = False # TODO: canfd... carrot, hyundai cars have radar + + ret.radarTimeStep = 0.05 #if params.get_int("EnableRadarTracks") > 0 else 0.02 + ret.pcmCruise = not ret.openpilotLongitudinalControl + ret.startingState = False # True # carrot + ret.vEgoStarting = 0.1 + ret.startAccel = 1.0 ret.longitudinalActuatorDelay = 0.5 + ret.longitudinalTuning.kpBP = [0.] + ret.longitudinalTuning.kpV = [1.] + ret.longitudinalTuning.kf = 1.0 + + # *** feature detection *** + if ret.flags & HyundaiFlags.CANFD: + print(f"$$$$$ CanFD ECAN = {CAN.ECAN}") + if 0x1fa in fingerprint[CAN.ECAN]: + ret.extFlags |= HyundaiExtFlags.NAVI_CLUSTER.value + print("$$$$ NaviCluster = True") + else: + print("$$$$ NaviCluster = False") + + else: + if 1348 in fingerprint[0]: + ret.extFlags |= HyundaiExtFlags.NAVI_CLUSTER.value + print("$$$$ NaviCluster = True") + if 1157 in fingerprint[0] or 1157 in fingerprint[2]: + ret.extFlags |= HyundaiExtFlags.HAS_LFAHDA.value + print("$$$$ HasLFAHDA") + if 1007 in fingerprint[0]: + print("#### cruiseButtonAlt") + + print(f"$$$$ enableBsm = {ret.enableBsm}") + if ret.openpilotLongitudinalControl: ret.safetyConfigs[-1].safetyParam |= HyundaiSafetyFlags.LONG.value if ret.flags & HyundaiFlags.HYBRID: @@ -152,95 +250,56 @@ class CarInterface(CarInterfaceBase): # Dashcam cars are missing a test route, or otherwise need validation # TODO: Optima Hybrid 2017 uses a different SCC12 checksum - if candidate in (CAR.KIA_OPTIMA_H,): - ret.dashcamOnly = True + #ret.dashcamOnly = candidate in {CAR.KIA_OPTIMA_H, } return ret @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: - # identical logic used in _get_params - # "LKA steering" if LKAS or LKAS_ALT messages are seen coming from the camera. - # Generally means our LKAS message is forwarded to another ECU (commonly ADAS ECU) - # that finally retransmits our steering command in LFA or LFA_ALT to the MDPS. - # "LFA steering" if camera directly sends LFA to the MDPS - cam_can = CanBus(None, fingerprint).CAM - lka_steering = 0x50 in fingerprint[cam_can] or 0x110 in fingerprint[cam_can] - CAN = CanBus(None, fingerprint, lka_steering) + def init(CP, can_recv, can_send): - if not stock_cp.flags & HyundaiFlags.CANFD: - # TODO-IQ: add route with ESCC message for process replay - if ESCC_MSG in fingerprint[0]: - ret.flags |= HyundaiFlagsIQ.ENHANCED_SCC.value + Params().put_int('LongitudinalPersonalityMax', 4) - if ret.flags & HyundaiFlagsIQ.ENHANCED_SCC: - ret.iqSafetyFlags |= HyundaiSafetyFlagsIQ.ESCC - stock_cp.radarUnavailable = False - - if stock_cp.flags & HyundaiFlags.HAS_LDA_BUTTON: - ret.iqSafetyFlags |= HyundaiSafetyFlagsIQ.HAS_LDA_BUTTON - - if stock_cp.flags & (HyundaiFlags.CANFD_CAMERA_SCC | HyundaiFlags.CAMERA_SCC): - stock_cp.radarUnavailable = False - - if stock_cp.flags & HyundaiFlags.ALT_LIMITS_2: - stock_cp.dashcamOnly = False - - if ret.flags & HyundaiFlagsIQ.NON_SCC: - stock_cp.alphaLongitudinalAvailable = False - stock_cp.openpilotLongitudinalControl = False - stock_cp.pcmCruise = True - ret.iqSafetyFlags |= HyundaiSafetyFlagsIQ.NON_SCC - - # untested non-SCC platforms, need user validations - if stock_cp.carFingerprint in (CAR.HYUNDAI_BAYON_1ST_GEN_NON_SCC, CAR.KIA_FORTE_2021_NON_SCC, - CAR.KIA_SELTOS_2023_NON_SCC, CAR.GENESIS_G70_2021_NON_SCC): - stock_cp.dashcamOnly = True - - if stock_cp.flags & HyundaiFlags.CANFD: - if 0x1fa in fingerprint[CAN.ECAN]: - ret.flags |= HyundaiFlagsIQ.SPEED_LIMIT_AVAILABLE.value - else: - # Detect smartMDPS, which bypasses EPS low-speed lockout, allowing iqpilot to send steering commands down to 0 - if 0x2AA in fingerprint[0]: - stock_cp.minSteerSpeed = 0.0 - stock_cp.flags &= ~HyundaiFlags.MIN_STEER_32_MPH.value - - if 0x544 in fingerprint[0]: - ret.flags |= HyundaiFlagsIQ.SPEED_LIMIT_AVAILABLE.value - - if 0x53E in fingerprint[2]: - ret.flags |= HyundaiFlagsIQ.HAS_LKAS12.value - - - return ret - - @staticmethod - def _get_longitudinal_tuning_iq(stock_cp: structs.CarParams, ret: structs.IQCarParams) -> structs.IQCarParams: - if ret.flags & (HyundaiFlagsIQ.LONG_TUNING_DYNAMIC | HyundaiFlagsIQ.LONG_TUNING_PREDICTIVE): - get_longitudinal_tune(stock_cp) - - return ret - - @staticmethod - def init(CP, CP_IQ, can_recv, can_send, communication_control=None): - # 0x80 silences response - if communication_control is None: - communication_control = bytes([uds.SERVICE_TYPE.COMMUNICATION_CONTROL, 0x80 | uds.CONTROL_TYPE.DISABLE_RX_DISABLE_TX, uds.MESSAGE_TYPE.NORMAL]) - - if CP.openpilotLongitudinalControl and not ((CP.flags & (HyundaiFlags.CANFD_CAMERA_SCC | HyundaiFlags.CAMERA_SCC)) or - (CP_IQ.flags & HyundaiFlagsIQ.ENHANCED_SCC)): - addr, bus = 0x7d0, CanBus(CP).ECAN if CP.flags & HyundaiFlags.CANFD else 0 - if CP.flags & HyundaiFlags.CANFD_LKA_STEERING.value: + if CP.openpilotLongitudinalControl and not (CP.flags & HyundaiFlags.CANFD_CAMERA_SCC): + addr, bus = 0x7d0, 0 + if CP.flags & HyundaiFlags.CANFD_HDA2.value: addr, bus = 0x730, CanBus(CP).ECAN - disable_ecu(can_recv, can_send, bus=bus, addr=addr, com_cont_req=communication_control) + disable_ecu(can_recv, can_send, bus=bus, addr=addr, com_cont_req=b'\x28\x83\x01') + + params = Params() + if params.get_int("EnableRadarTracks") > 0 and not CP.flags & HyundaiFlags.CANFD: + result = enable_radar_tracks(CP, can_recv, can_send) + params.put_bool("EnableRadarTracksResult", result) # for blinkers if CP.flags & HyundaiFlags.ENABLE_BLINKERS: - disable_ecu(can_recv, can_send, bus=CanBus(CP).ECAN, addr=0x7B1, com_cont_req=communication_control) + disable_ecu(can_recv, can_send, bus=CanBus(CP).ECAN, addr=0x7B1, com_cont_req=b'\x28\x83\x01') - @staticmethod - def deinit(CP, can_recv, can_send): - communication_control = bytes([uds.SERVICE_TYPE.COMMUNICATION_CONTROL, 0x80 | uds.CONTROL_TYPE.ENABLE_RX_ENABLE_TX, uds.MESSAGE_TYPE.NORMAL]) - CarInterface.init(CP, can_recv, can_send, communication_control) +def enable_radar_tracks(CP, logcan, sendcan): + from iqdbc.car.isotp_parallel_query import IsoTpParallelQuery + print("################ Try To Enable Radar Tracks ####################") + + ret = False + sccBus = 2 if CP.flags & HyundaiFlags.CAMERA_SCC.value else 0 + rdr_fw = None + rdr_fw_address = 0x7d0 # + try: + try: + query = IsoTpParallelQuery(sendcan, logcan, sccBus, [rdr_fw_address], [b'\x10\x07'], [b'\x50\x07']) + for addr, dat in query.get_data(0.1).items(): # pylint: disable=unused-variable + print("ecu write data by id ...") + new_config = b"\x00\x00\x00\x01\x00\x01" + #new_config = b"\x00\x00\x00\x00\x00\x01" + dataId = b'\x01\x42' + WRITE_DAT_REQUEST = b'\x2e' + WRITE_DAT_RESPONSE = b'\x68' + query = IsoTpParallelQuery(sendcan, logcan, sccBus, [rdr_fw_address], [WRITE_DAT_REQUEST+dataId+new_config], [WRITE_DAT_RESPONSE]) + result = query.get_data(0) + print("result=", result) + ret = True + break + except Exception as e: + print(f"Failed : {e}") + except Exception as e: + print("############## Failed to enable tracks" + str(e)) + print("################ END Try to enable radar tracks") + return ret diff --git a/iqdbc_repo/iqdbc/car/hyundai/radar_interface.py b/iqdbc_repo/iqdbc/car/hyundai/radar_interface.py index c2ed03c..7aab917 100644 --- a/iqdbc_repo/iqdbc/car/hyundai/radar_interface.py +++ b/iqdbc_repo/iqdbc/car/hyundai/radar_interface.py @@ -1,86 +1,885 @@ import math +import os +from collections import deque +from iqdbc import DBC_PATH from iqdbc.can import CANParser from iqdbc.car import Bus, structs from iqdbc.car.interfaces import RadarInterfaceBase -from iqdbc.car.hyundai.values import DBC - -from iqdbc.iqpilot.car.hyundai.radar_interface_ext import RadarInterfaceExt +from iqdbc.car.hyundai.values import DBC, HyundaiFlags, HyundaiExtFlags +from openpilot.common.params import Params +from iqdbc.car.hyundai.hyundaicanfd import CanBus +from openpilot.common.filter_simple import MyMovingAverage +SCC_TID = 0 RADAR_START_ADDR = 0x500 RADAR_MSG_COUNT = 32 +RADAR_MSG_COUNT4 = 8 +RADAR_GROUP4_MAX_LONG_DIST = 325.0 +RADAR_GROUP4_MAX_YREL = 6.0 +RADAR_START_ADDR_CANFD1 = 0x210 +RADAR_MSG_COUNT1 = 16 +RADAR_START_ADDR_CANFD2 = 0x3A5 # Group 2, Group 1: 0x210 2개씩?어???단 보류. +RADAR_MSG_COUNT2 = 32 +RADAR_START_ADDR_CANFD3 = 0x400 +RADAR_MSG_COUNT3 = 30 +CORNER_OBJECT_235_START_ADDR = 0x235 +CORNER_OBJECT_235_MSG_COUNT = 20 +CORNER_OBJECT_235_TRACK_ID_OFFSET = 200 +CORNER_OBJECT_235_DBC = 'hyundai_canfd_corner_radar_235_generated' +CORNER_OBJECT_180_START_ADDR = 0x180 +CORNER_OBJECT_180_MSG_COUNT = 5 +CORNER_OBJECT_180_SLOTS_PER_MSG = 2 +CORNER_OBJECT_180_TRACK_ID_OFFSET = 240 +CORNER_OBJECT_180_DBC = 'hyundai_canfd_corner_radar_180_generated' +CORNER_OBJECT_430_LEFT_START_ADDR = 0x430 +CORNER_OBJECT_430_RIGHT_START_ADDR = 0x440 +CORNER_OBJECT_430_MSG_COUNT_PER_SIDE = 8 +CORNER_OBJECT_430_SLOTS_PER_MSG = 7 +CORNER_OBJECT_430_TRACK_ID_OFFSET = 300 +CORNER_OBJECT_430_DBC = 'hyundai_canfd_corner_radar_430_generated' +CORNER_OBJECT_430_EMPTY_RAW_VALUES = (0x010d1f40, 0x00010d1f) +CORNER_OBJECT_430_DEFAULT_DISTANCE_RAW_MIN = 2520 # 126.0 m +CORNER_OBJECT_430_DEFAULT_DISTANCE_RAW_MAX = 2600 # 130.0 m +CORNER_OBJECT_430_MAX_DREL = 120.0 +CORNER_OBJECT_430_MAX_TRACKS_PER_SIDE = 4 +CORNER_OBJECT_430_DT = 0.05 +CORNER_OBJECT_430_MAX_DREL_DELTA = 1.5 +CORNER_OBJECT_430_CANDIDATE_META_BYTE_3 = (2,) +CORNER_OBJECT_430_CANDIDATE_EXCLUDED_SLOTS = (1,) +CORNER_OBJECT_430_CANDIDATE_RAW_DELTA = 200 +CORNER_OBJECT_430_STRONG_META_BYTE_2 = (10,) +CORNER_OBJECT_430_WEAK_META_BYTE_2 = (5, 6, 7, 8, 9) +CORNER_OBJECT_430_STRONG_MIN_SUPPORT = 2 +CORNER_OBJECT_430_WEAK_MIN_SUPPORT = 3 +CORNER_OBJECT_430_CLUSTER_RAW_GAP = 200 +CORNER_OBJECT_430_TRACK_MATCH_MAX_DREL_DELTA = 3.0 +CORNER_OBJECT_430_MAX_ABS_VREL = 20.0 +CORNER_OBJECT_430_MAX_ABS_YVREL = 3.0 +CORNER_OBJECT_430_VREL_ALPHA = 0.35 +CORNER_OBJECT_430_YVREL_ALPHA = 0.35 +CORNER_OBJECT_430_LATERAL_CELL_MSG_WEIGHT = 0.35 +CORNER_OBJECT_430_LATERAL_CELL_SLOT_WEIGHT = 0.65 +CORNER_OBJECT_430_YREL_OFFSET = 5.8 +CORNER_OBJECT_430_YREL_SCALE = 1.1 +CORNER_OBJECT_430_RIGHT_CELL_MIRROR = 7.0 +CORNER_OBJECT_430_MIN_ABS_YREL = 0.8 +CORNER_OBJECT_430_MAX_ABS_YREL = 4.2 +CORNER_OBJECT_430_HISTORY_SIZE = 8 +CORNER_OBJECT_430_MIN_HISTORY = 5 +CORNER_OBJECT_430_MIN_INWARD_YREL_DELTA = 0.35 +CORNER_OBJECT_430_MIN_RECENT_INWARD_YREL_DELTA = 0.05 +CORNER_OBJECT_430_MIN_INWARD_RATIO = 0.65 +CORNER_OBJECT_430_INWARD_CENTER_ABS_YREL = 1.55 +CORNER_OBJECT_430_INWARD_KEEP_YVREL_ABS_YREL = 2.2 +CORNER_OBJECT_430_EARLY_INWARD_NONCENTER_FRAMES = 2 +CORNER_OBJECT_430_SIDE_KEEP_ABS_YREL = 2.0 +CORNER_OBJECT_STABLE_TRACK_ID_START = 1000 +CORNER_SIDE_OBJECT_MAX_DREL = 0.2 +CORNER_SIDE_OBJECT_MIN_ABS_YREL = 1.4 +CORNER_SIDE_OBJECT_MAX_ABS_YREL = 4.5 # POC for parsing corner radars: https://github.com/commaai/openpilot/pull/24221/ -def get_radar_can_parser(CP): - if Bus.radar not in DBC[CP.carFingerprint]: +class CornerObjectTrackIdManager: + def __init__(self): + self.next_track_id = CORNER_OBJECT_STABLE_TRACK_ID_START + self.objects: dict[tuple[str, int], tuple[int, int]] = {} + + def get_track_id(self, source: str, object_id: int, age: int) -> int: + key = (source, object_id) + previous = self.objects.get(key) + if previous is None or age < previous[1]: + track_id = self.next_track_id + self.next_track_id += 1 + else: + track_id = previous[0] + self.objects[key] = (track_id, age) + return track_id + + def clear_source(self, source: str): + self.objects = {key: value for key, value in self.objects.items() if key[0] != source} + + +def corner_object_position_valid(d_rel: float, y_rel: float) -> bool: + normal_object = 0.2 < d_rel < 180.0 + clipped_side_object = ( + 0.0 <= d_rel <= CORNER_SIDE_OBJECT_MAX_DREL and + CORNER_SIDE_OBJECT_MIN_ABS_YREL <= abs(y_rel) <= CORNER_SIDE_OBJECT_MAX_ABS_YREL + ) + return (normal_object or clipped_side_object) and abs(y_rel) < 40.0 + + +def get_radar_can_parser(CP, radar_tracks, msg_start_addr, msg_count, radar_group4=False): + if not radar_tracks: + return None + #if Bus.radar not in DBC[CP.carFingerprint]: + # return None + print("RadarInterface: RadarTracks...") + + if CP.flags & HyundaiFlags.CANFD: + CAN = CanBus(CP) + messages = [(f"RADAR_TRACK_{addr:x}", 20) for addr in range(msg_start_addr, msg_start_addr + msg_count)] + return CANParser('hyundai_canfd_radar_generated', messages, CAN.ACAN) + else: + messages = [(f"RADAR_TRACK_{addr:x}", 20) for addr in range(msg_start_addr, msg_start_addr + msg_count)] + #return CANParser(DBC[CP.carFingerprint][Bus.radar], messages, 1) + dbc_name = 'hyundai_kia_denso_front_radar_generated' if radar_group4 else 'hyundai_kia_mando_front_radar_generated' + return CANParser(dbc_name, messages, 1) + +def get_corner_object_can_parser(CP, enabled): + if not enabled or not (CP.flags & HyundaiFlags.CANFD): return None - messages = [(f"RADAR_TRACK_{addr:x}", 50) for addr in range(RADAR_START_ADDR, RADAR_START_ADDR + RADAR_MSG_COUNT)] - return CANParser(DBC[CP.carFingerprint][Bus.radar], messages, 1) + dbc_path = os.path.join(DBC_PATH, f"{CORNER_OBJECT_235_DBC}.dbc") + if not os.path.exists(dbc_path): + print(f"RadarInterface: missing {CORNER_OBJECT_235_DBC}.dbc, 0x235 corner radar disabled") + return None + CAN = CanBus(CP) + messages = [(f"CORNER_RADAR_235_OBJECTS_{addr:x}", 33) for addr in range(CORNER_OBJECT_235_START_ADDR, CORNER_OBJECT_235_START_ADDR + CORNER_OBJECT_235_MSG_COUNT)] + return CANParser(CORNER_OBJECT_235_DBC, messages, CAN.ACAN) -class RadarInterface(RadarInterfaceBase, RadarInterfaceExt): - def __init__(self, CP, CP_IQ): - RadarInterfaceBase.__init__(self, CP, CP_IQ) - RadarInterfaceExt.__init__(self, CP, CP_IQ) - self.updated_messages = set() - self.trigger_msg = RADAR_START_ADDR + RADAR_MSG_COUNT - 1 +def get_corner_object_180_can_parser(CP, enabled): + if not enabled or not (CP.flags & HyundaiFlags.CANFD): + return None + + dbc_path = os.path.join(DBC_PATH, f"{CORNER_OBJECT_180_DBC}.dbc") + if not os.path.exists(dbc_path): + print(f"RadarInterface: missing {CORNER_OBJECT_180_DBC}.dbc, 0x180 corner radar disabled") + return None + + CAN = CanBus(CP) + messages = [(f"CORNER_RADAR_180_OBJECTS_{addr:x}", 33) for addr in range(CORNER_OBJECT_180_START_ADDR, CORNER_OBJECT_180_START_ADDR + CORNER_OBJECT_180_MSG_COUNT)] + return CANParser(CORNER_OBJECT_180_DBC, messages, CAN.ACAN) + +def get_corner_object_430_can_parser(CP, enabled): + if not enabled or not (CP.flags & HyundaiFlags.CANFD): + return None + + dbc_path = os.path.join(DBC_PATH, f"{CORNER_OBJECT_430_DBC}.dbc") + if not os.path.exists(dbc_path): + print(f"RadarInterface: missing {CORNER_OBJECT_430_DBC}.dbc, 0x430/0x440 corner radar disabled") + return None + + CAN = CanBus(CP) + messages = [(f"CORNER_RADAR_430_OBJECTS_{addr:x}", 33) for addr in range(CORNER_OBJECT_430_LEFT_START_ADDR, CORNER_OBJECT_430_LEFT_START_ADDR + CORNER_OBJECT_430_MSG_COUNT_PER_SIDE)] + messages += [(f"CORNER_RADAR_430_OBJECTS_{addr:x}", 33) for addr in range(CORNER_OBJECT_430_RIGHT_START_ADDR, CORNER_OBJECT_430_RIGHT_START_ADDR + CORNER_OBJECT_430_MSG_COUNT_PER_SIDE)] + return CANParser(CORNER_OBJECT_430_DBC, messages, CAN.ACAN) + +def get_radar_can_parser_scc(CP): + CAN = CanBus(CP) + if CP.flags & HyundaiFlags.CANFD: + messages = [("SCC_CONTROL", 50)] + bus = CAN.ECAN + else: + messages = [("SCC11", 50)] + bus = CAN.ECAN + + print("$$$$$$$$ ECAN = ", CAN.ECAN) + bus = CAN.CAM if CP.flags & HyundaiFlags.CAMERA_SCC else bus + return CANParser(DBC[CP.carFingerprint][Bus.pt], messages, bus) + +class RadarInterface(RadarInterfaceBase): + def __init__(self, CP, CP_IQ=None): + super().__init__(CP, CP_IQ or structs.IQCarParams()) + self.v_ego = 0.0 + + self.canfd = True if CP.flags & HyundaiFlags.CANFD else False + self.radar_group1 = False + self.radar_group3 = False + self.radar_group4 = not self.canfd and bool(CP.extFlags & HyundaiExtFlags.RADAR_GROUP4.value) + if self.canfd: + if CP.extFlags & HyundaiExtFlags.RADAR_GROUP1.value: + self.radar_start_addr = RADAR_START_ADDR_CANFD1 + self.radar_msg_count = RADAR_MSG_COUNT1 + self.radar_group1 = True + elif CP.extFlags & HyundaiExtFlags.RADAR_GROUP3.value: + self.radar_start_addr = RADAR_START_ADDR_CANFD3 + self.radar_msg_count = RADAR_MSG_COUNT3 + self.radar_group3 = True + else: + self.radar_start_addr = RADAR_START_ADDR_CANFD2 + self.radar_msg_count = RADAR_MSG_COUNT2 + else: + self.radar_start_addr = RADAR_START_ADDR + self.radar_msg_count = RADAR_MSG_COUNT4 if self.radar_group4 else RADAR_MSG_COUNT + + self.params = Params() + self.radar_tracks = self.params.get_int("EnableRadarTracks") >= 1 + self.corner_object_tracks = bool(CP.extFlags & HyundaiExtFlags.CORNER_RADAR_OBJECTS_235.value) and self.params.get_int("EnableCornerRadar") > 0 + self.corner_object_180_tracks = bool(CP.extFlags & HyundaiExtFlags.CORNER_RADAR_OBJECTS_180.value) and self.params.get_int("EnableCornerRadar") > 0 + self.corner_object_430_tracks = bool(CP.extFlags & HyundaiExtFlags.CORNER_RADAR_OBJECTS_430.value) and self.params.get_int("EnableCornerRadar") > 0 + self.updated_tracks = set() + self.updated_scc = set() + self.updated_corner_objects = set() + self.updated_corner_objects_180 = set() + self.updated_corner_objects_430 = set() + self.corner_object_missed_updates = 0 + self.corner_object_180_missed_updates = 0 + self.corner_object_430_missed_updates = 0 + self.corner_object_track_ids = CornerObjectTrackIdManager() + self.rcp_tracks = get_radar_can_parser(CP, self.radar_tracks, self.radar_start_addr, self.radar_msg_count, self.radar_group4) + self.rcp_corner_objects = get_corner_object_can_parser(CP, self.corner_object_tracks) + self.rcp_corner_objects_180 = get_corner_object_180_can_parser(CP, self.corner_object_180_tracks) + self.rcp_corner_objects_430 = get_corner_object_430_can_parser(CP, self.corner_object_430_tracks) + # Enabling raw radar tracks on legacy CAN disables the stock SCC11 stream on + # some Hyundai/Kia platforms. Camera-SCC cars may still use SCC11. + use_scc_parser = not (self.radar_tracks and not self.canfd and not (CP.flags & HyundaiFlags.CAMERA_SCC)) + self.rcp_scc = get_radar_can_parser_scc(CP) if use_scc_parser else None + self.trigger_msg_scc = 416 if self.canfd else 0x420 + + self.trigger_msg_tracks = self.radar_start_addr + self.radar_msg_count - 1 + self.trigger_msg_corner_objects = CORNER_OBJECT_235_START_ADDR + CORNER_OBJECT_235_MSG_COUNT - 1 + self.trigger_msg_corner_objects_180 = CORNER_OBJECT_180_START_ADDR + CORNER_OBJECT_180_MSG_COUNT - 1 + self.trigger_msg_corner_objects_430 = CORNER_OBJECT_430_RIGHT_START_ADDR + CORNER_OBJECT_430_MSG_COUNT_PER_SIDE - 1 self.track_id = 0 - self.radar_off_can = CP.radarUnavailable - self.rcp = get_radar_can_parser(CP) + self.corner_objects_available = self.rcp_corner_objects is not None or self.rcp_corner_objects_180 is not None or self.rcp_corner_objects_430 is not None + self.radar_off_can = CP.radarUnavailable and not self.corner_objects_available + print( + "RadarInterface: " + f"radarUnavailable={CP.radarUnavailable} radarTracks={self.radar_tracks} " + f"group4={self.radar_group4} " + f"corner235={self.rcp_corner_objects is not None} corner180={self.rcp_corner_objects_180 is not None} " + f"corner430={self.rcp_corner_objects_430 is not None} " + f"radarOffCan={self.radar_off_can}" + ) + + self.vRel_last = 0 + self.dRel_last = 0 + self.corner_object_430_prev_d_rel = {} + self.corner_object_430_prev_v_rel = {} + self.corner_object_430_prev_y_rel = {} + self.corner_object_430_prev_yv_rel = {} + self.corner_object_430_prev_code = {} + self.corner_object_430_history = {} + self.corner_object_430_noncenter_inward_frames = {} + + # Initialize pts + if self.rcp_tracks is not None: + total_tracks = self.radar_msg_count * (2 if self.radar_group1 else 1) + for track_id in range(total_tracks): + t_id = track_id + 32 + self.pts[t_id] = structs.RadarData.RadarPoint() + self.pts[t_id].measured = False + self.pts[t_id].trackId = t_id + + if self.rcp_scc is not None: + self.pts[SCC_TID] = structs.RadarData.RadarPoint() + self.pts[SCC_TID].trackId = SCC_TID + self.pts[SCC_TID].radarSource = "scc" + if self.rcp_corner_objects is not None: + for slot in range(CORNER_OBJECT_235_MSG_COUNT): + t_id = CORNER_OBJECT_235_TRACK_ID_OFFSET + slot + self.pts[t_id] = structs.RadarData.RadarPoint() + self.pts[t_id].measured = False + self.pts[t_id].trackId = t_id + self.pts[t_id].radarSource = "corner235" + if self.rcp_corner_objects_180 is not None: + for slot in range(CORNER_OBJECT_180_MSG_COUNT * CORNER_OBJECT_180_SLOTS_PER_MSG): + t_id = CORNER_OBJECT_180_TRACK_ID_OFFSET + slot + self.pts[t_id] = structs.RadarData.RadarPoint() + self.pts[t_id].measured = False + self.pts[t_id].trackId = t_id + self.pts[t_id].radarSource = "corner180" + if self.rcp_corner_objects_430 is not None: + for slot in range(CORNER_OBJECT_430_MSG_COUNT_PER_SIDE * 2 * CORNER_OBJECT_430_SLOTS_PER_MSG): + t_id = CORNER_OBJECT_430_TRACK_ID_OFFSET + slot + self.pts[t_id] = structs.RadarData.RadarPoint() + self.pts[t_id].measured = False + self.pts[t_id].trackId = t_id + + self.frame = 0 - if self.rcp is None: - self.initialize_radar_ext(self.trigger_msg) def update(self, can_strings): - if self.radar_off_can or (self.rcp is None): + self.frame += 1 + if self.radar_off_can or (self.rcp_tracks is None and self.rcp_scc is None and self.rcp_corner_objects is None and self.rcp_corner_objects_180 is None and self.rcp_corner_objects_430 is None): return super().update(None) - vls = self.rcp.update(can_strings) - self.updated_messages.update(vls) + if self.rcp_scc is not None: + vls_s = self.rcp_scc.update(can_strings) + self.updated_scc.update(vls_s) - if self.trigger_msg not in self.updated_messages: + track_ready = False + if self.radar_tracks and self.rcp_tracks is not None: + vls_t = self.rcp_tracks.update(can_strings) + self.updated_tracks.update(vls_t) + track_ready = self.trigger_msg_tracks in self.updated_tracks + + corner_ready = False + if self.rcp_corner_objects is not None: + vls_c = self.rcp_corner_objects.update(can_strings) + self.updated_corner_objects.update(vls_c) + corner_ready = self.trigger_msg_corner_objects in self.updated_corner_objects + + corner_180_ready = False + if self.rcp_corner_objects_180 is not None: + vls_180 = self.rcp_corner_objects_180.update(can_strings) + self.updated_corner_objects_180.update(vls_180) + corner_180_ready = self.trigger_msg_corner_objects_180 in self.updated_corner_objects_180 + + corner_430_ready = False + if self.rcp_corner_objects_430 is not None: + vls_430 = self.rcp_corner_objects_430.update(can_strings) + self.updated_corner_objects_430.update(vls_430) + corner_430_ready = self.trigger_msg_corner_objects_430 in self.updated_corner_objects_430 + + scc_ready = not self.radar_tracks and self.frame % 5 == 0 and self.rcp_scc is not None + + if track_ready: + self._update(self.updated_tracks) + self.updated_tracks.clear() + + if corner_ready: + self._update_corner_objects(self.updated_corner_objects) + self.corner_object_missed_updates = 0 + self.updated_corner_objects.clear() + + if corner_180_ready: + self._update_corner_objects_180(self.updated_corner_objects_180) + self.corner_object_180_missed_updates = 0 + self.updated_corner_objects_180.clear() + + if corner_430_ready: + self._update_corner_objects_430(self.updated_corner_objects_430) + self.corner_object_430_missed_updates = 0 + self.updated_corner_objects_430.clear() + + # Corner radar runs at its own cadence. Do not let corner-only frames publish + # RadarData, since liveTracks uses a fixed radarTimeStep for aLead/jLead. + publish_ready = track_ready or scc_ready + if not publish_ready: return None - rr = self._update(self.updated_messages) - self.updated_messages.clear() + if self.rcp_scc is not None: + self._update_scc(self.updated_scc) + if self.rcp_corner_objects is not None: + if self.updated_corner_objects: + self._update_corner_objects(self.updated_corner_objects) + self.corner_object_missed_updates = 0 + else: + self.corner_object_missed_updates += 1 + if self.corner_object_missed_updates > 10: + self._clear_corner_objects() + if self.rcp_corner_objects_180 is not None: + if self.updated_corner_objects_180: + self._update_corner_objects_180(self.updated_corner_objects_180) + self.corner_object_180_missed_updates = 0 + else: + self.corner_object_180_missed_updates += 1 + if self.corner_object_180_missed_updates > 10: + self._clear_corner_objects_180() + if self.rcp_corner_objects_430 is not None: + if self.updated_corner_objects_430: + self._update_corner_objects_430(self.updated_corner_objects_430) + self.corner_object_430_missed_updates = 0 + else: + self.corner_object_430_missed_updates += 1 + if self.corner_object_430_missed_updates > 10: + self._clear_corner_objects_430() + self.updated_scc.clear() + self.updated_corner_objects.clear() + self.updated_corner_objects_180.clear() + self.updated_corner_objects_430.clear() - return rr + ret = structs.RadarData() + if ((self.rcp_tracks is not None and self.radar_tracks and not self.rcp_tracks.can_valid) or + (self.rcp_scc is not None and not self.corner_objects_available and not self.rcp_scc.can_valid) or + (self.rcp_corner_objects is not None and not self.rcp_corner_objects.can_valid) or + (self.rcp_corner_objects_180 is not None and not self.rcp_corner_objects_180.can_valid) or + (self.rcp_corner_objects_430 is not None and not self.rcp_corner_objects_430.can_valid)): + ret.errors.canError = True + ret.points = [point for point in self.pts.values() if point.measured] + return ret def _update(self, updated_messages): - ret = structs.RadarData() - if self.rcp is None: - return ret - if not self.rcp.can_valid: - ret.errors.canError = True + t_id = 32 + for addr in range(self.radar_start_addr, self.radar_start_addr + self.radar_msg_count): - if self.use_radar_interface_ext: - return self.update_ext(ret) - - for addr in range(RADAR_START_ADDR, RADAR_START_ADDR + RADAR_MSG_COUNT): - msg = self.rcp.vl[f"RADAR_TRACK_{addr:x}"] - - if addr not in self.pts: - self.pts[addr] = structs.RadarData.RadarPoint() - self.pts[addr].trackId = self.track_id - self.track_id += 1 - - valid = msg['STATE'] in (3, 4) - if valid: - azimuth = math.radians(msg['AZIMUTH']) - self.pts[addr].measured = True - self.pts[addr].dRel = math.cos(azimuth) * msg['LONG_DIST'] - self.pts[addr].yRel = 0.5 * -math.sin(azimuth) * msg['LONG_DIST'] - self.pts[addr].vRel = msg['REL_SPEED'] - self.pts[addr].aRel = msg['REL_ACCEL'] - self.pts[addr].yvRel = float('nan') + msg = self.rcp_tracks.vl[f"RADAR_TRACK_{addr:x}"] + if self.radar_group1: + valid = msg['VALID_CNT1'] > 10 + elif self.radar_group3: + # Group 3 marks an empty object slot with LONG_DIST raw 0x7ff (204.7 m). + valid = msg['LONG_DIST'] < 204.7 + elif self.canfd: + valid = msg['VALID_CNT'] > 10 + elif self.radar_group4: + # EN: DNMWR006 exposes eight stable tracked-object slots at 0x500-0x507. + # Messages from 0x508 onward are distance-sorted raw detections without + # stable IDs, so they are excluded. OBJECT_STATE 3 is a confirmed track; + # empty slots use LONG_DIST raw 0xfff8 (409.55 m). Driving logs reached + # 317.80 m, so 325 m preserves every observed confirmed track while + # retaining margin from the empty-slot sentinel. Keep the +/-6 m + # ego/adjacent-lane envelope to suppress farther roadside reflections. + # KO: DNMWR006의 안정적인 추적 객체 슬롯은 0x500~0x507의 8개임. + # 0x508 이후 메시지는 고정 ID가 없는 거리순 raw detection이므로 제외함. + # OBJECT_STATE 3은 확정 추적 객체이며, 빈 슬롯은 LONG_DIST raw + # 0xfff8(409.55m)을 사용함. 주행 로그의 최대값은 317.80m였으므로 + # 325m 상한으로 관측된 확정 트랙을 모두 보존하면서 빈 슬롯 값과 충분한 + # 여유를 확보함. 원거리 도로변 반사를 줄이기 위해 좌우 6m 범위를 유지함. + valid = (msg['OBJECT_STATE'] == 3 and 0.2 < msg['LONG_DIST'] < RADAR_GROUP4_MAX_LONG_DIST and + abs(msg['LAT_DIST']) <= RADAR_GROUP4_MAX_YREL) else: - del self.pts[addr] + valid = msg['STATE'] in (3, 4) - ret.points = list(self.pts.values()) - return ret + self.pts[t_id].measured = bool(valid) + if not valid: + self.pts[t_id].dRel = 0 + self.pts[t_id].yRel = 0 + self.pts[t_id].vRel = 0 + self.pts[t_id].vLead = self.pts[t_id].vRel + self.v_ego + self.pts[t_id].aRel = float('nan') + self.pts[t_id].yvRel = 0 + elif self.radar_group1: + self.pts[t_id].dRel = msg['LONG_DIST1'] + self.pts[t_id].yRel = msg['LAT_DIST1'] + self.pts[t_id].vRel = msg['REL_SPEED1'] + self.pts[t_id].vLead = self.pts[t_id].vRel + self.v_ego + self.pts[t_id].aRel = msg['REL_ACCEL1'] + self.pts[t_id].yvRel = msg['LAT_SPEED1'] + elif self.canfd: + if self.radar_group3: + # Group 3 reports the object's center. Convert it to the rear surface to match SCC/vision dRel. + self.pts[t_id].dRel = max(0.0, msg['LONG_DIST'] - msg['OBJECT_LENGTH'] * 0.5 - 0.1) + else: + self.pts[t_id].dRel = msg['LONG_DIST'] + self.pts[t_id].yRel = msg['LAT_DIST'] + self.pts[t_id].vRel = msg['REL_SPEED'] + self.pts[t_id].vLead = self.pts[t_id].vRel + self.v_ego + self.pts[t_id].aRel = float('nan') if self.radar_group3 else msg['REL_ACCEL'] + self.pts[t_id].yvRel = 0.0 if self.radar_group3 else msg['LAT_SPEED'] + elif self.radar_group4: + self.pts[t_id].dRel = msg['LONG_DIST'] + self.pts[t_id].yRel = -msg['LAT_DIST'] + self.pts[t_id].vRel = msg['REL_SPEED'] + self.pts[t_id].vLead = self.pts[t_id].vRel + self.v_ego + self.pts[t_id].aRel = float('nan') + self.pts[t_id].yvRel = 0.0 + else: + azimuth = math.radians(msg['AZIMUTH']) + self.pts[t_id].dRel = math.cos(azimuth) * msg['LONG_DIST'] + self.pts[t_id].yRel = 0.5 * -math.sin(azimuth) * msg['LONG_DIST'] + self.pts[t_id].vRel = msg['REL_SPEED'] + self.pts[t_id].vLead = self.pts[t_id].vRel + self.v_ego + self.pts[t_id].aRel = msg['REL_ACCEL'] + self.pts[t_id].yvRel = 0.0 + + t_id += 1 + # radar group1? ?나??msg??2개의 ?이?? ?어?음. + if self.radar_group1: + for addr in range(self.radar_start_addr, self.radar_start_addr + self.radar_msg_count): + msg = self.rcp_tracks.vl[f"RADAR_TRACK_{addr:x}"] + + valid = msg['VALID_CNT2'] > 10 + self.pts[t_id].measured = bool(valid) + if not valid: + self.pts[t_id].dRel = 0 + self.pts[t_id].yRel = 0 + self.pts[t_id].vRel = 0 + self.pts[t_id].vLead = self.pts[t_id].vRel + self.v_ego + self.pts[t_id].aRel = float('nan') + self.pts[t_id].yvRel = 0 + else: + self.pts[t_id].dRel = msg['LONG_DIST2'] + self.pts[t_id].yRel = msg['LAT_DIST2'] + self.pts[t_id].vRel = msg['REL_SPEED2'] + self.pts[t_id].vLead = self.pts[t_id].vRel + self.v_ego + self.pts[t_id].aRel = msg['REL_ACCEL2'] + self.pts[t_id].yvRel = msg['LAT_SPEED2'] + + t_id += 1 + + def _update_corner_objects(self, updated_messages): + if self.rcp_corner_objects is None: + return + + if not updated_messages: + self._clear_corner_objects() + return + + candidates = [] + for slot, addr in enumerate(range(CORNER_OBJECT_235_START_ADDR, CORNER_OBJECT_235_START_ADDR + CORNER_OBJECT_235_MSG_COUNT)): + t_id = CORNER_OBJECT_235_TRACK_ID_OFFSET + slot + msg = self.rcp_corner_objects.vl[f"CORNER_RADAR_235_OBJECTS_{addr:x}"] + + d_rel = msg["OBJ_REL_POS_X"] + y_rel = msg["OBJ_REL_POS_Y"] + v_rel = msg["OBJ_REL_VEL_X"] + yv_rel = msg["OBJ_REL_VEL_Y"] + a_rel = msg["OBJ_REL_ACCEL_X"] + # Side objects are clipped to x=0 by the corner radar. Quality, identity, + # and lateral motion still describe a real object, so keep them for + # corner-confirmed front-radar association in radard. + valid = msg["OBJ_QUAL_LEVEL"] > 0 and corner_object_position_valid(d_rel, y_rel) and v_rel > -99.0 + + if not valid: + continue + candidates.append((t_id, int(msg["OBJ_OBJECT_ID"]), int(msg["OBJ_AGE"]), int(msg["OBJ_QUAL_LEVEL"]), + d_rel, y_rel, v_rel, yv_rel, a_rel)) + + self._apply_corner_objects("corner235", candidates, + range(CORNER_OBJECT_235_TRACK_ID_OFFSET, + CORNER_OBJECT_235_TRACK_ID_OFFSET + CORNER_OBJECT_235_MSG_COUNT)) + + def _update_corner_objects_180(self, updated_messages): + if self.rcp_corner_objects_180 is None: + return + + if not updated_messages: + self._clear_corner_objects_180() + return + + candidates = [] + for msg_index, addr in enumerate(range(CORNER_OBJECT_180_START_ADDR, CORNER_OBJECT_180_START_ADDR + CORNER_OBJECT_180_MSG_COUNT)): + msg = self.rcp_corner_objects_180.vl[f"CORNER_RADAR_180_OBJECTS_{addr:x}"] + for slot_index in range(CORNER_OBJECT_180_SLOTS_PER_MSG): + t_id = CORNER_OBJECT_180_TRACK_ID_OFFSET + msg_index * CORNER_OBJECT_180_SLOTS_PER_MSG + slot_index + prefix = f"SLOT{slot_index + 1}_" + d_rel = msg[f"{prefix}REL_POS_X"] + y_rel = msg[f"{prefix}REL_POS_Y"] + v_rel = msg[f"{prefix}REL_VEL_X"] + yv_rel = msg[f"{prefix}REL_VEL_Y"] + a_rel = msg[f"{prefix}REL_ACCEL_X"] + valid = msg[f"{prefix}QUAL_LEVEL"] > 0 and corner_object_position_valid(d_rel, y_rel) and v_rel > -99.0 + + if not valid: + continue + candidates.append((t_id, int(msg[f"{prefix}OBJECT_ID"]), int(msg[f"{prefix}AGE"]), int(msg[f"{prefix}QUAL_LEVEL"]), + d_rel, y_rel, v_rel, yv_rel, a_rel)) + + self._apply_corner_objects("corner180", candidates, + range(CORNER_OBJECT_180_TRACK_ID_OFFSET, + CORNER_OBJECT_180_TRACK_ID_OFFSET + CORNER_OBJECT_180_MSG_COUNT * CORNER_OBJECT_180_SLOTS_PER_MSG)) + + def _apply_corner_objects(self, source, candidates, slot_ids): + for t_id in slot_ids: + self._clear_point(t_id) + + # The same object can occupy two CAN slots for one cycle during a slot handoff. + # Publish only the newest/highest-quality copy so trackId stays unique. + objects = {} + for candidate in candidates: + object_id = candidate[1] + previous = objects.get(object_id) + if previous is None or (candidate[2], candidate[3]) > (previous[2], previous[3]): + objects[object_id] = candidate + + for t_id, object_id, age, _, d_rel, y_rel, v_rel, yv_rel, a_rel in objects.values(): + point = self.pts[t_id] + point.measured = True + point.trackId = self.corner_object_track_ids.get_track_id(source, object_id, age) + point.radarSource = source + point.dRel = d_rel + point.yRel = y_rel + point.vRel = v_rel + point.vLead = v_rel + self.v_ego + point.aRel = a_rel + point.yvRel = yv_rel + + + def _update_corner_objects_430(self, updated_messages): + if self.rcp_corner_objects_430 is None: + return + + if not updated_messages: + self._clear_corner_objects_430() + return + + bank_defs = ( + (CORNER_OBJECT_430_LEFT_START_ADDR, 1.0, 0), + (CORNER_OBJECT_430_RIGHT_START_ADDR, -1.0, CORNER_OBJECT_430_MSG_COUNT_PER_SIDE * CORNER_OBJECT_430_SLOTS_PER_MSG), + ) + for start_addr, side_sign, track_base in bank_defs: + bins = [] + for msg_index, addr in enumerate(range(start_addr, start_addr + CORNER_OBJECT_430_MSG_COUNT_PER_SIDE)): + msg = self.rcp_corner_objects_430.vl[f"CORNER_RADAR_430_OBJECTS_{addr:x}"] + for slot_index in range(CORNER_OBJECT_430_SLOTS_PER_MSG): + prefix = f"SLOT{slot_index + 1}_" + distance_raw = int(msg[f"{prefix}DISTANCE_RAW"]) + raw = ( + distance_raw | + (int(msg[f"{prefix}META_13_15"]) << 13) | + (int(msg[f"{prefix}META_BYTE_2"]) << 16) | + (int(msg[f"{prefix}META_BYTE_3"]) << 24) + ) + code = ( + int(msg[f"{prefix}META_13_15"]), + int(msg[f"{prefix}META_BYTE_2"]), + int(msg[f"{prefix}META_BYTE_3"]), + ) + d_rel = distance_raw * 0.05 + default_distance = CORNER_OBJECT_430_DEFAULT_DISTANCE_RAW_MIN <= distance_raw <= CORNER_OBJECT_430_DEFAULT_DISTANCE_RAW_MAX + base_valid = ( + raw not in CORNER_OBJECT_430_EMPTY_RAW_VALUES and + distance_raw not in (0, 8000, 8191) and + not default_distance and + 0.2 < d_rel < CORNER_OBJECT_430_MAX_DREL + ) + candidate_valid = ( + base_valid and + slot_index + 1 not in CORNER_OBJECT_430_CANDIDATE_EXCLUDED_SLOTS and + code[2] in CORNER_OBJECT_430_CANDIDATE_META_BYTE_3 and + code[1] in CORNER_OBJECT_430_STRONG_META_BYTE_2 + CORNER_OBJECT_430_WEAK_META_BYTE_2 + ) + bins.append({ + "msg_index": msg_index, + "slot_index": slot_index, + "distance_raw": distance_raw, + "d_rel": d_rel, + "code": code, + "candidate_valid": candidate_valid, + }) + + supported_bins = [] + candidates = [b for b in bins if b["candidate_valid"]] + for b in candidates: + support = 1 + for other in candidates: + if other is b: + continue + if abs(other["msg_index"] - b["msg_index"]) > 1: + continue + if abs(other["slot_index"] - b["slot_index"]) > 2: + continue + if abs(other["distance_raw"] - b["distance_raw"]) > CORNER_OBJECT_430_CANDIDATE_RAW_DELTA: + continue + support += 1 + min_support = (CORNER_OBJECT_430_STRONG_MIN_SUPPORT if b["code"][1] in CORNER_OBJECT_430_STRONG_META_BYTE_2 + else CORNER_OBJECT_430_WEAK_MIN_SUPPORT) + if support >= min_support: + supported_bins.append({**b, "support": support}) + + clusters = [] + for b in sorted(supported_bins, key=lambda item: item["distance_raw"]): + if not clusters or b["distance_raw"] - clusters[-1][-1]["distance_raw"] > CORNER_OBJECT_430_CLUSTER_RAW_GAP: + clusters.append([b]) + else: + clusters[-1].append(b) + clusters = sorted(clusters, key=lambda cluster: sum(b["distance_raw"] for b in cluster) / len(cluster))[:CORNER_OBJECT_430_MAX_TRACKS_PER_SIDE] + + cluster_objects = [] + for cluster in clusters: + msg_index = sum(b["msg_index"] for b in cluster) / len(cluster) + slot = sum(b["slot_index"] + 1 for b in cluster) / len(cluster) + lateral_cell = (CORNER_OBJECT_430_LATERAL_CELL_MSG_WEIGHT * msg_index + + CORNER_OBJECT_430_LATERAL_CELL_SLOT_WEIGHT * slot) + mapped_cell = lateral_cell if side_sign > 0.0 else CORNER_OBJECT_430_RIGHT_CELL_MIRROR - lateral_cell + y_abs = max(CORNER_OBJECT_430_MIN_ABS_YREL, + min(CORNER_OBJECT_430_MAX_ABS_YREL, + CORNER_OBJECT_430_YREL_OFFSET - CORNER_OBJECT_430_YREL_SCALE * mapped_cell)) + cluster_objects.append({ + "d_rel": sum(b["d_rel"] for b in cluster) / len(cluster), + "y_rel": side_sign * y_abs, + "code": max((b["code"] for b in cluster), key=lambda code: sum(1 for item in cluster if item["code"] == code)), + }) + + active_t_ids = set() + side_track_ids = [ + CORNER_OBJECT_430_TRACK_ID_OFFSET + track_base + slot + for slot in range(CORNER_OBJECT_430_MAX_TRACKS_PER_SIDE) + ] + unmatched_track_ids = {t_id for t_id in side_track_ids if t_id in self.corner_object_430_prev_d_rel} + unused_track_ids = [t_id for t_id in side_track_ids if t_id not in unmatched_track_ids] + + for cluster in cluster_objects: + d_rel = cluster["d_rel"] + code = cluster["code"] + matched_t_id = None + if unmatched_track_ids: + nearest_t_id = min(unmatched_track_ids, key=lambda t_id: abs(d_rel - self.corner_object_430_prev_d_rel[t_id])) + if abs(d_rel - self.corner_object_430_prev_d_rel[nearest_t_id]) <= CORNER_OBJECT_430_TRACK_MATCH_MAX_DREL_DELTA: + matched_t_id = nearest_t_id + unmatched_track_ids.remove(matched_t_id) + if matched_t_id is None and unused_track_ids: + matched_t_id = unused_track_ids.pop(0) + if matched_t_id is None: + continue + + t_id = matched_t_id + active_t_ids.add(t_id) + prev_d_rel = self.corner_object_430_prev_d_rel.get(t_id) + prev_code = self.corner_object_430_prev_code.get(t_id) + self.corner_object_430_prev_d_rel[t_id] = d_rel + self.corner_object_430_prev_y_rel[t_id] = cluster["y_rel"] + self.corner_object_430_prev_code[t_id] = code + reset_track = prev_d_rel is None or code != prev_code or abs(d_rel - prev_d_rel) > CORNER_OBJECT_430_MAX_DREL_DELTA + if reset_track: + self.corner_object_430_prev_v_rel.pop(t_id, None) + self.corner_object_430_prev_yv_rel.pop(t_id, None) + self.corner_object_430_history.pop(t_id, None) + self.corner_object_430_noncenter_inward_frames.pop(t_id, None) + + history = self.corner_object_430_history.setdefault(t_id, deque(maxlen=CORNER_OBJECT_430_HISTORY_SIZE)) + history.append((d_rel, cluster["y_rel"])) + if len(history) < CORNER_OBJECT_430_MIN_HISTORY: + self._clear_point(t_id) + continue + + window_dt = CORNER_OBJECT_430_DT * (len(history) - 1) + first_d_rel, first_y_rel = history[0] + hist_v_rel = (d_rel - first_d_rel) / window_dt + if abs(hist_v_rel) > CORNER_OBJECT_430_MAX_ABS_VREL: + self.corner_object_430_prev_v_rel.pop(t_id, None) + self.corner_object_430_prev_yv_rel.pop(t_id, None) + self.corner_object_430_history.pop(t_id, None) + self.corner_object_430_noncenter_inward_frames.pop(t_id, None) + self._clear_point(t_id) + continue + prev_v_rel = self.corner_object_430_prev_v_rel.get(t_id, hist_v_rel) + v_rel = (1.0 - CORNER_OBJECT_430_VREL_ALPHA) * prev_v_rel + CORNER_OBJECT_430_VREL_ALPHA * hist_v_rel + self.corner_object_430_prev_v_rel[t_id] = v_rel + + inward_steps = 0 + usable_steps = 0 + prev_abs_y = abs(history[0][1]) + for _, y_rel in list(history)[1:]: + abs_y = abs(y_rel) + delta = prev_abs_y - abs_y + if abs(delta) > 1e-3: + usable_steps += 1 + if delta > 0.0: + inward_steps += 1 + prev_abs_y = abs_y + net_inward_y = abs(first_y_rel) - abs(cluster["y_rel"]) + inward_ratio = inward_steps / usable_steps if usable_steps > 0 else 0.0 + hist_yv_rel = (cluster["y_rel"] - first_y_rel) / window_dt + recent_inward_y = abs(history[-3][1]) - abs(cluster["y_rel"]) if len(history) >= 3 else net_inward_y + if (net_inward_y < CORNER_OBJECT_430_MIN_INWARD_YREL_DELTA or + recent_inward_y < CORNER_OBJECT_430_MIN_RECENT_INWARD_YREL_DELTA or + inward_ratio < CORNER_OBJECT_430_MIN_INWARD_RATIO or + abs(hist_yv_rel) > CORNER_OBJECT_430_MAX_ABS_YVREL): + hist_yv_rel = 0.0 + inward_motion_candidate = hist_yv_rel != 0.0 and abs(cluster["y_rel"]) <= CORNER_OBJECT_430_INWARD_KEEP_YVREL_ABS_YREL + inward_center_candidate = inward_motion_candidate and abs(cluster["y_rel"]) <= CORNER_OBJECT_430_INWARD_CENTER_ABS_YREL + y_rel = cluster["y_rel"] + if inward_motion_candidate: + if inward_center_candidate: + self.corner_object_430_noncenter_inward_frames[t_id] = 0 + prev_yv_rel = self.corner_object_430_prev_yv_rel.get(t_id, hist_yv_rel) + yv_rel = (1.0 - CORNER_OBJECT_430_YVREL_ALPHA) * prev_yv_rel + CORNER_OBJECT_430_YVREL_ALPHA * hist_yv_rel + else: + noncenter_frames = self.corner_object_430_noncenter_inward_frames.get(t_id, 0) + 1 + self.corner_object_430_noncenter_inward_frames[t_id] = noncenter_frames + if noncenter_frames <= CORNER_OBJECT_430_EARLY_INWARD_NONCENTER_FRAMES: + prev_yv_rel = self.corner_object_430_prev_yv_rel.get(t_id, hist_yv_rel) + yv_rel = (1.0 - CORNER_OBJECT_430_YVREL_ALPHA) * prev_yv_rel + CORNER_OBJECT_430_YVREL_ALPHA * hist_yv_rel + else: + yv_rel = 0.0 + if not inward_center_candidate and abs(y_rel) < CORNER_OBJECT_430_SIDE_KEEP_ABS_YREL: + y_rel = math.copysign(CORNER_OBJECT_430_SIDE_KEEP_ABS_YREL, y_rel) + else: + hist_yv_rel = 0.0 + yv_rel = 0.0 + self.corner_object_430_noncenter_inward_frames[t_id] = 0 + if abs(y_rel) < CORNER_OBJECT_430_SIDE_KEEP_ABS_YREL: + y_rel = math.copysign(CORNER_OBJECT_430_SIDE_KEEP_ABS_YREL, y_rel) + self.corner_object_430_prev_yv_rel[t_id] = yv_rel + + self.pts[t_id].measured = True + self.pts[t_id].trackId = t_id + self.pts[t_id].dRel = d_rel + self.pts[t_id].yRel = y_rel + self.pts[t_id].vRel = v_rel + self.pts[t_id].vLead = v_rel + self.v_ego + self.pts[t_id].aRel = float('nan') + self.pts[t_id].yvRel = yv_rel + + side_track_count = CORNER_OBJECT_430_MSG_COUNT_PER_SIDE * CORNER_OBJECT_430_SLOTS_PER_MSG + for slot in range(side_track_count): + t_id = CORNER_OBJECT_430_TRACK_ID_OFFSET + track_base + slot + if t_id in active_t_ids: + continue + self.corner_object_430_prev_d_rel.pop(t_id, None) + self.corner_object_430_prev_v_rel.pop(t_id, None) + self.corner_object_430_prev_y_rel.pop(t_id, None) + self.corner_object_430_prev_yv_rel.pop(t_id, None) + self.corner_object_430_prev_code.pop(t_id, None) + self.corner_object_430_history.pop(t_id, None) + self.corner_object_430_noncenter_inward_frames.pop(t_id, None) + self._clear_point(t_id) + + + def _clear_point(self, t_id): + self.pts[t_id].measured = False + self.pts[t_id].dRel = 0 + self.pts[t_id].yRel = 0 + self.pts[t_id].vRel = 0 + self.pts[t_id].vLead = self.v_ego + self.pts[t_id].aRel = float('nan') + self.pts[t_id].yvRel = 0 + + def _clear_corner_objects(self): + for slot in range(CORNER_OBJECT_235_MSG_COUNT): + self._clear_point(CORNER_OBJECT_235_TRACK_ID_OFFSET + slot) + self.corner_object_track_ids.clear_source("corner235") + + def _clear_corner_objects_180(self): + for slot in range(CORNER_OBJECT_180_MSG_COUNT * CORNER_OBJECT_180_SLOTS_PER_MSG): + self._clear_point(CORNER_OBJECT_180_TRACK_ID_OFFSET + slot) + self.corner_object_track_ids.clear_source("corner180") + + def _clear_corner_objects_430(self): + self.corner_object_430_prev_d_rel.clear() + self.corner_object_430_prev_v_rel.clear() + self.corner_object_430_prev_y_rel.clear() + self.corner_object_430_prev_yv_rel.clear() + self.corner_object_430_prev_code.clear() + self.corner_object_430_history.clear() + self.corner_object_430_noncenter_inward_frames.clear() + for slot in range(CORNER_OBJECT_430_MSG_COUNT_PER_SIDE * 2 * CORNER_OBJECT_430_SLOTS_PER_MSG): + self._clear_point(CORNER_OBJECT_430_TRACK_ID_OFFSET + slot) + + def _update_scc(self, updated_messages): + cpt = self.rcp_scc.vl + t_id = SCC_TID + if self.canfd: + dRel = cpt["SCC_CONTROL"]['ACC_ObjDist'] + vRel = cpt["SCC_CONTROL"]['ACC_ObjRelSpd'] + new_pts = abs(dRel - self.dRel_last) > 3 or abs(vRel - self.vRel_last) > 1 + vLead = vRel + self.v_ego + valid = 0 < dRel < 150 and not new_pts #cpt["SCC_CONTROL"]['OBJ_STATUS'] and dRel < 150 + self.pts[t_id].measured = bool(valid) + if not valid: + self.pts[t_id].dRel = 0 + self.pts[t_id].yRel = 0 + self.pts[t_id].vRel = 0 + self.pts[t_id].vLead = self.pts[t_id].vRel + self.v_ego + self.pts[t_id].aRel = float('nan') + self.pts[t_id].yvRel = 0 + else: + self.pts[t_id].dRel = dRel + self.pts[t_id].yRel = 0 + self.pts[t_id].vRel = vRel + self.pts[t_id].vLead = vLead + self.pts[t_id].aRel = float('nan') + self.pts[t_id].yvRel = 0 #float('nan') + else: + dRel = cpt["SCC11"]['ACC_ObjDist'] + vRel = cpt["SCC11"]['ACC_ObjRelSpd'] + new_pts = abs(dRel - self.dRel_last) > 3 or abs(vRel - self.vRel_last) > 1 + vLead = vRel + self.v_ego + valid = cpt["SCC11"]['ACC_ObjStatus'] and dRel < 150 and not new_pts + self.pts[t_id].measured = bool(valid) + if not valid: + self.pts[t_id].dRel = 0 + self.pts[t_id].yRel = 0 + self.pts[t_id].vRel = 0 + self.pts[t_id].vLead = self.pts[t_id].vRel + self.v_ego + self.pts[t_id].aRel = float('nan') + self.pts[t_id].yvRel = 0 + else: + self.pts[t_id].dRel = dRel + self.pts[t_id].yRel = -cpt["SCC11"]['ACC_ObjLatPos'] # in car frame's y axis, left is negative + self.pts[t_id].vRel = vRel + self.pts[t_id].vLead = vLead + self.pts[t_id].aRel = float('nan') + self.pts[t_id].yvRel = 0 #float('nan') + + self.dRel_last = dRel + self.vRel_last = vRel diff --git a/iqdbc_repo/iqdbc/car/hyundai/tests/print_platform_codes.py b/iqdbc_repo/iqdbc/car/hyundai/tests/print_platform_codes.py old mode 100755 new mode 100644 diff --git a/iqdbc_repo/iqdbc/car/hyundai/tests/test_ev_mode.py b/iqdbc_repo/iqdbc/car/hyundai/tests/test_ev_mode.py new file mode 100644 index 0000000..7338d7e --- /dev/null +++ b/iqdbc_repo/iqdbc/car/hyundai/tests/test_ev_mode.py @@ -0,0 +1,194 @@ +import math + +import pytest + +from iqdbc.can import CANPacker, CANParser +from iqdbc.car import Bus, gen_empty_fingerprint, structs +from iqdbc.car.hyundai.carstate import CarState, EV_MODE_STATUS_TIMEOUT_NS, _get_ev_mode_state +from iqdbc.car.hyundai.interface import CarInterface +from iqdbc.car.hyundai.values import CANFD_HYBRID_STATUS_ADDR, CANFD_HYBRID_STATUS_DLC, CAR, DBC, EV_MODE_ACTIVE_VALUES, \ + EV_MODE_STATUS_ADDR, EV_MODE_STATUS_DLC, EV_MODE_STATUS_MSG, EV_MODE_STATUS_SIGNAL, \ + HyundaiExtFlags, HyundaiFlags +from openpilot.common.params import Params + + +def get_params(candidate, *, hybrid=True, hybrid_bus=0, hybrid_status=None, hybrid_status_bus=0, + hybrid_status_dlc=CANFD_HYBRID_STATUS_DLC, status_bus=0, status_dlc=EV_MODE_STATUS_DLC): + Params().put_int("HyundaiCameraSCC", 1) + Params().put_int("CanfdHDA2", 1) + + fingerprint = gen_empty_fingerprint() + if hybrid: + fingerprint[hybrid_bus][0x105] = 32 + if hybrid_status is None: + hybrid_status = hybrid + if hybrid_status: + fingerprint[hybrid_status_bus][CANFD_HYBRID_STATUS_ADDR] = hybrid_status_dlc + if status_bus is not None: + fingerprint[status_bus][EV_MODE_STATUS_ADDR] = status_dlc + return CarInterface.get_params(candidate, fingerprint, [], False, False, False) + + +@pytest.mark.parametrize(("candidate", "hybrid", "status_bus", "status_dlc", "expected"), ( + (CAR.HYUNDAI_SANTAFE_MX5_HEV, True, 0, 32, True), + (CAR.HYUNDAI_SANTAFE_MX5_HEV, False, 0, 32, False), + (CAR.HYUNDAI_SANTAFE_MX5_HEV, True, None, 32, False), + (CAR.HYUNDAI_SANTAFE_MX5_HEV, True, 1, 32, False), + (CAR.HYUNDAI_SANTAFE_MX5_HEV, True, 0, 16, False), + (CAR.KIA_SORENTO_4TH_GEN, False, None, 32, False), + # Shared ICE/HEV/PHEV candidates rely on the observed ECAN capability frames, not their model name. + (CAR.HYUNDAI_TUCSON_4TH_GEN, True, 0, 32, True), + (CAR.HYUNDAI_TUCSON_4TH_GEN, False, 0, 32, False), + (CAR.KIA_SORENTO_HEV_4TH_GEN, True, 0, 32, True), + (CAR.HYUNDAI_KONA_HEV_2ND_GEN, True, 0, 32, True), + (CAR.HYUNDAI_KONA_HEV_2ND_GEN, False, 0, 32, False), + (CAR.HYUNDAI_ELANTRA_HEV_2021, True, 0, 32, False), +)) +def test_ev_mode_capability(candidate, hybrid, status_bus, status_dlc, expected): + CP = get_params(candidate, hybrid=hybrid, status_bus=status_bus, status_dlc=status_dlc) + assert bool(CP.extFlags & HyundaiExtFlags.EV_MODE_STATUS_230) == expected + + +@pytest.mark.parametrize(("hybrid_status_bus", "hybrid_status_dlc"), ( + (1, CANFD_HYBRID_STATUS_DLC), + (0, 16), +)) +def test_ev_mode_capability_requires_ecan_hybrid_status_dlc32(hybrid_status_bus, hybrid_status_dlc): + CP = get_params(CAR.HYUNDAI_SANTAFE_MX5_HEV, hybrid_status_bus=hybrid_status_bus, + hybrid_status_dlc=hybrid_status_dlc) + + assert not bool(CP.extFlags & HyundaiExtFlags.EV_MODE_STATUS_230) + + +def test_0x105_and_ev_status_without_0xfa_do_not_enable_ev_mode(): + CP = get_params(CAR.HYUNDAI_TUCSON_4TH_GEN, hybrid=True, hybrid_status=False) + + assert bool(CP.flags & HyundaiFlags.HYBRID) + assert not bool(CP.extFlags & HyundaiExtFlags.EV_MODE_STATUS_230) + + +def test_ev_mode_display_capability_does_not_change_hybrid_safety_classification(): + CP = get_params(CAR.HYUNDAI_TUCSON_4TH_GEN, hybrid=False, hybrid_status=True) + + assert not bool(CP.flags & HyundaiFlags.HYBRID) + assert bool(CP.extFlags & HyundaiExtFlags.EV_MODE_STATUS_230) + + +def test_ev_mode_capability_uses_the_detected_ecan_offset(): + CP = get_params(CAR.KIA_SORENTO_HEV_4TH_GEN, hybrid_bus=4, hybrid_status_bus=4, status_bus=4) + + assert bool(CP.extFlags & HyundaiExtFlags.EV_MODE_STATUS_230) + + +def test_ev_mode_parser_registration_is_capability_gated(): + supported = get_params(CAR.HYUNDAI_SANTAFE_MX5_HEV) + unsupported = get_params(CAR.KIA_SORENTO_4TH_GEN, hybrid=False, status_bus=1, status_dlc=16) + + supported_parser = CarState.get_can_parsers_canfd(None, supported)[Bus.pt] + unsupported_parser = CarState.get_can_parsers_canfd(None, unsupported)[Bus.pt] + + assert EV_MODE_STATUS_ADDR in supported_parser.addresses + assert supported_parser.message_states[EV_MODE_STATUS_ADDR].ignore_alive + assert supported_parser.message_states[EV_MODE_STATUS_ADDR].ignore_counter + assert EV_MODE_STATUS_ADDR not in unsupported_parser.addresses + + +def test_sorento_ice_corner_radar_status_does_not_enable_ev_mode(): + Params().put_int("HyundaiCameraSCC", 1) + Params().put_int("CanfdHDA2", 1) + + fingerprint = gen_empty_fingerprint() + fingerprint[1][0x230] = 16 # Actual Sorento ICE ACAN corner-radar status frame. + CP = CarInterface.get_params(CAR.KIA_SORENTO_4TH_GEN, fingerprint, [], False, False, False) + parser = CarState.get_can_parsers_canfd(None, CP)[Bus.pt] + + assert not bool(CP.extFlags & HyundaiExtFlags.EV_MODE_STATUS_230) + assert EV_MODE_STATUS_ADDR not in parser.addresses + + +def test_ev_mode_state_requires_a_fresh_dlc32_frame(): + CP = get_params(CAR.HYUNDAI_SANTAFE_MX5_HEV) + parser = CarState.get_can_parsers_canfd(None, CP)[Bus.pt] + packer = CANPacker(DBC[CP.carFingerprint][Bus.pt]) + + assert _get_ev_mode_state(parser) == (False, False) + + timestamp = 1_000_000_000 + wrong_bus_short_status = (EV_MODE_STATUS_ADDR, b"\x00" * 16, 1) + parser.update([timestamp, [wrong_bus_short_status]]) + assert _get_ev_mode_state(parser) == (False, False) + + ev_active = packer.make_can_msg(EV_MODE_STATUS_MSG, parser.bus, {"COUNTER": 1, EV_MODE_STATUS_SIGNAL: 6}) + parser.update([timestamp + 100_000_000, [ev_active]]) + assert _get_ev_mode_state(parser) == (True, True) + + ev_inactive = packer.make_can_msg(EV_MODE_STATUS_MSG, parser.bus, {"COUNTER": 2, EV_MODE_STATUS_SIGNAL: 3}) + parser.update([timestamp + 200_000_000, [ev_inactive]]) + assert _get_ev_mode_state(parser) == (False, True) + + parser.dat[EV_MODE_STATUS_ADDR] = b"\x00" * 16 + assert _get_ev_mode_state(parser) == (False, False) + + parser.dat[EV_MODE_STATUS_ADDR] = ev_inactive[1] + parser.update([timestamp + 200_000_000 + EV_MODE_STATUS_TIMEOUT_NS + 1, []]) + assert not parser.bus_timeout + assert _get_ev_mode_state(parser) == (False, False) + + +@pytest.mark.parametrize("mode", range(16)) +def test_ev_mode_enum_mapping(mode): + CP = get_params(CAR.HYUNDAI_SANTAFE_MX5_HEV) + parser = CarState.get_can_parsers_canfd(None, CP)[Bus.pt] + packer = CANPacker(DBC[CP.carFingerprint][Bus.pt]) + msg = packer.make_can_msg(EV_MODE_STATUS_MSG, parser.bus, {"COUNTER": mode, EV_MODE_STATUS_SIGNAL: mode}) + + parser.update([1_000_000_000, [msg]]) + + assert int(parser.vl[EV_MODE_STATUS_MSG][EV_MODE_STATUS_SIGNAL]) == mode + assert _get_ev_mode_state(parser) == (mode in EV_MODE_ACTIVE_VALUES, True) + + +@pytest.mark.parametrize(("payload", "expected_mode", "expected_active"), ( + ("758139048402000000000000000000000000d3009805001c24000000c05dc80f", 1, True), + ("4d466f048402000000000000000000000000bf007408001c24000000c05dc80f", 2, True), + ("32206e048402000000000000000000000000c9007418001c24000000c05dc80f", 6, True), + # Route 455 mode 3 was a false positive with the old single-bit 0x230 interpretation. + ("4f935e0484020000000000000000000000004400640d001c10000000c05dc40f", 3, False), + ("066558048402000000000000000000000000c4003020001c24000000c05dc80f", 8, False), + ("059683048402000000000000000000000000a1008425001c24000000c05dc80f", 9, False), + ("011305048402000000000000000000000000d600a829001c24000000c05dc80f", 10, False), +)) +def test_ev_mode_dbc_decodes_real_mx5_frames(payload, expected_mode, expected_active): + parser = CANParser("hyundai_canfd_generated", [(EV_MODE_STATUS_MSG, math.nan)], 0) + updated = parser.update([1_000_000_000, [(EV_MODE_STATUS_ADDR, bytes.fromhex(payload), 0)]]) + + assert updated == {EV_MODE_STATUS_ADDR} + assert int(parser.vl[EV_MODE_STATUS_MSG][EV_MODE_STATUS_SIGNAL]) == expected_mode + assert _get_ev_mode_state(parser) == (expected_active, True) + + +def test_ev_mode_rejects_checksum_corruption(): + CP = get_params(CAR.HYUNDAI_SANTAFE_MX5_HEV) + parser = CarState.get_can_parsers_canfd(None, CP)[Bus.pt] + payload = bytearray.fromhex("32206e048402000000000000000000000000c9007418001c24000000c05dc80f") + payload[-1] ^= 1 + + parser.update([1_000_000_000, [(EV_MODE_STATUS_ADDR, bytes(payload), parser.bus)]]) + + assert EV_MODE_STATUS_ADDR not in parser.dat + assert _get_ev_mode_state(parser) == (False, False) + + +def test_ev_mode_fields_default_invalid(): + state = structs.CarState() + assert not state.evModeActive + assert not state.evModeValid + + +def test_ev_mode_parser_is_optional_for_can_validity(): + CP = get_params(CAR.HYUNDAI_SANTAFE_MX5_HEV) + parser = CarState.get_can_parsers_canfd(None, CP)[Bus.pt] + state = parser.message_states[EV_MODE_STATUS_ADDR] + + assert state.ignore_alive + assert state.ignore_counter diff --git a/iqdbc_repo/iqdbc/car/hyundai/tests/test_hyundai.py b/iqdbc_repo/iqdbc/car/hyundai/tests/test_hyundai.py index fdbc357..edf1f73 100644 --- a/iqdbc_repo/iqdbc/car/hyundai/tests/test_hyundai.py +++ b/iqdbc_repo/iqdbc/car/hyundai/tests/test_hyundai.py @@ -6,13 +6,11 @@ from iqdbc.car import gen_empty_fingerprint from iqdbc.car.structs import CarParams from iqdbc.car.fw_versions import build_fw_dict from iqdbc.car.hyundai.interface import CarInterface -from iqdbc.car.hyundai.hyundaicanfd import CanBus from iqdbc.car.hyundai.radar_interface import RADAR_START_ADDR -from iqdbc.car.hyundai.values import CAMERA_SCC_CAR, CANFD_CAR, CAN_GEARS, CAR, CHECKSUM, DATE_FW_ECUS, \ - HYBRID_CAR, EV_CAR, FW_QUERY_CONFIG, LEGACY_SAFETY_MODE_CAR, CANFD_FUZZY_WHITELIST, \ - UNSUPPORTED_LONGITUDINAL_CAR, PLATFORM_CODE_ECUS, HYUNDAI_VERSION_REQUEST_LONG, \ - HyundaiFlags, get_platform_codes, HyundaiSafetyFlags, \ - NON_SCC_CAR +from iqdbc.car.hyundai.values import CANFD_CAR, CAN_GEARS, CAR, CHECKSUM, DATE_FW_ECUS, \ + HYBRID_CAR, EV_CAR, FW_QUERY_CONFIG, LEGACY_SAFETY_MODE_CAR, \ + PLATFORM_CODE_ECUS, HYUNDAI_VERSION_REQUEST_LONG, \ + HyundaiFlags, get_platform_codes, HyundaiSafetyFlags from iqdbc.car.hyundai.fingerprints import FW_VERSIONS Ecu = CarParams.Ecu @@ -45,16 +43,8 @@ CANFD_EXPECTED_ECUS = {Ecu.fwdCamera, Ecu.fwdRadar} class TestHyundaiFingerprint: - def test_feature_detection(self): - # LKA steering - for lka_steering in (True, False): - fingerprint = gen_empty_fingerprint() - if lka_steering: - cam_can = CanBus(None, fingerprint).CAM - fingerprint[cam_can] = [0x50, 0x110] # LKA steering messages - CP = CarInterface.get_params(CAR.KIA_EV6, fingerprint, [], False, False, False) - assert bool(CP.flags & HyundaiFlags.CANFD_LKA_STEERING) == lka_steering - + def test_feature_detection(self, monkeypatch, tmp_path): + monkeypatch.setenv("PARAMS_ROOT", str(tmp_path)) # radar available for radar in (True, False): fingerprint = gen_empty_fingerprint() @@ -74,19 +64,20 @@ class TestHyundaiFingerprint: # Test no EV/HEV in any gear lists (should all use ELECT_GEAR) assert set.union(*CAN_GEARS.values()) & (HYBRID_CAR | EV_CAR) == set() - # Test CAN FD car not in CAN feature lists - can_specific_feature_list = set.union(*CAN_GEARS.values(), *CHECKSUM.values(), LEGACY_SAFETY_MODE_CAR, UNSUPPORTED_LONGITUDINAL_CAR, CAMERA_SCC_CAR) + # Test CAN FD cars are not classified with classic-CAN-only parsing or safety modes. + can_specific_feature_list = set.union(*CAN_GEARS.values(), *CHECKSUM.values(), LEGACY_SAFETY_MODE_CAR) for car_model in CANFD_CAR: assert car_model not in can_specific_feature_list, "CAN FD car unexpectedly found in a CAN feature list" def test_hybrid_ev_sets(self): assert HYBRID_CAR & EV_CAR == set(), "Shared cars between hybrid and EV" - assert CANFD_CAR & HYBRID_CAR == set(), "Hard coding CAN FD cars as hybrid is no longer supported" + assert HYBRID_CAR <= set(CAR) + assert EV_CAR <= set(CAR) def test_canfd_ecu_whitelist(self): # Asserts only expected Ecus can exist in database for CAN-FD cars for car_model in CANFD_CAR: - ecus = {fw[0] for fw in FW_VERSIONS[car_model].keys()} + ecus = {fw[0] for fw in FW_VERSIONS.get(car_model, {}).keys()} ecus_not_in_whitelist = ecus - CANFD_EXPECTED_ECUS ecu_strings = ", ".join([f"Ecu.{ecu}" for ecu in ecus_not_in_whitelist]) assert len(ecus_not_in_whitelist) == 0, \ @@ -158,8 +149,6 @@ class TestHyundaiFingerprint: continue if platform_code_ecu == Ecu.eps and car_model in no_eps_platforms: continue - if car_model in NON_SCC_CAR: - continue assert platform_code_ecu in [e[0] for e in ecus] def test_fw_format(self, subtests): @@ -174,9 +163,6 @@ class TestHyundaiFingerprint: if ecu[0] not in PLATFORM_CODE_ECUS: continue - if car_model in NON_SCC_CAR: - continue - codes = set() for fw in fws: result = get_platform_codes([fw]) @@ -225,15 +211,6 @@ class TestHyundaiFingerprint: (b"ON-S9100", b"190405"), (b"ON-S9100", b"190720")} def test_fuzzy_excluded_platforms(self): - # Asserts a list of platforms that will not fuzzy fingerprint with platform codes due to them being shared. - # This list can be shrunk as we combine platforms and detect features - excluded_platforms = { - CAR.GENESIS_G70, # shared platform code, part number, and date - CAR.GENESIS_G70_2020, - } - excluded_platforms |= CANFD_CAR - EV_CAR - CANFD_FUZZY_WHITELIST # shared platform codes - excluded_platforms |= NO_DATES_PLATFORMS # date codes are required to match - platforms_with_shared_codes = set() for platform, fw_by_addr in FW_VERSIONS.items(): car_fw = [] @@ -243,9 +220,6 @@ class TestHyundaiFingerprint: car_fw.append(CarParams.CarFw(ecu=ecu_name, fwVersion=fw, address=addr, subAddress=0 if sub_addr is None else sub_addr)) - if platform in NON_SCC_CAR: - continue - CP = CarParams(carFw=car_fw) matches = FW_QUERY_CONFIG.match_fw_to_car_fuzzy(build_fw_dict(CP.carFw), CP.carVin, FW_VERSIONS) if len(matches) == 1: @@ -253,4 +227,6 @@ class TestHyundaiFingerprint: else: platforms_with_shared_codes.add(platform) - assert platforms_with_shared_codes == excluded_platforms + # A unique fuzzy match must always resolve back to the platform that supplied the firmware. + # Ambiguity is expected for shared platform codes and for platforms without parseable dates. + assert {CAR.GENESIS_G70, CAR.GENESIS_G70_2020} <= platforms_with_shared_codes diff --git a/iqdbc_repo/iqdbc/car/hyundai/tests/test_hyundaican.py b/iqdbc_repo/iqdbc/car/hyundai/tests/test_hyundaican.py deleted file mode 100644 index 2cd7ce3..0000000 --- a/iqdbc_repo/iqdbc/car/hyundai/tests/test_hyundaican.py +++ /dev/null @@ -1,61 +0,0 @@ -from iqdbc.can import CANParser, CANPacker -from iqdbc.car import Bus -from iqdbc.car.hyundai import hyundaican -from iqdbc.car.hyundai.values import CAR, DBC - - -class DummyHudControl: - leadDistanceBars = 3 - leadVisible = True - - -class DummyLeadData: - lead_visible = False - lead_rel_speed = -7 - lead_distance = 42 - object_gap = 5 - object_rel_gap = 2 - - -class DummyTuning: - comfort_band_upper = 0.2 - comfort_band_lower = 0.3 - jerk_upper = 1.7 - jerk_lower = 1.2 - desired_accel = 0.4 - actual_accel = 0.3 - stopping = False - - -class DummyCP: - carFingerprint = CAR.HYUNDAI_PALISADE - flags = 0 - - -def _decode(msg_name: str, addr: int, dat: bytes): - cp = CANParser(DBC[CAR.HYUNDAI_PALISADE][Bus.pt], [(msg_name, 0)], 0) - cp.update([(0, [(addr, dat, 0)])]) - return cp.vl[msg_name] - - -def test_palisade_uses_stock_scc_surrogates(): - packer = CANPacker(DBC[CAR.HYUNDAI_PALISADE][Bus.pt]) - cp = DummyCP() - hud = DummyHudControl() - tuning = DummyTuning() - lead = DummyLeadData() - - scc11 = hyundaican.create_acc_commands( - packer, True, 0.5, 3.0, 1, lead, hud, 72, False, False, True, cp, False, tuning - )[0] - scc14 = hyundaican.create_acc_commands( - packer, True, 0.5, 3.0, 1, lead, hud, 72, False, False, True, cp, False, tuning - )[2] - - scc11_vals = _decode("SCC11", scc11[0], scc11[1]) - assert scc11_vals["ObjValid"] == 1 - assert scc11_vals["ACC_ObjStatus"] == 1 - assert scc11_vals["ACC_ObjDist"] == 1 - - scc14_vals = _decode("SCC14", scc14[0], scc14[1]) - assert "ObjDistStat" not in scc14_vals or scc14_vals["ObjDistStat"] == 0 diff --git a/iqdbc_repo/iqdbc/car/hyundai/tests/test_integration.py b/iqdbc_repo/iqdbc/car/hyundai/tests/test_integration.py new file mode 100644 index 0000000..a0a92d4 --- /dev/null +++ b/iqdbc_repo/iqdbc/car/hyundai/tests/test_integration.py @@ -0,0 +1,41 @@ +import pytest + +from iqdbc.car import gen_empty_fingerprint, structs +from iqdbc.car.hyundai.interface import CarInterface +from iqdbc.car.hyundai.values import CAR + + +@pytest.mark.parametrize("candidate", list(CAR), ids=lambda candidate: candidate.value) +@pytest.mark.parametrize("alpha_long", (False, True), ids=("stock_long", "openpilot_long")) +def test_all_platform_state_controller_and_radar(candidate, alpha_long, monkeypatch, tmp_path): + """Every declared HKG platform must initialize and execute one complete interface cycle.""" + monkeypatch.setenv("PARAMS_ROOT", str(tmp_path / candidate.value)) + fingerprint = gen_empty_fingerprint() + + cp = CarInterface.get_params(candidate, fingerprint, [], alpha_long, False, False) + cp_iq = CarInterface.get_params_iq(cp, candidate, fingerprint, [], alpha_long, False, False) + interface = CarInterface(cp, cp_iq) + + state, state_iq = interface.update([]) + actuators, can_sends = interface.apply(structs.CarControl().as_reader(), structs.IQCarControl()) + radar = interface.RadarInterface(cp, cp_iq) + radar_result = radar.update([]) + + assert state.vEgo == 0.0 + assert state_iq is not None + assert actuators is not None + assert isinstance(can_sends, list) + assert radar_result is None + + +def test_parameter_defaults_do_not_require_persisted_fingerprint(monkeypatch, tmp_path): + """A clean installation must not crash when carrotpilot-specific Params have not been written yet.""" + monkeypatch.setenv("PARAMS_ROOT", str(tmp_path)) + fingerprint = gen_empty_fingerprint() + + cp = CarInterface.get_params(CAR.HYUNDAI_SONATA, fingerprint, [], False, False, False) + cp_iq = CarInterface.get_params_iq(cp, CAR.HYUNDAI_SONATA, fingerprint, [], False, False, False) + interface = CarInterface(cp, cp_iq) + + state, _ = interface.update([]) + assert state.vEgo == 0.0 diff --git a/iqdbc_repo/iqdbc/car/hyundai/tests/test_radar.py b/iqdbc_repo/iqdbc/car/hyundai/tests/test_radar.py new file mode 100644 index 0000000..ceace1f --- /dev/null +++ b/iqdbc_repo/iqdbc/car/hyundai/tests/test_radar.py @@ -0,0 +1,326 @@ +import math + +import pytest + +from iqdbc.can import CANParser +from iqdbc.car import Bus, structs +import iqdbc.car.hyundai.hyundaicanfd as hyundaicanfd +import iqdbc.car.hyundai.radar_interface as radar_interface_module +from iqdbc.car.hyundai.radar_interface import ( + CORNER_OBJECT_STABLE_TRACK_ID_START, + RADAR_MSG_COUNT3, + RADAR_MSG_COUNT4, + RADAR_START_ADDR_CANFD3, + CornerObjectTrackIdManager, + RadarInterface, + corner_object_position_valid, +) +from iqdbc.car.hyundai.values import CAR, HyundaiExtFlags, HyundaiFlags + + +class TestDensoRadar: + @staticmethod + def parse(addr, dat): + name = f"RADAR_TRACK_{addr:x}" + parser = CANParser("hyundai_kia_denso_front_radar_generated", [(name, 20)], 1) + parser.update([0, [(addr, bytes.fromhex(dat), 1)]]) + return parser.vl[name] + + def test_active_track_signals(self): + # Person walking toward the parked car, left of the camera center. + track = self.parse(0x503, "bc047efcc1fe8b00") + + assert track["LONG_DIST"] == pytest.approx(7.1875) + assert track["LAT_DIST"] == pytest.approx(-1.625) + assert track["REL_SPEED"] == pytest.approx(-0.734375) + assert track["OBJECT_STATE"] == 3 + + def test_empty_track(self): + track = self.parse(0x507, "53fff80000000081") + + assert track["LONG_DIST"] == pytest.approx(409.55) + assert track["LAT_DIST"] == 0 + assert track["REL_SPEED"] == 0 + assert track["OBJECT_STATE"] == 0 + + def test_long_range_lateral_distance(self): + # Real driving sample: treating the signed field as -12 degrees would put + # this target about 34 m sideways at 161 m. It is instead -3.0 m lateral. + track = self.parse(0x506, "b664eafa00cd230b") + + assert track["LONG_DIST"] == pytest.approx(161.4625) + assert track["LAT_DIST"] == pytest.approx(-3.0) + assert track["OBJECT_STATE"] == 3 + + def test_parser_selection_and_point_conversion(self, monkeypatch): + class FakeParams: + def get_int(self, key): + return 1 if key == "EnableRadarTracks" else 0 + + monkeypatch.setattr(radar_interface_module, "Params", FakeParams) + cp = structs.CarParams() + cp.carFingerprint = CAR.KIA_SORENTO + cp.flags = 0 + cp.extFlags = HyundaiExtFlags.RADAR_GROUP4.value + cp.radarUnavailable = False + cp.safetyConfigs = [structs.CarParams.SafetyConfig()] + + radar_interface = RadarInterface(cp) + + assert radar_interface.radar_group4 + assert RADAR_MSG_COUNT4 == 8 + assert radar_interface.radar_msg_count == RADAR_MSG_COUNT4 + assert radar_interface.trigger_msg_tracks == 0x507 + + active_dat = bytes.fromhex("bc047efcc1fe8b00") + empty_dat = bytes.fromhex("bcfff80000000081") + packets = [(addr, active_dat if addr == 0x503 else empty_dat, 1) for addr in range(0x500, 0x508)] + radar_data = radar_interface.update([0, packets]) + point = next(point for point in radar_data.points if point.trackId == 35) + + assert point.measured + assert point.dRel == pytest.approx(7.1875) + assert point.yRel == pytest.approx(1.625) + assert point.vRel == pytest.approx(-0.734375) + assert math.isnan(point.aRel) + + # EN: Confirm that the long-range sample survives the filter and converts + # radar-left-negative to openpilot-left-positive coordinates. + # KO: 장거리 샘플의 필터 통과와 레이더 좌측 음수 좌표가 openpilot 좌측 + # 양수 좌표로 변환되는지 확인함. + long_range_dat = bytes.fromhex("b664eafa00cd230b") + packets = [(addr, long_range_dat if addr == 0x506 else empty_dat, 1) for addr in range(0x500, 0x508)] + radar_data = radar_interface.update([0, packets]) + point = next(point for point in radar_data.points if point.trackId == 38) + + assert point.dRel == pytest.approx(161.4625) + assert point.yRel == pytest.approx(3.0) + + # EN: A state-0 raw detection must not enter a stable tracked-object slot. + # KO: 상태 0인 raw detection이 안정적인 추적 객체 슬롯에 들어오지 않음을 확인함. + raw_detection = bytes.fromhex("d702f4fc200000e4") + packets = [(addr, raw_detection if addr == 0x503 else empty_dat, 1) for addr in range(0x500, 0x508)] + radar_data = radar_interface.update([0, packets]) + assert not radar_data.points + + # EN: A real confirmed track beyond the former 205 m limit remains valid. + # KO: 기존 205m 상한을 넘는 실제 확정 트랙도 유효하게 유지됨. + confirmed_213m_track = bytes.fromhex("35854c0780f163e0") + packets = [(addr, confirmed_213m_track if addr == 0x503 else empty_dat, 1) for addr in range(0x500, 0x508)] + radar_data = radar_interface.update([0, packets]) + point = next(point for point in radar_data.points if point.trackId == 35) + assert point.dRel == pytest.approx(213.275) + assert point.yRel == pytest.approx(-3.75) + + # EN: The 325 m boundary is rejected, leaving ample separation from the + # 409.55 m empty-slot sentinel. + # KO: 325m 경계값을 제외해 409.55m 빈 슬롯 값과 충분한 간격을 확보함. + boundary_track = bytes.fromhex("bccb200000000300") + packets = [(addr, boundary_track if addr == 0x503 else empty_dat, 1) for addr in range(0x500, 0x508)] + radar_data = radar_interface.update([0, packets]) + assert not radar_data.points + + # EN: The wider profile keeps a real stable track at 4.875 m, covering more + # of the outer adjacent lane than the conservative 4.5 m profile. + # KO: 넓어진 필터에서 4.875m의 실제 안정 트랙을 유지해 보수적인 4.5m + # 설정보다 바깥쪽 인접 차선을 더 넓게 포함함. + outer_lane_track = bytes.fromhex("d80b66f640000300") + packets = [(addr, outer_lane_track if addr == 0x503 else empty_dat, 1) for addr in range(0x500, 0x508)] + radar_data = radar_interface.update([0, packets]) + point = next(point for point in radar_data.points if point.trackId == 35) + assert point.yRel == pytest.approx(4.875) + + # EN: Tracks beyond the widened envelope are rejected as roadside clutter; + # this payload differs only in lateral distance (-7.0 m). + # KO: 넓어진 범위를 벗어난 트랙은 도로변 잡음으로 제외함. 이 payload는 + # 횡방향 거리(-7.0m)만 다름. + far_side_reflection = bytes.fromhex("d80b66f200000300") + packets = [(addr, far_side_reflection if addr == 0x503 else empty_dat, 1) for addr in range(0x500, 0x508)] + radar_data = radar_interface.update([0, packets]) + assert not radar_data.points + + +class TestRadarGroup3: + @staticmethod + def parse(addr, dat): + name = f"RADAR_TRACK_{addr:x}" + parser = CANParser("hyundai_canfd_radar_generated", [(name, 20)], 1) + parser.update([0, [(addr, bytes.fromhex(dat), 1)]]) + return parser.vl[name] + + def test_group3_active_track(self): + track = self.parse(0x406, "e1043b0f02590e692a227e16f80fe00f28fcc753a20a0000") + + assert track["OBJECT_LENGTH"] == pytest.approx(4.4) + assert track["LONG_DIST"] == pytest.approx(55.4) + assert track["LAT_DIST"] == pytest.approx(-3.0) + assert track["REL_SPEED"] == pytest.approx(4.4) + + def test_group3_empty_track(self): + track = self.parse(0x407, "c03d3b0000000000ff0700000000000000d0020000000000") + + assert track["OBJECT_LENGTH"] == 0 + assert track["LONG_DIST"] == pytest.approx(204.7) + assert track["LAT_DIST"] == 0 + assert track["REL_SPEED"] == 0 + + def test_group3_parser_selection(self, monkeypatch): + class FakeParams: + def get_int(self, key): + return 1 if key == "EnableRadarTracks" else 0 + + monkeypatch.setattr(radar_interface_module, "Params", FakeParams) + monkeypatch.setattr(hyundaicanfd, "Params", FakeParams) + cp = structs.CarParams() + cp.carFingerprint = next(car for car, dbc in radar_interface_module.DBC.items() if "hyundai_canfd" in dbc[Bus.pt]) + cp.flags = HyundaiFlags.CANFD.value + cp.extFlags = HyundaiExtFlags.RADAR_GROUP3.value + cp.radarUnavailable = False + cp.safetyConfigs = [structs.CarParams.SafetyConfig()] + + radar_interface = RadarInterface(cp) + + assert radar_interface.radar_group3 + assert radar_interface.radar_start_addr == RADAR_START_ADDR_CANFD3 + assert radar_interface.radar_msg_count == RADAR_MSG_COUNT3 + assert radar_interface.trigger_msg_tracks == 0x41D + + active_dat = bytes.fromhex("e1043b0f02590e692a227e16f80fe00f28fcc753a20a0000") + empty_dat = bytes.fromhex("c03d3b0000000000ff0700000000000000d0020000000000") + packets = [(addr, active_dat if addr == 0x406 else empty_dat, 1) for addr in range(0x400, 0x41E)] + radar_data = radar_interface.update([0, packets]) + point = next(point for point in radar_data.points if point.trackId == 38) + + assert point.measured + assert point.dRel == pytest.approx(53.1) + assert point.yRel == pytest.approx(-3.0) + assert point.vRel == pytest.approx(4.4) + + +class TestCornerRadarObjectIdentity: + @staticmethod + def set_bits(data, start, size, value): + for offset in range(size): + bit = start + offset + data[bit // 8] |= ((value >> offset) & 1) << (bit % 8) + + @pytest.mark.parametrize( + "dbc,msg_name,addr,age_signal,id_signal,age_start,id_start", + ( + ("hyundai_canfd_corner_radar_180_generated", "CORNER_RADAR_180_OBJECTS_180", 0x180, + "SLOT1_AGE", "SLOT1_OBJECT_ID", 32, 44), + ("hyundai_canfd_corner_radar_235_generated", "CORNER_RADAR_235_OBJECTS_235", 0x235, + "OBJ_AGE", "OBJ_OBJECT_ID", 32, 44), + ), + ) + def test_object_identity_signals(self, dbc, msg_name, addr, age_signal, id_signal, age_start, id_start): + data = bytearray(32) + self.set_bits(data, age_start, 8, 23) + self.set_bits(data, id_start, 7, 46) + parser = CANParser(dbc, [(msg_name, 33)], 1) + parser.update([0, [(addr, bytes(data), 1)]]) + + assert parser.vl[msg_name][age_signal] == 23 + assert parser.vl[msg_name][id_signal] == 46 + + def test_track_id_survives_slot_move_and_resets_with_age(self): + manager = CornerObjectTrackIdManager() + first_id = manager.get_track_id("corner180", object_id=108, age=240) + + assert first_id == CORNER_OBJECT_STABLE_TRACK_ID_START + assert manager.get_track_id("corner180", object_id=108, age=241) == first_id + assert manager.get_track_id("corner235", object_id=108, age=241) != first_id + assert manager.get_track_id("corner180", object_id=108, age=2) != first_id + + def test_clipped_side_object_position_is_valid(self): + assert corner_object_position_valid(0.0, 2.8) + assert corner_object_position_valid(25.0, 0.2) + assert not corner_object_position_valid(0.0, 0.0) + assert not corner_object_position_valid(0.0, 5.0) + + +class TestCornerRadar430CandidateFilter: + @staticmethod + def slot_word(distance_raw, meta13=0, b2=10, b3=2): + return distance_raw | (meta13 << 13) | (b2 << 16) | (b3 << 24) + + @classmethod + def message(cls, slots): + words = [0x010d1f40] * 7 + for slot, word in slots.items(): + words[slot - 1] = word + + dat = bytearray(32) + for idx, word in enumerate(words): + dat[4 + idx * 4:8 + idx * 4] = int(word).to_bytes(4, "little") + return bytes(dat) + + @staticmethod + def build_interface(monkeypatch): + class FakeParams: + def get_int(self, key): + return 1 if key == "EnableCornerRadar" else 0 + + monkeypatch.setattr(radar_interface_module, "Params", FakeParams) + monkeypatch.setattr(hyundaicanfd, "Params", FakeParams) + cp = structs.CarParams() + cp.carFingerprint = next(car for car, dbc in radar_interface_module.DBC.items() if "hyundai_canfd" in dbc[Bus.pt]) + cp.flags = HyundaiFlags.CANFD.value + cp.extFlags = HyundaiExtFlags.CORNER_RADAR_OBJECTS_430.value + cp.radarUnavailable = True + cp.safetyConfigs = [structs.CarParams.SafetyConfig()] + return RadarInterface(cp) + + @staticmethod + def update_frames(radar_interface, packets, frames=5): + radar_data = None + for _ in range(frames): + radar_data = radar_interface.update([0, packets]) + return radar_data + + def test_430_promotes_supported_neighbor_bins(self, monkeypatch): + radar_interface = self.build_interface(monkeypatch) + empty = self.message({}) + supported_bins = self.message({ + 6: self.slot_word(1000), + 7: self.slot_word(1004), + }) + packets = [(addr, supported_bins if addr == 0x436 else empty, 1) for addr in range(0x430, 0x438)] + packets += [(addr, empty, 1) for addr in range(0x440, 0x448)] + + radar_data = self.update_frames(radar_interface, packets) + points = {point.trackId: point for point in radar_data.points} + + assert points[300].measured + assert points[300].dRel == pytest.approx(50.1) + assert points[300].yRel == pytest.approx(2.0) + assert points[300].yvRel == 0.0 + + def test_430_expires_noncenter_inward_yvrel(self, monkeypatch): + radar_interface = self.build_interface(monkeypatch) + empty = self.message({}) + frame_defs = ( + (0x431, 4, 5), + (0x433, 3, 4), + (0x435, 2, 3), + (0x430, 5, 6), + (0x432, 4, 5), + (0x434, 3, 4), + (0x436, 2, 3), + ) + + radar_data = None + for addr, first_slot, second_slot in frame_defs: + msg = self.message({ + first_slot: self.slot_word(1000), + second_slot: self.slot_word(1004), + }) + packets = [(a, msg if a == addr else empty, 1) for a in range(0x430, 0x438)] + packets += [(a, empty, 1) for a in range(0x440, 0x448)] + radar_data = radar_interface.update([0, packets]) + radar_data = self.update_frames(radar_interface, packets, frames=3) + points = {point.trackId: point for point in radar_data.points} + + assert points[300].measured + assert points[300].yRel == pytest.approx(2.0) + assert points[300].yvRel == 0.0 diff --git a/iqdbc_repo/iqdbc/car/hyundai/values.py b/iqdbc_repo/iqdbc/car/hyundai/values.py index a67aae5..69ac2f4 100644 --- a/iqdbc_repo/iqdbc/car/hyundai/values.py +++ b/iqdbc_repo/iqdbc/car/hyundai/values.py @@ -1,21 +1,37 @@ import re from dataclasses import dataclass, field -from enum import IntFlag +from enum import Enum, IntFlag from iqdbc.car import Bus, CarSpecs, DbcDict, PlatformConfig, Platforms, uds +from iqdbc.car.lateral import AngleSteeringLimits from iqdbc.car.common.conversions import Conversions as CV from iqdbc.car.structs import CarParams -from iqdbc.car.docs_definitions import CarHarness, CarDocs, CarParts, SupportType +from iqdbc.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column from iqdbc.car.fw_query_definitions import FwQueryConfig, Request, p16 -from iqdbc.iqpilot.car.hyundai.values import HyundaiFlagsIQ - Ecu = CarParams.Ecu class CarControllerParams: - ACCEL_MIN = -3.5 # m/s - ACCEL_MAX = 2.0 # m/s + ACCEL_MIN = -4.0 # m/s + ACCEL_MAX = 2.5 # m/s + ANGLE_LIMITS: AngleSteeringLimits = AngleSteeringLimits( + # LKAS angle command is unlimited, but LFA is limited to 176.7 deg (but does not fault if requesting above) + 175, # deg + # stock comma's + #([0, 9, 16, 25], [1.4, 0.6, 0.4, 0.1]), + #([0, 9, 16, 25], [1.4, 0.7, 0.5, 0.1]), + ([0, 9, 16, 25], [1.8, 1.6, 1.3, 0.8]), + ([0, 9, 16, 25], [2.4, 2.0, 1.6, 1.0]), + #([0, 9, 16, 25], [1.6, 1.0, 0.6, 0.15]), + #([0, 9, 16, 25], [2.0, 1.2, 0.8, 0.28]), + ) + # Stock LFA system is seen sending 250 max, but for LKAS events it's 175 max. + # 250 can at least achieve 4 m/s^2, 80 corresponds to ~2.5 m/s^2 + ANGLE_MAX_TORQUE = 200 # The maximum amount of torque that will be allowed + ANGLE_MIN_TORQUE = 25 # equivalent to ~0.8 m/s^2 of torque (based on ANGLE_MAX_TORQUE) when overriding + ANGLE_TORQUE_UP_RATE = 8 #2 # Indicates how fast the torque ramps up after user intervention. + ANGLE_TORQUE_DOWN_RATE = 12 #4 Indicates how fast the torque ramps down during user intervention (handing off). def __init__(self, CP): self.STEER_DELTA_UP = 3 @@ -41,20 +57,17 @@ class CarControllerParams: CAR.KIA_OPTIMA_H, CAR.KIA_OPTIMA_H_G4_FL, CAR.KIA_SORENTO): self.STEER_MAX = 255 + elif CP.carFingerprint in (CAR.HYUNDAI_SANTA_FE_PHEV_2022): + self.STEER_MAX = 409 # these cars have significantly more torque than most HKG; limit to 70% of max elif CP.flags & HyundaiFlags.ALT_LIMITS: - self.STEER_MAX = 270 - self.STEER_DELTA_UP = 2 - self.STEER_DELTA_DOWN = 3 - - elif CP.flags & HyundaiFlags.ALT_LIMITS_2: - self.STEER_MAX = 170 + self.STEER_MAX = 384 self.STEER_DELTA_UP = 2 self.STEER_DELTA_DOWN = 3 # Default for most HKG else: - self.STEER_MAX = 384 + self.STEER_MAX = 409 class HyundaiSafetyFlags(IntFlag): @@ -72,12 +85,7 @@ class HyundaiSafetyFlags(IntFlag): class HyundaiFlags(IntFlag): # Dynamic Flags - - # Default assumption: all cars use LFA (ADAS) steering from the camera. - # CANFD_LKA_STEERING/CANFD_LKA_STEERING_ALT cars typically have both LKA (camera) and LFA (ADAS) steering messages, - # with LKA commands forwarded to the ADAS DRV ECU. - # Most HDA2 trims are assumed to be equipped with the ADAS DRV ECU, though some variants may not be equipped with one. - CANFD_LKA_STEERING = 1 + CANFD_HDA2 = 1 CANFD_ALT_BUTTONS = 2 CANFD_ALT_GEARS = 2 ** 2 CANFD_CAMERA_SCC = 2 ** 3 @@ -87,7 +95,7 @@ class HyundaiFlags(IntFlag): CANFD_ALT_GEARS_2 = 2 ** 6 SEND_LFA = 2 ** 7 USE_FCA = 2 ** 8 - CANFD_LKA_STEERING_ALT = 2 ** 9 + CANFD_HDA2_ALT_STEERING = 2 ** 9 # these cars use a different gas signal HYBRID = 2 ** 10 @@ -103,7 +111,7 @@ class HyundaiFlags(IntFlag): # The radar does SCC on these cars when HDA I, rather than the camera RADAR_SCC = 2 ** 14 # The camera does SCC on these cars, rather than the radar - CAMERA_SCC = 2 ** 15 + CAMERA_SCC = CANFD_CAMERA_SCC #2 ** 15 CHECKSUM_CRC8 = 2 ** 16 CHECKSUM_6B = 2 ** 17 @@ -122,23 +130,41 @@ class HyundaiFlags(IntFlag): MIN_STEER_32_MPH = 2 ** 23 - HAS_LDA_BUTTON = 2 ** 24 + ANGLE_CONTROL = 2 ** 24 FCEV = 2 ** 25 ALT_LIMITS_2 = 2 ** 26 + CC_ONLY_CAR = 2 ** 31 + +class HyundaiExtFlags(IntFlag): + NAVI_CLUSTER = 2 ** 2 + HAS_LFAHDA = 2 ** 4 + CANFD_GEARS_NONE = 2 ** 6 + RADAR_GROUP1 = 2 ** 7 # 0x210 radar group 1, 0x3A5 radar group 2 + CANFD_GEARS_69 = 2 ** 10 + RADAR_GROUP3 = 2 ** 11 # 0x400-0x41D radar object group + CORNER_RADAR_OBJECTS_235 = 2 ** 12 # 0x230 status + 0x235-0x248 raw corner radar objects + CORNER_RADAR_OBJECTS_180 = 2 ** 13 # 0x180-0x184 bus 1 two-slot raw corner/front radar objects + CORNER_RADAR_OBJECTS_430 = 2 ** 14 # 0x430-0x437 left + 0x440-0x447 right IONIQ 9 corner radar bins + RADAR_GROUP4 = 2 ** 15 # 0x500-0x507 Denso DNMWR006 stable radar tracks + EV_MODE_STATUS_230 = 2 ** 16 # ECAN 0x230/DLC32 exposes the hybrid power-flow mode used for the EV indicator + +class Footnote(Enum): + CANFD = CarFootnote( + "Requires a CAN FD panda kit if not using " + + "comma 3X for this CAN FD car.", + Column.MODEL) + @dataclass class HyundaiCarDocs(CarDocs): package: str = "Smart Cruise Control (SCC)" - -@dataclass -class HyundaiNonSccCarDocs(CarDocs): - package: str = "No Smart Cruise Control (Non-SCC)" - support_type: SupportType = SupportType.COMMUNITY - support_link: str = "community" + def init_make(self, CP: CarParams): + if CP.flags & HyundaiFlags.CANFD: + self.footnotes.insert(0, Footnote.CANFD) @dataclass @@ -153,20 +179,9 @@ class HyundaiPlatformConfig(PlatformConfig): self.specs = self.specs.override(minSteerSpeed=32 * CV.MPH_TO_MS) -@dataclass -class HyundaiNonSccPlatformConfig(PlatformConfig): - dbc_dict: DbcDict = field(default_factory=lambda: {Bus.pt: "hyundai_kia_generic"}) - - def init(self): - self.iq_flags |= HyundaiFlagsIQ.NON_SCC - - if self.flags & HyundaiFlags.MIN_STEER_32_MPH: - self.specs = self.specs.override(minSteerSpeed=32 * CV.MPH_TO_MS) - - @dataclass class HyundaiCanFDPlatformConfig(PlatformConfig): - dbc_dict: DbcDict = field(default_factory=lambda: {Bus.pt: "hyundai_canfd_generated"}) + dbc_dict: DbcDict = field(default_factory=lambda: {Bus.pt: "hyundai_canfd_generated", Bus.radar: 'hyundai_canfd_radar_generated'}) def init(self): self.flags |= HyundaiFlags.CANFD @@ -174,6 +189,10 @@ class HyundaiCanFDPlatformConfig(PlatformConfig): class CAR(Platforms): # Hyundai + HYUNDAI_AZERA_7TH_GEN = HyundaiCanFDPlatformConfig( + [HyundaiCarDocs("Hyundai Azera 2023-2024", "All", car_parts=CarParts.common([CarHarness.hyundai_a]))], + CarSpecs(mass=1700, wheelbase=2.895, steerRatio=16.5), + ) HYUNDAI_AZERA_6TH_GEN = HyundaiPlatformConfig( [HyundaiCarDocs("Hyundai Azera 2022", "All", car_parts=CarParts.common([CarHarness.hyundai_k]))], CarSpecs(mass=1600, wheelbase=2.885, steerRatio=14.5), @@ -260,9 +279,9 @@ class CAR(Platforms): flags=HyundaiFlags.CLUSTER_GEARS | HyundaiFlags.ALT_LIMITS, ) HYUNDAI_KONA_2022 = HyundaiPlatformConfig( - [HyundaiCarDocs("Hyundai Kona 2022-23", car_parts=CarParts.common([CarHarness.hyundai_o]))], + [HyundaiCarDocs("Hyundai Kona 2022", car_parts=CarParts.common([CarHarness.hyundai_o]))], CarSpecs(mass=1491, wheelbase=2.6, steerRatio=13.42, tireStiffnessFactor=0.385), - flags=HyundaiFlags.CAMERA_SCC | HyundaiFlags.ALT_LIMITS_2, + flags=HyundaiFlags.CAMERA_SCC, ) HYUNDAI_KONA_EV = HyundaiPlatformConfig( [HyundaiCarDocs("Hyundai Kona Electric 2018-21", car_parts=CarParts.common([CarHarness.hyundai_g]))], @@ -285,6 +304,11 @@ class CAR(Platforms): CarSpecs(mass=1425, wheelbase=2.6, steerRatio=13.42, tireStiffnessFactor=0.385), flags=HyundaiFlags.HYBRID | HyundaiFlags.ALT_LIMITS, ) + HYUNDAI_KONA_HEV_2ND_GEN = HyundaiCanFDPlatformConfig( + [HyundaiCarDocs("Hyundai Kona Hybrid 2024", car_parts=CarParts.common([CarHarness.hyundai_l]))], + CarSpecs(mass=1590, wheelbase=2.66, steerRatio=13.6, tireStiffnessFactor=0.385), + flags=HyundaiFlags.HYBRID, + ) HYUNDAI_NEXO_1ST_GEN = HyundaiPlatformConfig( [HyundaiCarDocs("Hyundai Nexo 2021", "All", car_parts=CarParts.common([CarHarness.hyundai_h]))], CarSpecs(mass=3990 * CV.LB_TO_KG, wheelbase=2.79, steerRatio=14.19), # https://www.hyundainews.com/assets/documents/original/42768-2021NEXOProductGuideSpecs.pdf @@ -300,17 +324,17 @@ class CAR(Platforms): [HyundaiCarDocs("Hyundai Santa Fe 2021-23", "All", video="https://youtu.be/VnHzSTygTS4", car_parts=CarParts.common([CarHarness.hyundai_l]))], HYUNDAI_SANTA_FE.specs, - flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.CHECKSUM_CRC8, + flags=HyundaiFlags.CHECKSUM_CRC8, ) HYUNDAI_SANTA_FE_HEV_2022 = HyundaiPlatformConfig( [HyundaiCarDocs("Hyundai Santa Fe Hybrid 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_l]))], HYUNDAI_SANTA_FE.specs, - flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.HYBRID, + flags=HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.HYBRID, ) HYUNDAI_SANTA_FE_PHEV_2022 = HyundaiPlatformConfig( [HyundaiCarDocs("Hyundai Santa Fe Plug-in Hybrid 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_l]))], HYUNDAI_SANTA_FE.specs, - flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.HYBRID, + flags=HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.HYBRID, ) HYUNDAI_SONATA = HyundaiPlatformConfig( [HyundaiCarDocs("Hyundai Sonata 2020-23", "All", video="https://www.youtube.com/watch?v=ix63r9kE3Fw", @@ -321,8 +345,14 @@ class CAR(Platforms): HYUNDAI_SONATA_LF = HyundaiPlatformConfig( [HyundaiCarDocs("Hyundai Sonata 2018-19", car_parts=CarParts.common([CarHarness.hyundai_e]))], CarSpecs(mass=1536, wheelbase=2.804, steerRatio=13.27 * 1.15), # 15% higher at the center seems reasonable + flags=HyundaiFlags.UNSUPPORTED_LONGITUDINAL | HyundaiFlags.TCU_GEARS, ) + HYUNDAI_SONATA_2024 = HyundaiCanFDPlatformConfig( + [HyundaiCarDocs("Hyundai Sonata 2024-25", "All", car_parts=CarParts.common([CarHarness.hyundai_a]))], + CarSpecs(mass=1556, wheelbase=2.84, steerRatio=12.81), + flags=HyundaiFlags.CAMERA_SCC, + ) HYUNDAI_STARIA_4TH_GEN = HyundaiCanFDPlatformConfig( [HyundaiCarDocs("Hyundai Staria 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_k]))], CarSpecs(mass=2205, wheelbase=3.273, steerRatio=11.94), # https://www.hyundai.com/content/dam/hyundai/au/en/models/staria-load/premium-pip-update-2023/spec-sheet/STARIA_Load_Spec-Table_March_2023_v3.1.pdf @@ -362,11 +392,32 @@ class CAR(Platforms): CarSpecs(mass=1948, wheelbase=2.97, steerRatio=14.26, tireStiffnessFactor=0.65), flags=HyundaiFlags.EV, ) + HYUNDAI_IONIQ_5_PE = HyundaiCanFDPlatformConfig( + [ + HyundaiCarDocs("Hyundai IONIQ 5 PE (NE1)", car_parts=CarParts.common([CarHarness.hyundai_q])), + HyundaiCarDocs("Hyundai Ioniq 5 PE (with HDA II) 2024", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_q])), + ], + #CarSpecs(mass=2012, wheelbase=3.0, steerRatio=14.26, tireStiffnessFactor=0.65), + CarSpecs(mass=2012, wheelbase=3.0, steerRatio=14.26, tireStiffnessFactor=1.0), + flags=HyundaiFlags.EV | HyundaiFlags.ANGLE_CONTROL, + ) + HYUNDAI_IONIQ_5_N = HyundaiCanFDPlatformConfig( + [HyundaiCarDocs("Hyundai Ioniq 5 N (with HDA II) 2024", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_m]))], + CarSpecs(mass=2200, wheelbase=3.00, steerRatio=12.54), + flags=HyundaiFlags.EV, + ) HYUNDAI_IONIQ_6 = HyundaiCanFDPlatformConfig( [HyundaiCarDocs("Hyundai Ioniq 6 (with HDA II) 2023-24", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_p]))], HYUNDAI_IONIQ_5.specs, flags=HyundaiFlags.EV | HyundaiFlags.CANFD_NO_RADAR_DISABLE, ) + HYUNDAI_IONIQ_9 = HyundaiCanFDPlatformConfig( + [ + HyundaiCarDocs("Hyundai Ioniq 9", "All", car_parts=CarParts.common([CarHarness.hyundai_m])), + ], + CarSpecs(mass=2505, wheelbase=3.13, steerRatio=16.02), + flags=HyundaiFlags.EV | HyundaiFlags.ANGLE_CONTROL, + ) HYUNDAI_TUCSON_4TH_GEN = HyundaiCanFDPlatformConfig( [ HyundaiCarDocs("Hyundai Tucson 2022", car_parts=CarParts.common([CarHarness.hyundai_n])), @@ -386,6 +437,37 @@ class CAR(Platforms): CarSpecs(mass=1690, wheelbase=3.055, steerRatio=17), # mass: from https://www.hyundai-motor.com.tw/clicktobuy/custin#spec_0, steerRatio: from learner flags=HyundaiFlags.CHECKSUM_CRC8, ) + HYUNDAI_CASPER = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Casper 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_k]))], + CarSpecs(mass=1060, wheelbase=2.4, steerRatio=14.3), # mass: from https://www.hyundai-motor.com.tw/clicktobuy/custin#spec_0, steerRatio: from learner + flags=HyundaiFlags.CAMERA_SCC | HyundaiFlags.CHECKSUM_CRC8, + ) + + HYUNDAI_CASPER_EV = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Casper EV 2024", "All", car_parts=CarParts.common([CarHarness.hyundai_k]))], + CarSpecs(mass=1355, wheelbase=2.58, steerRatio=14.3), # mass: from https://www.hyundai-motor.com.tw/clicktobuy/custin#spec_0, steerRatio: from learner + flags=HyundaiFlags.CAMERA_SCC | HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.EV + ) + HYUNDAI_PORTER_II_EV = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Porter II EV 2024", car_parts=CarParts.common([CarHarness.hyundai_h]))], + CarSpecs(mass=1970, wheelbase=2.64, steerRatio=14.5), + flags=HyundaiFlags.EV | HyundaiFlags.CC_ONLY_CAR, + ) + HYUNDAI_SANTAFE_MX5 = HyundaiCanFDPlatformConfig( + [ + HyundaiCarDocs("Hyundai SANTAFE (MX5)", car_parts=CarParts.common([CarHarness.hyundai_k])), + ], + CarSpecs(mass=1910, wheelbase=2.76, steerRatio=15.8, tireStiffnessFactor=0.82), + flags=HyundaiFlags.ANGLE_CONTROL, + ) + HYUNDAI_SANTAFE_MX5_HEV = HyundaiCanFDPlatformConfig( + [ + HyundaiCarDocs("Hyundai SANTAFE HYBRID (MX5)", car_parts=CarParts.common([CarHarness.hyundai_k])), + ], + HYUNDAI_SANTAFE_MX5.specs, + flags=HyundaiFlags.ANGLE_CONTROL, + ) + # Kia KIA_FORTE = HyundaiPlatformConfig( @@ -405,6 +487,18 @@ class CAR(Platforms): KIA_K5_2021.specs, flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.HYBRID, ) + KIA_K5_DL3_24 = HyundaiCanFDPlatformConfig( + [ + HyundaiCarDocs("Kia K5 2024", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_k])), + ], + CarSpecs(mass=1553, wheelbase=2.85, steerRatio=13.27, tireStiffnessFactor=0.5), + ) + KIA_K5_DL3_24_HEV = HyundaiCanFDPlatformConfig( + [ + HyundaiCarDocs("Kia K5 Hybrid 2024", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_k])), + ], + CarSpecs(mass=1553, wheelbase=2.85, steerRatio=13.27, tireStiffnessFactor=0.5), + ) KIA_K8_HEV_1ST_GEN = HyundaiCanFDPlatformConfig( [HyundaiCarDocs("Kia K8 Hybrid (with HDA II) 2023", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_q]))], # mass: https://carprices.ae/brands/kia/2023/k8/1.6-turbo-hybrid, steerRatio: guesstimate from K5 platform @@ -421,16 +515,13 @@ class CAR(Platforms): flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.EV, ) KIA_NIRO_EV_2ND_GEN = HyundaiCanFDPlatformConfig( - [ - HyundaiCarDocs("Kia Niro EV (without HDA II) 2023-25", "All", car_parts=CarParts.common([CarHarness.hyundai_a])), - HyundaiCarDocs("Kia Niro EV (with HDA II) 2025", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_r])), - ], + [HyundaiCarDocs("Kia Niro EV 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_a]))], KIA_NIRO_EV.specs, flags=HyundaiFlags.EV, ) KIA_NIRO_PHEV = HyundaiPlatformConfig( [ - HyundaiCarDocs("Kia Niro Hybrid 2018", min_enable_speed=10. * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_c])), + HyundaiCarDocs("Kia Niro Hybrid 2018", "All", min_enable_speed=10. * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_c])), HyundaiCarDocs("Kia Niro Plug-in Hybrid 2018-19", "All", min_enable_speed=10. * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_c])), HyundaiCarDocs("Kia Niro Plug-in Hybrid 2020", car_parts=CarParts.common([CarHarness.hyundai_d])), ], @@ -471,7 +562,7 @@ class CAR(Platforms): # TODO: may support adjacent years. may have a non-zero minimum steering speed KIA_OPTIMA_H = HyundaiPlatformConfig( [HyundaiCarDocs("Kia Optima Hybrid 2017", "Advanced Smart Cruise Control", car_parts=CarParts.common([CarHarness.hyundai_c]))], - CarSpecs(mass=3558 * CV.LB_TO_KG, wheelbase=2.8, steerRatio=13.75, tireStiffnessFactor=0.5), + CarSpecs(mass=3758 * CV.LB_TO_KG, wheelbase=2.8, steerRatio=13.75, tireStiffnessFactor=0.5), flags=HyundaiFlags.HYBRID | HyundaiFlags.LEGACY, ) KIA_OPTIMA_H_G4_FL = HyundaiPlatformConfig( @@ -499,6 +590,7 @@ class CAR(Platforms): HyundaiCarDocs("Kia Sorento 2019", video="https://www.youtube.com/watch?v=Fkh3s6WHJz8", car_parts=CarParts.common([CarHarness.hyundai_e])), ], CarSpecs(mass=1985, wheelbase=2.78, steerRatio=14.4 * 1.1), # 10% higher at the center seems reasonable + dbc_dict={Bus.pt: "hyundai_kia_generic", Bus.radar: "hyundai_kia_denso_front_radar_generated"}, flags=HyundaiFlags.CHECKSUM_6B | HyundaiFlags.UNSUPPORTED_LONGITUDINAL, ) KIA_SORENTO_4TH_GEN = HyundaiCanFDPlatformConfig( @@ -528,6 +620,11 @@ class CAR(Platforms): CarSpecs(mass=1450, wheelbase=2.65, steerRatio=13.75, tireStiffnessFactor=0.5), flags=HyundaiFlags.LEGACY, ) + KIA_EV4 = HyundaiCanFDPlatformConfig( + [HyundaiCarDocs("Kia EV4 2025", "All", car_parts=CarParts.common([CarHarness.hyundai_q]))], + CarSpecs(mass=1710, wheelbase=2.83, steerRatio=14.5, tireStiffnessFactor=0.65), + flags=HyundaiFlags.EV, + ) KIA_EV6 = HyundaiCanFDPlatformConfig( [ HyundaiCarDocs("Kia EV6 (Southeast Asia only) 2022-24", "All", car_parts=CarParts.common([CarHarness.hyundai_p])), @@ -537,6 +634,14 @@ class CAR(Platforms): CarSpecs(mass=2055, wheelbase=2.9, steerRatio=16, tireStiffnessFactor=0.65), flags=HyundaiFlags.EV, ) + KIA_EV6_PE = HyundaiCanFDPlatformConfig( + [ + HyundaiCarDocs("Kia EV6 PE (CV1)", car_parts=CarParts.common([CarHarness.hyundai_p])), + HyundaiCarDocs("Kia EV6 PE (with HDA II) 2025", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_p])) + ], + CarSpecs(mass=2055, wheelbase=2.9, steerRatio=16, tireStiffnessFactor=0.65), + flags=HyundaiFlags.EV | HyundaiFlags.ANGLE_CONTROL, + ) KIA_CARNIVAL_4TH_GEN = HyundaiCanFDPlatformConfig( [ HyundaiCarDocs("Kia Carnival 2022-24", car_parts=CarParts.common([CarHarness.hyundai_a])), @@ -605,54 +710,116 @@ class CAR(Platforms): CarSpecs(mass=2258, wheelbase=2.95, steerRatio=14.14), flags=HyundaiFlags.RADAR_SCC, ) - - # port extensions - HYUNDAI_BAYON_1ST_GEN_NON_SCC = HyundaiNonSccPlatformConfig( - [HyundaiNonSccCarDocs("Hyundai Bayon Non-SCC 2021", car_parts=CarParts.common([CarHarness.hyundai_n]))], - CarSpecs(mass=1150, wheelbase=2.58, steerRatio=13.27 * 1.15), - flags=HyundaiFlags.CHECKSUM_CRC8, + GENESIS_GV70_EV_1ST_GEN = HyundaiCanFDPlatformConfig( + [HyundaiCarDocs("Genesis GV70 EV 2020-2023", "All", car_parts=CarParts.common([CarHarness.hyundai_m]))], + CarSpecs(mass=2230, wheelbase=2.87, steerRatio=14.6), + flags=HyundaiFlags.EV | HyundaiFlags.RADAR_SCC, ) - HYUNDAI_ELANTRA_2022_NON_SCC = HyundaiNonSccPlatformConfig( - [HyundaiNonSccCarDocs("Hyundai Elantra Non-SCC 2022", car_parts=CarParts.common([CarHarness.hyundai_k]))], - HYUNDAI_ELANTRA_2021.specs, - flags=HyundaiFlags.CHECKSUM_CRC8, + HYUNDAI_GRANDEUR_IG = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Grandeur 2018-19", "All", car_parts=CarParts.common([CarHarness.hyundai_c]))], + CarSpecs(mass=1570, wheelbase=2.845, steerRatio=16., tireStiffnessFactor=0.7), + flags=HyundaiFlags.LEGACY | HyundaiFlags.CLUSTER_GEARS, ) - HYUNDAI_KONA_NON_SCC = HyundaiNonSccPlatformConfig( - [HyundaiNonSccCarDocs("Hyundai Kona Non-SCC 2019", car_parts=CarParts.common([CarHarness.hyundai_b]))], - HYUNDAI_KONA.specs, - flags=HyundaiFlags.ALT_LIMITS, + HYUNDAI_GRANDEUR_IG_HEV = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Grandeur HEV 2018-19", "All", car_parts=CarParts.common([CarHarness.hyundai_c]))], + CarSpecs(mass=1570, wheelbase=2.845, steerRatio=16., tireStiffnessFactor=0.7), + flags=HyundaiFlags.HYBRID | HyundaiFlags.LEGACY, ) - HYUNDAI_KONA_EV_NON_SCC = HyundaiNonSccPlatformConfig( - [HyundaiNonSccCarDocs("Hyundai Kona Electric Non-SCC 2019", car_parts=CarParts.common([CarHarness.hyundai_g]))], - HYUNDAI_KONA_EV.specs, - flags=HyundaiFlags.EV | HyundaiFlags.ALT_LIMITS, + GENESIS_EQ900 = HyundaiPlatformConfig( + [HyundaiCarDocs("Genesis EQ900 2017", "All", car_parts=CarParts.common([CarHarness.hyundai_c]))], + CarSpecs(mass=2200, wheelbase=3.15, steerRatio=16., tireStiffnessFactor=0.7), + flags=HyundaiFlags.LEGACY, ) - KIA_CEED_PHEV_2022_NON_SCC = HyundaiNonSccPlatformConfig( - [HyundaiNonSccCarDocs("Kia Ceed Plug-in Hybrid Non-SCC 2022", car_parts=CarParts.common([CarHarness.hyundai_i]))], - CarSpecs(mass=1650, wheelbase=2.65, steerRatio=13.75, tireStiffnessFactor=0.5), + GENESIS_EQ900_L = HyundaiPlatformConfig( + [HyundaiCarDocs("Genesis EQ900 LIMOUSINE", "All", car_parts=CarParts.common([CarHarness.hyundai_c]))], + CarSpecs(mass=2290, wheelbase=3.45, steerRatio=16., tireStiffnessFactor=0.7), + flags=HyundaiFlags.LEGACY, + ) + GENESIS_G90_2019 = HyundaiPlatformConfig( + [HyundaiCarDocs("Genesis G90 2019", "All", car_parts=CarParts.common([CarHarness.hyundai_c]))], + CarSpecs(mass=2150, wheelbase=3.16, steerRatio=16., tireStiffnessFactor=0.7), + flags=HyundaiFlags.LEGACY, + ) + HYUNDAI_NEXO = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Nexo", "All", car_parts=CarParts.common([CarHarness.hyundai_a]))], + CarSpecs(mass=1885, wheelbase=2.79, steerRatio=15.3, tireStiffnessFactor=0.385), + flags=HyundaiFlags.EV, + ) + KIA_MOHAVE = HyundaiPlatformConfig( + [HyundaiCarDocs("Kia Mohave 2019", "All", car_parts=CarParts.common([CarHarness.hyundai_k]))], + CarSpecs(mass=2285, wheelbase=2.895, steerRatio=16., tireStiffnessFactor=0.7), + flags=HyundaiFlags.LEGACY, + ) + KIA_K5 = HyundaiPlatformConfig( + [HyundaiCarDocs("Kia K5 2019 & 2016", "All", car_parts=CarParts.common([CarHarness.hyundai_b]))], + CarSpecs(mass=1515, wheelbase=2.80, steerRatio=15.5, tireStiffnessFactor=0.7), + flags=HyundaiFlags.LEGACY | HyundaiFlags.TCU_GEARS, + ) + KIA_K5_HEV = HyundaiPlatformConfig( + [HyundaiCarDocs("Kia K5 Hybrid 2017", "All", car_parts=CarParts.common([CarHarness.hyundai_c]))], + CarSpecs(mass=1705, wheelbase=2.80, steerRatio=15.5, tireStiffnessFactor=0.7), + flags=HyundaiFlags.HYBRID | HyundaiFlags.LEGACY, + ) + KIA_K5_HEV_2022 = HyundaiPlatformConfig( + [HyundaiCarDocs("Kia K5 Hybrid 2022", "All", car_parts=CarParts.common([CarHarness.hyundai_c]))], + CarSpecs(mass=1515, wheelbase=2.85, steerRatio=15.5, tireStiffnessFactor=0.7), + flags=HyundaiFlags.HYBRID | HyundaiFlags.LEGACY, + ) + KIA_K7 = HyundaiPlatformConfig( + [HyundaiCarDocs("Kia K7 2016-2019", "All", car_parts=CarParts.common([CarHarness.hyundai_c]))], + CarSpecs(mass=1850, wheelbase=2.855, steerRatio=15.5, tireStiffnessFactor=0.7), + flags=HyundaiFlags.LEGACY | HyundaiFlags.CLUSTER_GEARS, + ) + KIA_K7_HEV = HyundaiPlatformConfig( + [HyundaiCarDocs("Kia K7 Hybrid 2016-2019", "All", car_parts=CarParts.common([CarHarness.hyundai_c]))], + CarSpecs(mass=1515, wheelbase=2.855, steerRatio=15.5, tireStiffnessFactor=0.7), + flags=HyundaiFlags.HYBRID | HyundaiFlags.LEGACY, + ) + KIA_K7_PE = HyundaiPlatformConfig( + [HyundaiCarDocs("Kia K7 2020", "All", car_parts=CarParts.common([CarHarness.hyundai_c]))], + CarSpecs(mass=1850, wheelbase=2.855, steerRatio=15.5, tireStiffnessFactor=0.7), + ) + KIA_K7_HEV_PE = HyundaiPlatformConfig( + [HyundaiCarDocs("Kia K7 Hybrid 2020", "All", car_parts=CarParts.common([CarHarness.hyundai_c]))], + CarSpecs(mass=1515, wheelbase=2.855, steerRatio=15.5, tireStiffnessFactor=0.7), flags=HyundaiFlags.HYBRID, ) - KIA_FORTE_2019_NON_SCC = HyundaiNonSccPlatformConfig( - [HyundaiNonSccCarDocs("Kia Forte Non-SCC 2019", car_parts=CarParts.common([CarHarness.hyundai_g]))], - KIA_FORTE.specs, - iq_flags=HyundaiFlagsIQ.NON_SCC_NO_FCA, + KIA_K9 = HyundaiPlatformConfig( + [HyundaiCarDocs("Kia K9 2016-2019", "All", car_parts=CarParts.common([CarHarness.hyundai_h]))], + CarSpecs(mass=2075, wheelbase=3.15, steerRatio=14.5, tireStiffnessFactor=0.7), + flags=HyundaiFlags.LEGACY, ) - KIA_FORTE_2021_NON_SCC = HyundaiNonSccPlatformConfig( - [HyundaiNonSccCarDocs("Kia Forte Non-SCC 2021", car_parts=CarParts.common([CarHarness.hyundai_g]))], - KIA_FORTE.specs, + KIA_EV_SK3 = HyundaiPlatformConfig( + [HyundaiCarDocs("Kia Soul EV 2019", car_parts=CarParts.common([CarHarness.hyundai_c]))], + CarSpecs(mass=1695, wheelbase=2.6, steerRatio=13.75), + flags=HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.EV, ) - KIA_SELTOS_2023_NON_SCC = HyundaiNonSccPlatformConfig( - [HyundaiNonSccCarDocs("Kia Seltos Non-SCC 2023-24", car_parts=CarParts.common([CarHarness.hyundai_l]))], - KIA_SELTOS.specs, - flags=HyundaiFlags.CHECKSUM_CRC8, + KIA_EV9 = HyundaiCanFDPlatformConfig( + [ + HyundaiCarDocs("Kia EV9 (MV)", car_parts=CarParts.common([CarHarness.hyundai_k])), + ], + CarSpecs(mass=2625, wheelbase=3.1, steerRatio=16.02), + flags=HyundaiFlags.EV | HyundaiFlags.ANGLE_CONTROL, ) - GENESIS_G70_2021_NON_SCC = HyundaiNonSccPlatformConfig( - [HyundaiNonSccCarDocs("Genesis G70 Non-SCC 2021", car_parts=CarParts.common([CarHarness.hyundai_f]))], - GENESIS_G70_2020.specs, - flags=HyundaiFlags.CHECKSUM_CRC8, - iq_flags=HyundaiFlagsIQ.NON_SCC_RADAR_FCA, + KIA_EV3 = HyundaiCanFDPlatformConfig( + [ + HyundaiCarDocs("Kia EV3 (SV1)", car_parts=CarParts.common([CarHarness.hyundai_n])), + ], + CarSpecs(mass=2055, wheelbase=2.90, steerRatio=16.0, tireStiffnessFactor=0.65), + flags=HyundaiFlags.EV, + ) + KIA_PV5 = HyundaiCanFDPlatformConfig( + [ + HyundaiCarDocs("Kia PV5 (SW1)", car_parts=CarParts.common([CarHarness.hyundai_n])), + ], + CarSpecs(mass=2600, wheelbase=2.995, steerRatio=16.0, tireStiffnessFactor=0.65), + flags=HyundaiFlags.EV, + ) + KIA_RAY_EV = HyundaiPlatformConfig( + [HyundaiCarDocs("Kia Ray EV", car_parts=CarParts.common([CarHarness.hyundai_h]))], + CarSpecs(mass=1295, wheelbase=2.520, steerRatio=14.5), + flags=HyundaiFlags.EV | HyundaiFlags.CC_ONLY_CAR | HyundaiFlags.CHECKSUM_CRC8, ) - class Buttons: NONE = 0 @@ -660,6 +827,7 @@ class Buttons: SET_DECEL = 2 GAP_DIST = 3 CANCEL = 4 # on newer models, this is a pause/resume button + LFA_BUTTON = 5 def get_platform_codes(fw_versions: list[bytes]) -> set[tuple[bytes, bytes | None]]: @@ -840,11 +1008,21 @@ CAN_GEARS = { # which message has the gear. hybrid and EV use ELECT_GEAR "use_cluster_gears": CAR.with_flags(HyundaiFlags.CLUSTER_GEARS), "use_tcu_gears": CAR.with_flags(HyundaiFlags.TCU_GEARS), + "send_mdps12": {CAR.GENESIS_G90, CAR.GENESIS_G90_2019, CAR.KIA_K9, CAR.KIA_K7}, } CANFD_CAR = CAR.with_flags(HyundaiFlags.CANFD) CANFD_RADAR_SCC_CAR = CAR.with_flags(HyundaiFlags.RADAR_SCC) # TODO: merge with UNSUPPORTED_LONGITUDINAL_CAR +CANFD_HYBRID_STATUS_ADDR = 0xFA +CANFD_HYBRID_STATUS_DLC = 32 + +EV_MODE_STATUS_ADDR = 0x230 +EV_MODE_STATUS_DLC = 32 +EV_MODE_STATUS_MSG = "HCU_STATUS_230" +EV_MODE_STATUS_SIGNAL = "HYBRID_POWER_FLOW_MODE" +EV_MODE_ACTIVE_VALUES = frozenset((1, 2, 6)) + CANFD_UNSUPPORTED_LONGITUDINAL_CAR = CAR.with_flags(HyundaiFlags.CANFD_NO_RADAR_DISABLE) # TODO: merge with UNSUPPORTED_LONGITUDINAL_CAR CAMERA_SCC_CAR = CAR.with_flags(HyundaiFlags.CAMERA_SCC) @@ -859,7 +1037,13 @@ LEGACY_SAFETY_MODE_CAR = CAR.with_flags(HyundaiFlags.LEGACY) # HyundaiFlags.CANFD_RADAR_SCC | HyundaiFlags.CANFD_NO_RADAR_DISABLE | ) UNSUPPORTED_LONGITUDINAL_CAR = CAR.with_flags(HyundaiFlags.LEGACY) | CAR.with_flags(HyundaiFlags.UNSUPPORTED_LONGITUDINAL) -# port extensions -NON_SCC_CAR = CAR.with_iq_flags(HyundaiFlagsIQ.NON_SCC) - DBC = CAR.create_dbc_map() + +if __name__ == "__main__": + cars = [] + for platform in CAR: + for doc in platform.config.car_docs: + cars.append(doc.name) + cars.sort() + for c in cars: + print(c) diff --git a/iqdbc_repo/iqdbc/car/interfaces.py b/iqdbc_repo/iqdbc/car/interfaces.py index 79feab4..aeeef70 100644 --- a/iqdbc_repo/iqdbc/car/interfaces.py +++ b/iqdbc_repo/iqdbc/car/interfaces.py @@ -332,6 +332,12 @@ class CarStateBase(ABC): x0=[[0.0], [0.0]] K = get_kalman_gain(DT_CTRL, np.array(A), np.array(C), np.array(Q), R) self.v_ego_kf = KF1D(x0=x0, A=A, C=C[0], K=K) + self.v_ego_clu_kf = KF1D(x0=x0, A=A, C=C[0], K=K) + + self.softHoldActive = 0 + self.is_metric = True + self.lkas_enabled = False + self.modelV2 = None @abstractmethod def update(self, can_parsers) -> tuple[structs.CarState, structs.IQCarState]: @@ -348,6 +354,22 @@ class CarStateBase(ABC): v_ego_x = self.v_ego_kf.update(v_ego_raw) return float(v_ego_x[0]), float(v_ego_x[1]) + def update_clu_speed_kf(self, v_ego_raw): + if abs(v_ego_raw - self.v_ego_clu_kf.x[0][0]) > 2.0: + self.v_ego_clu_kf.set_x([[v_ego_raw], [0.0]]) + + v_ego_x = self.v_ego_clu_kf.update(v_ego_raw) + return float(v_ego_x[0]), float(v_ego_x[1]) + + def get_wheel_speeds(self, fl, fr, rl, rr, unit=CV.KPH_TO_MS): + factor = unit * self.CP.wheelSpeedFactor + wheel_speeds = structs.CarState.WheelSpeeds() + wheel_speeds.fl = fl * factor + wheel_speeds.fr = fr * factor + wheel_speeds.rl = rl * factor + wheel_speeds.rr = rr * factor + return wheel_speeds + def update_blinker_from_lamp(self, blinker_time: int, left_blinker_lamp: bool, right_blinker_lamp: bool): """Update blinkers from lights. Enable output when light was seen within the last `blinker_time` iterations""" diff --git a/iqdbc_repo/iqdbc/car/torque_data/override.toml b/iqdbc_repo/iqdbc/car/torque_data/override.toml index cbd80de..5fd55a3 100644 --- a/iqdbc_repo/iqdbc/car/torque_data/override.toml +++ b/iqdbc_repo/iqdbc/car/torque_data/override.toml @@ -7,9 +7,6 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] "NISSAN_LEAF" = [nan, 1.5, nan] "NISSAN_ROGUE" = [nan, 1.5, nan] -# PSA angle based controllers -"PSA_PEUGEOT_208" = [nan, 2.0, nan] - # New subarus angle based controllers "SUBARU_FORESTER_2022" = [nan, 3.0, nan] "SUBARU_OUTBACK_2023" = [nan, 3.0, nan] @@ -21,14 +18,11 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] # Tesla angle based controllers "TESLA_MODEL_3" = [nan, 2.5, nan] "TESLA_MODEL_Y" = [nan, 2.5, nan] -"TESLA_MODEL_X" = [nan, 2.5, nan] # Guess "FORD_BRONCO_SPORT_MK1" = [nan, 1.5, nan] "FORD_ESCAPE_MK4" = [nan, 1.5, nan] -"FORD_ESCAPE_MK4_5" = [nan, 1.5, nan] "FORD_EXPLORER_MK6" = [nan, 1.5, nan] -"FORD_EXPEDITION_MK4" = [nan, 1.5, nan] "FORD_F_150_MK14" = [nan, 1.5, nan] "FORD_FOCUS_MK4" = [nan, 1.5, nan] "FORD_MAVERICK_MK1" = [nan, 1.5, nan] @@ -44,30 +38,23 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] "RAM_1500_5TH_GEN" = [2.0, 2.0, 0.05] "RAM_HD_5TH_GEN" = [1.4, 1.4, 0.05] "SUBARU_OUTBACK" = [2.0, 1.5, 0.2] +"BUICK_BABYENCLAVE" = [1.45, 1.6, 0.2] "CADILLAC_ESCALADE" = [1.899999976158142, 1.842270016670227, 0.1120000034570694] "CADILLAC_ESCALADE_ESV_2019" = [1.15, 1.3, 0.2] "CADILLAC_XT4" = [1.45, 1.6, 0.2] -"CHEVROLET_BOLT_EUV" = [1.0, 2.0, 0.175] +"CHEVROLET_BOLT_EUV" = [2.0, 2.0, 0.05] +"CHEVROLET_MALIBU_CC" = [1.85, 1.85, 0.075] "CHEVROLET_SILVERADO" = [1.9, 1.9, 0.112] "CHEVROLET_TRAILBLAZER" = [1.33, 1.9, 0.16] "CHEVROLET_TRAVERSE" = [1.33, 1.33, 0.18] "CHEVROLET_EQUINOX" = [2.5, 2.5, 0.05] "CHEVROLET_VOLT_2019" = [1.4, 1.4, 0.16] -"VOLKSWAGEN_GOLF_MK8" = [nan, 2.5, nan] -"CUPRA_BORN_MK1" = [nan, 2.5, nan] -"VOLKSWAGEN_ID3_MK1" = [nan, 2.5, nan] -"VOLKSWAGEN_ID3_MK2" = [nan, 2.5, nan] -"VOLKSWAGEN_ID4_MK1" = [nan, 2.5, nan] -"VOLKSWAGEN_ID4_MK2" = [nan, 2.5, nan] -"AUDI_Q4_MK1" = [nan, 2.5, nan] -"AUDI_Q4_MK2" = [nan, 2.5, nan] -"SEAT_LEON_MK4" = [nan, 2.5, nan] -"SKODA_ENYAQ_MK1" = [nan, 2.5, nan] -"SKODA_ENYAQ_MK2" = [nan, 2.5, nan] +"CHEVROLET_TRAX" = [1.33, 1.9, 0.16] +"VOLKSWAGEN_ID4_MK1" = [2.0, 2.0, 0.1] +"VOLKSWAGEN_ID4_MK2" = [2.0, 2.0, 0.1] "VOLKSWAGEN_CADDY_MK3" = [1.2, 1.2, 0.1] "VOLKSWAGEN_PASSAT_NMS" = [2.5, 2.5, 0.1] "VOLKSWAGEN_SHARAN_MK2" = [2.5, 2.5, 0.1] -"SEAT_ALHAMBRA_MK1" = [2.5, 2.5, 0.1] "HYUNDAI_SANTA_CRUZ_1ST_GEN" = [2.7, 2.7, 0.1] "KIA_SPORTAGE_5TH_GEN" = [2.6, 2.6, 0.1] "GENESIS_GV70_1ST_GEN" = [2.42, 2.42, 0.1] @@ -82,33 +69,22 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] "GMC_ACADIA" = [1.6, 1.6, 0.2] "LEXUS_IS_TSS2" = [2.0, 2.0, 0.1] "HYUNDAI_KONA_EV_2ND_GEN" = [2.5, 2.5, 0.1] +"HYUNDAI_KONA_HEV_2ND_GEN" = [2.5, 2.5, 0.1] "HYUNDAI_IONIQ_6" = [2.5, 2.5, 0.005] +"HYUNDAI_IONIQ_9" = [1.75, 1.75, 0.15] +"HYUNDAI_AZERA_7TH_GEN" = [1.8, 1.8, 0.1] "HYUNDAI_AZERA_6TH_GEN" = [1.8, 1.8, 0.1] "HYUNDAI_AZERA_HEV_6TH_GEN" = [1.8, 1.8, 0.1] "KIA_K8_HEV_1ST_GEN" = [2.5, 2.5, 0.1] "HYUNDAI_CUSTIN_1ST_GEN" = [2.5, 2.5, 0.1] "LEXUS_GS_F" = [2.5, 2.5, 0.08] "HYUNDAI_STARIA_4TH_GEN" = [1.8, 2.0, 0.15] +"HYUNDAI_PORTER_II_EV" = [1.8, 2.0, 0.15] +"KIA_RAY_EV" = [1.8, 2.0, 0.15] "GENESIS_GV70_ELECTRIFIED_1ST_GEN" = [1.9, 1.9, 0.09] "GENESIS_G80_2ND_GEN_FL" = [2.5819356441497803, 2.5, 0.11244568973779678] -# Note that some Rivians achieve significantly less lateral acceleration than this "RIVIAN_R1_GEN1" = [2.8, 2.5, 0.07] "HYUNDAI_NEXO_1ST_GEN" = [2.5, 2.5, 0.1] -"HONDA_ACCORD_11G" = [1.35, 1.35, 0.17] -"HONDA_PILOT_4G" = [1.25, 1.25, 0.21] -"HONDA_PASSPORT_4G" = [1.2, 1.2, 0.16] -"ACURA_MDX_4G_MMR" = [1.25, 1.25, 0.15] -"HONDA_CRV_6G" = [1.3, 1.3, 0.2] -"HONDA_CITY_7G" = [1.2, 1.2, 0.23] -"HONDA_ODYSSEY_5G_MMR" = [0.9, 0.9, 0.2] -"HONDA_NBOX_2G" = [1.2, 1.2, 0.2] -"ACURA_TLX_2G" = [1.2, 1.2, 0.15] -"ACURA_TLX_2G_MMR" = [1.7, 1.7, 0.16] -"PORSCHE_MACAN_MK1" = [2.0, 2.0, 0.2] -"AUDI_Q5_MK1" = [1.8, 1.8, 0.18] -"LEXUS_LS" = [1.35, 1.7, 0.17] -"TOYOTA_RAV4_PRIME" = [1.7, 2.0, 0.14] -"TOYOTA_RAV4_TSS2_2022" = [1.9, 1.9304407208090029, 0.112174] # Dashcam or fallback configured as ideal car "MOCK" = [10.0, 10, 0.0] @@ -117,6 +93,25 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] "HONDA_CIVIC_2022" = [2.5, 1.2, 0.15] "HONDA_HRV_3G" = [2.5, 1.2, 0.2] -# port extensions -"HONDA_CLARITY" = [0.96, 0.4018518740819229, 0.19] -"CHEVROLET_MALIBU_NON_ACC_9TH_GEN" = [1.85, 1.85, 0.075] +# Community +"HYUNDAI_GRANDEUR_IG" = [2.3, 2.3, 0.1] +"HYUNDAI_GRANDEUR_IG_HEV" = [2.3, 2.3, 0.1] +"GENESIS_EQ900" = [2.3, 2.3, 0.1] +"GENESIS_EQ900_L" = [2.3, 2.3, 0.1] +"GENESIS_G90_2019" = [2.3, 2.3, 0.1] +"KIA_MOHAVE" = [2.3, 2.3, 0.1] +"KIA_K5" = [2.3, 2.3, 0.1] +"KIA_K5_HEV" = [2.3, 2.3, 0.1] +"KIA_K5_HEV_2022" = [2.3, 2.3, 0.1] +"KIA_K7" = [2.3, 2.3, 0.1] +"KIA_K7_HEV" = [2.3, 2.3, 0.1] +"KIA_K7_PE" = [2.3, 2.3, 0.1] +"KIA_K7_HEV_PE" = [2.3, 2.3, 0.1] +"KIA_K9" = [2.3, 2.3, 0.1] +"GENESIS_GV70_EV_1ST_GEN" = [2.42, 2.42, 0.1] +"HYUNDAI_NEXO" = [2.7, 2.7, 0.1] +"KIA_EV_SK3" = [2.5, 2.5, 0.1] +"HYUNDAI_CASPER"= [2.5, 2.5, 0.1] +"HYUNDAI_CASPER_EV"= [2.5, 2.5, 0.1] +"HYUNDAI_IONIQ_5_N" = [3.17, 2.71, 0.097] +"HYUNDAI_IONIQ_5_PE" = [1.75, 1.75, 0.15] diff --git a/iqdbc_repo/iqdbc/car/torque_data/params.toml b/iqdbc_repo/iqdbc/car/torque_data/params.toml index 1fbabf6..1f56375 100644 --- a/iqdbc_repo/iqdbc/car/torque_data/params.toml +++ b/iqdbc_repo/iqdbc/car/torque_data/params.toml @@ -37,13 +37,21 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] "HYUNDAI_SONATA" = [2.9638737459977467, 2.1259108157250735, 0.07813665616927593] "HYUNDAI_SONATA_HYBRID" = [2.8990264092395734, 2.061410192222139, 0.0899805488717382] "HYUNDAI_TUCSON_4TH_GEN" = [2.960174, 2.860284, 0.108745] +"HYUNDAI_SANTAFE_MX5" = [3.2, 3.0, 0.05] +"HYUNDAI_SANTAFE_MX5_HEV" = [3.2, 3.0, 0.05] "JEEP_GRAND_CHEROKEE_2019" = [2.30972, 1.289689569171081, 0.117048] "JEEP_GRAND_CHEROKEE" = [2.27116, 1.4057367824262523, 0.11725947414922003] "KIA_EV6" = [3.2, 2.093457, 0.005] +"KIA_EV6_PE" = [3.2, 2.093457, 0.005] "KIA_K5_2021" = [2.405339728085138, 1.460032270828705, 0.11650989850813716] +"KIA_K5_DL3_24" = [2.5, 2.5, 0.1] +"KIA_K5_DL3_24_HEV" = [2.5, 2.5, 0.1] "KIA_NIRO_EV" = [2.9215954981365337, 2.1500583840260044, 0.09236802474810267] "KIA_SORENTO" = [2.464854685101844, 1.5335274218367956, 0.12056170567599558] "KIA_STINGER" = [2.7499043387418967, 1.849652021986449, 0.12048334239559202] +"KIA_EV9" = [1.75, 1.75, 0.15] +"KIA_EV3" = [3.2, 2.093457, 0.005] +"KIA_PV5" = [3.2, 2.093457, 0.005] "LEXUS_ES_TSS2" = [2.0357564999999997, 1.999082295195227, 0.101533] "LEXUS_NX" = [2.3525924753753613, 1.9731412277641067, 0.15168101064205927] "LEXUS_NX_TSS2" = [2.4331999786982936, 2.1045680431705414, 0.14099899317761067] @@ -69,8 +77,9 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] "TOYOTA_PRIUS" = [1.60, 1.5023147650693636, 0.151515] "TOYOTA_PRIUS_TSS2" = [1.972600, 1.9104337425537743, 0.170968] "TOYOTA_RAV4" = [2.085695074355425, 2.2142832316984733, 0.13339165270103975] -"TOYOTA_RAV4_TSS2" = [1.9557514786720276, 2.087101966779332, 0.12075843289494514] +"TOYOTA_RAV4_TSS2" = [2.279239424615458, 2.087101966779332, 0.13682208413446817] "TOYOTA_RAV4H" = [1.9796257271652042, 1.7503987331707576, 0.14628860048885406] +"TOYOTA_RAV4_TSS2_2022" = [2.241883248393209, 1.9304407208090029, 0.112174] "TOYOTA_SIENNA" = [1.689726, 1.3208264576110418, 0.140456] "TOYOTA_YARIS" = [2.22984, 1.86145, 0.168189] "VOLKSWAGEN_ARTEON_MK1" = [1.45136518053819, 1.3639364049316804, 0.23806361745695032] diff --git a/iqdbc_repo/iqdbc/car/torque_data/substitute.toml b/iqdbc_repo/iqdbc/car/torque_data/substitute.toml index 4070b84..6ac4533 100644 --- a/iqdbc_repo/iqdbc/car/torque_data/substitute.toml +++ b/iqdbc_repo/iqdbc/car/torque_data/substitute.toml @@ -9,12 +9,12 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] "TOYOTA_ALPHARD_TSS2" = "TOYOTA_SIENNA" "TOYOTA_PRIUS_V" = "TOYOTA_PRIUS" -"TOYOTA_SIENNA_4TH_GEN" = "TOYOTA_RAV4_PRIME" +"TOYOTA_RAV4_PRIME" = "TOYOTA_RAV4_TSS2" +"TOYOTA_SIENNA_4TH_GEN" = "TOYOTA_RAV4_TSS2" "LEXUS_IS" = "LEXUS_NX" "LEXUS_CTH" = "LEXUS_NX" "LEXUS_ES" = "TOYOTA_CAMRY" "LEXUS_RC" = "LEXUS_NX_TSS2" -"LEXUS_RC_TSS2" = "LEXUS_NX_TSS2" "LEXUS_LC_TSS2" = "LEXUS_NX_TSS2" "KIA_OPTIMA_G4" = "HYUNDAI_SONATA" @@ -25,6 +25,7 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] "KIA_CEED" = "HYUNDAI_SONATA" "KIA_SELTOS" = "HYUNDAI_SONATA" "KIA_NIRO_PHEV" = "KIA_NIRO_EV" +"KIA_EV4" = "KIA_EV6" "KIA_NIRO_PHEV_2022" = "KIA_NIRO_EV" "KIA_NIRO_HEV_2021" = "KIA_NIRO_EV" "HYUNDAI_VELOSTER" = "HYUNDAI_SONATA_LF" @@ -45,12 +46,13 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] "GENESIS_G90" = "GENESIS_G70" "GENESIS_G80" = "GENESIS_G70" "GENESIS_G70_2020" = "HYUNDAI_SONATA" +"HYUNDAI_SONATA_2024" = "HYUNDAI_SONATA" "HONDA_FREED" = "HONDA_ODYSSEY" "HONDA_CRV_EU" = "HONDA_CRV" "HONDA_CIVIC_BOSCH_DIESEL" = "HONDA_CIVIC_BOSCH" "HONDA_E" = "HONDA_CIVIC_BOSCH" -"HONDA_ODYSSEY_TWN" = "HONDA_ODYSSEY" +"HONDA_ODYSSEY_CHN" = "HONDA_ODYSSEY" "BUICK_LACROSSE" = "CHEVROLET_VOLT" "BUICK_REGAL" = "CHEVROLET_VOLT" @@ -58,6 +60,18 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] "CADILLAC_ATS" = "CHEVROLET_VOLT" "CHEVROLET_MALIBU" = "CHEVROLET_VOLT" "HOLDEN_ASTRA" = "CHEVROLET_VOLT" +"CHEVROLET_VOLT_CC" = "CHEVROLET_VOLT" +"CHEVROLET_BOLT_CC" = "CHEVROLET_BOLT_EUV" +"CHEVROLET_BOLT_2017" = "CHEVROLET_BOLT_EUV" +"CHEVROLET_BOLT_2018" = "CHEVROLET_BOLT_EUV" +"CHEVROLET_EQUINOX_CC" = "CHEVROLET_EQUINOX" +"CHEVROLET_SUBURBAN" = "CHEVROLET_SILVERADO" +"CHEVROLET_SUBURBAN_CC" = "CHEVROLET_SILVERADO" +"CHEVROLET_TRAX_2024" = "CHEVROLET_VOLT" +"CADILLAC_CT6_CC" = "CHEVROLET_VOLT" +"CADILLAC_CT6_ACC" = "CHEVROLET_VOLT" +"CHEVROLET_TRAILBLAZER_CC" = "CHEVROLET_TRAILBLAZER" +"CADILLAC_XT5_CC" = "GMC_ACADIA" "SKODA_FABIA_MK4" = "VOLKSWAGEN_GOLF_MK7" "SKODA_OCTAVIA_MK3" = "SKODA_SUPERB_MK3" @@ -74,9 +88,6 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] "VOLKSWAGEN_POLO_MK6" = "VOLKSWAGEN_GOLF_MK7" "SEAT_ATECA_MK1" = "VOLKSWAGEN_GOLF_MK7" "VOLKSWAGEN_JETTA_MK6" = "VOLKSWAGEN_PASSAT_NMS" -"VOLKSWAGEN_PASSAT_MK7" = "VOLKSWAGEN_PASSAT_NMS" -"VOLKSWAGEN_PASSAT_NMS_PLUS" = "VOLKSWAGEN_PASSAT_NMS" -"VOLKSWAGEN_PASSAT_B7" = "VOLKSWAGEN_PASSAT_NMS" "SUBARU_CROSSTREK_HYBRID" = "SUBARU_IMPREZA_2020" "SUBARU_FORESTER_HYBRID" = "SUBARU_IMPREZA_2020" @@ -88,22 +99,3 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] "SUBARU_FORESTER_PREGLOBAL" = "SUBARU_IMPREZA" "SUBARU_LEGACY_PREGLOBAL" = "SUBARU_IMPREZA" "SUBARU_ASCENT" = "SUBARU_FORESTER" - -# port extensions -"KIA_CEED_PHEV_2022_NON_SCC" = "HYUNDAI_SONATA" -"HYUNDAI_KONA_EV_NON_SCC" = "HYUNDAI_KONA_EV" -"KIA_FORTE_2019_NON_SCC" = "HYUNDAI_SONATA" -"KIA_FORTE_2021_NON_SCC" = "HYUNDAI_SONATA" -"KIA_SELTOS_2023_NON_SCC" = "HYUNDAI_SONATA" -"HYUNDAI_KONA_NON_SCC" = "HYUNDAI_KONA_EV" -"HYUNDAI_ELANTRA_2022_NON_SCC" = "HYUNDAI_ELANTRA_2021" -"GENESIS_G70_2021_NON_SCC" = "HYUNDAI_SONATA" -"HYUNDAI_BAYON_1ST_GEN_NON_SCC" = "HYUNDAI_SONATA" -"CHEVROLET_BOLT_NON_ACC_2ND_GEN" = "CHEVROLET_BOLT_EUV" -"CHEVROLET_BOLT_NON_ACC" = "CHEVROLET_BOLT_EUV" -"CHEVROLET_BOLT_NON_ACC_1ST_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" -"CADILLAC_XT5_NON_ACC_1ST_GEN" = "GMC_ACADIA" diff --git a/iqdbc_repo/iqdbc/dbc/generator/hyundai/.gitignore b/iqdbc_repo/iqdbc/dbc/generator/hyundai/.gitignore index 81f73f3..9f93c92 100644 --- a/iqdbc_repo/iqdbc/dbc/generator/hyundai/.gitignore +++ b/iqdbc_repo/iqdbc/dbc/generator/hyundai/.gitignore @@ -1,2 +1,3 @@ hyundai_kia_mando_front_radar.dbc +hyundai_kia_denso_front_radar.dbc hyundai_kia_mando_corner_radar.dbc diff --git a/iqdbc_repo/iqdbc/dbc/generator/hyundai/_hyundai_canfd_common.dbc b/iqdbc_repo/iqdbc/dbc/generator/hyundai/_hyundai_common.dbc similarity index 94% rename from iqdbc_repo/iqdbc/dbc/generator/hyundai/_hyundai_canfd_common.dbc rename to iqdbc_repo/iqdbc/dbc/generator/hyundai/_hyundai_common.dbc index 1975155..52a0693 100644 --- a/iqdbc_repo/iqdbc/dbc/generator/hyundai/_hyundai_canfd_common.dbc +++ b/iqdbc_repo/iqdbc/dbc/generator/hyundai/_hyundai_common.dbc @@ -40,18 +40,21 @@ BO_ 80 LKAS: 16 XXX SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX SG_ LKA_MODE : 24|3@1+ (1,0) [0|7] "" XXX - SG_ LKA_AVAILABLE : 27|2@1+ (1,0) [0|255] "" XXX + SG_ LKA_ACTIVE : 27|2@1+ (1,0) [0|255] "" XXX SG_ LKA_WARNING : 32|1@1+ (1,0) [0|1] "" XXX SG_ LKA_ICON : 38|2@1+ (1,0) [0|255] "" XXX SG_ FCA_SYSWARN : 40|1@0+ (1,0) [0|1] "" XXX SG_ TORQUE_REQUEST : 41|11@1+ (1,-1024) [0|4095] "" XXX SG_ STEER_REQ : 52|1@1+ (1,0) [0|1] "" XXX SG_ LFA_BUTTON : 56|1@1+ (1,0) [0|255] "" XXX - SG_ LKA_ASSIST : 62|1@1+ (1,0) [0|1] "" XXX - SG_ STEER_MODE : 65|3@1+ (1,0) [0|1] "" XXX - SG_ NEW_SIGNAL_2 : 70|2@0+ (1,0) [0|3] "" XXX + SG_ VALUE63 : 63|4@0+ (1,0) [0|15] "" XXX + SG_ VALUE64 : 64|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_1 : 75|4@0+ (1,0) [0|15] "" XXX + SG_ LKAS_ANGLE_ACTIVE : 77|2@0+ (1,0) [0|3] "" XXX SG_ HAS_LANE_SAFETY : 80|1@0+ (1,0) [0|1] "" XXX - SG_ DAMP_FACTOR : 64|8@1+ (1,0) [0|255] "" XXX + SG_ LKAS_ANGLE_CMD : 82|14@1- (-0.1,0) [0|511] "" XXX + SG_ LKAS_ANGLE_MAX_TORQUE : 96|8@1+ (1,0) [0|255] "" XXX + SG_ VALUE104 : 104|8@1+ (1,0) [0|255] "" XXX BO_ 81 ADRV_0x51: 32 ADRV SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX diff --git a/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd.dbc b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd.dbc index e97cb97..26aa743 100644 --- a/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd.dbc +++ b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd.dbc @@ -1,4 +1,40 @@ -CM_ "IMPORT _hyundai_canfd_common.dbc"; +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX CAMERA FRONT_RADAR ADRV APRK + BO_ 53 ACCELERATOR: 32 XXX SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX @@ -10,22 +46,56 @@ BO_ 64 GEAR_ALT: 32 XXX SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX SG_ GEAR : 32|3@1+ (1,0) [0|7] "" XXX + SG_ GEAR_STEP : 67|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_4 : 68|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_1 : 75|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_3 : 76|4@1+ (1,0) [0|15] "" XXX BO_ 69 GEAR: 24 XXX SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX SG_ GEAR : 44|3@1+ (1,0) [0|7] "" XXX + SG_ RIGHT_PADDLE : 57|1@0+ (1,0) [0|1] "" XXX + SG_ LEFT_PADDLE : 58|1@0+ (1,0) [0|1] "" XXX + SG_ GEAR_STEP : 146|5@1+ (1,0) [0|31] "" XXX + SG_ GEAR_STEP1 : 154|5@1+ (1,0) [0|31] "" XXX + +BO_ 80 LKAS: 16 XXX + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ LKA_MODE : 24|3@1+ (1,0) [0|7] "" XXX + SG_ LKA_ACTIVE : 27|2@1+ (1,0) [0|255] "" XXX + SG_ LKA_WARNING : 32|1@1+ (1,0) [0|1] "" XXX + SG_ LKA_ICON : 38|2@1+ (1,0) [0|255] "" XXX + SG_ FCA_SYSWARN : 40|1@0+ (1,0) [0|1] "" XXX + SG_ TORQUE_REQUEST : 41|11@1+ (1,-1024) [0|4095] "" XXX + SG_ STEER_REQ : 52|1@1+ (1,0) [0|1] "" XXX + SG_ LFA_BUTTON : 56|1@1+ (1,0) [0|255] "" XXX + SG_ VALUE63 : 63|4@0+ (1,0) [0|15] "" XXX + SG_ VALUE64 : 64|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_1 : 75|4@0+ (1,0) [0|15] "" XXX + SG_ LKAS_ANGLE_ACTIVE : 77|2@0+ (1,0) [0|3] "" XXX + SG_ HAS_LANE_SAFETY : 80|1@0+ (1,0) [0|1] "" XXX + SG_ LKAS_ANGLE_CMD : 82|14@1- (-0.1,0) [0|511] "" XXX + SG_ LKAS_ANGLE_MAX_TORQUE : 96|8@1+ (1,0) [0|255] "" XXX + SG_ DampingGain : 104|8@1+ (1,0) [0|255] "" XXX + +BO_ 81 ADRV_0x51: 32 ADRV + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX BO_ 96 ESP_STATUS: 32 XXX SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX SG_ TRACTION_AND_STABILITY_CONTROL : 42|3@1+ (1,0) [0|63] "" XXX - SG_ BRAKE_PRESSURE : 128|10@1+ (1,0) [0|65535] "" XXX + SG_ BRAKE_PRESSURE : 128|11@1+ (1,0) [0|2047] "" XXX SG_ BRAKE_PRESSED : 148|1@1+ (1,0) [0|3] "" XXX + SG_ AUTO_HOLD : 192|1@0+ (1,0) [0|1] "" XXX BO_ 101 BRAKE: 32 XXX SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ BRAKE_LIGHT : 29|1@0+ (1,0) [0|1] "" XXX SG_ BRAKE_POSITION : 40|16@1- (1,0) [0|65535] "" XXX SG_ BRAKE_PRESSED : 57|1@1+ (1,0) [0|3] "" XXX @@ -41,32 +111,35 @@ BO_ 160 WHEEL_SPEEDS: 24 XXX SG_ MOVING_BACKWARD : 57|1@0+ (1,0) [0|1] "" XXX SG_ MOVING_FORWARD2 : 58|1@0+ (1,0) [0|1] "" XXX SG_ MOVING_BACKWARD2 : 59|1@0+ (1,0) [0|1] "" XXX - SG_ WHL_SpdFLVal : 64|14@1+ (0.03125,0) [0|0] "km^h" XXX - SG_ WHL_SpdFRVal : 80|14@1+ (0.03125,0) [0|0] "km^h" XXX - SG_ WHL_SpdRLVal : 96|14@1+ (0.03125,0) [0|0] "km^h" XXX - SG_ WHL_SpdRRVal : 112|14@1+ (0.03125,0) [0|0] "km^h" XXX + SG_ WHEEL_SPEED_1 : 64|16@1+ (0.03125,0) [0|65535] "kph" XXX + SG_ WHEEL_SPEED_2 : 80|16@1+ (0.03125,0) [0|65535] "kph" XXX + SG_ WHEEL_SPEED_3 : 96|16@1+ (0.03125,0) [0|65535] "kph" XXX + SG_ WHEEL_SPEED_4 : 112|16@1+ (0.03125,0) [0|65535] "kph" XXX -BO_ 203 ADAS_CMD_35_10ms: 24 CGW_CCU - SG_ CHECKSUM : 0|16@1+ (1,0) [0|0] "0" FCU_C,GW_RGW,MDPS,SFA - SG_ COUNTER : 16|8@1+ (1,0) [0|0] "0" FCU_C,GW_RGW,MDPS,SFA - SG_ ADAS_ActvACISta : 24|4@1+ (1,0) [0|0] "" GW_RGW,MDPS,SFA - SG_ ADAS_ActvACILvl2Sta : 28|4@1+ (1,0) [0|0] "" ESC,FCU_C,GW_RGW,MDPS,SFA,VPC_C - SG_ ADAS_StrAnglReqVal : 32|14@1- (0.1,0) [0|119.9] "Deg" GW_RGW,MDPS,SFA - SG_ ADAS_ACIAnglTqRedcGainVal : 48|8@1+ (0.004,0) [0|1] "" GW_RGW,MDPS,SFA - SG_ FCA_ESA_ActvSta : 56|2@1+ (1,0) [0|0] "" GW_RGW,MDPS,SFA - SG_ FCA_ESA_TqBstGainVal : 64|8@1+ (0.004,0) [0|0] "" GW_RGW,MDPS,SFA +BO_ 203 LFA_ALT: 24 ADRV + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ LKAS_ANGLE_ACTIVE : 29|2@0+ (1,0) [0|3] "" XXX + SG_ LKAS_ANGLE_CMD : 32|14@1- (-0.1,0) [0|511] "" XXX + SG_ LKAS_ANGLE_MAX_TORQUE : 55|8@0+ (1,0) [0|255] "" XXX BO_ 234 MDPS: 24 XXX SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_1 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_2 : 39|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_3 : 47|8@0+ (1,0) [0|255] "" XXX SG_ LKA_ACTIVE : 48|1@0+ (1,0) [0|16777215] "" XXX SG_ LKA_FAULT : 54|1@0+ (1,0) [0|1] "" XXX SG_ STEERING_OUT_TORQUE : 64|12@1+ (0.1,-204.8) [0|65535] "" XXX SG_ STEERING_COL_TORQUE : 80|13@1+ (1,-4095) [0|4095] "" XXX - SG_ STEERING_ANGLE : 96|16@1- (0.1,0) [0|255] "deg" XXX - SG_ STEERING_ANGLE_2 : 128|16@1- (0.1,0) [0|65535] "deg" XXX - SG_ LKA_ANGLE_ACTIVE : 145|2@0+ (1,0) [0|3] "" XXX - SG_ LKA_ANGLE_FAULT : 149|1@0+ (1,0) [0|1] "" XXX + SG_ STEERING_ANGLE : 96|16@1- (-0.1,0) [0|255] "deg" XXX + SG_ STEERING_ANGLE_2 : 128|16@1- (-0.1,0) [0|65535] "deg" XXX + SG_ LFA2_ACTIVE : 145|2@0+ (1,0) [0|3] "" XXX + SG_ LFA2_FAULT : 149|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_4 : 159|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_5 : 167|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_6 : 175|8@0+ (1,0) [0|255] "" XXX BO_ 256 ACCELERATOR_BRAKE_ALT: 32 XXX SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX @@ -79,73 +152,63 @@ BO_ 261 ACCELERATOR_ALT: 32 XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX SG_ ACCELERATOR_PEDAL : 103|10@1+ (0.25,0) [0|1022] "" XXX +BO_ 267 CRUISE_BUTTONS_ALT2: 16 XXX + SG_ CRUISE_BUTTONS : 83|4@0+ (1,0) [0|15] "" XXX + SG_ LFA_BTN : 87|1@0+ (1,0) [0|1] "" XXX + BO_ 272 LKAS_ALT: 32 XXX SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX SG_ LKA_MODE : 24|3@1+ (1,0) [0|7] "" XXX - SG_ LKA_AVAILABLE : 27|2@1+ (1,0) [0|255] "" XXX + SG_ LKA_ACTIVE : 27|2@1+ (1,0) [0|3] "" XXX SG_ LKA_WARNING : 32|1@1+ (1,0) [0|1] "" XXX - SG_ LKA_ICON : 38|2@1+ (1,0) [0|255] "" XXX + SG_ LKA_ICON : 38|2@1+ (1,0) [0|3] "" XXX SG_ FCA_SYSWARN : 40|1@0+ (1,0) [0|1] "" XXX SG_ TORQUE_REQUEST : 41|11@1+ (1,-1024) [0|4095] "" XXX SG_ STEER_REQ : 52|1@1+ (1,0) [0|1] "" XXX - SG_ LFA_BUTTON : 56|1@1+ (1,0) [0|255] "" XXX - SG_ LKA_ASSIST : 62|1@1+ (1,0) [0|1] "" XXX - SG_ STEER_MODE : 65|3@1+ (1,0) [0|1] "" XXX - SG_ NEW_SIGNAL_2 : 70|2@0+ (1,0) [0|3] "" XXX + SG_ LFA_BUTTON : 56|1@1+ (1,0) [0|1] "" XXX + SG_ VALUE63 : 63|4@0+ (1,0) [0|15] "" XXX + SG_ VALUE64 : 64|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_1 : 75|4@0+ (1,0) [0|15] "" XXX SG_ LKAS_ANGLE_ACTIVE : 77|2@0+ (1,0) [0|3] "" XXX SG_ HAS_LANE_SAFETY : 80|1@0+ (1,0) [0|1] "" XXX - SG_ ADAS_StrAnglReqVal : 82|14@1- (0.1,0) [0|176.7] "Deg" GW_RGW,MDPS,SFA - SG_ ADAS_ACIAnglTqRedcGainVal : 96|8@1+ (0.004,0) [0|1] "" GW_RGW,MDPS,SFA - SG_ DAMP_FACTOR : 64|8@1+ (1,0) [0|255] "" XXX - -BO_ 282 FR_CMR_01_10ms: 16 FR_CMR - SG_ FR_CMR_Crc1Val : 0|16@1+ (1,0) [0|0] "" Dummy,IBU_HS,vBDM - SG_ FR_CMR_AlvCnt1Val : 16|8@1+ (1,0) [0|0] "" CLU,IBU_HS,vBDM - SG_ HBA_SysOptSta : 24|2@1+ (1,0) [0|3] "" CLU,IBU_HS,vBDM - SG_ HBA_SysSta : 26|3@1+ (1,0) [0|7] "" CLU,IBU_HS,vBDM - SG_ HBA_IndLmpReq : 29|2@1+ (1,0) [0|3] "" CLU,vBDM - SG_ iHBAref_VehLftSta : 31|2@1+ (1,0) [0|3] "" IBU_HS,ICU,vBDM - SG_ iHBAref_VehCtrSta : 33|2@1+ (1,0) [0|3] "" IBU_HS,ICU,vBDM - SG_ iHBAref_VehRtSta : 35|2@1+ (1,0) [0|3] "" IBU_HS,ICU,vBDM - SG_ iHBAref_ILLAmbtSta : 37|2@1+ (1,0) [0|3] "" IBU_HS,ICU,vBDM - SG_ FCA_Equip_MFC : 39|3@1+ (1,0) [0|0] "" ADAS_DRV,RR_C_RDR,vBDM - SG_ HBA_OptUsmSta : 42|2@1+ (1,0) [0|3] "" CLU,H_U_MM - SG_ FCAref_FusSta : 45|3@1+ (1,0) [0|0] "" vBDM - SG_ DAW_LVDA_PUDis : 48|2@1+ (1,0) [0|0] "" CLU,vBDM - SG_ DAW_LVDA_OptUsmSta : 50|2@1+ (1,0) [0|3] "" CLU,H_U_MM,vBDM - SG_ DAW_OptUsmSta : 52|3@1+ (1,0) [0|0] "" CLU,H_U_MM - SG_ DAW_SysSta : 55|4@1+ (1,0) [0|0] "" CLU - SG_ DAW_WrnMsgSta : 59|3@1+ (1,0) [0|0] "" CLU - SG_ DAW_TimeRstReq : 62|2@1+ (1,0) [0|0] "" CLU - SG_ DAW_SnstvtyModRetVal : 64|3@1+ (1,0) [0|0] "" CLU,H_U_MMz - SG_ FR_CMR_SCCEquipSta : 85|2@1+ (1,0) [0|3] "" CGW - SG_ FR_CMR_ReqADASMapMsgVal : 96|16@1+ (1,0) [0|65535] "" CGW - SG_ FR_CMR_SwVer1Val : 112|4@1+ (1,0) [0|15] "" CGW - SG_ FR_CMR_SwVer2Val : 120|8@1+ (1,0) [0|255] "" CGW + SG_ LKAS_ANGLE_CMD : 82|14@1- (-0.1,0) [0|511] "" XXX + SG_ LKAS_ANGLE_MAX_TORQUE : 96|8@1+ (1,0) [0|255] "" XXX + SG_ DampingGain : 104|8@1+ (1,0) [0|255] "" XXX + SG_ VALUE231 : 231|8@0+ (1,0) [0|255] "" XXX + SG_ VALUE239 : 239|8@0+ (1,0) [0|255] "" XXX + SG_ VALUE247 : 247|8@0+ (1,0) [0|255] "" XXX + SG_ VALUE255 : 255|8@0+ (1,0) [0|255] "" XXX BO_ 293 STEERING_SENSORS: 16 XXX SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX - SG_ STEERING_ANGLE : 24|16@1- (0.1,0) [0|255] "deg" XXX + SG_ STEERING_ANGLE : 24|16@1- (-0.1,0) [0|255] "deg" XXX SG_ STEERING_RATE : 40|8@1+ (4,0) [0|1016] "deg/s" XXX BO_ 298 LFA: 16 ADRV SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX SG_ LKA_MODE : 24|3@1+ (1,0) [0|7] "" XXX - SG_ NEW_SIGNAL_1 : 27|2@1+ (1,0) [0|255] "" XXX + SG_ LKA_ACTIVE : 27|2@1+ (1,0) [0|3] "" XXX SG_ LKA_WARNING : 32|1@1+ (1,0) [0|1] "" XXX - SG_ LKA_ICON : 38|2@1+ (1,0) [0|255] "" XXX + SG_ LKA_ICON : 38|2@1+ (1,0) [0|3] "" XXX + SG_ FCA_SYSWARN : 40|1@0+ (1,0) [0|1] "" XXX SG_ TORQUE_REQUEST : 41|11@1+ (1,-1024) [0|4095] "" XXX SG_ STEER_REQ : 52|1@1+ (1,0) [0|1] "" XXX - SG_ LFA_BUTTON : 56|1@1+ (1,0) [0|255] "" XXX - SG_ LKA_ASSIST : 62|1@1+ (1,0) [0|1] "" XXX - SG_ STEER_MODE : 65|3@1+ (1,0) [0|1] "" XXX - SG_ NEW_SIGNAL_2 : 70|2@0+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_4 : 72|4@1+ (1,0) [0|15] "" XXX + SG_ LFA_BUTTON : 56|1@1+ (1,0) [0|1] "" XXX + SG_ VALUE63 : 63|4@0+ (1,0) [0|15] "" XXX + SG_ VALUE64 : 64|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_1 : 75|4@0+ (1,0) [0|15] "" XXX + SG_ LKAS_ANGLE_ACTIVE : 77|2@0+ (1,0) [0|3] "" XXX SG_ HAS_LANE_SAFETY : 80|1@0+ (1,0) [0|1] "" XXX - SG_ DAMP_FACTOR : 104|8@1+ (1,0) [0|255] "" XXX + SG_ LKAS_ANGLE_CMD : 82|14@1- (-0.1,0) [0|511] "" XXX + SG_ LKAS_ANGLE_MAX_TORQUE : 96|8@1+ (1,0) [0|255] "" XXX + SG_ DampingGain : 104|8@1+ (1,0) [0|255] "" XXX + SG_ VALUE231 : 231|8@0+ (1,0) [0|255] "" XXX + SG_ VALUE239 : 239|8@0+ (1,0) [0|255] "" XXX + SG_ VALUE247 : 247|8@0+ (1,0) [0|255] "" XXX + SG_ VALUE255 : 255|8@0+ (1,0) [0|255] "" XXX BO_ 304 GEAR_SHIFTER: 16 XXX SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX @@ -154,75 +217,77 @@ BO_ 304 GEAR_SHIFTER: 16 XXX SG_ KNOB_POSITION : 40|3@1+ (1,0) [0|3] "" XXX SG_ GEAR : 64|3@1+ (1,0) [0|7] "" XXX +BO_ 1079 TRAILER_STATUS: 8 XXX + SG_ TRAILER_CONNECTED : 0|1@1+ (1,0) [0|1] "" XXX + BO_ 352 ADRV_0x160: 16 ADRV SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX SG_ AEB_SETTING : 24|2@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_1 : 30|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_4 : 31|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_5 : 39|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_6 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_2 : 55|8@0+ (1,0) [0|255] "" XXX SG_ SET_ME_2 : 56|8@1+ (1,0) [0|1] "" XXX SG_ SET_ME_FF : 64|8@1+ (1,0) [0|255] "" XXX SG_ SET_ME_FC : 72|8@1+ (1,0) [0|255] "" XXX SG_ SET_ME_9 : 80|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_3 : 95|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 102|1@0+ (1,0) [0|1] "" XXX -BO_ 353 CCNC_0x161: 32 CCNC +BO_ 353 ADRV_0x161: 32 ADRV SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX SG_ FCA_ICON : 24|3@1+ (1,0) [0|7] "" XXX SG_ FCA_ALT_ICON : 27|3@1+ (1,0) [0|7] "" XXX SG_ LKA_ICON : 30|3@1+ (1,0) [0|3] "" XXX SG_ HBA_ICON : 33|3@1+ (1,0) [0|7] "" XXX - SG_ ZEROS_1 : 36|4@1+ (1,0) [0|15] "" XXX - SG_ ZEROS_2 : 40|2@1+ (1,0) [0|3] "" XXX SG_ FCA_IMAGE : 42|3@1+ (1,0) [0|7] "" XXX - SG_ ZEROS_3 : 45|3@1+ (1,0) [0|7] "" XXX - SG_ ZEROS_4 : 48|3@1+ (1,0) [0|7] "" XXX SG_ BCA_LEFT : 51|3@1+ (1,0) [0|7] "" XXX SG_ BCA_RIGHT : 54|3@1+ (1,0) [0|7] "" XXX SG_ LCA_LEFT_ARROW : 57|3@1+ (1,0) [0|7] "" XXX SG_ LCA_RIGHT_ARROW : 60|3@1+ (1,0) [0|7] "" XXX - SG_ ZEROS_5 : 63|1@0+ (1,0) [0|1] "" XXX SG_ CENTERLINE : 64|2@1+ (1,0) [0|3] "" XXX SG_ TARGET : 66|3@1+ (1,0) [0|7] "" XXX SG_ TARGET_DISTANCE : 69|11@1+ (0.1,0) [0|204.7] "m" XXX SG_ LANELINE_LEFT : 80|4@1+ (1,0) [0|15] "" XXX SG_ LANELINE_LEFT_POSITION : 84|6@1+ (1,0) [0|15] "" XXX SG_ LANELINE_RIGHT : 90|4@1+ (1,0) [0|15] "" XXX - SG_ LANELINE_RIGHT_POSITION : 94|6@1+ (1,0) [0|3] "" XXX - SG_ LANELINE_CURVATURE : 100|5@1- (1,15) [0|31] "" XXX + SG_ LANELINE_RIGHT_POSITION : 94|6@1+ (1,0) [0|15] "" XXX + SG_ LANELINE_CURVATURE : 100|4@1+ (1,0) [0|31] "" XXX + SG_ LANELINE_CURVATURE_DIRECTION : 104|1@0+ (1,0) [0|1] "" XXX SG_ LANE_HIGHLIGHT : 105|4@1+ (1,0) [0|15] "" XXX SG_ LANE_HIGHLIGHT_DISTANCE : 109|11@1+ (0.1,0) [0|204.7] "m" XXX SG_ LANE_LEFT : 120|3@1+ (1,0) [0|7] "" XXX SG_ LANE_RIGHT : 123|3@1+ (1,0) [0|7] "" XXX SG_ LANE_ZOOM : 126|2@1+ (1,0) [0|3] "" XXX SG_ ALERTS_1 : 128|6@1+ (1,0) [0|63] "" XXX - SG_ ALERTS_2 : 134|5@1+ (1,0) [0|3] "" XXX - SG_ ALERTS_3 : 139|5@1+ (1,0) [0|15] "" XXX - SG_ ALERTS_4 : 144|8@1+ (1,0) [0|511] "" XXX - SG_ ALERTS_5 : 152|5@1+ (1,0) [0|7] "" XXX + SG_ ALERTS_2 : 134|5@1+ (1,0) [0|31] "" XXX + SG_ ALERTS_3 : 139|5@1+ (1,0) [0|31] "" XXX + SG_ ALERTS_4 : 144|8@1+ (1,0) [0|255] "" XXX + SG_ ALERTS_5 : 152|5@1+ (1,0) [0|31] "" XXX SG_ MUTE : 157|3@1+ (1,0) [0|7] "" XXX SG_ SOUNDS_1 : 160|4@1+ (1,0) [0|3] "" XXX SG_ SOUNDS_2 : 164|4@1+ (1,0) [0|3] "" XXX SG_ SOUNDS_3 : 168|4@1+ (1,0) [0|15] "" XXX SG_ SOUNDS_4 : 172|3@1+ (1,0) [0|7] "" XXX - SG_ ZEROS_6 : 175|1@0+ (1,0) [0|1] "" XXX - SG_ ZEROS_7 : 176|5@1+ (1,0) [0|31] "" XXX - SG_ SETSPEED_HUD : 181|3@1+ (1,0) [0|3] "" XXX + SG_ SETSPEED_HUD : 181|3@1+ (1,0) [0|7] "" XXX SG_ DISTANCE_LEAD : 184|5@1+ (1,0) [0|31] "" XXX SG_ DISTANCE_CAR : 189|3@1+ (1,0) [0|7] "" XXX SG_ DISTANCE_SPACING : 192|4@1+ (1,0) [0|15] "" XXX SG_ DISTANCE : 196|4@1+ (1,0) [0|7] "" XXX - SG_ SETSPEED_SPEED : 200|8@1+ (1,0) [0|255] "" XXX - SG_ SETSPEED : 208|4@1+ (1,0) [0|3] "" XXX - SG_ HDA_ICON : 212|4@1+ (1,0) [0|3] "" XXX + SG_ vSetDis : 200|8@1+ (1,0) [0|255] "" XXX + SG_ SETSPEED : 208|4@1+ (1,0) [0|7] "" XXX + SG_ HDA_ICON : 212|3@1+ (1,0) [0|7] "" XXX SG_ SLA_ICON : 216|4@1+ (1,0) [0|15] "" XXX - SG_ NAV_ICON : 220|4@1+ (1,0) [0|3] "" XXX - SG_ LFA_ICON : 224|4@1+ (1,0) [0|3] "" XXX - SG_ LCA_LEFT_ICON : 228|4@1+ (1,0) [0|15] "" XXX - SG_ LCA_RIGHT_ICON : 232|4@1+ (1,0) [0|15] "" XXX + SG_ NAV_ICON : 220|3@1+ (1,0) [0|7] "" XXX + SG_ LFA_ICON : 224|3@1+ (1,0) [0|7] "" XXX + SG_ LCA_LEFT_ICON : 228|3@1+ (1,0) [0|7] "" XXX + SG_ LCA_RIGHT_ICON : 232|3@1+ (1,0) [0|7] "" XXX SG_ BACKGROUND : 236|4@1+ (1,0) [0|15] "" XXX SG_ DAW_ICON : 240|3@1+ (1,0) [0|7] "" XXX SG_ CAR_CIRCLE : 243|3@1+ (1,0) [0|7] "" XXX - SG_ ZEROS_8 : 246|2@1+ (1,0) [0|3] "" XXX - SG_ ZEROS_9 : 248|8@1+ (1,0) [0|255] "" XXX BO_ 354 CCNC_0x162: 32 CCNC SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX @@ -232,35 +297,25 @@ BO_ 354 CCNC_0x162: 32 CCNC SG_ SPEEDLIMIT : 32|8@1+ (1,0) [0|255] "" XXX SG_ SIGNS : 40|8@1+ (1,0) [0|15] "" XXX SG_ SPEEDLIMIT_WEATHER : 48|4@1+ (1,0) [0|15] "" XXX - SG_ VIBRATE : 52|3@1+ (1,0) [0|7] "" XXX - SG_ ZEROS_1 : 55|1@0+ (1,0) [0|1] "" XXX - SG_ ZEROS_2 : 56|8@1+ (1,0) [0|255] "" XXX - SG_ LEAD : 64|5@1+ (1,0) [0|31] "" XXX - SG_ LEAD_DISTANCE : 69|11@1+ (0.1,0) [0|204.7] "m" XXX - SG_ LEAD_LATERAL : 80|7@1+ (0.1,0) [0|127] "m" XXX - SG_ ZEROS_3 : 87|1@0+ (1,0) [0|1] "" XXX - SG_ LEAD_ALT : 88|5@1+ (1,0) [0|31] "" XXX - SG_ LEAD_ALT_DISTANCE : 93|11@1+ (0.1,0) [0|204.7] "m" XXX - SG_ LEAD_ALT_LATERAL : 104|7@1+ (0.1,0) [0|127] "m" XXX - SG_ ZEROS_4 : 111|1@0+ (1,0) [0|1] "" XXX - SG_ LEAD_LEFT : 112|5@1+ (1,0) [0|31] "" XXX - SG_ LEAD_LEFT_DISTANCE : 117|11@1+ (0.1,0) [0|204.7] "m" XXX - SG_ LEAD_LEFT_LATERAL : 128|7@1+ (0.1,0) [0|127] "m" XXX - SG_ ZEROS_5 : 135|1@0+ (1,0) [0|1] "" XXX - SG_ LEAD_RIGHT : 136|5@1+ (1,0) [0|31] "" XXX - SG_ LEAD_RIGHT_DISTANCE : 141|11@1+ (0.1,0) [0|204.7] "m" XXX - SG_ LEAD_RIGHT_LATERAL : 152|7@1+ (0.1,0) [0|127] "m" XXX - SG_ ZEROS_6 : 159|1@0+ (1,0) [0|1] "" XXX - SG_ ZEROS_7 : 162|3@0+ (1,0) [0|7] "" XXX - SG_ LEAD_LEFT_REAR_STATUS : 167|5@0+ (1,0) [0|31] "" XXX - SG_ LEAD_LEFT_REAR_DISTANCE : 175|8@0+ (0.1,0) [0|255] "m" XXX - SG_ LEAD_LEFT_REAR_LATERAL : 182|7@0+ (0.1,0) [0|127] "m" XXX - SG_ ZEROS_8 : 183|1@0+ (1,0) [0|1] "" XXX - SG_ ZEROS_9 : 191|8@0+ (1,0) [0|255] "" XXX - SG_ LEAD_RIGHT_REAR_STATUS : 196|5@0+ (1,0) [0|31] "" XXX - SG_ LEAD_RIGHT_REAR_DISTANCE : 197|8@1+ (0.1,0) [0|255] "m" XXX - SG_ LEAD_RIGHT_REAR_LATERAL : 205|7@1+ (0.1,0) [0|127] "m" XXX - SG_ ZEROS_10 : 212|1@0+ (1,0) [0|1] "" XXX + SG_ VIBRATE : 52|1@0+ (1,0) [0|1] "" XXX + SG_ FF_DETECT : 64|5@1+ (1,0) [0|31] "" XXX + SG_ FF_DISTANCE : 69|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ FF_LATERAL : 80|7@1+ (0.1,0) [0|127] "m" XXX + SG_ FF_DETECT_ALT : 88|5@1+ (1,0) [0|31] "" XXX + SG_ FF_DISTANCE_ALT : 93|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ FF_LATERAL_ALT : 104|7@1+ (0.1,0) [0|127] "m" XXX + SG_ LF_DETECT : 112|5@1+ (1,0) [0|31] "" XXX + SG_ LF_DETECT_DISTANCE : 117|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LF_DETECT_LATERAL : 128|7@1+ (0.1,0) [0|127] "m" XXX + SG_ RF_DETECT : 136|5@1+ (1,0) [0|31] "" XXX + SG_ RF_DETECT_DISTANCE : 141|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ RF_DETECT_LATERAL : 152|7@1+ (0.1,0) [0|127] "m" XXX + SG_ LR_DETECT : 163|5@1+ (1,0) [0|31] "" XXX + SG_ LR_DETECT_DISTANCE : 175|8@0+ (0.1,0) [0|255] "" XXX + SG_ LR_DETECT_LATERAL : 176|7@1+ (0.1,0) [0|127] "" XXX + SG_ RR_DETECT : 192|5@1+ (1,0) [0|31] "" XXX + SG_ RR_DETECT_DISTANCE : 197|8@1+ (0.1,0) [0|255] "" XXX + SG_ RR_DETECT_LATERAL : 205|7@1+ (0.1,0) [0|127] "" XXX SG_ FAULT_FSS : 213|3@1+ (1,0) [0|7] "" XXX SG_ FAULT_FCA : 216|3@1+ (1,0) [0|7] "" XXX SG_ FAULT_LSS : 219|3@1+ (1,0) [0|7] "" XXX @@ -274,7 +329,6 @@ BO_ 354 CCNC_0x162: 32 CCNC SG_ FAULT_HDP : 243|3@1+ (1,0) [0|7] "" XXX SG_ FAULT_DAS : 246|3@1+ (1,0) [0|7] "" XXX SG_ FAULT_ESS : 249|3@1+ (1,0) [0|7] "" XXX - SG_ ZEROS_11 : 252|4@1+ (1,0) [0|15] "" XXX BO_ 357 SPAS1: 24 APRK SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX @@ -291,56 +345,95 @@ BO_ 373 TCS: 24 XXX SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_4 : 24|7@1+ (1,0) [0|127] "" XXX + SG_ NEW_SIGNAL_9 : 31|1@0+ (1,0) [0|1] "" XXX SG_ aBasis : 32|11@1+ (0.01,-10.23) [0|7] "m/s^2" XXX + SG_ NEW_SIGNAL_1 : 47|5@0+ (1,0) [0|31] "" XXX SG_ ACCEL_REF_ACC : 48|11@1- (1,0) [0|1023] "" XXX - SG_ EQUIP_MAYBE : 64|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_2 : 63|5@0+ (1,0) [0|31] "" XXX + SG_ SCC_OptTyp : 64|2@1+ (1,0) [0|0] "" AWD,EMS,FR_CMR,HCU,H_U_MM,TCU,VCU,vBDM SG_ ACCEnable : 67|2@0+ (1,0) [0|3] "" XXX SG_ ACC_REQ : 68|1@0+ (1,0) [0|1] "" XXX - SG_ NEW_SIGNAL_5 : 72|1@0+ (1,0) [0|1] "" XXX - SG_ NEW_SIGNAL_2 : 74|1@0+ (1,0) [0|1] "" XXX - SG_ NEW_SIGNAL_3 : 76|1@0+ (1,0) [0|1] "" XXX - SG_ NEW_SIGNAL_1 : 80|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_3 : 69|1@0+ (1,0) [0|1] "" XXX + SG_ SCC_ReqLimSta : 70|2@1+ (1,0) [0|0] "" ADAS_DRV,AWD,Dummy,EMS,FR_CMR,H_U_MM,TCU,vBDM + SG_ ESC_StdStillVal : 72|2@1+ (1,0) [0|3] "" ADAS_DRV,AWD,Dummy,EMS,FR_CMR,H_U_MM,TCU,vBDM + SG_ BrakeLight : 74|2@1+ (1,0) [0|3] "" XXX + SG_ ESC_DclEnblReq : 76|2@1+ (1,0) [0|3] "" AWD,Dummy,EMS,FR_CMR,H_U_MM,TCU,vBDM + SG_ NEW_SIGNAL_5 : 79|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_21 : 80|1@0+ (1,0) [0|1] "" XXX SG_ DriverBraking : 81|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_20 : 82|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_11 : 83|1@0+ (1,0) [0|1] "" XXX SG_ DriverBrakingLowSens : 84|1@1+ (1,0) [0|1] "" XXX - SG_ AEB_EQUIP_MAYBE : 96|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_10 : 85|1@0+ (1,0) [0|1] "" XXX + SG_ ESC_PrkBrkActvSta : 86|2@1+ (1,0) [0|3] "" ADAS_DRV,AWD,Dummy,EMS,FR_CMR,H_U_MM,RR_C_RDR,TCU,vBDM + SG_ NEW_SIGNAL_12 : 95|8@0+ (1,0) [0|255] "" XXX + SG_ FCA_EquipSta : 96|2@1+ (1,0) [0|3] "" ADAS_DRV,FR_CMR,H_U_MM,vBDM + SG_ FCA_AvlblSta : 98|2@1+ (1,0) [0|3] "" ADAS_DRV,AFCU_DRV,CLU,Dummy,FR_CMR,H_U_MM,vBDM + SG_ NEW_SIGNAL_13 : 103|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_14 : 111|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_15 : 119|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_16 : 127|8@0+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_6 : 128|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_17 : 133|2@0+ (1,0) [0|3] "" XXX SG_ NEW_SIGNAL_7 : 135|2@0+ (1,0) [0|3] "" XXX SG_ PROBABLY_EQUIP : 136|2@1+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_18 : 143|6@0+ (1,0) [0|63] "" XXX + SG_ NEW_SIGNAL_19 : 151|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_8 : 183|16@0+ (1,0) [0|65535] "" XXX + +BO_ 384 CAM_0x180: 32 CAMERA + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 385 CAM_0x181: 32 CAMERA + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 386 CAM_0x182: 32 CAMERA + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 387 CAM_0x183: 32 CAMERA + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 388 CAM_0x184: 32 CAMERA + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 389 CAM_0x185: 8 CAMERA + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX BO_ 416 SCC_CONTROL: 32 ADRV SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX SG_ ACC_ObjDist : 24|11@1+ (0.1,0) [0|204.7] "m" XXX - SG_ ACC_ObjRelSpd : 35|9@1+ (0.1,-16.4) [-16.4|34.7] "m/s" XXX - SG_ SET_ME_3 : 45|2@0+ (1,0) [0|3] "" XXX - SG_ ObjValid : 46|1@0+ (1,0) [0|3] "" XXX - SG_ SET_ME_TMP_64 : 55|8@0+ (1,0) [0|63] "" XXX + SG_ ACC_ObjRelSpd : 35|12@1+ (0.1,-170) [-16.4|34.7] "m/s" XXX + SG_ ACC_ObjLatPos : 47|9@1- (0.1,-20) [0|511] "" XXX SG_ ZEROS_7 : 63|8@0+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_1 : 64|2@1+ (1,0) [0|3] "" XXX + SG_ SysFailState : 64|2@1+ (1,0) [0|3] "" XXX SG_ MainMode_ACC : 66|1@1+ (1,0) [0|1] "" XXX SG_ ACCMode : 68|3@1+ (1,0) [0|7] "" XXX - SG_ ZEROS_9 : 71|5@1+ (1,0) [0|15] "" XXX - SG_ CRUISE_STANDSTILL : 76|1@1+ (1,0) [0|1] "" XXX - SG_ ZEROS_5 : 77|11@1+ (1,0) [0|2047] "" XXX - SG_ DISTANCE_SETTING : 88|3@1+ (1,0) [0|3] "" XXX - SG_ ZEROS_8 : 95|5@0+ (1,0) [0|31] "" XXX + SG_ TakeOverReq : 73|2@0+ (1,0) [0|3] "" XXX + SG_ InfoDisplay : 74|3@1+ (1,0) [0|7] "" XXX + SG_ DriverAlert : 77|2@1+ (1,0) [0|3] "" XXX + SG_ ObjDistLevel : 80|8@1+ (1,0) [0|255] "" XXX + SG_ DISTANCE_SETTING : 88|4@1+ (1,0) [0|15] "" XXX SG_ VSetDis : 103|8@0+ (1,0) [0|255] "km/h or mph" XXX - SG_ NEW_SIGNAL_6 : 104|1@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_2 : 105|3@1+ (1,0) [0|7] "" XXX - SG_ SCC_ObjSta : 108|3@1+ (1,0) [0|7] "" CLU,CGW - SG_ ZEROS_10 : 111|2@0+ (1,0) [0|3] "" XXX - SG_ ZEROS_6 : 119|16@0+ (1,0) [0|65535] "" XXX + SG_ NSCCOper : 104|2@1+ (1,0) [0|3] "" XXX + SG_ NSCCOnOff : 106|2@1+ (1,0) [0|3] "" XXX + SG_ HUD_LEAD_INFO : 108|3@1+ (1,0) [0|7] "" XXX + SG_ DriveMode : 112|3@1+ (1,0) [0|7] "" XXX SG_ aReqValue : 128|11@1+ (0.01,-10.23) [-10.23|10.24] "m/s^2" XXX SG_ aReqRaw : 140|11@1+ (0.01,-10.23) [-10.23|10.24] "m/s^2" XXX SG_ JerkUpperLimit : 158|7@0+ (0.1,0) [0|0] "" XXX SG_ JerkLowerLimit : 166|7@0+ (0.1,0) [0|12.7] "m/s^3" XXX - SG_ NEW_SIGNAL_2 : 168|2@1+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_8 : 170|4@1+ (1,0) [0|15] "" XXX - SG_ OBJ_STATUS : 176|3@1+ (1,0) [0|7] "" XXX - SG_ ZEROS_4 : 183|4@0+ (1,0) [0|63] "" XXX - SG_ StopReq : 184|1@0+ (1,0) [0|1] "" XXX - SG_ ZEROS_3 : 191|7@0+ (1,0) [0|127] "" XXX - SG_ NEW_SIGNAL_15 : 192|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ AccelLimitBandUpper : 173|6@0+ (0.02,0) [0|63] "" XXX + SG_ AccelLimitBandLower : 181|6@0+ (0.02,0) [0|63] "" XXX + SG_ StopReq : 185|2@0+ (1,0) [0|3] "" XXX + SG_ CRUSE_INFO_SET_2 : 189|2@0+ (1,0) [0|3] "" XXX + SG_ TARGET_DISTANCE : 192|11@1+ (0.1,0) [0|204.7] "m" XXX SG_ ZEROS_2 : 207|5@0+ (1,0) [0|63] "" XXX SG_ ZEROS : 215|48@0+ (1,0) [0|281474976710655] "" XXX @@ -354,7 +447,7 @@ BO_ 426 CRUISE_BUTTONS_ALT: 16 XXX SG_ ADAPTIVE_CRUISE_MAIN_BTN : 34|1@1+ (1,0) [0|1] "" XXX SG_ NEW_SIGNAL_3 : 35|1@1+ (1,0) [0|1] "" XXX SG_ CRUISE_BUTTONS : 36|3@1+ (1,0) [0|4] "" XXX - SG_ LDA_BTN : 39|1@1+ (1,0) [0|1] "" XXX + SG_ LFA_BTN : 39|1@1+ (1,0) [0|1] "" XXX SG_ NEW_SIGNAL_4 : 40|1@1+ (1,0) [0|1] "" XXX SG_ NORMAL_CRUISE_MAIN_BTN : 41|1@1+ (1,0) [0|1] "" XXX SG_ NEW_SIGNAL_5 : 42|2@1+ (1,0) [0|3] "" XXX @@ -362,7 +455,7 @@ BO_ 426 CRUISE_BUTTONS_ALT: 16 XXX SG_ NEW_SIGNAL_6 : 47|1@1+ (1,0) [0|1] "" XXX SG_ BYTE6 : 48|8@1+ (1,0) [0|255] "" XXX SG_ BYTE7 : 56|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE8 : 64|8@1+ (1,0) [0|255] "" XXX + SG_ CLU_SPEED : 64|8@1+ (1,0) [0|255] "" XXX SG_ BYTE9 : 72|8@1+ (1,0) [0|255] "" XXX SG_ BYTE10 : 80|8@1+ (1,0) [0|255] "" XXX SG_ BYTE11 : 88|8@1+ (1,0) [0|255] "" XXX @@ -371,38 +464,55 @@ BO_ 426 CRUISE_BUTTONS_ALT: 16 XXX SG_ BYTE14 : 112|8@1+ (1,0) [0|255] "" XXX SG_ BYTE15 : 120|8@1+ (1,0) [0|255] "" XXX -BO_ 437 FR_CMR_03_50ms: 32 FR_CMR - SG_ FR_CMR_Crc3Val : 0|16@1+ (1,0) [0|65535] "" RR_C_RDR,CGW - SG_ FR_CMR_AlvCnt3Val : 16|8@1+ (1,0) [0|255] "" RR_C_RDR,CGW - SG_ Info_LftLnQualSta : 24|3@1+ (1,0) [0|7] "" RR_C_RDR,CGW - SG_ Info_LftLnDptSta : 27|2@1+ (1,0) [0|3] "" RR_C_RDR,CGW - SG_ Info_LftLnPosVal : 29|14@1- (0.0039625,0) [-32.4608|32.4568375] "m" RR_C_RDR,CGW - SG_ Info_LftLnHdingAnglVal : 43|10@1- (0.000976563,0) [-0.500000256|0.499023693] "rad" RR_C_RDR,CGW - SG_ Info_LftLnCvtrVal : 64|16@1- (1e-06,0) [-0.032768|0.032767] "1/m" CGW - SG_ Info_LftLnCrvtrDrvtvVal : 80|16@1- (4e-09,0) [-0.000131072|0.000131068] "1/m2" CGW - SG_ Info_RtLnQualSta : 96|3@1+ (1,0) [0|7] "" RR_C_RDR,CGW - SG_ Info_RtLnDptSta : 99|2@1+ (1,0) [0|3] "" RR_C_RDR,CGW - SG_ Info_RtLnPosVal : 101|14@1- (0.0039625,0) [-32.4608|32.4568375] "m" RR_C_RDR,CGW - SG_ Info_RtLnHdingAnglVal : 115|10@1- (0.000976563,0) [-0.500000256|0.499023693] "rad" RR_C_RDR,CGW - SG_ Info_RtLnCvtrVal : 128|16@1- (1e-06,0) [-0.032768|0.032767] "1/m" CGW - SG_ Info_RtLnCrvtrDrvtvVal : 144|16@1- (4e-09,0) [-0.000131072|0.000131068] "1/m2" CGW - SG_ ID_CIPV : 192|8@1+ (1,0) [0|255] "" XXX - SG_ Relative_Velocity : 200|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX - SG_ Longitudinal_Distance : 212|12@1+ (0.05,0) [0|204.75] "m" XXX +BO_ 437 CCNC_0x1B5: 32 CCNC + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ LEFT_QUAL : 24|3@1+ (1,0) [0|7] "" XXX + SG_ LEFT_LDW : 27|2@1+ (1,0) [0|3] "" XXX + SG_ LEFT_POSITION : 29|14@1- (0.0039625,0) [-32.4608|32.4568375] "m" XXX + SG_ LEFT_HEADING : 43|10@1- (0.000976563,0) [-0.500000256|0.499023693] "rad" XXX + SG_ LEFT_CURVATURE : 64|16@1- (1e-06,0) [-0.032768|0.032767] "1/m" XXX + SG_ LEFT_CURVATURE_DERIVATIVE : 80|16@1- (4e-09,0) [-0.000131072|0.000131068] "1/m2" XXX + SG_ RIGHT_QUAL : 96|3@1+ (1,0) [0|7] "" XXX + SG_ RIGHT_LDW : 99|2@1+ (1,0) [0|3] "" XXX + SG_ RIGHT_POSITION : 101|14@1- (0.0039625,0) [-32.4608|32.4568375] "m" XXX + SG_ RIGHT_HEADING : 115|10@1- (0.000976563,0) [-0.500000256|0.499023693] "rad" XXX + SG_ RIGHT_CURVATURE : 128|16@1- (1e-06,0) [-0.032768|0.032767] "1/m" XXX + SG_ RIGHT_CURVATURE_DERIVATIVE : 144|16@1- (4e-09,0) [-0.000131072|0.000131068] "1/m2" XXX + SG_ LEAD : 192|7@1+ (1,0) [0|127] "" XXX + SG_ LEAD_SPEED : 200|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ LEAD_DISTANCE : 212|12@1+ (0.05,0) [0|204.75] "m" XXX + +BO_ 438 CAM_0x1b6: 32 CAMERA + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 439 CAM_0x1b7: 32 CAMERA + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 440 CAM_0x1b8: 32 CAMERA + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 441 CAM_0x1b9: 32 CAMERA + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX BO_ 442 BLINDSPOTS_REAR_CORNERS: 24 XXX SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX SG_ LEFT_BLOCKED : 24|1@0+ (1,0) [0|1] "" XXX - SG_ LEFT_MB : 30|1@0+ (1,0) [0|3] "" XXX - SG_ MORE_LEFT_PROB : 32|1@1+ (1,0) [0|3] "" XXX + SG_ INDICATOR_LEFT_TWO : 30|1@0+ (1,0) [0|3] "" XXX + SG_ INDICATOR_RIGHT_TWO : 32|1@1+ (1,0) [0|3] "" XXX SG_ FL_INDICATOR : 46|6@0+ (1,0) [0|1] "" XXX SG_ FR_INDICATOR : 54|6@0+ (1,0) [0|63] "" XXX SG_ RIGHT_BLOCKED : 64|1@0+ (1,0) [0|1] "" XXX SG_ COLLISION_AVOIDANCE_ACTIVE : 68|1@0+ (1,0) [0|1] "" XXX - SG_ NEW_SIGNAL_2 : 96|1@0+ (1,0) [0|1] "" XXX - SG_ FL_INDICATOR_ALT : 138|1@0+ (1,0) [0|1] "" XXX - SG_ FR_INDICATOR_ALT : 141|1@0+ (1,0) [0|1] "" XXX + SG_ INDICATOR_LEFT_THREE : 128|1@0+ (1,0) [0|1] "" XXX + SG_ INDICATOR_RIGHT_THREE : 130|1@0+ (1,0) [0|1] "" XXX + SG_ INDICATOR_LEFT_FOUR : 138|1@0+ (1,0) [0|1] "" XXX + SG_ INDICATOR_RIGHT_FOUR : 141|1@0+ (1,0) [0|1] "" XXX BO_ 463 CRUISE_BUTTONS: 8 XXX SG_ _CHECKSUM : 0|8@1+ (1,0) [0|65535] "" XXX @@ -410,10 +520,11 @@ BO_ 463 CRUISE_BUTTONS: 8 XXX SG_ CRUISE_BUTTONS : 16|3@1+ (1,0) [0|3] "" XXX SG_ ADAPTIVE_CRUISE_MAIN_BTN : 19|1@1+ (1,0) [0|1] "" XXX SG_ NORMAL_CRUISE_MAIN_BTN : 21|1@1+ (1,0) [0|1] "" XXX - SG_ LDA_BTN : 23|1@1+ (1,0) [0|1] "" XXX + SG_ LFA_BTN : 23|1@1+ (1,0) [0|1] "" XXX SG_ RIGHT_PADDLE : 25|1@1+ (1,0) [0|1] "" XXX SG_ LEFT_PADDLE : 27|1@1+ (1,0) [0|1] "" XXX SG_ SET_ME_1 : 29|1@1+ (1,0) [0|1] "" XXX + SG_ SET_ME_1_ : 40|1@0+ (1,0) [0|1] "" XXX BO_ 474 ADRV_0x1da: 32 ADRV SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX @@ -421,16 +532,20 @@ BO_ 474 ADRV_0x1da: 32 ADRV SG_ SET_ME_22 : 31|8@0+ (1,0) [0|255] "" XXX SG_ SET_ME_41 : 47|8@0+ (1,0) [0|255] "" XXX -BO_ 480 LFAHDA_CLUSTER: 16 ADRV +BO_ 480 LFAHDA_CLUSTER: 16 FR_CMR SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_4 : 24|1@0+ (1,0) [0|1] "" XXX - SG_ NEW_SIGNAL_5 : 25|1@0+ (1,0) [0|1] "" XXX - SG_ NEW_SIGNAL_2 : 30|1@0+ (1,0) [0|1] "" XXX - SG_ HDA_ICON : 31|1@1+ (1,0) [0|1] "" XXX - SG_ NEW_SIGNAL_1 : 32|3@1+ (1,0) [0|7] "" XXX - SG_ LFA_ICON : 47|2@1+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_3 : 49|1@0+ (1,0) [0|1] "" XXX + SG_ HDA_OptUsmSta : 24|3@1+ (1,0) [0|0] "" CGW + SG_ LFA_OptUsmSta : 27|3@1+ (1,0) [0|0] "" CGW + SG_ HDA_CntrlModSta : 30|2@1+ (1,0) [0|0] "" CGW + SG_ HDA_InfoPUDis : 32|3@1+ (1,0) [0|0] "" CGW + SG_ HDA_AutoSetSpdSta : 35|2@1+ (1,0) [0|0] "" CGW + SG_ HDA_AutoSetSpdUpdtSta : 37|2@1+ (1,0) [0|0] "" CGW + SG_ HDA_AutoSetSpdVal : 39|8@1+ (1,0) [0|0] "km/h" CGW + SG_ HDA_LFA_SymSta : 47|2@1+ (1,0) [0|0] "" CGW + SG_ HDA_LFA_WrnSnd : 49|2@1+ (1,0) [0|0] "" Dummy + SG_ HDA_InfoPUDis1 : 51|3@1+ (1,0) [0|7] "" CLU,CGW + SG_ HDA_TDMRMDclReq : 54|2@1+ (1,0) [0|3] "" Dummy BO_ 485 BLINDSPOTS_FRONT_CORNER_1: 16 XXX SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX @@ -448,61 +563,55 @@ BO_ 485 BLINDSPOTS_FRONT_CORNER_1: 16 XXX BO_ 490 ADRV_0x1ea: 32 ADRV SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX - SG_ SET_ME_1C : 31|8@0+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_1 : 32|2@1+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_2 : 47|2@0+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_3 : 55|8@0+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_4 : 64|6@1+ (1,0) [0|31] "" XXX - SG_ NEW_SIGNAL_5 : 72|2@1+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_6 : 75|5@1+ (1,0) [0|31] "" XXX - SG_ NEW_SIGNAL_7 : 80|5@1+ (1,0) [0|31] "" XXX - SG_ NEW_SIGNAL_8 : 88|7@1+ (1,0) [0|127] "" XXX - SG_ NEW_SIGNAL_9 : 96|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_4 : 25|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_3 : 26|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_2 : 27|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_1 : 28|1@0+ (1,0) [0|1] "" XXX + SG_ LEFT_BLINK_HOLD : 29|1@0+ (1,0) [0|1] "" XXX + SG_ RIGHT_BLINK_HOLD : 30|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_5 : 31|1@0+ (1,0) [0|1] "" XXX + SG_ HDA_MODE2 : 32|3@1+ (1,0) [0|3] "" XXX + SG_ LANE_LEFT : 36|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_6 : 39|3@0+ (1,0) [0|7] "" XXX + SG_ LANE_RIGHT : 41|2@0+ (1,0) [0|3] "" XXX + SG_ LANE_CHANGING : 45|3@0+ (1,0) [0|1] "" XXX + SG_ LF_DETECT_DISTANCE : 46|11@1+ (0.1,0) [0|2047] "" XXX + SG_ LF_DETECT_LATERAL : 70|7@0+ (0.1,0) [0|127] "" XXX + SG_ LF_DETECT : 74|3@0+ (1,0) [0|7] "" XXX + SG_ RF_DETECT_DISTANCE : 75|11@1+ (0.1,0) [0|2047] "" XXX + SG_ RF_DETECT_LATERAL : 94|7@0+ (0.1,0) [0|127] "" XXX + SG_ RF_DETECT : 98|3@0+ (1,0) [0|7] "" XXX SG_ SET_ME_FF : 120|8@1+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_10 : 143|5@0+ (1,0) [0|31] "" XXX - SG_ NEW_SIGNAL_11 : 144|3@1+ (1,0) [0|7] "" XXX - SG_ NEW_SIGNAL_12 : 152|6@1+ (1,0) [0|63] "" XXX - SG_ NEW_SIGNAL_13 : 160|1@0+ (1,0) [0|1] "" XXX - SG_ NEW_SIGNAL_14 : 163|5@1+ (1,0) [0|31] "" XXX - SG_ NEW_SIGNAL_16 : 168|3@1+ (1,0) [0|7] "" XXX - SG_ NEW_SIGNAL_15 : 175|4@0+ (1,0) [0|63] "" XXX - SG_ NEW_SIGNAL_17 : 176|2@1+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_18 : 184|1@0+ (1,0) [0|1] "" XXX - SG_ NEW_SIGNAL_19 : 208|3@1+ (1,0) [0|7] "" XXX - SG_ NEW_SIGNAL_20 : 212|1@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_TMP_F : 232|5@1+ (1,0) [0|31] "" XXX - SG_ SET_ME_TMP_F_2 : 240|5@1+ (1,0) [0|31] "" XXX + SG_ LR_DETECT_DISTANCE : 139|8@1+ (0.1,0) [0|511] "m" XXX + SG_ LR_DETECT_LATERAL : 152|6@1+ (0.1,0) [0|63] "" XXX + SG_ LR_DETECT : 162|3@0+ (1,0) [0|1] "" XXX + SG_ RR_DETECT_DISTANCE : 163|8@1+ (0.1,0) [0|511] "m" XXX + SG_ RR_DETECT_LATERAL : 172|6@1+ (0.1,0) [0|63] "" XXX + SG_ RR_DETECT : 186|3@0+ (1,0) [0|1] "" XXX + SG_ AUTOLANECHANGE_MSG : 207|4@0+ (1,0) [0|3] "" XXX + SG_ LANELINE_CURVATURE : 208|4@1+ (1,0) [0|31] "" XXX + SG_ LANELINE_CURVATURE_DIRECTION : 212|1@0+ (1,0) [0|1] "" XXX + SG_ LANELINE_LEFT_POSITION : 239|8@0+ (1,0) [0|255] "" XXX + SG_ LANELINE_RIGHT_POSITION : 247|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 248|1@0+ (1,0) [0|1] "" XXX -BO_ 506 FR_CMR_02_100ms: 32 FR_CMR - SG_ FR_CMR_Crc2Val : 0|16@1+ (1,0) [0|65535] "" CGW - SG_ FR_CMR_AlvCnt2Val : 16|8@1+ (1,0) [0|255] "" CGW - SG_ ISLW_OptUsmSta : 24|2@1+ (1,0) [0|3] "" CLU,CGW - SG_ ISLW_SysSta : 26|2@1+ (1,0) [0|3] "" CLU,CGW - SG_ ISLW_NoPassingInfoDis : 28|3@1+ (1,0) [0|7] "" CLU,CGW - SG_ ISLW_OvrlpSignDis : 31|2@1+ (1,0) [0|3] "" CLU,CGW - SG_ ISLW_SpdCluMainDis : 33|8@1+ (1,0) [0|255] "" CLU,CGW - SG_ ISLW_SpdNaviMainDis : 41|8@1+ (1,0) [0|255] "" CGW - SG_ ISLW_SubCondinfoSta1 : 49|4@1+ (1,0) [0|15] "" CLU,CGW - SG_ ISLW_SubCondinfoSta2 : 53|4@1+ (1,0) [0|15] "" CLU,CGW - SG_ ISLW_SpdCluSubMainDis : 64|8@1+ (1,0) [0|255] "" CLU - SG_ ISLW_SpdCluDisSubCond1 : 72|8@1+ (1,0) [0|255] "" CLU,CGW - SG_ ISLW_SpdCluDisSubCond2 : 80|8@1+ (1,0) [0|255] "" CLU,CGW - SG_ ISLW_SpdNaviSubMainDis : 88|8@1+ (1,0) [0|255] "" CLU - SG_ ISLW_SpdNaviDisSubCond1 : 96|8@1+ (1,0) [0|255] "" CLU,CGW - SG_ ISLW_SpdNaviDisSubCond2 : 104|8@1+ (1,0) [0|255] "" CLU,CGW - SG_ ISLA_SpdwOffst : 112|8@1+ (1,0) [0|255] "" CLU,CGW - SG_ ISLA_SwIgnoreReq : 120|2@1+ (1,0) [0|3] "" CGW - SG_ ISLA_SpdChgReq : 122|2@1+ (1,0) [0|3] "" CGW - SG_ ISLA_SpdWrn : 124|2@1+ (1,0) [0|3] "" CLU,CGW - SG_ ISLA_IcyWrn : 126|2@1+ (1,0) [0|3] "" CLU,CGW - SG_ ISLA_SymFlashMod : 128|3@1+ (1,0) [0|7] "" CLU,CGW - SG_ ISLA_Popup : 131|3@1+ (1,0) [0|7] "" CLU - SG_ ISLA_OptUsmSta : 136|3@1+ (1,0) [0|7] "" CLU,CGW - SG_ ISLA_OffstUsmSta : 139|3@1+ (1,0) [0|7] "" CLU,CGW - SG_ ISLA_AutoUsmSta : 142|2@1+ (1,0) [0|3] "" CLU,CGW - SG_ ISLA_Cntry : 144|4@1+ (1,0) [0|15] "" CLU,CGW - SG_ ISLA_AddtnlSign : 149|5@1+ (1,0) [0|31] "" CLU,CGW - SG_ ISLA_SchoolZone : 154|2@1+ (1,0) [0|3] "" CLU,CGW +BO_ 506 CLUSTER_SPEED_LIMIT: 32 CAM + SG_ SPEED_LIMIT_1 : 39|7@0+ (1,0) [0|255] "" XXX + SG_ SPEED_LIMIT_2 : 47|7@0+ (1,0) [0|255] "" XXX + SG_ SECONDARY_LIMIT_1 : 79|8@0+ (1,0) [0|127] "" XXX + SG_ SECONDARY_LIMIT_2 : 103|8@0+ (1,0) [0|127] "" XXX + SG_ SPEED_LIMIT_3 : 119|8@0+ (1,0) [0|255] "" XXX + SG_ ARROW_DOWN : 120|1@0+ (1,0) [0|1] "" XXX + SG_ ARROW_UP : 121|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_2 : 122|3@1+ (1,0) [0|7] "" XXX + SG_ SPEED_CHANGE_BLINKING : 129|1@1+ (1,0) [0|3] "" XXX + SG_ CHIME_1 : 133|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_4 : 143|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_3 : 146|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_1 : 147|7@1+ (1,0) [0|127] "" XXX + SG_ SCHOOL_ZONE : 155|1@0+ (1,0) [0|1] "" XXX + SG_ SPEED_LIMIT_4 : 215|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_5 : 223|8@0+ (1,0) [0|255] "" XXX BO_ 507 CAM_0x1fb: 32 CAMERA SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX @@ -512,54 +621,158 @@ BO_ 512 ADRV_0x200: 8 ADRV SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX SG_ SET_ME_E1 : 24|8@1+ (1,0) [0|255] "" XXX - SG_ SET_ME_3A : 32|8@1+ (1,0) [0|255] "" XXX + SG_ TauGapSet : 32|3@1+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_2 : 35|2@1+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_1 : 39|3@0+ (1,0) [0|7] "" XXX + SG_ TauGapSet_ : 42|3@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_3 : 47|5@0+ (1,0) [0|31] "" XXX + +BO_ 513 RADAR_0x201: 32 FRONT_RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 528 RADAR_0x210: 32 FRONT_RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 529 RADAR_0x211: 32 FRONT_RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 530 RADAR_0x212: 32 FRONT_RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 531 RADAR_0x213: 32 FRONT_RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 532 RADAR_0x214: 32 FRONT_RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 533 RADAR_0x215: 32 FRONT_RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 534 RADAR_0x216: 32 FRONT_RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 535 RADAR_0x217: 32 FRONT_RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 536 RADAR_0x218: 32 FRONT_RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 537 RADAR_0x219: 32 FRONT_RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 538 RADAR_0x21a: 32 FRONT_RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 539 RADAR_0x21b: 32 FRONT_RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 540 RADAR_0x21c: 32 FRONT_RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 541 RADAR_0x21d: 32 FRONT_RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 542 RADAR_0x21e: 32 FRONT_RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 543 RADAR_0x21f: 32 FRONT_RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 560 HCU_STATUS_230: 32 XXX + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ HYBRID_POWER_FLOW_MODE : 170|4@1+ (1,0) [0|15] "" XXX + +CM_ BO_ 560 "Hyundai/Kia CAN-FD hybrid power-flow status observed on ECAN at 10 Hz; ACAN 0x230/DLC16 is an unrelated radar frame."; +CM_ SG_ 560 HYBRID_POWER_FLOW_MODE "Reverse-engineered enum; observed values 1, 2, and 6 correspond to the OEM EV indicator being on."; + +BO_ 576 RADAR_0x240: 16 FRONT_RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX BO_ 593 RADAR_0x251: 16 FRONT_RADAR SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX -BO_ 687 HOD_FD_01_100ms: 8 XXX - SG_ HOD_Dir_Status : 18|3@0+ (1,0) [0|7] "" XXX - SG_ NEW_SIGNAL_2 : 32|8@1+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_3 : 40|8@1+ (1,0) [0|255] "" XXX - SG_ HOD_Option : 48|2@1+ (1,0) [0|255] "" XXX +BO_ 674 CAM_0x2a2: 32 CAMERA + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX -BO_ 698 FR_CMR_04_40ms: 32 FR_CMR - SG_ FR_CMR_Crc4Val : 0|16@1+ (1,0) [0|65535] "" Dummy - SG_ FR_CMR_AlvCnt4Val : 16|8@1+ (1,0) [0|255] "" Dummy - SG_ IFSref_FR_CMR_Sta : 24|2@1+ (1,0) [0|3] "" CGW - SG_ IFSref_VehNumVal : 26|4@1+ (1,0) [0|15] "" CGW - SG_ IFSref_ILLAmbtSta : 30|2@1+ (0.1,0) [0|0.3] "" CGW - SG_ IFSref_VehLftAngl1Val : 32|9@1+ (0.1,-25) [-25|26.1] "Deg" CGW - SG_ IFSref_VehRtAngl1Val : 41|9@1+ (0.1,-25) [-25|26.1] "Deg" CGW - SG_ IFSref_VehLftAngl2Val : 50|9@1+ (0.1,-25) [-25|26.1] "Deg" CGW - SG_ IFSref_VehDst1Val : 59|4@1+ (1,0) [0|15] "" CGW - SG_ IFSref_VehRtAngl2Val : 64|9@1+ (0.1,-25) [-25|26.1] "Deg" CGW - SG_ IFSref_VehLftAngl3Val : 73|9@1+ (0.1,-25) [-25|26.1] "Deg" CGW - SG_ IFSref_VehRtAngl3Val : 82|9@1+ (0.1,-25) [-25|26.1] "Deg" CGW - SG_ IFSref_VehLftAngl4Val : 91|9@1+ (0.1,-25) [-25|26.1] "Deg" CGW - SG_ IFSref_VehRtAngl4Val : 100|9@1+ (0.1,-25) [-25|26.1] "Deg" CGW - SG_ IFSref_VehLftAngl5Val : 109|9@1+ (0.1,-25) [-25|26.1] "Deg" CGW - SG_ IFSref_VehRtAngl5Val : 118|9@1+ (0.1,-25) [-25|26.1] "Deg" CGW - SG_ IFSref_VehLftAngl6Val : 128|9@1+ (0.1,-25) [-25|26.1] "Deg" CGW - SG_ IFSref_VehRtAngl6Val : 137|9@1+ (0.1,-25) [-25|26.1] "Deg" CGW - SG_ IFSref_VehLftAngl7Val : 146|9@1+ (0.1,-25) [-25|26.1] "Deg" CGW - SG_ IFSref_VehRtAngl7Val : 155|9@1+ (0.1,-25) [-25|26.1] "Deg" CGW - SG_ IFSref_VehLftAngl8Val : 164|9@1+ (0.1,-25) [-25|26.1] "Deg" CGW - SG_ IFSref_VehRtAngl8Val : 173|9@1+ (0.1,-25) [-25|26.1] "Deg" CGW - SG_ IFSref_VehLftAngl9Val : 182|9@1+ (0.1,-25) [-25|26.1] "Deg" CGW - SG_ IFSref_VehRtAngl9Val : 192|9@1+ (0.1,-25) [-25|26.1] "Deg" CGW - SG_ IFSref_VehLftAngl10Val : 201|9@1+ (0.1,-25) [-25|26.1] "Deg" CGW - SG_ IFSref_VehRtAngl10Val : 210|9@1+ (0.1,-25) [-25|26.1] "Deg" CGW - SG_ IFSref_VehDst2Val : 219|4@1+ (1,0) [0|15] "" CGW - SG_ IFSref_VehDst3Val : 223|4@1+ (1,0) [0|15] "" CGW - SG_ IFSref_VehDst4Val : 227|4@1+ (1,0) [0|15] "" CGW - SG_ IFSref_VehDst5Val : 231|4@1+ (1,0) [0|15] "" CGW - SG_ IFSref_VehDst6Val : 235|4@1+ (1,0) [0|15] "" CGW - SG_ IFSref_VehDst7Val : 239|4@1+ (1,0) [0|15] "" CGW - SG_ IFSref_VehDst8Val : 243|4@1+ (1,0) [0|15] "" CGW - SG_ IFSref_VehDst9Val : 247|4@1+ (1,0) [0|15] "" CGW - SG_ IFSref_VehDst10Val : 251|4@1+ (1,0) [0|15] "" CGW +BO_ 675 CAM_0x2a3: 32 CAMERA + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 676 CAM_0x2a4: 24 XXX + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ LEFT_LANE_PROB : 31|8@0+ (1,0) [0|255] "" XXX + SG_ RIGHT_LANE_PROB : 39|8@0+ (1,0) [0|255] "" XXX + SG_ LEFT_LANE_TYPE : 43|4@0+ (1,0) [0|15] "" XXX + SG_ RIGHT_LANE_TYPE : 47|4@0+ (1,0) [0|15] "" XXX + SG_ LEFT_LANE_COLOR : 48|4@1+ (1,0) [0|15] "" XXX + SG_ RIGHT_LANE_COLOR : 52|4@1+ (1,0) [0|15] "" XXX + SG_ LEFT_LANE_LINE : 56|2@1+ (1,0) [0|3] "" XXX + SG_ SET_ME_0 : 58|2@1+ (1,0) [0|3] "" XXX + SG_ RIGHT_LANE_LINE : 60|2@1+ (1,0) [0|3] "" XXX + SG_ SET_ME_0_2 : 62|2@1+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_2 : 67|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_1 : 71|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_4 : 75|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_3 : 79|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 80|10@1- (1,0) [0|1023] "" XXX + SG_ NEW_SIGNAL_6 : 96|10@1- (1,0) [0|1023] "" XXX + SG_ NEW_SIGNAL_7 : 112|16@1+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_8 : 128|16@1+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_9 : 144|16@1+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_10 : 160|16@1+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_11 : 176|16@1+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_12 : 192|16@1+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_13 : 208|16@1+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_14 : 224|16@1+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_15 : 240|16@1+ (1,0) [0|65535] "" XXX + +BO_ 687 STEER_TOUCH_2AF: 8 XXX + SG_ CHECKSUM_ : 7|8@0+ (1,0) [0|255] "" XXX + SG_ COUNTER_ : 8|8@1+ (1,0) [0|255] "" XXX + SG_ TOUCH_DETECT : 23|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_2 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ TOUCH1 : 39|8@0+ (1,0) [0|255] "" XXX + SG_ TOUCH2 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_3 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_4 : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 699 CAM_0x2bb: 32 CAMERA + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 700 CAM_0x2bc: 32 CAMERA + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 701 CAM_0x2bd: 32 CAMERA + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 702 CAM_0x2be: 32 CAMERA + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX BO_ 736 MANUAL_SPEED_LIMIT_ASSIST: 32 XXX SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX @@ -577,42 +790,45 @@ BO_ 837 ADRV_0x345: 8 ADRV BO_ 866 CAM_0x362: 32 CAMERA SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE3 : 24|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE4 : 32|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE5 : 40|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE6 : 48|8@1+ (1,0) [0|255] "" XXX + SG_ LEFT_LANE_PROB : 31|8@0+ (1,0) [0|255] "" XXX + SG_ RIGHT_LANE_PROB : 39|8@0+ (1,0) [0|255] "" XXX + SG_ LEFT_LANE_TYPE : 43|4@0+ (1,0) [0|15] "" XXX + SG_ RIGHT_LANE_TYPE : 47|4@0+ (1,0) [0|15] "" XXX + SG_ LEFT_LANE_COLOR : 48|4@1+ (1,0) [0|15] "" XXX + SG_ RIGHT_LANE_COLOR : 52|4@1+ (1,0) [0|15] "" XXX SG_ LEFT_LANE_LINE : 56|2@1+ (1,0) [0|3] "" XXX SG_ SET_ME_0 : 58|2@1+ (1,0) [0|3] "" XXX SG_ RIGHT_LANE_LINE : 60|2@1+ (1,0) [0|3] "" XXX SG_ SET_ME_0_2 : 62|2@1+ (1,0) [0|3] "" XXX - SG_ BYTE8 : 64|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE9 : 72|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE10 : 80|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE11 : 88|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE12 : 96|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE13 : 104|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE14 : 112|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE15 : 120|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE16 : 128|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE17 : 136|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE18 : 144|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE19 : 152|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE20 : 160|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE21 : 168|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE22 : 176|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE23 : 184|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE24 : 192|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE25 : 200|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE26 : 208|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE27 : 216|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE28 : 224|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE29 : 232|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE30 : 240|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE31 : 248|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_2 : 67|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_1 : 71|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_4 : 75|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_3 : 79|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 80|10@1- (1,0) [0|1023] "" XXX + SG_ NEW_SIGNAL_6 : 96|10@1- (1,0) [0|1023] "" XXX + SG_ NEW_SIGNAL_7 : 112|16@1+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_8 : 128|16@1+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_9 : 144|16@1+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_10 : 160|16@1+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_11 : 176|16@1+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_12 : 192|16@1+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_13 : 208|16@1+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_14 : 224|16@1+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_15 : 240|16@1+ (1,0) [0|65535] "" XXX BO_ 874 BLINDSPOTS_FRONT_CORNER_2: 16 XXX SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ RIGHT_BSD : 27|1@0+ (1,0) [0|1] "" XXX + SG_ LEFT_BSD : 28|1@0+ (1,0) [0|1] "" XXX + +BO_ 928 TPMS: 16 XXX + SG_ PRESSURE_FL : 39|8@0+ (1,0) [0|255] "" XXX + SG_ PRESSURE_FR : 47|8@0+ (1,0) [0|255] "" XXX + SG_ PRESSURE_RL : 55|8@0+ (1,0) [0|255] "" XXX + SG_ PRESSURE_RR : 63|8@0+ (1,0) [0|255] "" XXX + SG_ STATUS_TPMS : 66|3@0+ (1,0) [0|3] "" XXX + SG_ UNIT : 68|2@0+ (1,0) [0|3] "" XXX BO_ 961 BLINKER_STALKS: 8 XXX SG_ CHECKSUM_MAYBE : 7|8@0+ (1,0) [0|255] "" XXX @@ -623,6 +839,16 @@ BO_ 961 BLINKER_STALKS: 8 XXX SG_ LEFT_BLINKER : 30|1@0+ (1,0) [0|1] "" XXX SG_ RIGHT_BLINKER : 32|1@0+ (1,0) [0|1] "" XXX +BO_ 995 BLINKERS_ALT: 16 XXX + SG_ LEFT_BLINKER : 74|1@0+ (1,0) [0|1] "" XXX + SG_ RIGHT_BLINKER : 76|1@0+ (1,0) [0|1] "" XXX + SG_ LEFT_LAMP_ALT : 89|1@0+ (1,0) [0|1] "" XXX + SG_ LEFT_LAMP : 90|1@0+ (1,0) [0|1] "" XXX + SG_ RIGHT_LAMP_ALT : 91|1@0+ (1,0) [0|1] "" XXX + SG_ RIGHT_LAMP : 92|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_2 : 95|1@0+ (1,0) [0|1] "" XXX + SG_ BLINKER_ACTIVE : 97|1@0+ (1,0) [0|1] "" XXX + BO_ 1041 DOORS_SEATBELTS: 8 XXX SG_ CHECKSUM_MAYBE : 7|8@0+ (1,0) [0|65535] "" XXX SG_ COUNTER_ALT : 15|4@0+ (1,0) [0|15] "" XXX @@ -643,6 +869,12 @@ BO_ 1043 BLINKERS: 8 XXX SG_ RIGHT_LAMP_ALT : 61|1@0+ (1,0) [0|1] "" XXX SG_ USE_ALT_LAMP : 62|1@0+ (1,0) [0|1] "" XXX +BO_ 1052 LIGHT_SENSOR: 8 XXX + SG_ CHECKSUM_MAYBE : 7|8@0+ (1,0) [0|255] "" XXX + SG_ COUNTER_ALT : 15|4@0+ (1,0) [0|15] "" XXX + SG_ IS_DARK : 19|1@0+ (1,0) [0|1] "" XXX + SG_ LIGHT_LEVEL : 24|10@1+ (1,0) [0|1023] "" XXX + BO_ 1144 DRIVE_MODE: 8 XXX SG_ DRIVE_MODE : 0|16@1+ (1,-61611) [0|61611] "" XXX SG_ DRIVE_MODE2 : 28|3@1+ (1,0) [1|3] "" XXX @@ -660,6 +892,47 @@ BO_ 1151 HVAC_TOUCH_BUTTONS: 8 XXX SG_ RECIRC_BUTTON : 48|1@0+ (1,0) [0|1] "" XXX SG_ HEAT_BUTTON : 52|1@0+ (1,0) [0|1] "" XXX +BO_ 1187 HDA_INFO_4A3: 8 XXX + SG_ LinkClass : 0|3@1+ (1,0) [0|7] "" XXX + SG_ Frwinfo : 3|3@1+ (1,0) [0|7] "" XXX + SG_ SpeedUnit : 6|2@1+ (1,0) [0|3] "" XXX + SG_ SPEED_LIMIT : 15|8@0+ (1,0) [0|255] "" XXX + SG_ CountryCode : 16|10@1+ (1,0) [0|1023] "" XXX + SG_ MapSource : 27|3@1+ (1,0) [0|7] "" XXX + SG_ TollExist : 30|2@1+ (1,0) [0|3] "" XXX + SG_ TunnelExist : 38|2@1+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_6 : 47|24@0+ (1,0) [0|16777215] "" XXX + +BO_ 1204 NEW_MSG_4B4: 8 XXX + SG_ NEW_SIGNAL_1 : 7|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_8 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_2 : 23|16@0+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_7 : 35|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_3 : 39|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_4 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_5 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_6 : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 1209 NEW_MSG_4B9: 8 XXX + SG_ BYTE_1 : 7|8@0+ (1,0) [0|255] "" XXX + SG_ BYTE_2 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ BYTE_3 : 23|8@0+ (1,0) [0|255] "" XXX + SG_ BYTE_4 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ BYTE_5 : 39|8@0+ (1,0) [0|255] "" XXX + SG_ BYTE_6 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ BYTE_7 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ BYTE_8 : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 1214 NEW_MSG_4BE: 8 XXX + SG_ BYTE_1 : 7|8@0+ (1,0) [0|255] "" XXX + SG_ BYTE_2 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ BYTE_3 : 23|8@0+ (1,0) [0|255] "" XXX + SG_ BYTE_4 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ BYTE_5 : 39|8@0+ (1,0) [0|255] "" XXX + SG_ BYTE_6 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ BYTE_7 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ BYTE_8 : 63|8@0+ (1,0) [0|255] "" XXX + BO_ 1240 CLUSTER_INFO: 8 XXX SG_ DISTANCE_UNIT : 0|1@1+ (1,0) [0|1] "" XXX @@ -673,166 +946,41 @@ BO_ 1264 LOCAL_TIME: 8 XXX SG_ HOURS : 12|5@0+ (1,0) [0|31] "" XXX SG_ MINUTES : 21|6@0+ (1,0) [0|63] "" XXX SG_ SECONDS : 31|8@0+ (1,0) [0|59] "" XXX + SG_ MONTH : 37|4@0+ (1,0) [0|15] "" XXX + SG_ YEAR : 47|8@0+ (1,0) [0|255] "" XXX + SG_ DATE : 48|5@1+ (1,0) [0|31] "" XXX +CM_ SG_ 80 HAS_LANE_SAFETY "If 0, hides LKAS 'Lane Safety' menu from vehicle settings"; CM_ SG_ 96 BRAKE_PRESSURE "User applied brake pedal pressure. Ramps from computer applied pressure on falling edge of cruise. Cruise cancels if !=0"; CM_ SG_ 101 BRAKE_POSITION "User applied brake pedal position, max is ~700. Signed on some vehicles"; -CM_ SG_ 203 ADAS_ActvACISta "ADAS Active AngleControlInterface State"; -CM_ SG_ 203 ADAS_ActvACILvl2Sta "ADAS Active AngleControlInterface Level 2 State"; -CM_ SG_ 203 ADAS_StrAnglReqVal "(LFA) ADAS Steering Angle Request Value; Capped at 119.9;"; -CM_ SG_ 203 ADAS_ACIAnglTqRedcGainVal "(LFA) ADAS AngleControlInterface Angle Torque Reduction Gain Value"; -CM_ SG_ 203 FCA_ESA_ActvSta "FCA_ESA Active State"; -CM_ SG_ 203 FCA_ESA_TqBstGainVal "FCA_ESA Torque Boost Gain Value"; -CM_ BO_ 272 "Alternative LKAS message, used on cars such as 2023 Ioniq 6, 2nd gen Kona. Matches LKAS except size is 32 bytes"; -CM_ SG_ 272 LKA_AVAILABLE "Angle control cars: 3 when LKA is generally available, goes to 0 during changes with LFA"; -CM_ SG_ 272 ADAS_StrAnglReqVal "(LKAS) ADAS Steering Angle Request Value; Capped at 176.7; tracks MDPS->STEERING_ANGLE when not engaged, not STEERING_SENSORS->STEERING_ANGLE"; -CM_ SG_ 272 ADAS_ACIAnglTqRedcGainVal "(LKAS) ADAS AngleControlInterface Angle Torque Reduction Gain Value"; -CM_ BO_ 282 "Sent by the camera containing DAW (Driver Attention Warning) information and information about HBA (High Beam Assist)."; -CM_ SG_ 282 FR_CMR_Crc1Val "The data area for CRC calculation is based on the data length (DLC) of the message DB. The CRC shall be calculated over the entire data block (excluding the CRC bytes) including the user data, alive counter and Data ID - CRC Polynomial (0x1021) , In"; -CM_ SG_ 282 FR_CMR_AlvCnt1Val "For the first transmission request for a data element the counter shall be initialized with 0 and shall be incremented by 1 for every subsequent send request. When the counter reaches the maximum value(0xFF), then it shall restart with 0 for the next s"; -CM_ SG_ 282 HBA_SysOptSta "HBA System Option Information to Lamp Controller"; -CM_ SG_ 282 HBA_SysSta "This signal indicates the status of High Beam Assist system."; -CM_ SG_ 282 HBA_IndLmpReq "HBA System Indicator Lamp Status"; -CM_ SG_ 282 FCA_Equip_MFC "FCA Sensor Type"; -CM_ SG_ 282 HBA_OptUsmSta "HBA Option USM Status"; -CM_ SG_ 282 DAW_LVDA_PUDis "Message for displaying LVDA(Leading Vehicle Departure Alert) Warning"; -CM_ SG_ 282 DAW_LVDA_OptUsmSta "LVDA USM state"; -CM_ SG_ 282 DAW_OptUsmSta "This signal represents the lastest DAW ON/OFF value of USM."; -CM_ SG_ 282 DAW_SysSta "This signal represents Attention Assist System Status or Attention Level."; -CM_ SG_ 282 DAW_WrnMsgSta "0x1 value requests DAW Rest recommend warning message popup at CLU. 0x2 value requests HDA/LFA Hands-Off call at TMS."; -CM_ SG_ 282 DAW_TimeRstReq "This signal requests CLU 'Last Break Time' Reset. DAW send '0x1' when detecting driver's rest."; -CM_ SG_ 282 DAW_SnstvtyModRetVal "This signal represents the feedback value of the current ADAS warning timing."; -CM_ SG_ 282 FR_CMR_SCCEquipSta "This signal indicates equipment for SCC"; -CM_ SG_ 282 FR_CMR_ReqADASMapMsgVal "This signal indicates an ADAS map message request from FR_CMR to H_U. Each bit indicates the request messages as follows. - Bit 0 : H_U_NAVI_V2_STUB_E - Bit 1 : HU_NAVI_V2_PROSHORT_E_00 (곡률) - Bit 2 : HU_NAVI_V2_PROSHORT_E_00 (곡률 외 정보)"; -CM_ SG_ 282 FR_CMR_SwVer1Val "This signal indicates a major version of FR_CMR software. If FR_CMR software version is A.00, 'A' and '00' mean major and minor version respectively."; -CM_ SG_ 282 FR_CMR_SwVer2Val "This signal indicates a minor version of FR_CMR software. If FR_CMR software version is A.00, 'A' and '00' mean major and minor version respectively."; -CM_ SG_ 298 NEW_SIGNAL_4 "todo: figure out why always set to 9"; +CM_ SG_ 272 LKAS_ANGLE_CMD "tracks MDPS->STEERING_ANGLE when not engaged, not STEERING_SENSORS->STEERING_ANGLE"; CM_ SG_ 352 SET_ME_9 "has something to do with AEB settings"; CM_ SG_ 373 ACCEnable "Likely a copy of CAN's TCS13->ACCEnable"; CM_ SG_ 373 DriverBraking "Likely derived from BRAKE->BRAKE_POSITION"; CM_ SG_ 373 DriverBrakingLowSens "Higher threshold version of DriverBraking"; CM_ SG_ 373 PROBABLY_EQUIP "aeb equip?"; CM_ SG_ 416 VSetDis "set speed in display units"; -CM_ BO_ 437 "Sent by the camera containing lane and lead information."; -CM_ SG_ 437 FR_CMR_Crc3Val "The data area for CRC calculation is based on the data length (DLC) of the message DB. The CRC shall be calculated over the entire data block (excluding the CRC bytes) including the user data, alive counter and Data ID - CRC Polynomial (0x1021) , In"; -CM_ SG_ 437 FR_CMR_AlvCnt3Val "For the first transmission request for a data element the counter shall be initialized with 0 and shall be incremented by 1 for every subsequent send request. When the counter reaches the maximum value(0xFF), then it shall restart with 0 for the next s"; -CM_ SG_ 437 Info_LftLnQualSta "This signal indicates the quality of left line."; -CM_ SG_ 437 Info_LftLnDptSta "This signal indicates the lane departure status of left line."; -CM_ SG_ 437 Info_LftLnPosVal "This signal outputs the position of left line from camera center."; -CM_ SG_ 437 Info_LftLnHdingAnglVal "This signal outputs the heading angle of left line."; -CM_ SG_ 437 Info_LftLnCvtrVal "This signal outputs the curvature of left line."; -CM_ SG_ 437 Info_RtLnQualSta "This signal indicates the quality of right line."; -CM_ SG_ 437 Info_RtLnDptSta "This signal indicates the lane departure status of right line."; -CM_ SG_ 437 Info_RtLnPosVal "This signal outputs the position of right line from camera center."; -CM_ SG_ 437 Info_RtLnHdingAnglVal "This signal outputs the heading angle of right line."; -CM_ SG_ 437 Info_RtLnCvtrVal "This signal outputs the curvature of right line."; -CM_ SG_ 437 ID_CIPV "Valid Object = 1 to 255 - ID detected by front camera can vary depending on vehicle environment. - Additional logic would be required to apply this signal for ISG."; -CM_ SG_ 437 Relative_Velocity "+ : Preceding, - : Oncoming - Velocity detected by front camera can vary depending on vehicle environment. - Additional logic would be required to apply this signal for ISG. - Confirmaiton by Autonomous Driving Engineering Team is required to use ID_C"; -CM_ SG_ 416 SCC_ObjSta "state of in-path object and information of controllable state."; -CM_ SG_ 480 NEW_SIGNAL_5 "todo: figure out why always set to 1"; -CM_ BO_ 506 "Sent by the camera containing speed limit information. ISLW stands for Intelligent Speed Limit Warning, and ISLA is Intelligent Speed Limit Assist. it also contains road sign information."; -CM_ SG_ 506 FR_CMR_Crc2Val "The data area for CRC calculation is based on the data length (DLC) of the message DB.The CRC shall be calculated over the entire data block (excluding the CRC bytes) including the user data, alive counter and Data ID - CRC Polynomial (0x1021) , In"; -CM_ SG_ 506 FR_CMR_AlvCnt2Val "For the first transmission request for a data element the counter shall be initialized with 0 and shall be incremented by 1 for every subsequent send request. When the counter reaches the maximum value(0xFF), then it shall restart with 0 for the next s"; -CM_ SG_ 506 ISLW_OptUsmSta "ISLW option information"; -CM_ SG_ 506 ISLW_SysSta "Validity of ISLW information"; -CM_ SG_ 506 ISLW_NoPassingInfoDis "This signal indicates additional information of ISLW. For example no passing."; -CM_ SG_ 506 ISLW_OvrlpSignDis "indicates presence of Overlap sign"; -CM_ SG_ 506 ISLW_SpdCluMainDis "Main Speed Information for cluster display in main page(0x1~0xFCH: 1*(HEX VALUE) [KPH or MPH :Reference signal is CF_Clu_SPEED_UNIT of CLU])"; -CM_ SG_ 506 ISLW_SpdNaviMainDis "Main Speed information for navigation display in main page(0x1~0xFCH: 1*(HEX VALUE) [KPH or MPH :Reference signal is Navi_ISLW_SpdUnit of Navigation)"; -CM_ SG_ 506 ISLW_SubCondinfoSta1 "Indicates 1st conditional traffic sign status"; -CM_ SG_ 506 ISLW_SubCondinfoSta2 "Indicates 2nd conditional traffic sign status"; -CM_ SG_ 506 ISLW_SpdCluSubMainDis "Main Speed Information for cluster display in ISLW detail page"; -CM_ SG_ 506 ISLW_SpdCluDisSubCond1 "Indicates conditional speed limit/no passing of 1st conditional traffic sign for Cluster in ISLW Detail page"; -CM_ SG_ 506 ISLW_SpdCluDisSubCond2 "Indicates conditional speed limit/no passing of 2nd conditional traffic sign for Cluster in ISLW Detail page"; -CM_ SG_ 506 ISLW_SpdNaviSubMainDis "Main Speed Information for NAVI display in ISLW detail page"; -CM_ SG_ 506 ISLW_SpdNaviDisSubCond1 "Indicates conditional speed limit/no passing of 1st conditional traffic sign for NAVI in ISLW Detail page"; -CM_ SG_ 506 ISLW_SpdNaviDisSubCond2 "Indicates conditional speed limit/no passing of 2nd conditional traffic sign for NAVI in ISLW Detail page"; -CM_ SG_ 506 ISLA_SpdwOffst "This is a ISLA speed with offset to change the set speed of MSLA/CC/SCC.Unit (kph or mph) refers to cluster signal: CLU_SpdUnitTyp@CLU_01_20ms"; -CM_ SG_ 506 ISLA_SwIgnoreReq "This is a signal requesting to ignore the -(SET) or +(SET) switch input of the driver."; -CM_ SG_ 506 ISLA_SpdChgReq "This is a signal requesting to change the set speed of MSLA/CC/SCC to the ISLA speed."; -CM_ SG_ 506 ISLA_SpdWrn "This is a warning signal when VANZ exceeds the speed limit."; -CM_ SG_ 506 ISLA_IcyWrn "This is a warning signal when the snow or ice sign is recognized when it is less than 4 'C."; -CM_ SG_ 506 ISLA_SymFlashMod "This is a signal for the flashing mode of the symbol."; -CM_ SG_ 506 ISLA_Popup "This is a signal for ISLA pop-up."; -CM_ SG_ 506 ISLA_OptUsmSta "This is a ISLA option USM signal set by the driver."; -CM_ SG_ 506 ISLA_OffstUsmSta "This is a signal for offset speed set by the driver. Unit (kph or mph) refers to cluster signal: CLU_SpdUnitTyp@CLU_01_20ms"; -CM_ SG_ 506 ISLA_AutoUsmSta "This is a signal for ISLA AUTO USM set by the driver."; -CM_ SG_ 506 ISLA_Cntry "This is a signal for categorizing countries"; -CM_ SG_ 506 ISLA_AddtnlSign "This is a signal for additional sign"; -CM_ SG_ 506 ISLA_SchoolZone "This is a signal for School Zone"; -CM_ SG_ 687 HOD_Dir_Status "This signal indicates the status of hands on/off"; -CM_ BO_ 698 "Sent by the camera containing information about vehicles in front of us. IFS stands for Intelligent Front-lighting System, and this signal provides the information necessary for it to operate."; -CM_ SG_ 698 FR_CMR_Crc4Val "The data area for CRC calculation is based on the data length (DLC) of the message DB. The CRC shall be calculated over the entire data block (excluding the CRC bytes) including the user data, alive counter and Data ID - CRC Polynomial (0x1021) , In"; -CM_ SG_ 698 FR_CMR_AlvCnt4Val "For the first transmission request for a data element the counter shall be initialized with 0 and shall be incremented by 1 for every subsequent send request. When the counter reaches the maximum value(0xFF), then it shall restart with 0 for the next s"; -CM_ SG_ 698 IFSref_FR_CMR_Sta "This is IFS system status needed for operate the IFS function of headlamp highbeam"; -CM_ SG_ 698 IFSref_VehNumVal "This is number of vehicles detected from camera"; -CM_ SG_ 698 IFSref_ILLAmbtSta "This signal is status of the ambient brightness 0x0 is bright condition (HighBeam off), 0x1 is dark condition (None)"; -CM_ SG_ 698 IFSref_VehLftAngl1Val "This is left angle of vehicle 1 Deg = (HEX)*0.1-25"; -CM_ SG_ 698 IFSref_VehRtAngl1Val "This is right angle of vehicle 1 Deg = (HEX)*0.1-25"; -CM_ SG_ 698 IFSref_VehLftAngl2Val "This is left angle of vehicle 2 Deg = (HEX)*0.1-25"; -CM_ SG_ 698 IFSref_VehDst1Val "IFSref_VehicleDistance1Value"; -CM_ SG_ 698 IFSref_VehRtAngl2Val "This is right angle of vehicle 2 Deg = (HEX)*0.1-25"; -CM_ SG_ 698 IFSref_VehLftAngl3Val "This is left angle of vehicle 3 Deg = (HEX)*0.1-25"; -CM_ SG_ 698 IFSref_VehRtAngl3Val "This is right angle of vehicle 3 Deg = (HEX)*0.1-25"; -CM_ SG_ 698 IFSref_VehLftAngl4Val "This is left angle of vehicle 4 Deg = (HEX)*0.1-25"; -CM_ SG_ 698 IFSref_VehRtAngl4Val "This is right angle of vehicle 4 Deg = (HEX)*0.1-25"; -CM_ SG_ 698 IFSref_VehLftAngl5Val "This is left angle of vehicle 5 Deg = (HEX)*0.1-25"; -CM_ SG_ 698 IFSref_VehRtAngl5Val "This is right angle of vehicle 5 Deg = (HEX)*0.1-25"; -CM_ SG_ 698 IFSref_VehLftAngl6Val "This is left angle of vehicle 6 Deg = (HEX)*0.1-25"; -CM_ SG_ 698 IFSref_VehRtAngl6Val "This is right angle of vehicle 6 Deg = (HEX)*0.1-25"; -CM_ SG_ 698 IFSref_VehLftAngl7Val "This is left angle of vehicle 7 Deg = (HEX)*0.1-25"; -CM_ SG_ 698 IFSref_VehRtAngl7Val "This is right angle of vehicle 7 Deg = (HEX)*0.1-25"; -CM_ SG_ 698 IFSref_VehLftAngl8Val "This is left angle of vehicle 8 Deg = (HEX)*0.1-25"; -CM_ SG_ 698 IFSref_VehRtAngl8Val "This is right angle of vehicle 8 Deg = (HEX)*0.1-25"; -CM_ SG_ 698 IFSref_VehLftAngl9Val "This is left angle of vehicle 9 Deg = (HEX)*0.1-25"; -CM_ SG_ 698 IFSref_VehRtAngl9Val "This is right angle of vehicle 9 Deg = (HEX)*0.1-25"; -CM_ SG_ 698 IFSref_VehLftAngl10Val "This is left angle of vehicle 10 Deg = (HEX)*0.1-25"; -CM_ SG_ 698 IFSref_VehRtAngl10Val "This is right angle of vehicle 10 Deg = (HEX)*0.1-25"; -CM_ SG_ 698 IFSref_VehDst2Val "IFSref_VehicleDistance2Value"; -CM_ SG_ 698 IFSref_VehDst3Val "IFSref_VehicleDistance3Value"; -CM_ SG_ 698 IFSref_VehDst4Val "IFSref_VehicleDistance4Value"; -CM_ SG_ 698 IFSref_VehDst5Val "IFSref_VehicleDistance5Value"; -CM_ SG_ 698 IFSref_VehDst6Val "IFSref_VehicleDistance6Value"; -CM_ SG_ 698 IFSref_VehDst7Val "IFSref_VehicleDistance7Value"; -CM_ SG_ 698 IFSref_VehDst8Val "IFSref_VehicleDistance8Value"; -CM_ SG_ 698 IFSref_VehDst9Val "IFSref_VehicleDistance9Value"; -CM_ SG_ 698 IFSref_VehDst10Val "IFSref_VehicleDistance10Value"; +CM_ SG_ 676 LEFT_LANE_LINE "Left lane line confidence"; +CM_ SG_ 676 RIGHT_LANE_LINE "Right lane line confidence"; CM_ SG_ 736 MAX_SPEED "Display units. Restricts car from driving above this speed unless accelerator pedal is depressed beyond pressure point"; -CM_ BO_ 866 "Contains signals with detailed lane line information. Used by ADAS ECU on HDA 2 vehicles to operate LFA. Used on cars that use message 272."; CM_ SG_ 866 LEFT_LANE_LINE "Left lane line confidence"; CM_ SG_ 866 RIGHT_LANE_LINE "Right lane line confidence"; CM_ SG_ 961 COUNTER_ALT "only increments on change"; CM_ SG_ 1041 COUNTER_ALT "only increments on change"; -CM_ BO_ 1043 "Lamp signals do not seem universal on cars that use LKAS_ALT, but stalk signals do."; CM_ SG_ 1043 COUNTER_ALT "only increments on change"; CM_ SG_ 1043 USE_ALT_LAMP "likely 1 on cars that use alt lamp signals"; VAL_ 53 GEAR 0 "P" 5 "D" 6 "N" 7 "R"; -VAL_ 64 GEAR 0 "P" 5 "D" 6 "N" 7 "R"; +VAL_ 64 GEAR 0 "P" 5 "D" 6 "N" 7 "R" 4 "T"; VAL_ 69 GEAR 0 "P" 5 "D" 6 "N" 7 "R"; +VAL_ 80 LKA_MODE 1 "warning only" 2 "assist" 6 "off"; +VAL_ 80 LKA_ICON 0 "hidden" 1 "grey" 2 "green" 3 "flashing green"; VAL_ 96 TRACTION_AND_STABILITY_CONTROL 0 "On" 5 "Limited" 1 "Off"; VAL_ 112 GEAR 0 "P" 5 "D" 6 "N" 7 "R"; -VAL_ 203 ADAS_ActvACISta 0 "INIT" 1 "INACTIVE" 2 "ACTIVE35(ACTIVE)" 3 "ACTIVE33(Redundancy)" 4 "RESERVED" 5 "RESERVED" 6 "RESERVED" 7 "RESERVED" 8 "RESERVED" 9 "RESERVED" 10 "RESERVED" 11 "RESERVED" 12 "RESERVED" 13 "RESERVED" 14 "RESERVED" 15 "RESERVED"; -VAL_ 203 ADAS_ActvACILvl2Sta 0 "INIT" 1 "INACTIVE" 2 "ACTIVE35(ACTIVE)" 3 "RESERVED" 4 "RESERVED" 5 "RESERVED" 6 "RESERVED" 7 "RESERVED" 8 "RESERVED" 9 "RESERVED" 10 "RESERVED" 11 "RESERVED" 12 "RESERVED" 13 "RESERVED" 14 "RESERVED" 15 "RESERVED"; -VAL_ 203 ADAS_StrAnglReqVal 0 "0x0x000~0x3FFF:Real Values" 16383 "0x0x000~0x3FFF:Real Values"; -VAL_ 203 ADAS_ACIAnglTqRedcGainVal 0 "0x0x00~0xFA:Real Values" 250 "0x0x00~0xFA:Real Values" 251 "RESERVED" 252 "RESERVED" 253 "RESERVED" 254 "RESERVED" 255 "RESERVED"; -VAL_ 203 FCA_ESA_ActvSta 0 "Inactive" 1 "Active" 2 "RESERVED" 3 "RESERVED"; -VAL_ 203 FCA_ESA_TqBstGainVal 0 "0x0x00~0xFA:Real Values" 250 "0x0x00~0xFA:Real Values" 251 "RESERVED" 252 "RESERVED" 253 "RESERVED" 254 "RESERVED" 255 "RESERVED"; VAL_ 234 LKA_FAULT 0 "ok" 1 "lka fault"; +VAL_ 267 CRUISE_BUTTONS 8 "CRUISE_MAIN" 4 "CANCEL" 1 "RES" 2 "SET" 3 "GAP"; VAL_ 272 LKA_MODE 1 "warning only" 2 "assist" 6 "off"; VAL_ 272 LKA_ICON 0 "hidden" 1 "grey" 2 "green" 3 "flashing green"; -VAL_ 272 LKAS_ANGLE_ACTIVE 0 "off" 1 "not active" 2 "active"; -VAL_ 282 HBA_SysOptSta 0 "None HBA Option (Default)" 1 "HBA Option" 2 "Reserved" 3 "Error indicator"; -VAL_ 282 HBA_SysSta 0 "HBA Disable" 1 "HBA Enable & High Beam Off" 2 "HBA Enable & High Beam On" 3 "Reserved" 4 "Reserved" 5 "Reserved" 6 "Reserved" 7 "System Fail"; -VAL_ 282 HBA_IndLmpReq 0 "HBA Indicator Lamp Off" 1 "HBA Indicator Lamp On" 2 "Reserved" 3 "Error indicator"; -VAL_ 282 FCA_Equip_MFC 0 "No Coding" 1 "Sensor Fusion FCA" 2 "Camera only FCA" 3 "No FCA Option" 4 "ADAS_DRV Option" 5 "Reserved" 6 "Not used" 7 "Error indicator"; -VAL_ 282 HBA_OptUsmSta 0 "None HBA Option (Default)" 1 "HBA Function Off" 2 "HBA Function On" 3 "Invalid (Fail)"; -VAL_ 282 DAW_LVDA_PUDis 0 "Default" 1 "Display “Leading vehicle departure alert”" 2 "Reserved" 3 "Error indicator"; -VAL_ 282 DAW_LVDA_OptUsmSta 0 "No Option (default)" 1 "Off" 2 "On" 3 "Error Indicator"; -VAL_ 282 DAW_OptUsmSta 0 "None DAW Option (Default)" 1 "System Off" 2 "System On" 3 "Reserved" 4 "Reserved" 5 "Reserved" 6 "Reserved" 7 "Invalid (Gray)"; -VAL_ 282 DAW_SysSta 0 "System Off" 1 "Attention Level 1" 2 "Attention Level 2" 3 "Attention Level 3" 4 "Attention Level 4" 5 "Attention Level 5" 6 "Reserved" 7 "Reserved" 8 "Reserved" 9 "Reserved" 10 "Reserved" 11 "Reserved" 12 "Reserved" 13 "Reserved" 14 "System Standby" 15 "System Fail"; -VAL_ 282 DAW_WrnMsgSta 0 "No Warning" 1 "Rest Recommend Warning" 2 "Hands-Off TMS call request" 3 "Reserved" 4 "Reserved" 5 "Reserved" 6 "Reserved" 7 "Error indicator"; -VAL_ 282 DAW_TimeRstReq 0 "No signal" 1 "Time reset" 2 "Reserved" 3 "Error indicator"; -VAL_ 282 DAW_SnstvtyModRetVal 0 "Default" 1 "Late" 2 "Normal" 3 "Reserved" 4 "Reserved" 5 "Reserved" 6 "Reserved" 7 "Invalid"; -VAL_ 282 FR_CMR_SCCEquipSta 0 "Not Applied" 1 "Applied" 2 "Not used" 3 "Error Indicator"; +VAL_ 272 LKAS_ANGLE_ACTIVE 1 "not active" 2 "active"; VAL_ 298 LKA_MODE 1 "warning only" 2 "assist" 6 "off"; VAL_ 298 LKA_ICON 0 "hidden" 1 "grey" 2 "green" 3 "flashing green"; VAL_ 304 PARK_BUTTON 1 "Pressed" 2 "Not Pressed"; @@ -858,7 +1006,7 @@ VAL_ 353 LANE_RIGHT 0 "HIDDEN" 1 "GREEN"; VAL_ 353 LANE_ZOOM 0 "ZOOM" 1 "HIDDEN"; VAL_ 353 ALERTS_1 0 "HIDDEN" 1 "WARNING_ONLY_CAR_CENTER" 2 "WARNING_ONLY_CAR_LEFT" 3 "WARNING_ONLY_CAR_RIGHT" 4 "WARNING_ONLY_LEFT" 5 "WARNING_ONLY_RIGHT" 11 "EMERGENCY_BRAKING_CAR_CENTER" 12 "EMERGENCY_BRAKING_CAR_LEFT" 13 "EMERGENCY_BRAKING_CAR_RIGHT" 14 "EMERGENCY_BRAKING_LEFT" 15 "EMERGENCY_BRAKING_RIGHT" 21 "EMERGENCY_STEERING_CAR_LEFT" 22 "EMERGENCY_STEERING_CAR_RIGHT" 23 "EMERGENCY_STEERING_CAR_LEFT_AWAY" 24 "EMERGENCY_STEERING_CAR_RIGHT_AWAY" 25 "EMERGENCY_STEERING_REAR_LEFT" 26 "EMERGENCY_STEERING_REAR_RIGHT" 33 "DRIVE_CAREFULLY"; VAL_ 353 ALERTS_2 0 "HIDDEN" 1 "KEEP_HANDS_ON_STEERING_WHEEL" 2 "KEEP_HANDS_ON_STEERING_WHEEL_RED" 3 "LANE_FOLLOWING_ASSIST_DEACTIVATED" 4 "HIGHWAY_DRIVING_ASSIST_DEACTIVATED" 5 "CONSIDER_TAKING_A_BREAK" 6 "PRESS_OK_BUTTON_TO_ENABLE_LANE_CHANGE_ASSIST" 7 "COLLISION_RISK_VEHICLE_TAKING_EMERGENCY_CONTROL" 8 "TAKE_CONTROL_OF_THE_VEHICLE_IMMEDIATELY_VEHICLE_IS_STOPPING" 9 "TAKE_CONTROL_OF_THE_VEHICLE_IMMEDIATELY" 11 "HIGHWAY_DRIVING_PILOT_SYSTEM_DEACTIVATED_AUDIBLE" 12 "KEEP_YOUR_EYES_ON_THE_ROAD" 13 "HIGHWAY_DRIVING_PILOT_CONDITIONS_NOT_MET_AUDIBLE" 14 "COLLISION_RISK_VEHICLE_TAKING_EMERGENCY_CONTROL" 15 "SET_THE_WIPER_AND_LIGHT_CONTROLS_TO_AUTO" 16 "BE_PREPARED_TO_TAKE_CONTROL_OF_THE_VEHICLE_AT_ANY_TIME" 21 "TAKE_CONTROL_OF_THE_VEHICLE_IMMEDIATELY_VEHICLE_IS_STOPPING" 10 "TAKE_CONTROL_OF_THE_VEHICLE_IMMEDIATELY"; -VAL_ 353 ALERTS_3 1 "AUTOMATICALLY_ADJUSTING_TO_THE_POSTED_SPEED_LIMIT" 2 "SET_SPEED_CHANGED" 3 "AUTOMATICALLY_ADJUSTING_TO_THE_POSTED_SPEED_LIMIT" 4 "SET_SPEED_CHANGED" 7 "DISTANCE_1" 8 "DISTANCE_2" 9 "DISTANCE_3" 10 "DISTANCE_4" 17 "DRIVE_CAREFULLY" 18 "CHECK_SURROUNDINGS" 19 "CONDITIONS_NOT_MET" 20 "LANES_NOT_DETECTED" 21 "CURVE_TOO_SHARP" 22 "LANE_TOO_NARROW" 23 "ROAD_TYPE_NOT_SUPPORTED" 24 "UNAVAILABLE_WITH_HAZARD_LIGHTS_ON" 25 "VEHICLE_SPEED_IS_TOO_LOW" 26 "KEEP_HANDS_ON_STEERING_WHEEL" 27 "LANE_TYPE_NOT_SUPPORTED" 28 "LANE_ASSIST_CANCELED_STEERING_INPUT_DETECTED" 0 "HIDDEN"; +VAL_ 353 ALERTS_3 0 "HIDDEN" 1 "AUTOMATICALLY_ADJUSTING_TO_THE_POSTED_SPEED_LIMIT" 2 "SET_SPEED_CHANGED" 3 "AUTOMATICALLY_ADJUSTING_TO_THE_POSTED_SPEED_LIMIT" 4 "SET_SPEED_CHANGED" 7 "DISTANCE_1" 8 "DISTANCE_2" 9 "DISTANCE_3" 10 "DISTANCE_4" 17 "DRIVE_CAREFULLY" 18 "CHECK_SURROUNDINGS" 19 "CONDITIONS_NOT_MET" 20 "LANES_NOT_DETECTED" 21 "CURVE_TOO_SHARP" 22 "LANE_TOO_NARROW" 23 "ROAD_TYPE_NOT_SUPPORTED" 24 "UNAVAILABLE_WITH_HAZARD_LIGHTS_ON" 25 "VEHICLE_SPEED_IS_TOO_LOW" 26 "KEEP_HANDS_ON_STEERING_WHEEL" 27 "LANE_TYPE_NOT_SUPPORTED" 28 "LANE_ASSIST_CANCELED_STEERING_INPUT_DETECTED"; VAL_ 353 ALERTS_4 0 "HIDDEN" 1 "TAKE_FOOT_OFF_THE_ACCELERATOR_PEDAL" 2 "TAKE_FOOT_OFF_THE_BRAKE_PEDAL" 3 "UNAVAILABLE_WHILE_HIGHWAY_DRIVING_PILOT_SYSTEM_IS_ACTIVE" 4 "TO_EXIT_HDP_GRASP_THE_STEERING_WHEEL_THEN_PRESS_AND_HOLD_THE_HDP_BUTTON" 5 "ACCELERATOR_PEDAL_OPERATION_LIMITED_FOR_SAFETY" 6 "TURN_OFF_HAZARD_WARNING_LIGHTS_AND_TURN_SIGNAL" 7 "KEEP_THE_DRIVERS_SEAT_IN_A_SAFE_DRIVING_POSITION" 16 "SET_SPEED_CHANGED" 17 "ACTIVATING_WINDSHIELD_DEFOG_TO_MAINTAIN_THE_DRIVERS_VIEW" 18 "SET_THE_WIPER_AND_LIGHT_CONTROLS_TO_AUTO" 19 "VEHICLE_SPEED_REDUCED_FOR_SAFETY_MERGING_LANES_AHEAD" 20 "SPEED_REDUCED_FOR_SAFETY_CONSTRUCTION_ZONE_DETECTED" 21 "VEHICLE_SPEED_LIMITED_SENSOR_DETECTION_RANGE_LIMITED" 22 "PREPARE_TO_TAKE_CONTROL_UNSUPPORTED_ROAD_TYPE_AHEAD" 23 "PREPARE_TO_TAKE_CONTROL_ENTRANCE_AND_EXIT_RAMPS_AHEAD" 24 "PREPARE_TO_TAKE_CONTROL_TOLLGATE_AHEAD" 25 "PREPARE_TO_TAKE_CONTROL_ROAD_EVENT_AHEAD" 26 "CLEARING_PATH_FOR_EMERGENCY_VEHICLE" 27 "VEHICLE_IS_TOO_SLOW_COMPARED_TO_TRAFFIC_FLOW" 28 "AFTER_SUNSET_HDP_IS_AVAILABLE_IN_AN_INSIDE_LANE_BEHIND_A_LEADING_VEHICLE" 29 "VEHICLE_SPEED_LIMITED_MERGING_LANES_AHEAD" 30 "VEHICLE_SPEED_LIMITED_CONSTRUCTION_ZONE_DETECTED" 31 "VEHICLE_SPEED_TEMPORARILY_LIMITED_FOR_SAFETY" 32 "PRESS_AND_HOLD_THE_BUTTON_TO_ACTIVATE_HIGHWAY_DRIVING_PILOT" 40 "HIGHWAY_DRIVING_PILOT_SYSTEM_IS_AVAILABLE" 64 "RESTART_VEHICLE_AFTER_EMERGENCY_STOP" 65 "CONNECTED_SERVICES_UNAVAILABLE" 66 "AVAILABLE_AFTER_VEHICLE_SOFTWARE_IS_UPDATED" 67 "ROAD_TYPE_NOT_SUPPORTED" 68 "ONLY_AVAILABLE_WHILE_DRIVING_ON_HIGHWAY_LANES" 69 "UNAVAILABLE_WHILE_OTHER_WARNINGS_ARE_ACTIVE" 70 "CANNOT_ACTIVATE_AT_ENTRANCE_EXIT_RAMPS" 71 "LANE_UNSUPPORTED" 72 "NOT_AVAILABLE_IN_THIS_COUNTRY" 79 "CHECKING_THE_DETECTION_RANGE_OF_THE_SENSOR" 80 "SHIFT_TO_D" 81 "ENGINE_STOPPED_BY_AUTO_STOP" 82 "INCREASE_DISTANCE_FROM_VEHICLE_AHEAD" 83 "VEHICLE_SPEED_IS_TOO_HIGH" 84 "CENTER_VEHICLE_IN_THE_LANE" 85 "PARKING_ASSIST_IS_ACTIVE" 86 "ESC_ACTIVIATION_REQUIRED" 87 "UNFOLD_SIDE_VIEW_MIRRORS" 88 "UNAVAILABLE_IN_THE_OUTER_LANE_AFTER_SUNSET" 89 "VEHICLE_SPEED_LIMITED_AFTER_SUNSET_FOR_SAFETY" 90 "LEADING_VEHICLE_NOT_DETECTED" 104 "AGGRESSIVE_BRAKING_OR_STEERING_DETECTED" 110 "SENSOR_AUTO_CALIBRATION_IN_PROGRESS_THIS_MAY_TAKE_SEVERAL_MINUTES" 111 "HIGHWAY_DRIVING_PILOT_WILL_BE_AVAILABLE_SHORTLY" 112 "IF_STEERING_WHEEL_IS_USED_HDP_WILL_BE_DEACTIVATED" 120 "IMPACT_DETECTED" 128 "UNSUITABLE_USE_OF_ACCELERATOR_PEDAL_DETECTED" 129 "GEAR_SHIFTER_USE_DETECTED" 130 "UNSUITABLE_BRAKE_PEDAL_USE_DETECTED" 131 "VEHICLE_START_BUTTON_PRESSED" 132 "VEHICLE_HAS_BEEN_STOPPED_FOR_TOO_LONG" 141 "TRAFFIC_CONGESTION_HAS_CLEARED" 142 "ENTRANCE_AND_EXIT_RAMPS_AHEAD" 143 "UNSUPPORTED_LANE_AHEAD" 144 "UNSUPPORTED_ROAD_TYPE_AHEAD" 145 "LANE_DEPARTURE_DETECTED" 146 "MAXIMUM_SPEED_EXCEEDED" 147 "HIGHWAY_DRIVING_PILOT_LIMITED_ABNORMAL_VEHICLE_CONTROLLER_STATUS" 148 "WIPER_LIGHT_CONTROL_SETTINGS_ARE_UNSUITABLE_FOR_USE_WITH_HDP" 149 "WINDSHIELD_DEFOG_SYSTEM_STATUS_IS_UNSUITABLE_FOR_USE_WITH_HDP" 150 "HAZARD_WARNING_LIGHTS_OR_TURN_SIGNAL_OPERATION_DETECTED" 151 "PERFORMING_EVASIVE_STEERING_OBSTACLES_DETECTED_AHEAD" 152 "HIGHWAY_DRIVING_PILOT_LIMITED_SENSOR_DETECTION_RANGE_LIMITED" 160 "CHECK_HIGHWAY_DRIVING_PILOT_SYSTEM" 161 "SAFETY_FUNCTION_ACTIVATED" 176 "CAMERA_OBSCURED" 177 "RADAR_BLOCKED" 178 "LIDAR_BLOCKED" 179 "AIRBAG_WARNING_LIGHT_IS_ON" 180 "ATTACHED_TRAILED_DETECTED" 181 "HIGH_OUTSIDE_TEMPERATURE" 182 "LOW_OUTSIDE_TEMPERATURE" 190 "UNAVAILABLE_DUE_TO_THE_ROAD_EVENT_INFORMATION_RECEIVED" 191 "UNAVAILABLE_NEAR_TOLLGATES" 192 "DRIVERS_SEAT_IS_NOT_IN_A_SAFE_DRIVING_POSITION" 193 "VEHICLE_DRIVING_THE_WRONG_WAY_DETECTED_AHEAD" 194 "EMERGENCY_VEHICLE_DETECTED" 195 "OBSTACLE_DETECTED_AHEAD" 196 "SENSOR_BLOCKED_DUE_TO_RAIN_SNOW_OR_ROAD_DEBRIS" 197 "SLIPPERY_ROAD_SURFACE_DETECTED" 198 "CONSTRUCTION_ZONE_DETECTED_AHEAD" 199 "PEDESTRIAN_DETECTED_AHEAD" 200 "UNSUITABLE_DRIVERS_SEAT_POSITION_DETECTED" 201 "FOLDED_SIDE_VIEW_MIRRORS_DETECTED" 208 "VEHICLE_POSITION_NOT_DETECTED" 209 "LANE_NOT_DETECTED" 210 "DRIVER_NOT_DETECTED" 211 "KEEP_YOUR_EYES_ON_THE_ROAD" 212 "LEADING_VEHICLE_REQUIRED_AFTER_SUNSET" 213 "TBD" 240 "LOW_FUEL" 241 "LOW_TIRE_PRESSURE" 242 "DOOR_OPEN" 243 "TRUNK_OPEN" 244 "HOOD_OPEN" 245 "SEAT_BELT_NOT_FASTENED" 246 "PARKING_BRAKE_ACTIVATED" 247 "LOW_EV_BATTERY" 248 "HDP_DEACTIVATION_DELAYED_RISK_OF_COLLISION_DETECTED" 249 "LIFTGATE_OPENED"; VAL_ 353 ALERTS_5 0 "HIDDEN" 1 "DRIVERS_GRASP_NOT_DETECTED_DRIVING_SPEED_WILL_BE_LIMITED" 2 "WATCH_FOR_SURROUNDING_VEHICLES" 3 "SMART_CRUISE_CONTROL_DEACTIVATED" 4 "SMART_CRUISE_CONTROL_CONDITIONS_NOT_MET" 5 "USE_SWITCH_OR_PEDAL_TO_ACCELERATE" 6 "DRIVER_ASSISTNCE_SYSTEM_LIMITED_TRAILER_ATTACHED" 7 "DRIVER_ASSISTNCE_SYSTEM_LIMITED_DRIVER_FULL_FACE_NOT_VISIBLE" 11 "LEADING_VEHICLE_IS_DRIVING_AWAY" 12 "STOP_VEHICLE_THEN_TRY_AGAIN" 19 "ACTIVATING_HIGHWAY_DRIVING_PILOT_SYSTEM" 20 "CONTINUING_USE_OF_HIGHWAY_DRIVING_PILOT_WILL_RESULT_IN_DEVIATION_FROM_THE_NAVIGATION_ROUTE" 21 "HIGHWAY_DRIVING_PILOT_SYSTEM_DEACTIVATED_SILENT" 22 "HIGHWAY_DRIVING_PILOT_SYSTEM_NOT_APPLIED" 23 "HIGHWAY_DRIVING_PILOT_CONDITIONS_NOT_MET_SILENT"; VAL_ 353 MUTE 0 "NONE" 1 "MUTED"; @@ -868,7 +1016,7 @@ VAL_ 353 SOUNDS_3 0 "NONE" 3 "SOFT CHIME" 5 "SINGLE CHIME"; VAL_ 353 SOUNDS_4 0 "NONE" 2 "DOUBLE CHIME"; VAL_ 353 SETSPEED_HUD 0 "HIDDEN" 1 "GRAY" 2 "GREEN" 3 "WHITE" 5 "CYAN"; VAL_ 353 DISTANCE_LEAD 0 "HIDDEN" 1 "GRAY" 2 "WHITE"; -VAL_ 353 DISTANCE_CAR 0 "HIDDEN" 1 "GRAY" 2 "WHITE" 3 "CYAN A"; +VAL_ 353 DISTANCE_CAR 0 "HIDDEN" 1 "GRAY" 2 "WHITE" 3 "CYAN"; VAL_ 353 DISTANCE_SPACING 0 "HIDDEN" 1 "BLUE" 3 "WHITE" 5 "CYAN"; VAL_ 353 SETSPEED 0 "HIDDEN" 1 "GRAY" 2 "GREEN" 3 "WHITE" 6 "CYAN"; VAL_ 353 HDA_ICON 0 "HIDDEN" 1 "GRAY" 2 "GREEN" 3 "WHITE" 5 "CYAN HDP"; @@ -885,10 +1033,12 @@ VAL_ 354 SPEEDLIMIT_FLASH 0 "HIDDEN" 1 "ERROR" 2 "NORMAL" 4 "RED"; VAL_ 354 SIGNS 0 "HIDDEN" 1 "PEDESTRIAN_CROSSING" 2 "SCHOOL_CROSSWALK" 8 "STOP" 9 "YIELD" 16 "DO_NOT_PASS" 19 "DO_NOT_ENTER" 24 "ROUNDABOUT" 26 "RIGHT_CURVE_AHEAD" 27 "LEFT_CURVE_AHEAD" 28 "SLIGHT_RIGHT_CURVE_AHEAD" 29 "SLIGHT_LEFT_CURVE_AHEAD"; VAL_ 354 SPEEDLIMIT_WEATHER 0 "HIDDEN" 1 "RAIN" 2 "SNOW" 3 "RAIN+SNOW" 4 "TRAILER"; VAL_ 354 VIBRATE 0 "NONE" 1 "VIBRATE"; -VAL_ 354 LEAD 0 "HIDDEN" 1 "GRAY BOX" 2 "WHITE BOX" 3 "GRAY CAR" 4 "WHITE CAR" 5 "GRAY TRUCK" 6 "WHITE TRUCK" 7 "GRAY PERSON" 8 "WHITE PERSON" 9 "GRAY BICYCLE" 10 "WHITE BICYCLE" 11 "GRAY MOTORCYCLE" 12 "WHITE MOTORCYCLE" 13 "DARK CONE" 14 "ORANGE CONE"; -VAL_ 354 LEAD_ALT 0 "HIDDEN" 1 "GRAY BOX" 2 "WHITE BOX" 3 "DIM CONE" 4 "ORANGE CONE"; -VAL_ 354 LEAD_LEFT 0 "HIDDEN" 1 "GRAY BOX" 2 "WHITE BOX" 3 "GRAY CAR" 4 "WHITE CAR" 5 "GRAY TRUCK" 6 "WHITE TRUCK" 7 "GRAY PERSON" 8 "WHITE PERSON" 9 "GRAY BICYCLE" 10 "WHITE BICYCLE" 11 "GRAY MOTORCYCLE" 12 "WHITE MOTORCYCLE" 13 "DARK CONE" 14 "ORANGE CONE"; -VAL_ 354 LEAD_RIGHT 0 "HIDDEN" 1 "GRAY BOX" 2 "WHITE BOX" 3 "GRAY CAR" 4 "WHITE CAR" 5 "GRAY TRUCK" 6 "WHITE TRUCK" 7 "GRAY PERSON" 8 "WHITE PERSON" 9 "GRAY BICYCLE" 10 "WHITE BICYCLE" 11 "GRAY MOTORCYCLE" 12 "WHITE MOTORCYCLE" 13 "DARK CONE" 14 "ORANGE CONE"; +VAL_ 354 FF_DETECT 0 "HIDDEN" 1 "GRAY BOX" 2 "WHITE BOX" 3 "GRAY CAR" 4 "WHITE CAR" 5 "GRAY TRUCK" 6 "WHITE TRUCK" 7 "GRAY PERSON" 8 "WHITE PERSON" 9 "GRAY BICYCLE" 10 "WHITE BICYCLE" 11 "GRAY MOTORCYCLE" 12 "WHITE MOTORCYCLE" 13 "DARK CONE" 14 "ORANGE CONE"; +VAL_ 354 FF_DETECT_ALT 0 "HIDDEN" 1 "GRAY BOX" 2 "WHITE BOX" 3 "DIM CONE" 4 "ORANGE CONE"; +VAL_ 354 LF_DETECT 0 "HIDDEN" 1 "GRAY BOX" 2 "WHITE BOX" 3 "GRAY CAR" 4 "WHITE CAR" 5 "GRAY TRUCK" 6 "WHITE TRUCK" 7 "GRAY PERSON" 8 "WHITE PERSON" 9 "GRAY BICYCLE" 10 "WHITE BICYCLE" 11 "GRAY MOTORCYCLE" 12 "WHITE MOTORCYCLE" 13 "DARK CONE" 14 "ORANGE CONE"; +VAL_ 354 RF_DETECT 0 "HIDDEN" 1 "GRAY BOX" 2 "WHITE BOX" 3 "GRAY CAR" 4 "WHITE CAR" 5 "GRAY TRUCK" 6 "WHITE TRUCK" 7 "GRAY PERSON" 8 "WHITE PERSON" 9 "GRAY BICYCLE" 10 "WHITE BICYCLE" 11 "GRAY MOTORCYCLE" 12 "WHITE MOTORCYCLE" 13 "DARK CONE" 14 "ORANGE CONE"; +VAL_ 354 LR_DETECT 0 "HIDDEN" 1 "GRAY BOX" 2 "WHITE BOX" 3 "GRAY CAR" 4 "WHITE CAR" 5 "GRAY TRUCK" 6 "WHITE TRUCK" 7 "GRAY PERSON" 8 "WHITE PERSON" 9 "GRAY BICYCLE" 10 "WHITE BICYCLE" 11 "GRAY MOTORCYCLE" 12 "WHITE MOTORCYCLE" 13 "DARK CONE" 14 "ORANGE CONE"; +VAL_ 354 RR_DETECT 0 "HIDDEN" 1 "GRAY BOX" 2 "WHITE BOX" 3 "GRAY CAR" 4 "WHITE CAR" 5 "GRAY TRUCK" 6 "WHITE TRUCK" 7 "GRAY PERSON" 8 "WHITE PERSON" 9 "GRAY BICYCLE" 10 "WHITE BICYCLE" 11 "GRAY MOTORCYCLE" 12 "WHITE MOTORCYCLE" 13 "DARK CONE" 14 "ORANGE CONE"; VAL_ 354 FAULT_FSS 0 "HIDDEN" 1 "CHECK_FORWARD_SAFETY_SYSTEM" 2 "FORWARD_SAFETY_SYSTEM_LIMITED_CAMERA_OBSCURED" 3 "FORWARD_SAFETY_SYSTEM_LIMITED_RADAR_BLOCKED"; VAL_ 354 FAULT_FCA 0 "HIDDEN" 1 "CHECK_FORWARD_SIDE_SAFETY_SYSTEM" 2 "FORWARD_SIDE_SAFETY_SYSTEM_LIMITED_CAMERA_OBSCURED" 3 "FORWARD_SIDE_SAFETY_SYSTEM_LIMITED_RADAR_BLOCKED"; VAL_ 354 FAULT_LSS 0 "HIDDEN" 1 "CHECK_LANE_SAFETY_SYSTEM" 2 "LANE_SAFETY_SYSTEM_DISABLED_CAMERA_OBSCURED"; @@ -903,80 +1053,46 @@ VAL_ 354 FAULT_HDP 0 "HIDDEN" 1 "CHECK_HIGHWAY_DRIVING_PILOT_SYSTEM" 2 "HIGHWAY_ VAL_ 354 FAULT_DAS 0 "HIDDEN" 1 "CHECK_DRIVER_ASSISTANCE_SYSTEM" 2 "DRIVER_ASSISTANCE_SYSTEM_LIMITED_CAMERA_OBSCURED" 3 "DRIVER_ASSISTANCE_SYSTEM_LIMITED_RADAR_BLOCKED" 4 "DRIVER_ASSISTANCE_SYSTEM_LIMITED_CAMERA_OBSCURED_AND_RADAR_BLOCKED"; VAL_ 354 FAULT_ESS 0 "HIDDEN" 1 "CHECK_EMERGENCY_STOPPING_FUNCTION" 2 "EMERGENCY_STOPPING_FUNCTION_DISABLED_CAMERA_OBSCURED" 3 "EMERGENCY_STOPPING_FUNCTION_DISABLED_RADAR_BLOCKED"; VAL_ 362 BLINKER_CONTROL 1 "hazards" 2 "hazards button backlight" 3 "left blinkers" 4 "right blinkers"; +VAL_ 373 SCC_OptTyp 0 "SCC is not equipped" 1 "SCC is equipped" 2 "Not used" 3 "Error Indicator"; VAL_ 373 ACCEnable 0 "SCC ready" 1 "SCC temp fault" 2 "SCC permanent fault" 3 "SCC permanent fault, communication issue"; +VAL_ 373 SCC_ReqLimSta 0 "No request" 1 "Limited No Limitation" 2 "Acceleration Limited" 3 "Deceleration Limited"; +VAL_ 373 ESC_StdStillVal 0 "No stand still detected" 1 "stand still detected" 2 "Not used" 3 "Error Indicator"; +VAL_ 373 ESC_DclEnblReq 0 "Disable deceleration control" 1 "Enable deceleration control" 2 "Not used" 3 "Error Indicator"; +VAL_ 373 ESC_PrkBrkActvSta 0 "Parking brake is not activated" 1 "Parking brake is activated" 2 "Not used" 3 "Error Indicator"; +VAL_ 373 FCA_EquipSta 0 "FCA is not equipped" 1 "FCA is equipped" 2 "Not used" 3 "Error Indicator"; +VAL_ 373 FCA_AvlblSta 0 "Available" 1 "Temporarily not available" 2 "Permanently not available" 3 "FCA Communication Error"; VAL_ 416 ACCMode 0 "off" 1 "enabled" 2 "driver_override" 3 "off_maybe_fault" 4 "cancelled"; -VAL_ 416 SCC_ObjSta 0 "No in-path object detected" 1 "In-path object detected (uncontrollable)" 2 "In-path object detected (controllable:longitudinal)" 3 "Reserved" 4 "Reserved" 5 "Reserved" 6 "Reserved" 7 "Reserved"; VAL_ 426 CRUISE_BUTTONS 0 "none" 1 "res_accel" 2 "set_decel" 3 "gap_distance" 4 "pause_resume"; -VAL_ 437 Info_LftLnQualSta 0 "Very Low Quality" 1 "Low Quality" 2 "High Quality" 3 "Very High Quality" 4 "Reserved" 5 "Reserved" 6 "Reserved" 7 "Error indicator"; -VAL_ 437 Info_LftLnDptSta 0 "No Left Line Departure" 1 "Left Line Departure" 2 "Reserved" 3 "Error Indicator"; -VAL_ 437 Info_RtLnQualSta 0 "Very Low Quality" 1 "Low Quality" 2 "High Quality" 3 "Very High Quality" 4 "Reserved" 5 "Reserved" 6 "Reserved" 7 "Error indicator"; -VAL_ 437 Info_RtLnDptSta 0 "No Right Line Departure" 1 "Right Line Departure" 2 "Reserved" 3 "Error Indicator"; -VAL_ 437 Info_RtLnCvtrVal 65534 "Reserved" 65535 "Error indicator"; VAL_ 463 CRUISE_BUTTONS 0 "none" 1 "res_accel" 2 "set_decel" 3 "gap_distance" 4 "pause_resume"; VAL_ 463 RIGHT_PADDLE 0 "Not Pulled" 1 "Pulled"; VAL_ 463 LEFT_PADDLE 0 "Not Pulled" 1 "Pulled"; -VAL_ 506 ISLW_OptUsmSta 0 "None ISLW Option (Default)" 1 "System Disabled by USM" 2 "System Enable by USM" 3 "Invalid"; -VAL_ 506 ISLW_SysSta 0 "Normal (Default)" 1 "System Fail" 2 "ISLW Temporary Unavailable" 3 "Reserved"; -VAL_ 506 ISLW_NoPassingInfoDis 0 "None Display (Default)" 1 "LHD No Passing Zone Display" 2 "RHD No Passing Zone Display" 3 "Reserved" 4 "Reserved" 5 "Reserved" 6 "Reserved" 7 "Invalid"; -VAL_ 506 ISLW_OvrlpSignDis 0 "None (Default)" 1 "Overlap Sign" 2 "Reserved" 3 "Error indicator"; -VAL_ 506 ISLW_SpdCluMainDis 0 "No Recognition (Default)" 253 "Unlimited Speed" 254 "Reserved" 255 "Invalid"; -VAL_ 506 ISLW_SpdNaviMainDis 0 "No Recognition (Default)" 253 "Unlimited Speed" 254 "Reserved" 255 "Invalid"; -VAL_ 506 ISLW_SubCondinfoSta1 0 "None (Default)" 1 "Rain" 2 "Snow" 3 "Snow&Rain" 4 "Trailer" 5 "Reserved" 6 "Reserved" 7 "Reserved" 8 "Reserved" 9 "Reserved" 10 "Reserved" 11 "Reserved" 12 "Reserved" 13 "Reserved" 14 "Generic" 15 "Invalid"; -VAL_ 506 ISLW_SubCondinfoSta2 0 "None (Default)" 1 "Rain" 2 "Snow" 3 "Snow&Rain" 4 "Trailer" 5 "Reserved" 6 "Reserved" 7 "Reserved" 8 "Reserved" 9 "Reserved" 10 "Reserved" 11 "Reserved" 12 "Reserved" 13 "Reserved" 14 "Generic" 15 "Invalid"; -VAL_ 506 ISLW_SpdCluSubMainDis 0 "No Recognition (Default)" 253 "Unlimited Speed" 254 "Reserved" 255 "Invalid"; -VAL_ 506 ISLW_SpdCluDisSubCond1 0 "No Recognition (Default)" 253 "LHD Conditional No Passing ZONE" 254 "RHD Conditional No Passing ZONE" 255 "Invalid"; -VAL_ 506 ISLW_SpdCluDisSubCond2 0 "No Recognition (Default)" 253 "LHD Conditional No Passing ZONE" 254 "RHD Conditional No Passing ZONE" 255 "Invalid"; -VAL_ 506 ISLW_SpdNaviSubMainDis 0 "No Recognition (Default)" 253 "Unlimited Speed" 254 "Reserved" 255 "Invalid"; -VAL_ 506 ISLW_SpdNaviDisSubCond1 0 "No Recognition (Default)" 253 "LHD Conditional No Passing ZONE" 254 "RHD Conditional No Passing ZONE" 255 "Invalid"; -VAL_ 506 ISLW_SpdNaviDisSubCond2 0 "No Recognition (Default)" 253 "LHD Conditional No Passing ZONE" 254 "RHD Conditional No Passing ZONE" 255 "Invalid"; -VAL_ 506 ISLA_SpdwOffst 0 "No Recognition" 253 "Unlimited Speed" 254 "Reserved" 255 "Invalid"; -VAL_ 506 ISLA_SwIgnoreReq 0 "Allow All Switch Inputs (default)" 1 "-(SET) Switch Input Ignore" 2 "+(SET) Switch Input Ignore" 3 "-(SET) & +(SET) Switch Inputs Ignore"; -VAL_ 506 ISLA_SpdChgReq 0 "Default" 1 "Speed Change Request" 2 "Reserved" 3 "Reserved"; -VAL_ 506 ISLA_SpdWrn 0 "No Warning" 1 "Warning" 2 "Reserved" 3 "Reserved"; -VAL_ 506 ISLA_IcyWrn 0 "No Warning" 1 "Warning" 2 "Reserved" 3 "Reserved"; -VAL_ 506 ISLA_SymFlashMod 0 "No Flasing" 1 "Flashing Sign" 2 "Flashing - Arrow Symbol" 3 "Flashing + Arrow Symbol" 4 "Flashing Auto Symbol" 5 "Reserved" 6 "Reserved" 7 "Reserved"; -VAL_ 506 ISLA_Popup 0 "No Popup" 1 "MSLA Speed will Change" 2 "MSLA Speed has Changed" 3 "CC_SCC Speed will Change" 4 "CC_SCC Speed has Changed" 5 "Reserved" 6 "Reserved" 7 "Reserved"; -VAL_ 506 ISLA_OptUsmSta 0 "None ISLA Option (속도 제한 메뉴 삭제)" 1 "Off" 2 "Warning" 3 "Assist" 4 "Reserved" 5 "Reserved" 6 "Reserved" 7 "Invalid (GRAY)"; -VAL_ 506 ISLA_OffstUsmSta 0 "None Offset Function" 1 "-10kph or -5mph" 2 "-5kph or -3mph" 3 "0kph or 0mph" 4 "+5kph or +3mph" 5 "+10kph or +5mph" 6 "Reserved" 7 "Invalid (GRAY)"; -VAL_ 506 ISLA_AutoUsmSta 0 "None Auto Function (Delete Menu)" 1 "Auto Off" 2 "Auto On" 3 "Invalid (GRAY)"; -VAL_ 506 ISLA_Cntry 0 "Europe/Russia/Australia" 1 "Domestic" 2 "China" 3 "USA" 4 "Canada" 5 "Australia" 6 "Reserved" 7 "Reserved" 8 "Reserved" 9 "Reserved" 10 "Reserved" 11 "Reserved" 12 "Reserved" 13 "Reserved" 14 "Reserved" 15 "Initial Value (default)"; -VAL_ 506 ISLA_AddtnlSign 0 "No Recognition (default)" 1 "School Crossing" 16 "Do Not Pass" 17 "Reserved" 18 "Reserved" 19 "Reserved" 20 "Reserved" 21 "Reserved" 22 "Reserved" 23 "Reserved" 24 "Exit" 25 "Roundabout" 26 "Right Curve" 27 "Left Curve" 28 "Winding Road" 29 "Reserved" 30 "Reserved" 31 "Reserved" 2 "Pedestrian Crossing" 3 "Bicycle Crossing" 4 "Reserved" 5 "Reserved" 6 "Reserved" 7 "Reserved" 8 "Stop" 9 "Yield" 10 "Stop Ahead" 11 "Yield Ahead" 12 "Road Construction Ahead" 13 "Lane Reduction" 14 "Reserved" 15 "Reserved"; -VAL_ 506 ISLA_SchoolZone 0 "No School Zone" 1 "School Zone" 2 "Reserved" 3 "Reserved"; -VAL_ 687 HOD_Dir_Status 0 "HANDS OFF" 1 "HAND TOUCH (SOFT)" 2 "HAND TOUCH (STRONG)" 3 "HAND GRIP (SOFT)" 4 "HAND GRIP (STRONG)" 5 "RESERVED" 6 "RESERVED"; -VAL_ 698 IFSref_FR_CMR_Sta 0 "None Option (Default)" 1 "Normal" 2 "Blockage Status" 3 "Error Indicator"; -VAL_ 698 IFSref_VehNumVal 0 "No vehicle" 1 "Number of vehicles" 2 "Number of vehicles" 3 "Number of vehicles" 4 "Number of vehicles" 5 "Number of vehicles" 6 "Number of vehicles" 7 "Number of vehicles" 8 "Number of vehicles" 9 "Number of vehicles" 10 "Number of vehicles" 11 "Over than 10 vehicles" 12 "Reserved" 13 "Reserved" 14 "Default" 15 "Error indicator"; -VAL_ 698 IFSref_ILLAmbtSta 0 "Bright" 1 "Dark" 2 "Not used" 3 "Error indicator"; -VAL_ 698 IFSref_VehLftAngl1Val 501 "Not used" 502 "Not used" 503 "Not used" 504 "Not used" 505 "Not used" 506 "Not used" 507 "Not used" 508 "Not used" 509 "Not used" 510 "Default" 511 "Error indicator"; -VAL_ 698 IFSref_VehRtAngl1Val 501 "Not used" 502 "Not used" 503 "Not used" 504 "Not used" 505 "Not used" 506 "Not used" 507 "Not used" 508 "Not used" 509 "Not used" 510 "Default" 511 "Error indicator"; -VAL_ 698 IFSref_VehLftAngl2Val 501 "Not used" 502 "Not used" 503 "Not used" 504 "Not used" 505 "Not used" 506 "Not used" 507 "Not used" 508 "Not used" 509 "Not used" 510 "Default" 511 "Error indicator"; -VAL_ 698 IFSref_VehDst1Val 0 "No Value" 1 "1~10m" 2 "11~20m" 3 "21~30m" 4 "31~40m" 5 "41~50m" 6 "51~60m" 7 "61~70m" 8 "71~80m" 9 "81~90m" 10 "91~100m" 11 "101~200m" 12 "201~300m" 13 "301~400m" 14 "401m~" 15 "Error indicator"; -VAL_ 698 IFSref_VehRtAngl2Val 501 "Not used" 502 "Not used" 503 "Not used" 504 "Not used" 505 "Not used" 506 "Not used" 507 "Not used" 508 "Not used" 509 "Not used" 510 "Default" 511 "Error indicator"; -VAL_ 698 IFSref_VehLftAngl3Val 501 "Not used" 502 "Not used" 503 "Not used" 504 "Not used" 505 "Not used" 506 "Not used" 507 "Not used" 508 "Not used" 509 "Not used" 510 "Default" 511 "Error indicator"; -VAL_ 698 IFSref_VehRtAngl3Val 501 "Not used" 502 "Not used" 503 "Not used" 504 "Not used" 505 "Not used" 506 "Not used" 507 "Not used" 508 "Not used" 509 "Not used" 510 "Default" 511 "Error indicator"; -VAL_ 698 IFSref_VehLftAngl4Val 501 "Not used" 502 "Not used" 503 "Not used" 504 "Not used" 505 "Not used" 506 "Not used" 507 "Not used" 508 "Not used" 509 "Not used" 510 "Default" 511 "Error indicator"; -VAL_ 698 IFSref_VehRtAngl4Val 501 "Not used" 502 "Not used" 503 "Not used" 504 "Not used" 505 "Not used" 506 "Not used" 507 "Not used" 508 "Not used" 509 "Not used" 510 "Default" 511 "Error indicator"; -VAL_ 698 IFSref_VehLftAngl5Val 501 "Not used" 502 "Not used" 503 "Not used" 504 "Not used" 505 "Not used" 506 "Not used" 507 "Not used" 508 "Not used" 509 "Not used" 510 "Default" 511 "Error indicator"; -VAL_ 698 IFSref_VehRtAngl5Val 501 "Not used" 502 "Not used" 503 "Not used" 504 "Not used" 505 "Not used" 506 "Not used" 507 "Not used" 508 "Not used" 509 "Not used" 510 "Default" 511 "Error indicator"; -VAL_ 698 IFSref_VehLftAngl6Val 501 "Not used" 502 "Not used" 503 "Not used" 504 "Not used" 505 "Not used" 506 "Not used" 507 "Not used" 508 "Not used" 509 "Not used" 510 "Default" 511 "Error indicator"; -VAL_ 698 IFSref_VehRtAngl6Val 501 "Not used" 502 "Not used" 503 "Not used" 504 "Not used" 505 "Not used" 506 "Not used" 507 "Not used" 508 "Not used" 509 "Not used" 510 "Default" 511 "Error indicator"; -VAL_ 698 IFSref_VehLftAngl7Val 501 "Not used" 502 "Not used" 503 "Not used" 504 "Not used" 505 "Not used" 506 "Not used" 507 "Not used" 508 "Not used" 509 "Not used" 510 "Default" 511 "Error indicator"; -VAL_ 698 IFSref_VehRtAngl7Val 501 "Not used" 502 "Not used" 503 "Not used" 504 "Not used" 505 "Not used" 506 "Not used" 507 "Not used" 508 "Not used" 509 "Not used" 510 "Default" 511 "Error indicator"; -VAL_ 698 IFSref_VehLftAngl8Val 501 "Not used" 502 "Not used" 503 "Not used" 504 "Not used" 505 "Not used" 506 "Not used" 507 "Not used" 508 "Not used" 509 "Not used" 510 "Default" 511 "Error indicator"; -VAL_ 698 IFSref_VehRtAngl8Val 501 "Not used" 502 "Not used" 503 "Not used" 504 "Not used" 505 "Not used" 506 "Not used" 507 "Not used" 508 "Not used" 509 "Not used" 510 "Default" 511 "Error indicator"; -VAL_ 698 IFSref_VehLftAngl9Val 501 "Not used" 502 "Not used" 503 "Not used" 504 "Not used" 505 "Not used" 506 "Not used" 507 "Not used" 508 "Not used" 509 "Not used" 510 "Default" 511 "Error indicator"; -VAL_ 698 IFSref_VehRtAngl9Val 501 "Not used" 502 "Not used" 503 "Not used" 504 "Not used" 505 "Not used" 506 "Not used" 507 "Not used" 508 "Not used" 509 "Not used" 510 "Default" 511 "Error indicator"; -VAL_ 698 IFSref_VehLftAngl10Val 501 "Not used" 502 "Not used" 503 "Not used" 504 "Not used" 505 "Not used" 506 "Not used" 507 "Not used" 508 "Not used" 509 "Not used" 510 "Default" 511 "Error indicator"; -VAL_ 698 IFSref_VehRtAngl10Val 501 "Not used" 502 "Not used" 503 "Not used" 504 "Not used" 505 "Not used" 506 "Not used" 507 "Not used" 508 "Not used" 509 "Not used" 510 "Default" 511 "Error indicator"; -VAL_ 698 IFSref_VehDst2Val 0 "No Value" 1 "1~10m" 2 "11~20m" 3 "21~30m" 4 "31~40m" 5 "41~50m" 6 "51~60m" 7 "61~70m" 8 "71~80m" 9 "81~90m" 10 "91~100m" 11 "101~200m" 12 "201~300m" 13 "301~400m" 14 "401m~" 15 "Error indicator"; -VAL_ 698 IFSref_VehDst3Val 0 "No Value" 1 "1~10m" 2 "11~20m" 3 "21~30m" 4 "31~40m" 5 "41~50m" 6 "51~60m" 7 "61~70m" 8 "71~80m" 9 "81~90m" 10 "91~100m" 11 "101~200m" 12 "201~300m" 13 "301~400m" 14 "401m~" 15 "Error indicator"; -VAL_ 698 IFSref_VehDst4Val 0 "No Value" 1 "1~10m" 2 "11~20m" 3 "21~30m" 4 "31~40m" 5 "41~50m" 6 "51~60m" 7 "61~70m" 8 "71~80m" 9 "81~90m" 10 "91~100m" 11 "101~200m" 12 "201~300m" 13 "301~400m" 14 "401m~" 15 "Error indicator"; -VAL_ 698 IFSref_VehDst5Val 0 "No Value" 1 "1~10m" 2 "11~20m" 3 "21~30m" 4 "31~40m" 5 "41~50m" 6 "51~60m" 7 "61~70m" 8 "71~80m" 9 "81~90m" 10 "91~100m" 11 "101~200m" 12 "201~300m" 13 "301~400m" 14 "401m~" 15 "Error indicator"; -VAL_ 698 IFSref_VehDst6Val 0 "No Value" 1 "1~10m" 2 "11~20m" 3 "21~30m" 4 "31~40m" 5 "41~50m" 6 "51~60m" 7 "61~70m" 8 "71~80m" 9 "81~90m" 10 "91~100m" 11 "101~200m" 12 "201~300m" 13 "301~400m" 14 "401m~" 15 "Error indicator"; -VAL_ 698 IFSref_VehDst7Val 0 "No Value" 1 "1~10m" 2 "11~20m" 3 "21~30m" 4 "31~40m" 5 "41~50m" 6 "51~60m" 7 "61~70m" 8 "71~80m" 9 "81~90m" 10 "91~100m" 11 "101~200m" 12 "201~300m" 13 "301~400m" 14 "401m~" 15 "Error indicator"; -VAL_ 698 IFSref_VehDst8Val 0 "No Value" 1 "1~10m" 2 "11~20m" 3 "21~30m" 4 "31~40m" 5 "41~50m" 6 "51~60m" 7 "61~70m" 8 "71~80m" 9 "81~90m" 10 "91~100m" 11 "101~200m" 12 "201~300m" 13 "301~400m" 14 "401m~" 15 "Error indicator"; -VAL_ 698 IFSref_VehDst9Val 0 "No Value" 1 "1~10m" 2 "11~20m" 3 "21~30m" 4 "31~40m" 5 "41~50m" 6 "51~60m" 7 "61~70m" 8 "71~80m" 9 "81~90m" 10 "91~100m" 11 "101~200m" 12 "201~300m" 13 "301~400m" 14 "401m~" 15 "Error indicator"; -VAL_ 698 IFSref_VehDst10Val 0 "No Value" 1 "1~10m" 2 "11~20m" 3 "21~30m" 4 "31~40m" 5 "41~50m" 6 "51~60m" 7 "61~70m" 8 "71~80m" 9 "81~90m" 10 "91~100m" 11 "101~200m" 12 "201~300m" 13 "301~400m" 14 "401m~" 15 "Error indicator"; +VAL_ 480 HDA_OptUsmSta 0 "Not Applied" 1 "Function Off" 2 "Function On" 3 "Reserved" 4 "Reserved" 5 "Reserved" 6 "Reserved" 7 "Invalid (Fail)"; +VAL_ 480 LFA_OptUsmSta 0 "Not Applied" 1 "Function Off" 2 "Function On" 3 "Reserved" 4 "Reserved" 5 "Reserved" 6 "Reserved" 7 "Invalid (Fail)"; +VAL_ 480 HDA_CntrlModSta 0 "System Deactive (Default)" 1 "System Ready" 2 "System Active" 3 "Reserved"; +VAL_ 480 HDA_InfoPUDis 0 "No pop-up" 1 "system start pop-up" 2 "system auto disengaged pop-up by highway off" 3 "system auto disengaged pop-up" 4 "system Fail pop-up" 5 "Hands-off pop up" 6 "Hands-off pop up w/ sound" 7 "System Automatic off"; +VAL_ 480 HDA_AutoSetSpdSta 0 "Auto Set Speed Off" 1 "Auto Set Speed On" 2 "Reserved" 3 "Error indicator"; +VAL_ 480 HDA_AutoSetSpdUpdtSta 0 "Auto Set Speed Update Off" 1 "Auto Set Speed Update On" 2 "Reserved" 3 "Error indicator"; +VAL_ 480 HDA_LFA_SymSta 0 "Off" 1 "Gray" 2 "Green" 3 "Green blink"; +VAL_ 480 HDA_LFA_WrnSnd 0 "Off" 1 "Additional Warning Sound" 2 "Reserved" 3 "Error indicator"; +VAL_ 480 HDA_InfoPUDis1 0 "No Pop-up" 1 "System Automatic off (LFA)" 2 "System Automatic off (HDA)" 3 "Reserved" 4 "Reserved" 5 "Reserved" 6 "Not Used" 7 "Error Indicator"; +VAL_ 480 HDA_TDMRMDclReq 0 "Not automatically deactivated state of LFA (default)" 1 "Automatically deactivated state of LFA" 2 "Reserved" 3 "Reserved"; +VAL_ 490 HDA_MODE2 1 "Lane change icon gray" 2 "lane green + lane change icon green" 3 "lane green + lane change icon green (both blinking)" 4 "lane white + lane change icon white (both blinking rapidly)" 5 "Lane Change Assist system check warning"; +VAL_ 490 LANE_LEFT 0 "IDLE" 1 "ON_SOURCE" 2 "ON_TARGET"; +VAL_ 490 LANE_RIGHT 0 "IDLE" 1 "ON_SOURCE" 2 "ON_TARGET"; +VAL_ 490 LANE_CHANGING 0 "IDLE" 1 "LEFT_CHECK" 3 "LEFT_CHANGING" 2 "RIGHT_CHECK" 4 "RIGHT_CHANGING"; +VAL_ 490 LF_DETECT 0 "none" 1 "gray" 2 "white" 3 "white" 4 "hide"; +VAL_ 490 RF_DETECT 0 "none" 1 "gray" 2 "white" 3 "white" 4 "hide"; +VAL_ 490 LR_DETECT 0 "none" 1 "gray" 2 "white" 3 "white" 4 "hide"; +VAL_ 490 RR_DETECT 0 "none" 1 "gray" 2 "white" 3 "white" 4 "hide"; +VAL_ 490 AUTOLANECHANGE_MSG 1 "Check surrounding conditions" 2 "Operating conditions not met" 3 "Analyzing driving lane" 4 "Sharp curve ahead" 5 "Current lane is too narrow" 6 "Not an operational section" 7 "Hazard lights are on" 8 "Vehicle speed is too low" 9 "Please hold the steering wheel" 10 "Not an operable lane" 11 "Steering input detected" 12 "Press the OK button to activate lane change assist"; +VAL_ 490 LANELINE_CURVATURE_DIRECTION 0 "LEFT" 1 "RIGHT"; +VAL_ 676 LEFT_LANE_COLOR 0 "Not Detected" 1 "White" 2 "Yellow" 3 "Blue"; +VAL_ 676 RIGHT_LANE_COLOR 0 "Not Detected" 1 "White" 2 "Yellow" 3 "Blue"; +VAL_ 676 LEFT_LANE_LINE 0 "Not Detected" 1 "Low Confidence" 2 "Medium Confidence" 3 "High Confidence"; +VAL_ 676 RIGHT_LANE_LINE 0 "Not Detected" 1 "Low Confidence" 2 "Medium Confidence" 3 "High Confidence"; VAL_ 736 MSLA_STATUS 0 "disabled" 1 "active" 2 "paused"; +VAL_ 866 LEFT_LANE_COLOR 0 "Not Detected" 1 "White" 2 "Yellow" 3 "Blue"; +VAL_ 866 RIGHT_LANE_COLOR 0 "Not Detected" 1 "White" 2 "Yellow" 3 "Blue"; VAL_ 866 LEFT_LANE_LINE 0 "Not Detected" 1 "Low Confidence" 2 "Medium Confidence" 3 "High Confidence"; VAL_ 866 RIGHT_LANE_LINE 0 "Not Detected" 1 "Low Confidence" 2 "Medium Confidence" 3 "High Confidence"; VAL_ 1041 DRIVER_DOOR 0 "Closed" 1 "Opened"; @@ -985,5 +1101,7 @@ VAL_ 1041 PASSENGER_SEATBELT 0 "Unlatched" 1 "Latched"; VAL_ 1041 DRIVER_SEATBELT 0 "Unlatched" 1 "Latched"; VAL_ 1041 DRIVER_REAR_DOOR 0 "Closed" 1 "Opened"; VAL_ 1041 PASSENGER_REAR_DOOR 0 "Closed" 1 "Opened"; +VAL_ 1079 TRAILER_CONNECTED 1 "CONNECTED" 0 "DISCONNECTED"; + VAL_ 1144 DRIVE_MODE2 3 "Set Sport" 1 "Set Normal" 2 "Set Eco"; VAL_ 1240 DISTANCE_UNIT 1 "Miles" 0 "Kilometers"; diff --git a/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_corner_radar_180.dbc b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_corner_radar_180.dbc new file mode 100644 index 0000000..a78803a --- /dev/null +++ b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_corner_radar_180.dbc @@ -0,0 +1,140 @@ +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + ENVVAR_TYPE_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX RADAR + +BA_DEF_ BO_ "GenMsgCycleTime" INT 0 100000; +BA_DEF_DEF_ "GenMsgCycleTime" 0; + +BO_ 384 CORNER_RADAR_180_OBJECTS_180: 32 RADAR + SG_ SLOT1_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ SLOT1_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ SLOT1_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ SLOT1_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ SLOT1_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ SLOT1_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ SLOT1_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX + SG_ SLOT2_QUAL_LEVEL : 152|7@1+ (1,0) [0|100] "%" XXX + SG_ SLOT2_AGE : 160|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_OBJECT_ID : 172|7@1+ (1,0) [0|127] "" XXX + SG_ SLOT2_REL_POS_X : 192|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ SLOT2_REL_POS_Y : 206|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ SLOT2_REL_VEL_X : 219|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ SLOT2_REL_VEL_Y : 232|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ SLOT2_REL_ACCEL_X : 243|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 384 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 384 30; + +BO_ 385 CORNER_RADAR_180_OBJECTS_181: 32 RADAR + SG_ SLOT1_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ SLOT1_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ SLOT1_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ SLOT1_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ SLOT1_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ SLOT1_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ SLOT1_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX + SG_ SLOT2_QUAL_LEVEL : 152|7@1+ (1,0) [0|100] "%" XXX + SG_ SLOT2_AGE : 160|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_OBJECT_ID : 172|7@1+ (1,0) [0|127] "" XXX + SG_ SLOT2_REL_POS_X : 192|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ SLOT2_REL_POS_Y : 206|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ SLOT2_REL_VEL_X : 219|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ SLOT2_REL_VEL_Y : 232|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ SLOT2_REL_ACCEL_X : 243|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 385 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 385 30; + +BO_ 386 CORNER_RADAR_180_OBJECTS_182: 32 RADAR + SG_ SLOT1_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ SLOT1_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ SLOT1_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ SLOT1_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ SLOT1_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ SLOT1_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ SLOT1_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX + SG_ SLOT2_QUAL_LEVEL : 152|7@1+ (1,0) [0|100] "%" XXX + SG_ SLOT2_AGE : 160|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_OBJECT_ID : 172|7@1+ (1,0) [0|127] "" XXX + SG_ SLOT2_REL_POS_X : 192|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ SLOT2_REL_POS_Y : 206|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ SLOT2_REL_VEL_X : 219|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ SLOT2_REL_VEL_Y : 232|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ SLOT2_REL_ACCEL_X : 243|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 386 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 386 30; + +BO_ 387 CORNER_RADAR_180_OBJECTS_183: 32 RADAR + SG_ SLOT1_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ SLOT1_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ SLOT1_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ SLOT1_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ SLOT1_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ SLOT1_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ SLOT1_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX + SG_ SLOT2_QUAL_LEVEL : 152|7@1+ (1,0) [0|100] "%" XXX + SG_ SLOT2_AGE : 160|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_OBJECT_ID : 172|7@1+ (1,0) [0|127] "" XXX + SG_ SLOT2_REL_POS_X : 192|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ SLOT2_REL_POS_Y : 206|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ SLOT2_REL_VEL_X : 219|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ SLOT2_REL_VEL_Y : 232|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ SLOT2_REL_ACCEL_X : 243|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 387 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 387 30; + +BO_ 388 CORNER_RADAR_180_OBJECTS_184: 32 RADAR + SG_ SLOT1_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ SLOT1_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ SLOT1_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ SLOT1_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ SLOT1_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ SLOT1_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ SLOT1_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX + SG_ SLOT2_QUAL_LEVEL : 152|7@1+ (1,0) [0|100] "%" XXX + SG_ SLOT2_AGE : 160|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_OBJECT_ID : 172|7@1+ (1,0) [0|127] "" XXX + SG_ SLOT2_REL_POS_X : 192|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ SLOT2_REL_POS_Y : 206|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ SLOT2_REL_VEL_X : 219|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ SLOT2_REL_VEL_Y : 232|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ SLOT2_REL_ACCEL_X : 243|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 388 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 388 30; diff --git a/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_corner_radar_180.py b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_corner_radar_180.py new file mode 100755 index 0000000..d7bf650 --- /dev/null +++ b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_corner_radar_180.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 +import os + + +HEADER = """VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + ENVVAR_TYPE_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX RADAR + +""" + + +def write_object_msg(f, addr): + name = f"CORNER_RADAR_180_OBJECTS_{addr:x}" + f.write(f""" +BO_ {addr} {name}: 32 RADAR + SG_ SLOT1_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ SLOT1_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ SLOT1_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ SLOT1_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ SLOT1_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ SLOT1_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ SLOT1_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX + SG_ SLOT2_QUAL_LEVEL : 152|7@1+ (1,0) [0|100] "%" XXX + SG_ SLOT2_AGE : 160|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_OBJECT_ID : 172|7@1+ (1,0) [0|127] "" XXX + SG_ SLOT2_REL_POS_X : 192|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ SLOT2_REL_POS_Y : 206|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ SLOT2_REL_VEL_X : 219|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ SLOT2_REL_VEL_Y : 232|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ SLOT2_REL_ACCEL_X : 243|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +""") + + f.write(f"""CM_ BO_ {addr} "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ {addr} 30; +""") + + +if __name__ == "__main__": + dbc_name = os.path.basename(__file__).replace(".py", ".dbc") + out_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), dbc_name) + with open(out_path, "w", encoding="ascii") as f: + f.write(HEADER) + f.write('BA_DEF_ BO_ "GenMsgCycleTime" INT 0 100000;\n') + f.write('BA_DEF_DEF_ "GenMsgCycleTime" 0;\n') + for addr in range(0x180, 0x185): + write_object_msg(f, addr) diff --git a/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_corner_radar_235.dbc b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_corner_radar_235.dbc new file mode 100644 index 0000000..f622a76 --- /dev/null +++ b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_corner_radar_235.dbc @@ -0,0 +1,278 @@ +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX RADAR + +BA_DEF_ BO_ "GenMsgCycleTime" INT 0 100000; +BA_DEF_DEF_ "GenMsgCycleTime" 0; + +BO_ 565 CORNER_RADAR_235_OBJECTS_235: 32 RADAR + SG_ OBJ_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ OBJ_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ OBJ_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ OBJ_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ OBJ_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ OBJ_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ OBJ_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ OBJ_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 565 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 565 30; + +BO_ 566 CORNER_RADAR_235_OBJECTS_236: 32 RADAR + SG_ OBJ_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ OBJ_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ OBJ_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ OBJ_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ OBJ_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ OBJ_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ OBJ_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ OBJ_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 566 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 566 30; + +BO_ 567 CORNER_RADAR_235_OBJECTS_237: 32 RADAR + SG_ OBJ_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ OBJ_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ OBJ_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ OBJ_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ OBJ_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ OBJ_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ OBJ_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ OBJ_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 567 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 567 30; + +BO_ 568 CORNER_RADAR_235_OBJECTS_238: 32 RADAR + SG_ OBJ_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ OBJ_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ OBJ_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ OBJ_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ OBJ_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ OBJ_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ OBJ_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ OBJ_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 568 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 568 30; + +BO_ 569 CORNER_RADAR_235_OBJECTS_239: 32 RADAR + SG_ OBJ_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ OBJ_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ OBJ_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ OBJ_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ OBJ_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ OBJ_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ OBJ_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ OBJ_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 569 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 569 30; + +BO_ 570 CORNER_RADAR_235_OBJECTS_23a: 32 RADAR + SG_ OBJ_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ OBJ_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ OBJ_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ OBJ_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ OBJ_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ OBJ_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ OBJ_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ OBJ_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 570 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 570 30; + +BO_ 571 CORNER_RADAR_235_OBJECTS_23b: 32 RADAR + SG_ OBJ_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ OBJ_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ OBJ_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ OBJ_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ OBJ_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ OBJ_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ OBJ_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ OBJ_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 571 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 571 30; + +BO_ 572 CORNER_RADAR_235_OBJECTS_23c: 32 RADAR + SG_ OBJ_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ OBJ_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ OBJ_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ OBJ_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ OBJ_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ OBJ_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ OBJ_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ OBJ_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 572 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 572 30; + +BO_ 573 CORNER_RADAR_235_OBJECTS_23d: 32 RADAR + SG_ OBJ_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ OBJ_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ OBJ_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ OBJ_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ OBJ_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ OBJ_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ OBJ_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ OBJ_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 573 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 573 30; + +BO_ 574 CORNER_RADAR_235_OBJECTS_23e: 32 RADAR + SG_ OBJ_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ OBJ_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ OBJ_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ OBJ_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ OBJ_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ OBJ_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ OBJ_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ OBJ_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 574 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 574 30; + +BO_ 575 CORNER_RADAR_235_OBJECTS_23f: 32 RADAR + SG_ OBJ_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ OBJ_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ OBJ_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ OBJ_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ OBJ_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ OBJ_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ OBJ_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ OBJ_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 575 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 575 30; + +BO_ 576 CORNER_RADAR_235_OBJECTS_240: 32 RADAR + SG_ OBJ_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ OBJ_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ OBJ_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ OBJ_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ OBJ_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ OBJ_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ OBJ_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ OBJ_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 576 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 576 30; + +BO_ 577 CORNER_RADAR_235_OBJECTS_241: 32 RADAR + SG_ OBJ_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ OBJ_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ OBJ_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ OBJ_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ OBJ_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ OBJ_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ OBJ_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ OBJ_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 577 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 577 30; + +BO_ 578 CORNER_RADAR_235_OBJECTS_242: 32 RADAR + SG_ OBJ_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ OBJ_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ OBJ_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ OBJ_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ OBJ_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ OBJ_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ OBJ_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ OBJ_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 578 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 578 30; + +BO_ 579 CORNER_RADAR_235_OBJECTS_243: 32 RADAR + SG_ OBJ_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ OBJ_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ OBJ_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ OBJ_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ OBJ_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ OBJ_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ OBJ_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ OBJ_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 579 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 579 30; + +BO_ 580 CORNER_RADAR_235_OBJECTS_244: 32 RADAR + SG_ OBJ_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ OBJ_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ OBJ_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ OBJ_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ OBJ_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ OBJ_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ OBJ_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ OBJ_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 580 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 580 30; + +BO_ 581 CORNER_RADAR_235_OBJECTS_245: 32 RADAR + SG_ OBJ_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ OBJ_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ OBJ_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ OBJ_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ OBJ_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ OBJ_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ OBJ_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ OBJ_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 581 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 581 30; + +BO_ 582 CORNER_RADAR_235_OBJECTS_246: 32 RADAR + SG_ OBJ_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ OBJ_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ OBJ_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ OBJ_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ OBJ_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ OBJ_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ OBJ_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ OBJ_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 582 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 582 30; + +BO_ 583 CORNER_RADAR_235_OBJECTS_247: 32 RADAR + SG_ OBJ_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ OBJ_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ OBJ_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ OBJ_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ OBJ_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ OBJ_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ OBJ_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ OBJ_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 583 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 583 30; + +BO_ 584 CORNER_RADAR_235_OBJECTS_248: 32 RADAR + SG_ OBJ_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ OBJ_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ OBJ_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ OBJ_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ OBJ_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ OBJ_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ OBJ_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ OBJ_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +CM_ BO_ 584 "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ 584 30; diff --git a/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_corner_radar_235.py b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_corner_radar_235.py new file mode 100755 index 0000000..6092d0d --- /dev/null +++ b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_corner_radar_235.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 +import os + + +HEADER = """VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX RADAR + +""" + + +def write_object_msg(f, addr): + name = f"CORNER_RADAR_235_OBJECTS_{addr:x}" + f.write(f""" +BO_ {addr} {name}: 32 RADAR + SG_ OBJ_QUAL_LEVEL : 24|7@1+ (1,0) [0|100] "%" XXX + SG_ OBJ_AGE : 32|8@1+ (1,0) [0|255] "" XXX + SG_ OBJ_OBJECT_ID : 44|7@1+ (1,0) [0|127] "" XXX + SG_ OBJ_REL_POS_X : 64|13@1+ (0.05,0) [0|409.55] "m" XXX + SG_ OBJ_REL_POS_Y : 78|12@1+ (0.05,-102.4) [-102.4|102.35] "m" XXX + SG_ OBJ_REL_VEL_X : 91|12@1+ (0.05,-100) [-100|104.75] "m/s" XXX + SG_ OBJ_REL_VEL_Y : 104|10@1+ (0.05,-25) [-25|26.15] "m/s" XXX + SG_ OBJ_REL_ACCEL_X : 115|9@1- (0.05,0) [-12.8|12.75] "m/s^2" XXX +""") + + f.write(f"""CM_ BO_ {addr} "Corner radar object payload on bus 1. Only signals consumed by Hyundai radar_interface are defined."; +BA_ "GenMsgCycleTime" BO_ {addr} 30; +""") + + +if __name__ == "__main__": + dbc_name = os.path.basename(__file__).replace(".py", ".dbc") + out_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), dbc_name) + with open(out_path, "w", encoding="ascii") as f: + f.write(HEADER) + f.write('BA_DEF_ BO_ "GenMsgCycleTime" INT 0 100000;\n') + f.write('BA_DEF_DEF_ "GenMsgCycleTime" 0;\n') + for addr in range(0x235, 0x249): + write_object_msg(f, addr) diff --git a/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_corner_radar_430.dbc b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_corner_radar_430.dbc new file mode 100644 index 0000000..528b741 --- /dev/null +++ b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_corner_radar_430.dbc @@ -0,0 +1,614 @@ +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX RADAR + +BA_DEF_ BO_ "GenMsgCycleTime" INT 0 100000; +BA_DEF_DEF_ "GenMsgCycleTime" 0; + +BO_ 1072 CORNER_RADAR_430_OBJECTS_430: 32 RADAR + SG_ HEADER_BYTE_0 : 0|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_1 : 8|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_2 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_3 : 24|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_DISTANCE_RAW : 32|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT1_META_13_15 : 45|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT1_META_BYTE_2 : 48|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_META_BYTE_3 : 56|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_DISTANCE_RAW : 64|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT2_META_13_15 : 77|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT2_META_BYTE_2 : 80|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_META_BYTE_3 : 88|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_DISTANCE_RAW : 96|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT3_META_13_15 : 109|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT3_META_BYTE_2 : 112|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_META_BYTE_3 : 120|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_DISTANCE_RAW : 128|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT4_META_13_15 : 141|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT4_META_BYTE_2 : 144|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_META_BYTE_3 : 152|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_DISTANCE_RAW : 160|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT5_META_13_15 : 173|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT5_META_BYTE_2 : 176|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_META_BYTE_3 : 184|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_DISTANCE_RAW : 192|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT6_META_13_15 : 205|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT6_META_BYTE_2 : 208|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_META_BYTE_3 : 216|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_DISTANCE_RAW : 224|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT7_META_13_15 : 237|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT7_META_BYTE_2 : 240|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_META_BYTE_3 : 248|8@1+ (1,0) [0|255] "" XXX +CM_ BO_ 1072 "IONIQ 9 candidate corner radar bin container. 0x430-0x437 correlate with left side and 0x440-0x447 with right side. Bytes 4-31 appear as seven 4-byte slots; lower 13 bits are a distance candidate at 0.05 m scale. This DBC intentionally exposes only raw candidate fields until lateral and velocity fields are validated."; +BA_ "GenMsgCycleTime" BO_ 1072 30; + +BO_ 1073 CORNER_RADAR_430_OBJECTS_431: 32 RADAR + SG_ HEADER_BYTE_0 : 0|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_1 : 8|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_2 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_3 : 24|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_DISTANCE_RAW : 32|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT1_META_13_15 : 45|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT1_META_BYTE_2 : 48|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_META_BYTE_3 : 56|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_DISTANCE_RAW : 64|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT2_META_13_15 : 77|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT2_META_BYTE_2 : 80|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_META_BYTE_3 : 88|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_DISTANCE_RAW : 96|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT3_META_13_15 : 109|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT3_META_BYTE_2 : 112|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_META_BYTE_3 : 120|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_DISTANCE_RAW : 128|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT4_META_13_15 : 141|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT4_META_BYTE_2 : 144|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_META_BYTE_3 : 152|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_DISTANCE_RAW : 160|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT5_META_13_15 : 173|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT5_META_BYTE_2 : 176|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_META_BYTE_3 : 184|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_DISTANCE_RAW : 192|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT6_META_13_15 : 205|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT6_META_BYTE_2 : 208|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_META_BYTE_3 : 216|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_DISTANCE_RAW : 224|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT7_META_13_15 : 237|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT7_META_BYTE_2 : 240|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_META_BYTE_3 : 248|8@1+ (1,0) [0|255] "" XXX +CM_ BO_ 1073 "IONIQ 9 candidate corner radar bin container. 0x430-0x437 correlate with left side and 0x440-0x447 with right side. Bytes 4-31 appear as seven 4-byte slots; lower 13 bits are a distance candidate at 0.05 m scale. This DBC intentionally exposes only raw candidate fields until lateral and velocity fields are validated."; +BA_ "GenMsgCycleTime" BO_ 1073 30; + +BO_ 1074 CORNER_RADAR_430_OBJECTS_432: 32 RADAR + SG_ HEADER_BYTE_0 : 0|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_1 : 8|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_2 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_3 : 24|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_DISTANCE_RAW : 32|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT1_META_13_15 : 45|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT1_META_BYTE_2 : 48|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_META_BYTE_3 : 56|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_DISTANCE_RAW : 64|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT2_META_13_15 : 77|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT2_META_BYTE_2 : 80|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_META_BYTE_3 : 88|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_DISTANCE_RAW : 96|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT3_META_13_15 : 109|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT3_META_BYTE_2 : 112|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_META_BYTE_3 : 120|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_DISTANCE_RAW : 128|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT4_META_13_15 : 141|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT4_META_BYTE_2 : 144|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_META_BYTE_3 : 152|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_DISTANCE_RAW : 160|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT5_META_13_15 : 173|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT5_META_BYTE_2 : 176|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_META_BYTE_3 : 184|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_DISTANCE_RAW : 192|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT6_META_13_15 : 205|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT6_META_BYTE_2 : 208|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_META_BYTE_3 : 216|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_DISTANCE_RAW : 224|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT7_META_13_15 : 237|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT7_META_BYTE_2 : 240|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_META_BYTE_3 : 248|8@1+ (1,0) [0|255] "" XXX +CM_ BO_ 1074 "IONIQ 9 candidate corner radar bin container. 0x430-0x437 correlate with left side and 0x440-0x447 with right side. Bytes 4-31 appear as seven 4-byte slots; lower 13 bits are a distance candidate at 0.05 m scale. This DBC intentionally exposes only raw candidate fields until lateral and velocity fields are validated."; +BA_ "GenMsgCycleTime" BO_ 1074 30; + +BO_ 1075 CORNER_RADAR_430_OBJECTS_433: 32 RADAR + SG_ HEADER_BYTE_0 : 0|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_1 : 8|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_2 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_3 : 24|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_DISTANCE_RAW : 32|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT1_META_13_15 : 45|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT1_META_BYTE_2 : 48|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_META_BYTE_3 : 56|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_DISTANCE_RAW : 64|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT2_META_13_15 : 77|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT2_META_BYTE_2 : 80|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_META_BYTE_3 : 88|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_DISTANCE_RAW : 96|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT3_META_13_15 : 109|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT3_META_BYTE_2 : 112|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_META_BYTE_3 : 120|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_DISTANCE_RAW : 128|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT4_META_13_15 : 141|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT4_META_BYTE_2 : 144|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_META_BYTE_3 : 152|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_DISTANCE_RAW : 160|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT5_META_13_15 : 173|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT5_META_BYTE_2 : 176|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_META_BYTE_3 : 184|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_DISTANCE_RAW : 192|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT6_META_13_15 : 205|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT6_META_BYTE_2 : 208|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_META_BYTE_3 : 216|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_DISTANCE_RAW : 224|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT7_META_13_15 : 237|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT7_META_BYTE_2 : 240|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_META_BYTE_3 : 248|8@1+ (1,0) [0|255] "" XXX +CM_ BO_ 1075 "IONIQ 9 candidate corner radar bin container. 0x430-0x437 correlate with left side and 0x440-0x447 with right side. Bytes 4-31 appear as seven 4-byte slots; lower 13 bits are a distance candidate at 0.05 m scale. This DBC intentionally exposes only raw candidate fields until lateral and velocity fields are validated."; +BA_ "GenMsgCycleTime" BO_ 1075 30; + +BO_ 1076 CORNER_RADAR_430_OBJECTS_434: 32 RADAR + SG_ HEADER_BYTE_0 : 0|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_1 : 8|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_2 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_3 : 24|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_DISTANCE_RAW : 32|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT1_META_13_15 : 45|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT1_META_BYTE_2 : 48|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_META_BYTE_3 : 56|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_DISTANCE_RAW : 64|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT2_META_13_15 : 77|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT2_META_BYTE_2 : 80|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_META_BYTE_3 : 88|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_DISTANCE_RAW : 96|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT3_META_13_15 : 109|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT3_META_BYTE_2 : 112|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_META_BYTE_3 : 120|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_DISTANCE_RAW : 128|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT4_META_13_15 : 141|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT4_META_BYTE_2 : 144|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_META_BYTE_3 : 152|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_DISTANCE_RAW : 160|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT5_META_13_15 : 173|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT5_META_BYTE_2 : 176|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_META_BYTE_3 : 184|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_DISTANCE_RAW : 192|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT6_META_13_15 : 205|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT6_META_BYTE_2 : 208|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_META_BYTE_3 : 216|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_DISTANCE_RAW : 224|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT7_META_13_15 : 237|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT7_META_BYTE_2 : 240|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_META_BYTE_3 : 248|8@1+ (1,0) [0|255] "" XXX +CM_ BO_ 1076 "IONIQ 9 candidate corner radar bin container. 0x430-0x437 correlate with left side and 0x440-0x447 with right side. Bytes 4-31 appear as seven 4-byte slots; lower 13 bits are a distance candidate at 0.05 m scale. This DBC intentionally exposes only raw candidate fields until lateral and velocity fields are validated."; +BA_ "GenMsgCycleTime" BO_ 1076 30; + +BO_ 1077 CORNER_RADAR_430_OBJECTS_435: 32 RADAR + SG_ HEADER_BYTE_0 : 0|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_1 : 8|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_2 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_3 : 24|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_DISTANCE_RAW : 32|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT1_META_13_15 : 45|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT1_META_BYTE_2 : 48|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_META_BYTE_3 : 56|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_DISTANCE_RAW : 64|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT2_META_13_15 : 77|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT2_META_BYTE_2 : 80|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_META_BYTE_3 : 88|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_DISTANCE_RAW : 96|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT3_META_13_15 : 109|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT3_META_BYTE_2 : 112|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_META_BYTE_3 : 120|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_DISTANCE_RAW : 128|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT4_META_13_15 : 141|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT4_META_BYTE_2 : 144|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_META_BYTE_3 : 152|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_DISTANCE_RAW : 160|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT5_META_13_15 : 173|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT5_META_BYTE_2 : 176|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_META_BYTE_3 : 184|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_DISTANCE_RAW : 192|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT6_META_13_15 : 205|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT6_META_BYTE_2 : 208|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_META_BYTE_3 : 216|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_DISTANCE_RAW : 224|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT7_META_13_15 : 237|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT7_META_BYTE_2 : 240|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_META_BYTE_3 : 248|8@1+ (1,0) [0|255] "" XXX +CM_ BO_ 1077 "IONIQ 9 candidate corner radar bin container. 0x430-0x437 correlate with left side and 0x440-0x447 with right side. Bytes 4-31 appear as seven 4-byte slots; lower 13 bits are a distance candidate at 0.05 m scale. This DBC intentionally exposes only raw candidate fields until lateral and velocity fields are validated."; +BA_ "GenMsgCycleTime" BO_ 1077 30; + +BO_ 1078 CORNER_RADAR_430_OBJECTS_436: 32 RADAR + SG_ HEADER_BYTE_0 : 0|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_1 : 8|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_2 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_3 : 24|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_DISTANCE_RAW : 32|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT1_META_13_15 : 45|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT1_META_BYTE_2 : 48|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_META_BYTE_3 : 56|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_DISTANCE_RAW : 64|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT2_META_13_15 : 77|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT2_META_BYTE_2 : 80|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_META_BYTE_3 : 88|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_DISTANCE_RAW : 96|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT3_META_13_15 : 109|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT3_META_BYTE_2 : 112|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_META_BYTE_3 : 120|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_DISTANCE_RAW : 128|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT4_META_13_15 : 141|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT4_META_BYTE_2 : 144|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_META_BYTE_3 : 152|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_DISTANCE_RAW : 160|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT5_META_13_15 : 173|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT5_META_BYTE_2 : 176|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_META_BYTE_3 : 184|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_DISTANCE_RAW : 192|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT6_META_13_15 : 205|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT6_META_BYTE_2 : 208|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_META_BYTE_3 : 216|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_DISTANCE_RAW : 224|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT7_META_13_15 : 237|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT7_META_BYTE_2 : 240|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_META_BYTE_3 : 248|8@1+ (1,0) [0|255] "" XXX +CM_ BO_ 1078 "IONIQ 9 candidate corner radar bin container. 0x430-0x437 correlate with left side and 0x440-0x447 with right side. Bytes 4-31 appear as seven 4-byte slots; lower 13 bits are a distance candidate at 0.05 m scale. This DBC intentionally exposes only raw candidate fields until lateral and velocity fields are validated."; +BA_ "GenMsgCycleTime" BO_ 1078 30; + +BO_ 1079 CORNER_RADAR_430_OBJECTS_437: 32 RADAR + SG_ HEADER_BYTE_0 : 0|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_1 : 8|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_2 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_3 : 24|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_DISTANCE_RAW : 32|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT1_META_13_15 : 45|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT1_META_BYTE_2 : 48|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_META_BYTE_3 : 56|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_DISTANCE_RAW : 64|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT2_META_13_15 : 77|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT2_META_BYTE_2 : 80|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_META_BYTE_3 : 88|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_DISTANCE_RAW : 96|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT3_META_13_15 : 109|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT3_META_BYTE_2 : 112|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_META_BYTE_3 : 120|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_DISTANCE_RAW : 128|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT4_META_13_15 : 141|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT4_META_BYTE_2 : 144|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_META_BYTE_3 : 152|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_DISTANCE_RAW : 160|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT5_META_13_15 : 173|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT5_META_BYTE_2 : 176|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_META_BYTE_3 : 184|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_DISTANCE_RAW : 192|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT6_META_13_15 : 205|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT6_META_BYTE_2 : 208|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_META_BYTE_3 : 216|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_DISTANCE_RAW : 224|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT7_META_13_15 : 237|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT7_META_BYTE_2 : 240|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_META_BYTE_3 : 248|8@1+ (1,0) [0|255] "" XXX +CM_ BO_ 1079 "IONIQ 9 candidate corner radar bin container. 0x430-0x437 correlate with left side and 0x440-0x447 with right side. Bytes 4-31 appear as seven 4-byte slots; lower 13 bits are a distance candidate at 0.05 m scale. This DBC intentionally exposes only raw candidate fields until lateral and velocity fields are validated."; +BA_ "GenMsgCycleTime" BO_ 1079 30; + +BO_ 1088 CORNER_RADAR_430_OBJECTS_440: 32 RADAR + SG_ HEADER_BYTE_0 : 0|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_1 : 8|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_2 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_3 : 24|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_DISTANCE_RAW : 32|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT1_META_13_15 : 45|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT1_META_BYTE_2 : 48|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_META_BYTE_3 : 56|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_DISTANCE_RAW : 64|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT2_META_13_15 : 77|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT2_META_BYTE_2 : 80|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_META_BYTE_3 : 88|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_DISTANCE_RAW : 96|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT3_META_13_15 : 109|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT3_META_BYTE_2 : 112|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_META_BYTE_3 : 120|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_DISTANCE_RAW : 128|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT4_META_13_15 : 141|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT4_META_BYTE_2 : 144|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_META_BYTE_3 : 152|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_DISTANCE_RAW : 160|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT5_META_13_15 : 173|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT5_META_BYTE_2 : 176|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_META_BYTE_3 : 184|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_DISTANCE_RAW : 192|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT6_META_13_15 : 205|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT6_META_BYTE_2 : 208|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_META_BYTE_3 : 216|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_DISTANCE_RAW : 224|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT7_META_13_15 : 237|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT7_META_BYTE_2 : 240|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_META_BYTE_3 : 248|8@1+ (1,0) [0|255] "" XXX +CM_ BO_ 1088 "IONIQ 9 candidate corner radar bin container. 0x430-0x437 correlate with left side and 0x440-0x447 with right side. Bytes 4-31 appear as seven 4-byte slots; lower 13 bits are a distance candidate at 0.05 m scale. This DBC intentionally exposes only raw candidate fields until lateral and velocity fields are validated."; +BA_ "GenMsgCycleTime" BO_ 1088 30; + +BO_ 1089 CORNER_RADAR_430_OBJECTS_441: 32 RADAR + SG_ HEADER_BYTE_0 : 0|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_1 : 8|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_2 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_3 : 24|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_DISTANCE_RAW : 32|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT1_META_13_15 : 45|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT1_META_BYTE_2 : 48|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_META_BYTE_3 : 56|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_DISTANCE_RAW : 64|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT2_META_13_15 : 77|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT2_META_BYTE_2 : 80|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_META_BYTE_3 : 88|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_DISTANCE_RAW : 96|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT3_META_13_15 : 109|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT3_META_BYTE_2 : 112|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_META_BYTE_3 : 120|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_DISTANCE_RAW : 128|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT4_META_13_15 : 141|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT4_META_BYTE_2 : 144|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_META_BYTE_3 : 152|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_DISTANCE_RAW : 160|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT5_META_13_15 : 173|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT5_META_BYTE_2 : 176|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_META_BYTE_3 : 184|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_DISTANCE_RAW : 192|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT6_META_13_15 : 205|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT6_META_BYTE_2 : 208|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_META_BYTE_3 : 216|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_DISTANCE_RAW : 224|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT7_META_13_15 : 237|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT7_META_BYTE_2 : 240|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_META_BYTE_3 : 248|8@1+ (1,0) [0|255] "" XXX +CM_ BO_ 1089 "IONIQ 9 candidate corner radar bin container. 0x430-0x437 correlate with left side and 0x440-0x447 with right side. Bytes 4-31 appear as seven 4-byte slots; lower 13 bits are a distance candidate at 0.05 m scale. This DBC intentionally exposes only raw candidate fields until lateral and velocity fields are validated."; +BA_ "GenMsgCycleTime" BO_ 1089 30; + +BO_ 1090 CORNER_RADAR_430_OBJECTS_442: 32 RADAR + SG_ HEADER_BYTE_0 : 0|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_1 : 8|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_2 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_3 : 24|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_DISTANCE_RAW : 32|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT1_META_13_15 : 45|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT1_META_BYTE_2 : 48|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_META_BYTE_3 : 56|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_DISTANCE_RAW : 64|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT2_META_13_15 : 77|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT2_META_BYTE_2 : 80|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_META_BYTE_3 : 88|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_DISTANCE_RAW : 96|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT3_META_13_15 : 109|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT3_META_BYTE_2 : 112|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_META_BYTE_3 : 120|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_DISTANCE_RAW : 128|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT4_META_13_15 : 141|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT4_META_BYTE_2 : 144|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_META_BYTE_3 : 152|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_DISTANCE_RAW : 160|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT5_META_13_15 : 173|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT5_META_BYTE_2 : 176|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_META_BYTE_3 : 184|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_DISTANCE_RAW : 192|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT6_META_13_15 : 205|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT6_META_BYTE_2 : 208|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_META_BYTE_3 : 216|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_DISTANCE_RAW : 224|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT7_META_13_15 : 237|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT7_META_BYTE_2 : 240|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_META_BYTE_3 : 248|8@1+ (1,0) [0|255] "" XXX +CM_ BO_ 1090 "IONIQ 9 candidate corner radar bin container. 0x430-0x437 correlate with left side and 0x440-0x447 with right side. Bytes 4-31 appear as seven 4-byte slots; lower 13 bits are a distance candidate at 0.05 m scale. This DBC intentionally exposes only raw candidate fields until lateral and velocity fields are validated."; +BA_ "GenMsgCycleTime" BO_ 1090 30; + +BO_ 1091 CORNER_RADAR_430_OBJECTS_443: 32 RADAR + SG_ HEADER_BYTE_0 : 0|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_1 : 8|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_2 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_3 : 24|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_DISTANCE_RAW : 32|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT1_META_13_15 : 45|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT1_META_BYTE_2 : 48|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_META_BYTE_3 : 56|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_DISTANCE_RAW : 64|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT2_META_13_15 : 77|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT2_META_BYTE_2 : 80|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_META_BYTE_3 : 88|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_DISTANCE_RAW : 96|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT3_META_13_15 : 109|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT3_META_BYTE_2 : 112|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_META_BYTE_3 : 120|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_DISTANCE_RAW : 128|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT4_META_13_15 : 141|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT4_META_BYTE_2 : 144|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_META_BYTE_3 : 152|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_DISTANCE_RAW : 160|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT5_META_13_15 : 173|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT5_META_BYTE_2 : 176|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_META_BYTE_3 : 184|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_DISTANCE_RAW : 192|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT6_META_13_15 : 205|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT6_META_BYTE_2 : 208|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_META_BYTE_3 : 216|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_DISTANCE_RAW : 224|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT7_META_13_15 : 237|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT7_META_BYTE_2 : 240|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_META_BYTE_3 : 248|8@1+ (1,0) [0|255] "" XXX +CM_ BO_ 1091 "IONIQ 9 candidate corner radar bin container. 0x430-0x437 correlate with left side and 0x440-0x447 with right side. Bytes 4-31 appear as seven 4-byte slots; lower 13 bits are a distance candidate at 0.05 m scale. This DBC intentionally exposes only raw candidate fields until lateral and velocity fields are validated."; +BA_ "GenMsgCycleTime" BO_ 1091 30; + +BO_ 1092 CORNER_RADAR_430_OBJECTS_444: 32 RADAR + SG_ HEADER_BYTE_0 : 0|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_1 : 8|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_2 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_3 : 24|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_DISTANCE_RAW : 32|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT1_META_13_15 : 45|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT1_META_BYTE_2 : 48|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_META_BYTE_3 : 56|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_DISTANCE_RAW : 64|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT2_META_13_15 : 77|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT2_META_BYTE_2 : 80|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_META_BYTE_3 : 88|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_DISTANCE_RAW : 96|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT3_META_13_15 : 109|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT3_META_BYTE_2 : 112|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_META_BYTE_3 : 120|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_DISTANCE_RAW : 128|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT4_META_13_15 : 141|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT4_META_BYTE_2 : 144|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_META_BYTE_3 : 152|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_DISTANCE_RAW : 160|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT5_META_13_15 : 173|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT5_META_BYTE_2 : 176|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_META_BYTE_3 : 184|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_DISTANCE_RAW : 192|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT6_META_13_15 : 205|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT6_META_BYTE_2 : 208|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_META_BYTE_3 : 216|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_DISTANCE_RAW : 224|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT7_META_13_15 : 237|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT7_META_BYTE_2 : 240|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_META_BYTE_3 : 248|8@1+ (1,0) [0|255] "" XXX +CM_ BO_ 1092 "IONIQ 9 candidate corner radar bin container. 0x430-0x437 correlate with left side and 0x440-0x447 with right side. Bytes 4-31 appear as seven 4-byte slots; lower 13 bits are a distance candidate at 0.05 m scale. This DBC intentionally exposes only raw candidate fields until lateral and velocity fields are validated."; +BA_ "GenMsgCycleTime" BO_ 1092 30; + +BO_ 1093 CORNER_RADAR_430_OBJECTS_445: 32 RADAR + SG_ HEADER_BYTE_0 : 0|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_1 : 8|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_2 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_3 : 24|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_DISTANCE_RAW : 32|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT1_META_13_15 : 45|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT1_META_BYTE_2 : 48|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_META_BYTE_3 : 56|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_DISTANCE_RAW : 64|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT2_META_13_15 : 77|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT2_META_BYTE_2 : 80|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_META_BYTE_3 : 88|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_DISTANCE_RAW : 96|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT3_META_13_15 : 109|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT3_META_BYTE_2 : 112|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_META_BYTE_3 : 120|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_DISTANCE_RAW : 128|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT4_META_13_15 : 141|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT4_META_BYTE_2 : 144|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_META_BYTE_3 : 152|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_DISTANCE_RAW : 160|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT5_META_13_15 : 173|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT5_META_BYTE_2 : 176|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_META_BYTE_3 : 184|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_DISTANCE_RAW : 192|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT6_META_13_15 : 205|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT6_META_BYTE_2 : 208|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_META_BYTE_3 : 216|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_DISTANCE_RAW : 224|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT7_META_13_15 : 237|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT7_META_BYTE_2 : 240|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_META_BYTE_3 : 248|8@1+ (1,0) [0|255] "" XXX +CM_ BO_ 1093 "IONIQ 9 candidate corner radar bin container. 0x430-0x437 correlate with left side and 0x440-0x447 with right side. Bytes 4-31 appear as seven 4-byte slots; lower 13 bits are a distance candidate at 0.05 m scale. This DBC intentionally exposes only raw candidate fields until lateral and velocity fields are validated."; +BA_ "GenMsgCycleTime" BO_ 1093 30; + +BO_ 1094 CORNER_RADAR_430_OBJECTS_446: 32 RADAR + SG_ HEADER_BYTE_0 : 0|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_1 : 8|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_2 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_3 : 24|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_DISTANCE_RAW : 32|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT1_META_13_15 : 45|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT1_META_BYTE_2 : 48|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_META_BYTE_3 : 56|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_DISTANCE_RAW : 64|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT2_META_13_15 : 77|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT2_META_BYTE_2 : 80|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_META_BYTE_3 : 88|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_DISTANCE_RAW : 96|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT3_META_13_15 : 109|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT3_META_BYTE_2 : 112|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_META_BYTE_3 : 120|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_DISTANCE_RAW : 128|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT4_META_13_15 : 141|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT4_META_BYTE_2 : 144|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_META_BYTE_3 : 152|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_DISTANCE_RAW : 160|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT5_META_13_15 : 173|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT5_META_BYTE_2 : 176|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_META_BYTE_3 : 184|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_DISTANCE_RAW : 192|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT6_META_13_15 : 205|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT6_META_BYTE_2 : 208|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_META_BYTE_3 : 216|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_DISTANCE_RAW : 224|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT7_META_13_15 : 237|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT7_META_BYTE_2 : 240|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_META_BYTE_3 : 248|8@1+ (1,0) [0|255] "" XXX +CM_ BO_ 1094 "IONIQ 9 candidate corner radar bin container. 0x430-0x437 correlate with left side and 0x440-0x447 with right side. Bytes 4-31 appear as seven 4-byte slots; lower 13 bits are a distance candidate at 0.05 m scale. This DBC intentionally exposes only raw candidate fields until lateral and velocity fields are validated."; +BA_ "GenMsgCycleTime" BO_ 1094 30; + +BO_ 1095 CORNER_RADAR_430_OBJECTS_447: 32 RADAR + SG_ HEADER_BYTE_0 : 0|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_1 : 8|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_2 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_3 : 24|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_DISTANCE_RAW : 32|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT1_META_13_15 : 45|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT1_META_BYTE_2 : 48|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT1_META_BYTE_3 : 56|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_DISTANCE_RAW : 64|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT2_META_13_15 : 77|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT2_META_BYTE_2 : 80|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT2_META_BYTE_3 : 88|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_DISTANCE_RAW : 96|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT3_META_13_15 : 109|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT3_META_BYTE_2 : 112|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT3_META_BYTE_3 : 120|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_DISTANCE_RAW : 128|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT4_META_13_15 : 141|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT4_META_BYTE_2 : 144|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT4_META_BYTE_3 : 152|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_DISTANCE_RAW : 160|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT5_META_13_15 : 173|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT5_META_BYTE_2 : 176|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT5_META_BYTE_3 : 184|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_DISTANCE_RAW : 192|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT6_META_13_15 : 205|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT6_META_BYTE_2 : 208|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT6_META_BYTE_3 : 216|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_DISTANCE_RAW : 224|13@1+ (1,0) [0|8191] "" XXX + SG_ SLOT7_META_13_15 : 237|3@1+ (1,0) [0|7] "" XXX + SG_ SLOT7_META_BYTE_2 : 240|8@1+ (1,0) [0|255] "" XXX + SG_ SLOT7_META_BYTE_3 : 248|8@1+ (1,0) [0|255] "" XXX +CM_ BO_ 1095 "IONIQ 9 candidate corner radar bin container. 0x430-0x437 correlate with left side and 0x440-0x447 with right side. Bytes 4-31 appear as seven 4-byte slots; lower 13 bits are a distance candidate at 0.05 m scale. This DBC intentionally exposes only raw candidate fields until lateral and velocity fields are validated."; +BA_ "GenMsgCycleTime" BO_ 1095 30; diff --git a/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_corner_radar_430.py b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_corner_radar_430.py new file mode 100755 index 0000000..d663db7 --- /dev/null +++ b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_corner_radar_430.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 +import os + + +HEADER = """VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX RADAR + +""" + + +def write_object_msg(f, addr): + name = f"CORNER_RADAR_430_OBJECTS_{addr:x}" + f.write(f""" +BO_ {addr} {name}: 32 RADAR + SG_ HEADER_BYTE_0 : 0|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_1 : 8|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_2 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ HEADER_BYTE_3 : 24|8@1+ (1,0) [0|255] "" XXX +""") + for slot in range(7): + bit = 32 + slot * 32 + prefix = f"SLOT{slot + 1}" + f.write(f""" SG_ {prefix}_DISTANCE_RAW : {bit}|13@1+ (1,0) [0|8191] "" XXX + SG_ {prefix}_META_13_15 : {bit + 13}|3@1+ (1,0) [0|7] "" XXX + SG_ {prefix}_META_BYTE_2 : {bit + 16}|8@1+ (1,0) [0|255] "" XXX + SG_ {prefix}_META_BYTE_3 : {bit + 24}|8@1+ (1,0) [0|255] "" XXX +""") + f.write(f"""CM_ BO_ {addr} "IONIQ 9 candidate corner radar bin container. 0x430-0x437 correlate with left side and 0x440-0x447 with right side. Bytes 4-31 appear as seven 4-byte slots; lower 13 bits are a distance candidate at 0.05 m scale. This DBC intentionally exposes only raw candidate fields until lateral and velocity fields are validated."; +BA_ "GenMsgCycleTime" BO_ {addr} 30; +""") + + +if __name__ == "__main__": + dbc_name = os.path.basename(__file__).replace(".py", ".dbc") + out_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), dbc_name) + with open(out_path, "w", encoding="ascii") as f: + f.write(HEADER) + f.write('BA_DEF_ BO_ "GenMsgCycleTime" INT 0 100000;\n') + f.write('BA_DEF_DEF_ "GenMsgCycleTime" 0;\n') + for addr in range(0x430, 0x438): + write_object_msg(f, addr) + for addr in range(0x440, 0x448): + write_object_msg(f, addr) diff --git a/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_radar.dbc b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_radar.dbc new file mode 100644 index 0000000..46c3032 --- /dev/null +++ b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_radar.dbc @@ -0,0 +1,1178 @@ + +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX + +BO_ 528 RADAR_TRACK_210: 32 RADAR + SG_ NEW_SIGNAL_25 : 26|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_24 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_21 : 36|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_20 : 39|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT1 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_15 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_14 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 63|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST1 : 64|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST1 : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED1 : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_16 : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED1 : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL1 : 118|10@1- (0.05,0) [0|1023] "" XXX + SG_ NEW_SIGNAL_27 : 154|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_26 : 156|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_23 : 164|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_22 : 167|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT2 : 175|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_13 : 179|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_12 : 183|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_11 : 191|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST2 : 192|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST2 : 204|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED2 : 216|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_17 : 231|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED2 : 232|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL2 : 246|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 529 RADAR_TRACK_211: 32 RADAR + SG_ NEW_SIGNAL_25 : 26|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_24 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_21 : 36|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_20 : 39|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT1 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_15 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_14 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 63|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST1 : 64|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST1 : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED1 : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_16 : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED1 : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL1 : 118|10@1- (0.05,0) [0|1023] "" XXX + SG_ NEW_SIGNAL_27 : 154|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_26 : 156|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_23 : 164|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_22 : 167|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT2 : 175|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_13 : 179|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_12 : 183|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_11 : 191|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST2 : 192|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST2 : 204|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED2 : 216|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_17 : 231|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED2 : 232|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL2 : 246|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 530 RADAR_TRACK_212: 32 RADAR + SG_ NEW_SIGNAL_25 : 26|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_24 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_21 : 36|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_20 : 39|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT1 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_15 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_14 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 63|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST1 : 64|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST1 : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED1 : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_16 : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED1 : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL1 : 118|10@1- (0.05,0) [0|1023] "" XXX + SG_ NEW_SIGNAL_27 : 154|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_26 : 156|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_23 : 164|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_22 : 167|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT2 : 175|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_13 : 179|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_12 : 183|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_11 : 191|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST2 : 192|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST2 : 204|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED2 : 216|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_17 : 231|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED2 : 232|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL2 : 246|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 531 RADAR_TRACK_213: 32 RADAR + SG_ NEW_SIGNAL_25 : 26|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_24 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_21 : 36|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_20 : 39|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT1 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_15 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_14 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 63|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST1 : 64|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST1 : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED1 : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_16 : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED1 : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL1 : 118|10@1- (0.05,0) [0|1023] "" XXX + SG_ NEW_SIGNAL_27 : 154|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_26 : 156|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_23 : 164|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_22 : 167|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT2 : 175|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_13 : 179|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_12 : 183|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_11 : 191|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST2 : 192|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST2 : 204|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED2 : 216|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_17 : 231|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED2 : 232|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL2 : 246|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 532 RADAR_TRACK_214: 32 RADAR + SG_ NEW_SIGNAL_25 : 26|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_24 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_21 : 36|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_20 : 39|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT1 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_15 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_14 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 63|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST1 : 64|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST1 : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED1 : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_16 : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED1 : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL1 : 118|10@1- (0.05,0) [0|1023] "" XXX + SG_ NEW_SIGNAL_27 : 154|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_26 : 156|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_23 : 164|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_22 : 167|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT2 : 175|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_13 : 179|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_12 : 183|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_11 : 191|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST2 : 192|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST2 : 204|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED2 : 216|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_17 : 231|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED2 : 232|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL2 : 246|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 533 RADAR_TRACK_215: 32 RADAR + SG_ NEW_SIGNAL_25 : 26|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_24 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_21 : 36|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_20 : 39|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT1 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_15 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_14 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 63|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST1 : 64|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST1 : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED1 : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_16 : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED1 : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL1 : 118|10@1- (0.05,0) [0|1023] "" XXX + SG_ NEW_SIGNAL_27 : 154|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_26 : 156|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_23 : 164|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_22 : 167|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT2 : 175|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_13 : 179|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_12 : 183|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_11 : 191|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST2 : 192|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST2 : 204|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED2 : 216|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_17 : 231|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED2 : 232|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL2 : 246|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 534 RADAR_TRACK_216: 32 RADAR + SG_ NEW_SIGNAL_25 : 26|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_24 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_21 : 36|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_20 : 39|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT1 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_15 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_14 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 63|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST1 : 64|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST1 : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED1 : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_16 : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED1 : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL1 : 118|10@1- (0.05,0) [0|1023] "" XXX + SG_ NEW_SIGNAL_27 : 154|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_26 : 156|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_23 : 164|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_22 : 167|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT2 : 175|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_13 : 179|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_12 : 183|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_11 : 191|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST2 : 192|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST2 : 204|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED2 : 216|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_17 : 231|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED2 : 232|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL2 : 246|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 535 RADAR_TRACK_217: 32 RADAR + SG_ NEW_SIGNAL_25 : 26|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_24 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_21 : 36|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_20 : 39|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT1 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_15 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_14 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 63|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST1 : 64|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST1 : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED1 : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_16 : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED1 : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL1 : 118|10@1- (0.05,0) [0|1023] "" XXX + SG_ NEW_SIGNAL_27 : 154|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_26 : 156|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_23 : 164|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_22 : 167|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT2 : 175|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_13 : 179|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_12 : 183|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_11 : 191|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST2 : 192|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST2 : 204|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED2 : 216|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_17 : 231|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED2 : 232|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL2 : 246|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 536 RADAR_TRACK_218: 32 RADAR + SG_ NEW_SIGNAL_25 : 26|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_24 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_21 : 36|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_20 : 39|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT1 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_15 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_14 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 63|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST1 : 64|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST1 : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED1 : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_16 : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED1 : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL1 : 118|10@1- (0.05,0) [0|1023] "" XXX + SG_ NEW_SIGNAL_27 : 154|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_26 : 156|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_23 : 164|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_22 : 167|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT2 : 175|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_13 : 179|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_12 : 183|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_11 : 191|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST2 : 192|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST2 : 204|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED2 : 216|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_17 : 231|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED2 : 232|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL2 : 246|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 537 RADAR_TRACK_219: 32 RADAR + SG_ NEW_SIGNAL_25 : 26|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_24 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_21 : 36|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_20 : 39|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT1 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_15 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_14 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 63|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST1 : 64|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST1 : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED1 : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_16 : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED1 : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL1 : 118|10@1- (0.05,0) [0|1023] "" XXX + SG_ NEW_SIGNAL_27 : 154|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_26 : 156|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_23 : 164|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_22 : 167|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT2 : 175|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_13 : 179|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_12 : 183|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_11 : 191|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST2 : 192|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST2 : 204|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED2 : 216|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_17 : 231|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED2 : 232|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL2 : 246|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 538 RADAR_TRACK_21a: 32 RADAR + SG_ NEW_SIGNAL_25 : 26|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_24 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_21 : 36|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_20 : 39|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT1 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_15 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_14 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 63|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST1 : 64|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST1 : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED1 : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_16 : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED1 : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL1 : 118|10@1- (0.05,0) [0|1023] "" XXX + SG_ NEW_SIGNAL_27 : 154|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_26 : 156|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_23 : 164|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_22 : 167|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT2 : 175|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_13 : 179|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_12 : 183|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_11 : 191|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST2 : 192|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST2 : 204|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED2 : 216|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_17 : 231|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED2 : 232|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL2 : 246|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 539 RADAR_TRACK_21b: 32 RADAR + SG_ NEW_SIGNAL_25 : 26|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_24 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_21 : 36|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_20 : 39|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT1 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_15 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_14 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 63|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST1 : 64|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST1 : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED1 : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_16 : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED1 : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL1 : 118|10@1- (0.05,0) [0|1023] "" XXX + SG_ NEW_SIGNAL_27 : 154|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_26 : 156|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_23 : 164|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_22 : 167|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT2 : 175|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_13 : 179|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_12 : 183|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_11 : 191|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST2 : 192|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST2 : 204|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED2 : 216|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_17 : 231|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED2 : 232|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL2 : 246|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 540 RADAR_TRACK_21c: 32 RADAR + SG_ NEW_SIGNAL_25 : 26|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_24 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_21 : 36|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_20 : 39|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT1 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_15 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_14 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 63|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST1 : 64|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST1 : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED1 : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_16 : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED1 : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL1 : 118|10@1- (0.05,0) [0|1023] "" XXX + SG_ NEW_SIGNAL_27 : 154|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_26 : 156|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_23 : 164|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_22 : 167|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT2 : 175|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_13 : 179|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_12 : 183|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_11 : 191|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST2 : 192|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST2 : 204|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED2 : 216|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_17 : 231|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED2 : 232|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL2 : 246|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 541 RADAR_TRACK_21d: 32 RADAR + SG_ NEW_SIGNAL_25 : 26|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_24 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_21 : 36|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_20 : 39|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT1 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_15 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_14 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 63|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST1 : 64|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST1 : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED1 : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_16 : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED1 : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL1 : 118|10@1- (0.05,0) [0|1023] "" XXX + SG_ NEW_SIGNAL_27 : 154|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_26 : 156|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_23 : 164|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_22 : 167|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT2 : 175|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_13 : 179|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_12 : 183|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_11 : 191|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST2 : 192|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST2 : 204|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED2 : 216|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_17 : 231|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED2 : 232|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL2 : 246|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 542 RADAR_TRACK_21e: 32 RADAR + SG_ NEW_SIGNAL_25 : 26|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_24 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_21 : 36|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_20 : 39|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT1 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_15 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_14 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 63|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST1 : 64|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST1 : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED1 : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_16 : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED1 : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL1 : 118|10@1- (0.05,0) [0|1023] "" XXX + SG_ NEW_SIGNAL_27 : 154|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_26 : 156|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_23 : 164|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_22 : 167|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT2 : 175|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_13 : 179|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_12 : 183|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_11 : 191|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST2 : 192|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST2 : 204|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED2 : 216|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_17 : 231|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED2 : 232|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL2 : 246|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 543 RADAR_TRACK_21f: 32 RADAR + SG_ NEW_SIGNAL_25 : 26|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_24 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_21 : 36|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_20 : 39|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT1 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_15 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_14 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 63|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST1 : 64|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST1 : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED1 : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_16 : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED1 : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL1 : 118|10@1- (0.05,0) [0|1023] "" XXX + SG_ NEW_SIGNAL_27 : 154|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_26 : 156|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_23 : 164|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_22 : 167|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT2 : 175|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_13 : 179|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_12 : 183|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_11 : 191|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST2 : 192|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST2 : 204|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED2 : 216|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_17 : 231|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED2 : 232|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL2 : 246|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 933 RADAR_TRACK_3a5: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 934 RADAR_TRACK_3a6: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 935 RADAR_TRACK_3a7: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 936 RADAR_TRACK_3a8: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 937 RADAR_TRACK_3a9: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 938 RADAR_TRACK_3aa: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 939 RADAR_TRACK_3ab: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 940 RADAR_TRACK_3ac: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 941 RADAR_TRACK_3ad: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 942 RADAR_TRACK_3ae: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 943 RADAR_TRACK_3af: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 944 RADAR_TRACK_3b0: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 945 RADAR_TRACK_3b1: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 946 RADAR_TRACK_3b2: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 947 RADAR_TRACK_3b3: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 948 RADAR_TRACK_3b4: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 949 RADAR_TRACK_3b5: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 950 RADAR_TRACK_3b6: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 951 RADAR_TRACK_3b7: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 952 RADAR_TRACK_3b8: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 953 RADAR_TRACK_3b9: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 954 RADAR_TRACK_3ba: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 955 RADAR_TRACK_3bb: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 956 RADAR_TRACK_3bc: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 957 RADAR_TRACK_3bd: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 958 RADAR_TRACK_3be: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 959 RADAR_TRACK_3bf: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 960 RADAR_TRACK_3c0: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 961 RADAR_TRACK_3c1: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 962 RADAR_TRACK_3c2: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 963 RADAR_TRACK_3c3: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 964 RADAR_TRACK_3c4: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + +BO_ 1024 RADAR_TRACK_400: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1025 RADAR_TRACK_401: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1026 RADAR_TRACK_402: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1027 RADAR_TRACK_403: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1028 RADAR_TRACK_404: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1029 RADAR_TRACK_405: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1030 RADAR_TRACK_406: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1031 RADAR_TRACK_407: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1032 RADAR_TRACK_408: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1033 RADAR_TRACK_409: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1034 RADAR_TRACK_40a: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1035 RADAR_TRACK_40b: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1036 RADAR_TRACK_40c: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1037 RADAR_TRACK_40d: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1038 RADAR_TRACK_40e: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1039 RADAR_TRACK_40f: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1040 RADAR_TRACK_410: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1041 RADAR_TRACK_411: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1042 RADAR_TRACK_412: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1043 RADAR_TRACK_413: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1044 RADAR_TRACK_414: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1045 RADAR_TRACK_415: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1046 RADAR_TRACK_416: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1047 RADAR_TRACK_417: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1048 RADAR_TRACK_418: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1049 RADAR_TRACK_419: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1050 RADAR_TRACK_41a: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1051 RADAR_TRACK_41b: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1052 RADAR_TRACK_41c: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + +BO_ 1053 RADAR_TRACK_41d: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + \ No newline at end of file diff --git a/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_radar.py b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_radar.py new file mode 100755 index 0000000..f3abf2e --- /dev/null +++ b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_canfd_radar.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +import os + +if __name__ == "__main__": + dbc_name = os.path.basename(__file__).replace(".py", ".dbc") + hyundai_path = os.path.dirname(os.path.realpath(__file__)) + with open(os.path.join(hyundai_path, dbc_name), "w", encoding='utf-8') as f: + f.write(""" +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX + """) + + for a in range(0x210, 0x210 + 16): + f.write(f""" +BO_ {a} RADAR_TRACK_{a:x}: 32 RADAR + SG_ NEW_SIGNAL_25 : 26|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_24 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_21 : 36|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_20 : 39|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT1 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_15 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_14 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 63|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST1 : 64|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST1 : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED1 : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_16 : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED1 : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL1 : 118|10@1- (0.05,0) [0|1023] "" XXX + SG_ NEW_SIGNAL_27 : 154|3@0+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_26 : 156|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_23 : 164|5@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_22 : 167|3@0+ (1,0) [0|7] "" XXX + SG_ VALID_CNT2 : 175|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_13 : 179|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_12 : 183|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_11 : 191|8@0- (1,0) [0|255] "" XXX + SG_ LONG_DIST2 : 192|12@1+ (0.05,0) [0|4095] "" XXX + SG_ LAT_DIST2 : 204|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED2 : 216|14@1- (0.01,0) [0|16383] "" XXX + SG_ NEW_SIGNAL_17 : 231|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED2 : 232|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL2 : 246|10@1- (0.05,0) [0|1023] "" XXX + """) + for a in range(0x3a5, 0x3a5 + 32): + f.write(f""" +BO_ {a} RADAR_TRACK_{a:x}: 24 RADAR + SG_ VALID : 25|2@0+ (1,0) [0|3] "" XXX + SG_ VALID2 : 28|2@0+ (1,0) [0|3] "" XXX + SG_ PROB : 30|10@1+ (1,0) [0|1023] "" XXX + SG_ VALID_CNT : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_7 : 51|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 55|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 62|7@0- (1,0) [0|127] "" XXX + SG_ LONG_DIST : 63|13@1+ (0.05,0) [0|8191] "" XXX + SG_ LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX + SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX + SG_ IN_MYLANE : 103|2@0+ (1,0) [0|3] "" XXX + SG_ LAT_SPEED : 104|13@1- (0.01,0) [0|8191] "" XXX + SG_ REL_ACCEL : 118|10@1- (0.05,0) [0|1023] "" XXX + """) + + # Group 3 radar object list: + # 30 one-object messages at 20 Hz, with an empty distance sentinel of 0x7ff. + for a in range(0x400, 0x400 + 30): + f.write(f""" +BO_ {a} RADAR_TRACK_{a:x}: 24 RADAR + SG_ OBJECT_LENGTH : 41|7@1+ (0.1,0) [0|12.7] "m" XXX + SG_ LONG_DIST : 64|11@1+ (0.1,0) [0|204.7] "m" XXX + SG_ LAT_DIST : 75|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ REL_SPEED : 87|11@1- (0.1,0) [-102.4|102.3] "m/s" XXX + """) diff --git a/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_kia_denso_front_radar.py b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_kia_denso_front_radar.py new file mode 100755 index 0000000..d00e5d3 --- /dev/null +++ b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_kia_denso_front_radar.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 +import os + + +if __name__ == "__main__": + dbc_name = os.path.basename(__file__).replace(".py", ".dbc") + hyundai_path = os.path.dirname(os.path.realpath(__file__)) + with open(os.path.join(hyundai_path, dbc_name), "w", encoding="utf-8") as f: + f.write(""" +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX +""") + + # EN: The Denso DNMWR006 radar in the 2018-2019 Kia Sorento UM publishes + # eight stable tracked objects at 20 Hz from 0x500 through 0x507. + # Do not decode 0x508+ distance-sorted raw detections as stable tracks. + # KO: 2018-2019 Kia Sorento UM의 Denso DNMWR006 레이더는 0x500~0x507에서 + # 안정적인 추적 객체 8개를 20Hz로 전송함. 0x508 이후의 거리순 raw + # detection은 안정적인 트랙으로 디코딩하지 않음. + for address in range(0x500, 0x508): + f.write(f""" +BO_ {address} RADAR_TRACK_{address:x}: 8 RADAR + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ LONG_DIST : 15|16@0+ (0.00625,0) [0|409.59375] "m" XXX + SG_ LAT_DIST : 31|11@0- (0.0625,0) [-64|63.9375] "m" XXX + SG_ OBJECT_FLAGS_1 : 36|5@0+ (1,0) [0|31] "" XXX + SG_ OBJECT_FLAG_2 : 47|1@0+ (1,0) [0|1] "" XXX + SG_ REL_SPEED : 46|12@0- (0.015625,0) [-32|31.984375] "m/s" XXX + SG_ OBJECT_STATE : 50|3@0+ (1,0) [0|7] "" XXX + SG_ OBJECT_DETAIL : 63|8@0+ (1,0) [0|255] "" XXX +""") diff --git a/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_palisade_2023.dbc b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_palisade_2023.dbc index 68f5d60..b8ecca7 100644 --- a/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_palisade_2023.dbc +++ b/iqdbc_repo/iqdbc/dbc/generator/hyundai/hyundai_palisade_2023.dbc @@ -1,4 +1,4 @@ -CM_ "IMPORT _hyundai_canfd_common.dbc"; +CM_ "IMPORT _hyundai_common.dbc"; BO_ 67 DATC13: 8 XXX SG_ CF_Datc_AcDisp : 22|2@1+ (1,0) [0|0] "" XXX diff --git a/iqdbc_repo/iqdbc/dbc/hyundai_kia_generic.dbc b/iqdbc_repo/iqdbc/dbc/hyundai_kia_generic.dbc index 6a67700..b3bde5f 100644 --- a/iqdbc_repo/iqdbc/dbc/hyundai_kia_generic.dbc +++ b/iqdbc_repo/iqdbc/dbc/hyundai_kia_generic.dbc @@ -1341,6 +1341,17 @@ BO_ 273 TCU11: 8 TCU BO_ 16 ACU13: 8 ACU SG_ CF_Acu_CshAct : 0|1@1+ (1.0,0.0) [0.0|1.0] "" CUBIS,IBOX,ODS +BO_ 1007 CRUISE_BUTTON_ALT: 8 XXX + SG_ SET_ME_1 : 52|1@0+ (1,0) [0|1] "" XXX + SG_ CruiseSwMain : 58|1@0+ (1,0) [0|1] "" XXX + SG_ CruiseSwState : 60|3@1+ (1,0) [0|7] "" XXX + +BO_ 1046 CRUISE_BUTTON_LFA: 8 XXX + SG_ NEW_SIGNAL_2 : 49|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_1 : 54|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_3 : 57|1@0+ (1,0) [0|1] "" XXX + SG_ CruiseSwLfa : 58|1@0+ (1,0) [0|1] "" XXX + BO_ 1040 CGW_USM1: 8 BCM SG_ CF_Gway_ATTurnRValue : 0|2@1+ (1.0,0.0) [0.0|3.0] "" CLU SG_ CF_Gway_PTGMRValue : 2|2@1+ (1.0,0.0) [0.0|3.0] "" CLU @@ -1384,6 +1395,8 @@ BO_ 1290 SCC13: 8 SCC SG_ SCC_Equip : 3|1@1+ (1,0) [0|1] "" ESC SG_ AebDrvSetStatus : 4|3@1+ (1,0) [0|7] "" CLU,ESC SG_ Lead_Veh_Dep_Alert_USM : 13|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_1 : 23|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_2 : 31|8@0+ (1,0) [0|255] "" XXX BO_ 1287 TCS15: 4 ESC SG_ ABS_W_LAMP : 0|1@1+ (1.0,0.0) [0.0|1.0] "" _4WD,CLU,CUBIS,IBOX @@ -1478,18 +1491,21 @@ BO_ 905 SCC14: 8 SCC SG_ ComfortBandLower : 6|6@1+ (0.02,0) [0|1.26] "m/s^2" ESC SG_ JerkUpperLimit : 12|7@1+ (0.1,0) [0|12.7] "m/s^3" ESC SG_ JerkLowerLimit : 19|7@1+ (0.1,0) [0|12.7] "m/s^3" ESC + SG_ NEW_SIGNAL_1 : 26|6@1+ (1,0) [0|63] "" XXX SG_ ACCMode : 32|3@1+ (1,0) [0|7] "" CLU,HUD,LDWS_LKAS,ESC - SG_ ObjGap : 56|8@1+ (1,0) [0|255] "" CLU,HUD,ESC SG_ ObjDistStat : 42|2@1+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_2 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ ObjGap : 56|8@1+ (1,0) [0|255] "" CLU,HUD,ESC -BO_ 1157 LFAHDA_MFC: 4 XXX +BO_ 1157 LFAHDA_MFC: 8 XXX SG_ HDA_USM : 0|2@1+ (1,0) [0|3] "" XXX SG_ HDA_Active : 2|1@1+ (1,0) [0|1] "" XXX SG_ HDA_Icon_State : 3|2@1+ (1,0) [0|3] "" XXX SG_ HDA_Chime : 7|1@1+ (1,0) [0|1] "" XXX SG_ HDA_VSetReq : 8|8@1+ (1,0) [0|255] "km/h" XXX SG_ LFA_SysWarning : 16|3@1+ (1,0) [0|7] "" XXX - SG_ NEW_SIGNAL_1 : 20|3@1+ (1,0) [0|7] "" XXX + SG_ HDA_Icon_Wheel : 20|1@1+ (1,0) [0|1] "" XXX + SG_ HDA_LdwSysState : 21|2@1+ (1,0) [0|3] "" XXX SG_ LFA_Icon_State : 24|2@1+ (1,0) [0|3] "" XXX SG_ LFA_USM : 27|2@1+ (1,0) [0|3] "" XXX SG_ HDA_SysWarning : 29|2@1+ (1,0) [0|3] "" XXX @@ -1497,11 +1513,10 @@ BO_ 1157 LFAHDA_MFC: 4 XXX BO_ 913 BCM_PO_11: 8 Vector__XXX SG_ BCM_Door_Dri_Status : 5|1@0+ (1,0) [0|1] "" PT_ESC_ABS SG_ BCM_Shift_R_MT_SW_Status : 39|2@0+ (1,0) [0|3] "" PT_ESC_ABS - SG_ LDA_BTN : 4|1@0+ (1,0) [0|1] "" XXX + SG_ LFA_Pressed : 4|1@0+ (1,0) [0|1] "" XXX BO_ 1426 LABEL11: 8 XXX SG_ CC_React : 34|1@1+ (1,0) [0|1] "" XXX - SG_ CC_ACT : 35|1@1+ (1,0) [0|1] "" XXX BO_ 910 WHL_SPD12_FS: 5 iBAU SG_ CRC : 0|8@1+ (1,0) [0|0] "" Vector__XXX @@ -1522,7 +1537,10 @@ BO_ 865 ADAS_PRK_11: 8 ADAS_PRK SG_ PCA_CHECK_SUM : 48|8@1+ (1,0) [0|0] "" Vector__XXX BO_ 882 ELECT_GEAR: 8 XXX - SG_ Elect_Gear_Shifter : 16|4@1+ (1,0) [0|7] "" CLU + SG_ Elect_Gear_Shifter : 16|4@1+ (1,0) [0|7] "" CLU + SG_ Elect_Gear_Shifter_NEXO : 16|16@1+ (1,0) [0|65535] "" CLU + SG_ Elect_Gear_Step : 22|3@0+ (1,0) [0|7] "" XXX + SG_ Elect_Motor_Speed : 0|8@1+ (1,0) [0|255] "" XXX SG_ SLC_ON : 31|1@0+ (1,0) [0|1] "" CLU SG_ SLC_SET_SPEED : 32|8@1+ (1,0) [0|255] "" CLU @@ -1534,14 +1552,12 @@ BO_ 881 E_EMS11: 8 XXX SG_ Cruise_Limit_Target : 23|8@1+ (1,0) [0|15] "" XXX SG_ Accel_Pedal_Pos : 31|8@1+ (1,0) [0|254] "" XXX SG_ CR_Vcu_AccPedDep_Pos : 56|8@1+ (1,0) [0|254] "" XXX + SG_ Engine_Run : 14|1@0+ (1,0) [0|1] "" XXX + SG_ N : 18|13@1+ (1,0) [0|15] "" XXX BO_ 1355 EV_PC6: 8 CGW SG_ CF_Vcu_SbwWarnMsg : 16|3@1+ (1,0) [0|7] "" Vector__XXX -BO_ 1429 E_CRUISE_CONTROL: 8 XXX - SG_ CRUISE_LAMP_M : 50|1@0+ (1,0) [0|1] "" XXX - SG_ CRUISE_LAMP_S : 51|1@0+ (1,0) [0|1] "" XXX - BO_ 1430 EV_PC2: 8 CGW SG_ CR_Ldc_ActVol_LS_V : 32|8@1+ (0.1,0) [0|0] "V" Vector__XXX @@ -1584,7 +1600,7 @@ BO_ 352 AHB1: 8 iBAU SG_ CF_Ahb_Bzzr : 26|1@1+ (1,0) [0|1] "" Vector__XXX SG_ CF_Ahb_ChkSum : 56|8@1+ (1,0) [0|255] "" Vector__XXX -BO_ 1191 MFC_4a7: 8 XXX +BO_ 1191 MFC_4a7: 2 XXX SG_ PAINT1 : 0|1@0+ (1,0) [0|1] "" XXX BO_ 1162 BCA11: 8 BCW @@ -1658,33 +1674,22 @@ BO_ 1348 Navi_HU: 8 XXX SG_ SpeedLim_Nav_General : 29|1@0+ (1,0) [0|1] "" XXX SG_ SpeedLim_Nav_Cam : 30|1@0+ (1,0) [0|1] "" XXX -BO_ 683 ESCC: 8 XXX - SG_ FCA_CmdAct : 0|1@1+ (1,0) [0|1] "" ESC - SG_ CF_VSM_Warn_FCA11 : 1|2@1+ (1,0) [0|3] "" ACU,CLU,ESC - SG_ AEB_CmdAct : 3|1@1+ (1,0) [0|1] "" ESC - SG_ CF_VSM_Warn_SCC12 : 4|2@1+ (1,0) [0|3] "" CLU,ESC,IAP - SG_ CF_VSM_DecCmdAct_SCC12 : 6|1@1+ (1,0) [0|1] "" ESC - SG_ CF_VSM_DecCmdAct_FCA11 : 7|1@1+ (1,0) [0|1] "" ESC - SG_ CR_VSM_DecCmd_SCC12 : 8|8@1+ (0.01,0) [0|2.55] "g" ESC - SG_ ObjValid : 16|1@1+ (1,0) [0|1] "" CLU,ESC,TCU - SG_ ACC_ObjStatus : 17|2@1+ (1,0) [0|3] "" ABS,ESC - SG_ ACC_ObjLatPos : 24|9@1+ (0.1,-20) [-20|31.1] "m" ABS,ESC - SG_ ACC_ObjRelSpd : 44|12@1+ (0.1,-170) [-170|239.5] "m/s" ABS,ESC - SG_ ACC_ObjDist : 33|11@1+ (0.1,0) [0|204.7] "m" ABS,ESC - SG_ CR_VSM_DecCmd_FCA11 : 56|8@1+ (0.01,0) [0|2.55] "g" ESC - +BO_ 1291 EV_Info: 8 XXX + SG_ OPKR_EV_Charge_Level : 17|7@1+ (1,0) [0|100] "%" XXX CM_ "BO_ E_EMS11: All (plug-in) hybrids use this gas signal: CR_Vcu_AccPedDep_Pos, and all EVs use the Accel_Pedal_Pos signal. See hyundai/values.py for a specific car list"; CM_ 145 "Contains signal with accelerator pedal press. Used by fuel cell hydrogen-powered (FCEV) cars such as the 2021 Hyundai Nexo."; CM_ 512 "Contains signal with gear shifter. Used by fuel cell hydrogen-powered (FCEV) cars such as the 2021 Hyundai Nexo."; CM_ SG_ 871 CF_Lvr_IsgState "Idle Stop and Go"; CM_ SG_ 1056 SCCInfoDisplay "Goes to 1 for a second while transitioning from Cruise Control to No Message"; CM_ SG_ 1348 SpeedLim_Nav_Clu "Speed limit displayed on Nav, Cluster and HUD"; +CM_ SG_ 1348 SpeedLim_Nav_Cam "Speed limit if speed cam exist"; +VAL_ 882 Elect_Gear_Shifter_NEXO 1546 "D" 2314 "N" 2566 "R" 2569 "P"; VAL_ 274 CUR_GR 1 "D" 2 "D" 3 "D" 4 "D" 5 "D" 6 "D" 7 "D" 8 "D" 14 "R" 0 "P"; VAL_ 512 HYDROGEN_GEAR_SHIFTER 5 "D" 8 "S" 6 "N" 7 "R" 0 "P"; VAL_ 871 CF_Lvr_IsgState 0 "enabled" 1 "activated" 2 "unknown" 3 "disabled"; VAL_ 871 CF_Lvr_Gear 12 "T" 5 "D" 8 "S" 6 "N" 7 "R" 0 "P"; -VAL_ 882 Elect_Gear_Shifter 4 "S" 5 "D" 8 "S" 6 "N" 7 "R" 0 "P"; +VAL_ 882 Elect_Gear_Shifter 4 "S" 5 "D" 8 "S" 6 "N" 7 "R" 0 "P" 12 "T"; VAL_ 905 ACCMode 0 "off" 1 "enabled" 2 "driver_override" 3 "off_maybe_fault" 4 "cancelled"; VAL_ 905 ObjDistStat 0 "no_object" 1 "receding" 2 "approaching"; VAL_ 909 CF_VSM_Warn 2 "FCW" 3 "AEB"; diff --git a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/__init__.py b/iqdbc_repo/iqdbc/iqpilot/car/hyundai/__init__.py deleted file mode 100644 index 297dca9..0000000 --- a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/__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/hyundai/aol.py b/iqdbc_repo/iqdbc/iqpilot/car/hyundai/aol.py deleted file mode 100644 index 53e9137..0000000 --- a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/aol.py +++ /dev/null @@ -1,99 +0,0 @@ -from enum import StrEnum -from collections import namedtuple - -from iqdbc.car import Bus, DT_CTRL, structs -from iqdbc.car.hyundai.values import CAR - -from iqdbc.car.hyundai.values import HyundaiFlags -from iqdbc.iqpilot.car.hyundai.values import HyundaiFlagsIQ -from iqdbc.iqpilot.aol_base import AolCarStateBase -from iqdbc.can.parser import CANParser - -ButtonType = structs.CarState.ButtonEvent.Type - -AolDataIQ = namedtuple("AolDataIQ", - ["enable_aol", "lat_active", "disengaging", "paused"]) - - -class AolCarController: - def __init__(self): - self.aol = AolDataIQ(False, False, False, False) - - self.lat_disengage_blink = 0 - self.lat_disengage_init = False - self.prev_lat_active = False - - self.lkas_icon = 0 - self.lfa_icon = 0 - - def aol_status_update(self, CC: structs.CarControl, CC_IQ: structs.IQCarControl, frame: int) -> AolDataIQ: - enable_aol = CC_IQ.aol.available - - if CC.latActive: - self.lat_disengage_init = False - elif self.prev_lat_active: - self.lat_disengage_init = True - - if not self.lat_disengage_init: - self.lat_disengage_blink = frame - - paused = CC_IQ.aol.enabled and not CC.latActive - disengaging = (frame - self.lat_disengage_blink) * DT_CTRL < 1.0 if self.lat_disengage_init else False - - self.prev_lat_active = CC.latActive - - return AolDataIQ(enable_aol, CC.latActive, disengaging, paused) - - def create_lkas_icon(self, CP: structs.CarParams, enabled: bool) -> int: - if self.aol.enable_aol: - lkas_icon = 2 if self.aol.lat_active else 3 if self.aol.disengaging else 1 - else: - lkas_icon = 2 if enabled else 1 - - if CP.carFingerprint in (CAR.KIA_OPTIMA_G4, CAR.KIA_OPTIMA_G4_FL, CAR.HYUNDAI_KONA_NON_SCC): - lkas_icon = 3 if (self.aol.lat_active if self.aol.enable_aol else enabled) else 1 - - return lkas_icon - - def create_lfa_icon(self, enabled: bool) -> int: - if self.aol.enable_aol: - lfa_icon = 2 if self.aol.lat_active else 3 if self.aol.disengaging else 1 if self.aol.paused else 0 - else: - lfa_icon = 2 if enabled else 0 - - return lfa_icon - - def update(self, CP: structs.CarParams, CC: structs.CarControl, CC_IQ: structs.IQCarControl, frame: int) -> None: - self.aol = self.aol_status_update(CC, CC_IQ, frame) - self.lkas_icon = self.create_lkas_icon(CP, CC.enabled) - self.lfa_icon = self.create_lfa_icon(CC.enabled) - - -class AolCarState(AolCarStateBase): - def __init__(self, CP: structs.CarParams, CP_IQ: structs.CarParams): - super().__init__(CP, CP_IQ) - self.main_cruise_enabled: bool = False - - @staticmethod - def get_parser(CP, CP_IQ, pt_messages) -> None: - pass - - def get_main_cruise(self, ret: structs.CarState) -> bool: - if self.CP_IQ.flags & HyundaiFlagsIQ.MAIN_BTN_LONG_TOGGLE: - if any(be.type == ButtonType.mainCruise and be.pressed for be in ret.buttonEvents): - self.main_cruise_enabled = not self.main_cruise_enabled - else: - self.main_cruise_enabled = True - - return self.main_cruise_enabled if ret.cruiseState.available else False - - def update_aol(self, ret: structs.CarState, can_parsers: dict[StrEnum, CANParser]) -> None: - pass - - def update_aol_canfd(self, ret: structs.CarState, can_parsers: dict[StrEnum, CANParser]) -> None: - cp = can_parsers[Bus.pt] - cp_cam = can_parsers[Bus.cam] - - if not self.CP.openpilotLongitudinalControl: - cp_cruise_info = cp_cam if self.CP.flags & HyundaiFlags.CANFD_CAMERA_SCC else cp - ret.cruiseState.available = cp_cruise_info.vl["SCC_CONTROL"]["MainMode_ACC"] == 1 diff --git a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/carstate_ext.py b/iqdbc_repo/iqdbc/iqpilot/car/hyundai/carstate_ext.py deleted file mode 100644 index b9415de..0000000 --- a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/carstate_ext.py +++ /dev/null @@ -1,79 +0,0 @@ -from enum import StrEnum - -from iqdbc.car import Bus, structs -from iqdbc.can.parser import CANParser -from iqdbc.car.hyundai.values import HyundaiFlags -from iqdbc.iqpilot.car.hyundai.values import HyundaiFlagsIQ - - -class CarStateExt: - def __init__(self, CP, CP_IQ): - self.CP = CP - self.CP_IQ = CP_IQ - - self.aBasis = 0.0 - - def update_speed_limit(self, cp, cp_cam) -> float: - speed_limit = 0 - - if self.CP.flags & HyundaiFlags.CANFD: - if self.CP_IQ.flags & HyundaiFlagsIQ.SPEED_LIMIT_AVAILABLE: - bus = cp if self.CP.flags & HyundaiFlags.CANFD_LKA_STEERING else cp_cam - speed_limit = bus.vl["FR_CMR_02_100ms"]["ISLW_SpdCluMainDis"] - else: - nav, cam = 0, 0 - if self.CP_IQ.flags & HyundaiFlagsIQ.SPEED_LIMIT_AVAILABLE: - nav = cp.vl["Navi_HU"]["SpeedLim_Nav_Clu"] - if self.CP_IQ.flags & HyundaiFlagsIQ.HAS_LKAS12: - cam = cp_cam.vl["LKAS12"]["CF_Lkas_TsrSpeed_Display_Clu"] - - speed_limit = cam if cam not in (0, 255) else nav - - if speed_limit in (0, 255): - speed_limit = 0 - - return speed_limit - - def update(self, ret: structs.CarState, ret_iq: structs.IQCarState, can_parsers: dict[StrEnum, CANParser], speed_conv: float) -> None: - cp = can_parsers[Bus.pt] - cp_cam = can_parsers[Bus.cam] - - self.aBasis = cp.vl["TCS13"]["aBasis"] - - if self.CP_IQ.flags & HyundaiFlagsIQ.NON_SCC: - cruise_msg = "LABEL11" if self.CP.flags & HyundaiFlags.EV else \ - "E_CRUISE_CONTROL" if self.CP.flags & HyundaiFlags.HYBRID else \ - "EMS16" - cruise_available_sig = "CC_React" if self.CP.flags & HyundaiFlags.EV else "CRUISE_LAMP_M" - cruise_enabled_sig = "CC_ACT" if self.CP.flags & HyundaiFlags.EV else "CRUISE_LAMP_S" - cruise_speed_msg = "E_EMS11" if self.CP.flags & HyundaiFlags.EV else \ - "ELECT_GEAR" if self.CP.flags & HyundaiFlags.HYBRID else \ - "LVR12" - cruise_speed_sig = "Cruise_Limit_Target" if self.CP.flags & HyundaiFlags.EV else \ - "SLC_SET_SPEED" if self.CP.flags & HyundaiFlags.HYBRID else \ - "CF_Lvr_CruiseSet" - ret.cruiseState.available = cp.vl[cruise_msg][cruise_available_sig] != 0 - ret.cruiseState.enabled = cp.vl[cruise_msg][cruise_enabled_sig] != 0 - ret.cruiseState.speed = cp.vl[cruise_speed_msg][cruise_speed_sig] * speed_conv - ret.cruiseState.standstill = False - ret.cruiseState.nonAdaptive = False - - if not self.CP_IQ.flags & HyundaiFlagsIQ.NON_SCC_NO_FCA: - cp_cruise = cp if self.CP_IQ.flags & HyundaiFlagsIQ.NON_SCC_RADAR_FCA else cp_cam - - aeb_src = "FCA11" - aeb_warning = cp_cruise.vl[aeb_src]["CF_VSM_Warn"] != 0 - aeb_braking = cp_cruise.vl[aeb_src]["CF_VSM_DecCmdAct"] != 0 or cp_cruise.vl[aeb_src]["FCA_CmdAct"] != 0 - ret.stockFcw = aeb_warning and not aeb_braking - ret.stockAeb = aeb_warning and aeb_braking - - ret_iq.speedLimit = self.update_speed_limit(cp, cp_cam) * speed_conv - - def update_canfd_ext(self, ret: structs.CarState, ret_iq: structs.IQCarState, can_parsers: dict[StrEnum, CANParser], - speed_factor: float) -> None: - cp = can_parsers[Bus.pt] - cp_cam = can_parsers[Bus.cam] - - self.aBasis = cp.vl["TCS"]["aBasis"] - - ret_iq.speedLimit = self.update_speed_limit(cp, cp_cam) * speed_factor diff --git a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/enable_radar_tracks.py b/iqdbc_repo/iqdbc/iqpilot/car/hyundai/enable_radar_tracks.py deleted file mode 100644 index bb554eb..0000000 --- a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/enable_radar_tracks.py +++ /dev/null @@ -1,67 +0,0 @@ -from iqdbc.car import uds -from iqdbc.car.carlog import carlog -from iqdbc.car.isotp_parallel_query import IsoTpParallelQuery - -DEVELOPER_DIAGNOSTIC = 0x07 -CUSTOM_DIAGNOSTIC_REQUEST = bytes([uds.SERVICE_TYPE.DIAGNOSTIC_SESSION_CONTROL, DEVELOPER_DIAGNOSTIC]) -CUSTOM_DIAGNOSTIC_RESPONSE = bytes([uds.SERVICE_TYPE.DIAGNOSTIC_SESSION_CONTROL + 0x40, DEVELOPER_DIAGNOSTIC]) - -READ_DATA_REQUEST = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER]) -READ_DATA_RESPONSE = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER + 0x40]) - -WRITE_DATA_REQUEST = bytes([uds.SERVICE_TYPE.WRITE_DATA_BY_IDENTIFIER]) -WRITE_DATA_RESPONSE = bytes([uds.SERVICE_TYPE.WRITE_DATA_BY_IDENTIFIER + 0x40]) - -CONFIG_DATA_ID = bytes([0x01, 0x42]) -DEFAULT_CONFIG = bytes([0x00, 0x00, 0x00, 0x01, 0x00, 0x00]) -TRACKS_ENABLED_CONFIG = bytes([0x00, 0x00, 0x00, 0x01, 0x00, 0x01]) -TRACKS_ENABLED_CONFIG_BYTES = b"\x00\x00\x01\x00\x01" - - -def enable_radar_tracks(logcan, sendcan, bus=0, addr=0x7d0, timeout=0.1, retry=2): - carlog.error("radar_tracks: enabling ...") - - for i in range(retry): - try: - query = IsoTpParallelQuery(sendcan, logcan, bus, [addr], [CUSTOM_DIAGNOSTIC_REQUEST], [CUSTOM_DIAGNOSTIC_RESPONSE]) - - for _, _ in query.get_data(timeout).items(): - carlog.error("radar_tracks: check current config ...") - - request = READ_DATA_REQUEST + CONFIG_DATA_ID - query = IsoTpParallelQuery(sendcan, logcan, bus, [addr], [request], [READ_DATA_RESPONSE]) - - for _, data in query.get_data(timeout).items(): - current_config = data[3:] - - carlog.error(f"radar_tracks: current config: {current_config.hex()}") - - if current_config == TRACKS_ENABLED_CONFIG_BYTES: - carlog.error("radar_tracks: already enabled, skipping ...") - else: - carlog.error("radar_tracks: reconfigure radar to output radar points ...") - request = WRITE_DATA_REQUEST + CONFIG_DATA_ID + TRACKS_ENABLED_CONFIG - query = IsoTpParallelQuery(sendcan, logcan, bus, [addr], [request], [WRITE_DATA_RESPONSE]) - query.get_data(0) - - carlog.error("radar_tracks: successfully enabled") - - return True - - except Exception as e: - carlog.exception(f"radar_tracks exception: {e}") - - carlog.error(f"radar_tracks retry ({i + 1}) ...") - carlog.error("radar_tracks: failed") - return False - - -if __name__ == "__main__": - import time - import cereal.messaging as messaging - sendcan = messaging.pub_sock('sendcan') - logcan = messaging.sub_sock('can') - time.sleep(1) - - enabled = enable_radar_tracks(logcan, sendcan, bus=0, addr=0x7d0, timeout=0.1) - print(f"enabled: {enabled}") diff --git a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/escc.py b/iqdbc_repo/iqdbc/iqpilot/car/hyundai/escc.py deleted file mode 100644 index 1e0ab77..0000000 --- a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/escc.py +++ /dev/null @@ -1,51 +0,0 @@ -from iqdbc.car import structs - -from iqdbc.iqpilot.car.hyundai.values import HyundaiFlagsIQ - -ESCC_MSG = 0x2AB - - -class EnhancedSmartCruiseControl: - def __init__(self, CP: structs.CarParams, CP_IQ: structs.IQCarParams): - self.CP = CP - self.CP_IQ = CP_IQ - - @property - def enabled(self): - return self.CP_IQ.flags & HyundaiFlagsIQ.ENHANCED_SCC - - @property - def trigger_msg(self): - return ESCC_MSG - - def update_car_state(self, car_state): - self.car_state = car_state - - def update_scc12(self, values): - values["AEB_CmdAct"] = self.car_state.escc_cmd_act - values["CF_VSM_Warn"] = self.car_state.escc_aeb_warning - values["CF_VSM_DecCmdAct"] = self.car_state.escc_aeb_dec_cmd_act - values["CR_VSM_DecCmd"] = self.car_state.escc_aeb_dec_cmd - values["AEB_Status"] = 2 # AEB enabled - - -class EsccCarStateBase: - def __init__(self): - self.escc_aeb_warning = 0 - self.escc_aeb_dec_cmd_act = 0 - self.escc_cmd_act = 0 - self.escc_aeb_dec_cmd = 0 - - -class EsccCarController: - def __init__(self, CP: structs.CarParams, CP_IQ: structs.IQCarParams): - self.ESCC = EnhancedSmartCruiseControl(CP, CP_IQ) - - def update(self, car_state): - self.ESCC.update_car_state(car_state) - - -class EsccRadarInterfaceBase: - def __init__(self, CP: structs.CarParams, CP_IQ: structs.IQCarParams): - self.ESCC = EnhancedSmartCruiseControl(CP, CP_IQ) - self.use_escc = False diff --git a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/fingerprints_ext.py b/iqdbc_repo/iqdbc/iqpilot/car/hyundai/fingerprints_ext.py deleted file mode 100644 index 4dc8679..0000000 --- a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/fingerprints_ext.py +++ /dev/null @@ -1,95 +0,0 @@ -from iqdbc.car.structs import CarParams -from iqdbc.car.hyundai.values import CAR - -Ecu = CarParams.Ecu - - -FW_VERSIONS_EXT = { - CAR.KIA_CEED_PHEV_2022_NON_SCC: { - (Ecu.eps, 0x7D4, None): [ - b'\xf1\x00CD MDPS C 1.00 1.01 56310-XX000 4CPHC101', - ], - (Ecu.fwdCamera, 0x7C4, None): [ - b'\xf1\x00CDH LKAS AT EUR LHD 1.00 1.01 99211-CR700 931', - ], - }, - CAR.GENESIS_G70_2021_NON_SCC: { - (Ecu.eps, 0x7d4, None): [ - b'\xf1\x00IK MDPS R 1.00 1.08 57700-G9200 4I2CL108', - ], - (Ecu.fwdRadar, 0x7d0, None): [ - b'\xf1\x00IK__ SCC --CUP 1.00 1.02 96400-G9100 ', - ], - (Ecu.fwdCamera, 0x7c4, None): [ - b'\xf1\x00IK MFC MT USA LHD 1.00 1.01 95740-G9000 170920', - ], - }, - CAR.HYUNDAI_KONA_NON_SCC: { - (Ecu.eps, 0x7d4, None): [ - b'\xf1\x00OS MDPS C 1.00 1.05 56310J9030\x00 4OSDC105', - b'\xf1\x00OS MDPS C 1.00 1.04 56310J9030\x00 4OSDC104', - ], - (Ecu.fwdCamera, 0x7c4, None): [ - b'\xf1\x00OS9 LKAS AT USA LHD 1.00 1.00 95740-J9200 g30', - ], - (Ecu.transmission, 0x7e1, None): [ - b'\xf1\x006T6J0_C2\x00\x006T6K1051\x00\x00TOS4N20NS2\x00\x00\x00\x00', - ], - }, - CAR.KIA_FORTE_2019_NON_SCC: { - (Ecu.eps, 0x7D4, None): [ - b'\xf1\x00BD MDPS C 1.00 1.04 56310/M6000 4BDDC104', - b'\xf1\x00BD MDPS C 1.00 1.05 56310/M6000 4BDDC105', - ], - (Ecu.fwdCamera, 0x7C4, None): [ - b'\xf1\x00BD LKAS AT USA LHD 1.00 1.02 95740-M6000 J31', - ], - }, - CAR.KIA_FORTE_2021_NON_SCC: { - (Ecu.eps, 0x7D4, None): [ - b'\xf1\x00BD MDPS C 1.00 1.08 56310M6000\x00 4BDDC108', - ], - (Ecu.fwdCamera, 0x7C4, None): [ - b'\xf1\x00BD LKAS AT USA LHD 1.00 1.04 95740-M6000 J33', - ], - }, - CAR.KIA_SELTOS_2023_NON_SCC: { - (Ecu.abs, 0x7d1, None): [ - b'\xf1\x00SP ESC \t 101"\t\x01 58910-Q5510', - b'\xf1\x00SP ESC \r 100"\x04\x01 58910-Q5510', - ], - (Ecu.eps, 0x7d4, None): [ - b'\xf1\x00SP2 MDPS C 1.00 1.04 56310Q5240 4SPSC104', - b'\xf1\x00SP2 MDPS C 1.00 1.01 56300Q5920 ', - ], - (Ecu.fwdCamera, 0x7c4, None): [ - b'\xf1\x00SP2 MFC AT USA LHD 1.00 1.03 99210-Q5500 230208', - b'\xf1\x00SP2 MFC AT AUS RHD 1.00 1.02 99210-Q5500 220624', - ], - (Ecu.transmission, 0x7e1, None): [ - b'\xf1\x006V2B0_C2\x00\x006V2D5051\x00\x00CSP2N20NL0\x00\x00\x00\x00', - b'\xf1\x006V2B0_C2\x00\x006V2D4051\x00\x00CSP2N20KL1\x00\x00\x00\x00', - ], - }, - CAR.HYUNDAI_ELANTRA_2022_NON_SCC: { - (Ecu.eps, 0x7d4, None): [ - b'\xf1\x00CN7 MDPS R 1.00 1.04 57700-IB000 4CNNP104', - ], - (Ecu.fwdCamera, 0x7c4, None): [ - b'\xf1\x00CN7 MFC AT USA LHD 1.00 1.01 99210-AB000 210205', - b'\xf1\x00CN7 MFC AT USA LHD 1.00 1.00 99210-IB000 210531', - ], - (Ecu.abs, 0x7d1, None): [ - b'\xf1\x00CN ESC \t 100!\x05\x01 58910-IB000', - ], - (Ecu.transmission, 0x7e1, None): [ - b'\xf1\x00T02601BL T02900A1 WCN7T20XXX900NS4\xf7\xccz\xf6', - ], - }, - CAR.HYUNDAI_BAYON_1ST_GEN_NON_SCC: { - # TODO: Check working route for more FW - (Ecu.fwdCamera, 0x7c4, None): [ - b'\xf1\x00BC3 LKA AT EUR LHD 1.00 1.01 99211-Q0100 261' - ], - }, -} diff --git a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/lead_data_ext.py b/iqdbc_repo/iqdbc/iqpilot/car/hyundai/lead_data_ext.py deleted file mode 100644 index f2c77de..0000000 --- a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/lead_data_ext.py +++ /dev/null @@ -1,111 +0,0 @@ -from abc import ABC, abstractmethod -from iqdbc.car import structs -from iqdbc.car.hyundai.values import HyundaiFlags - - -class LeadData(ABC): - def __init__(self, object_gap: int, lead_distance: float, lead_rel_speed: float, lead_visible: bool): - self.object_gap = object_gap - self.lead_distance = lead_distance - self.lead_rel_speed = lead_rel_speed - self.lead_visible = lead_visible - - @property - @abstractmethod - def object_rel_gap(self) -> int: - raise NotImplementedError("Subclasses must implement this method") - - -class CanLeadData(LeadData): - @property - def object_rel_gap(self) -> int: - return 0 if self.lead_distance == 0 else 2 if self.lead_rel_speed < -0.2 else 1 - - -class CanFdLeadData(LeadData): - @property - def object_rel_gap(self) -> int: - return 0 if not self.lead_visible else 2 if self.lead_rel_speed < 0 else 1 - - -def _hysteresis_update(current, new_value, counter, threshold): - """ - Updates a value based on a hysteresis threshold mechanism. This function - compares a new value against the current value and uses a counter to detect - when a transition should occur, avoiding rapid oscillations between states. - A new value will only be adopted if it differs from the current value and - the counter reaches the specified threshold. - - :param current: The current value being tracked. - :param new_value: The potential new value to compare against the current. - :param counter: The count of consecutive different values encountered. - :param threshold: The minimum count required before switching to the new value. - :return: A tuple containing: - - The updated current value, which is either the original current - value or the new value if the hysteresis condition was met. - - The updated counter, reset to 0 if the new value was adopted, - or incremented by 1 otherwise. - """ - if new_value == current: - return current, 0 - counter += 1 - return (new_value, 0) if counter >= threshold else (current, counter) - - -class LeadDataCarController: - # Hysteresis parameters - LEAD_HYSTERESIS_FRAMES: int = 50 - - def __init__(self, CP: structs.CarParams): - self.CP = CP - - self.lead_one = {} - self.lead_two = {} - - self._lead_on_counter = 0 - self._lead_off_counter = 0 - self.lead_visible = False - self.gap_counter = 0 - self.object_gap = 0 - self.lead_distance = 0 - self.lead_rel_speed = 0 - - def _update_object_gap(self, lead_distance: float | None): - new_gap = 5 # Default gap value if no lead distance is provided - if lead_distance is None or lead_distance == 0: - new_gap = 0 - elif lead_distance < 20: - new_gap = 2 - elif lead_distance < 25: - new_gap = 3 - elif lead_distance < 30: - new_gap = 4 - - self.object_gap, self.gap_counter = _hysteresis_update(self.object_gap, new_gap, self.gap_counter, self.LEAD_HYSTERESIS_FRAMES) - - def _update_lead_visible_hysteresis(self, raw_lead_visible: bool): - counter = self._lead_on_counter if raw_lead_visible else self._lead_off_counter - self.lead_visible, counter = _hysteresis_update(self.lead_visible, raw_lead_visible, counter, self.LEAD_HYSTERESIS_FRAMES) - - if raw_lead_visible: - self._lead_on_counter = counter - self._lead_off_counter = 0 # reset opposite counter - else: - self._lead_off_counter = counter - self._lead_on_counter = 0 # reset opposite counter - - def update(self, CC_IQ: structs.IQCarControl) -> None: - self.lead_one = CC_IQ.leadOne - self.lead_two = CC_IQ.leadTwo - - self.lead_distance = self.lead_one.dRel - self.lead_rel_speed = self.lead_one.vRel - self._update_lead_visible_hysteresis(self.lead_one.status) - self._update_object_gap(self.lead_distance) - - @property - def lead_data(self) -> CanLeadData | CanFdLeadData: - if self.CP.flags & HyundaiFlags.CANFD: - return CanFdLeadData(self.object_gap, self.lead_distance, self.lead_rel_speed, self.lead_visible) - - return CanLeadData(self.object_gap, self.lead_distance, self.lead_rel_speed, self.lead_visible) diff --git a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/longitudinal/__init__.py b/iqdbc_repo/iqdbc/iqpilot/car/hyundai/longitudinal/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/longitudinal/config.py b/iqdbc_repo/iqdbc/iqpilot/car/hyundai/longitudinal/config.py deleted file mode 100644 index dc04044..0000000 --- a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/longitudinal/config.py +++ /dev/null @@ -1,49 +0,0 @@ -from dataclasses import dataclass, field - -from iqdbc.car.hyundai.values import CAR - - -@dataclass -class CarTuningConfig: - lookahead_jerk_bp: list[float] = field(default_factory=lambda: [5., 20.]) - lookahead_jerk_upper_v: list[float] = field(default_factory=lambda: [0.25, 0.5]) - lookahead_jerk_lower_v: list[float] = field(default_factory=lambda: [0.15, 0.3]) - longitudinal_actuator_delay: float = 0.45 - jerk_limits: float = 4.0 - - -# Default configurations for different car types -TUNING_CONFIGS = { - "CANFD": CarTuningConfig( - lookahead_jerk_bp=[2., 5., 20.], - lookahead_jerk_upper_v=[0.25, 0.5, 1.0], - lookahead_jerk_lower_v=[0.05, 0.10, 0.325], - ), - "EV": CarTuningConfig( - lookahead_jerk_upper_v=[0.3, 0.7], - lookahead_jerk_lower_v=[0.2, 0.4], - ), - "HYBRID": CarTuningConfig(), - "DEFAULT": CarTuningConfig( - lookahead_jerk_bp=[2., 5., 20.], - lookahead_jerk_upper_v=[0.25, 0.5, 1.0], - lookahead_jerk_lower_v=[0.05, 0.10, 0.3], - ) -} - -# Car-specific configs -CAR_SPECIFIC_CONFIGS = { - CAR.KIA_NIRO_EV: CarTuningConfig( - lookahead_jerk_upper_v=[0.3, 1.0], - lookahead_jerk_lower_v=[0.2, 0.4], - jerk_limits=2.5, - ), - CAR.KIA_NIRO_PHEV_2022: CarTuningConfig( - lookahead_jerk_upper_v=[0.3, 1.0], - lookahead_jerk_lower_v=[0.15, 0.3], - jerk_limits=4.0, - ), - CAR.HYUNDAI_IONIQ: CarTuningConfig( - jerk_limits=4.5, - ) -} diff --git a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/longitudinal/controller.py b/iqdbc_repo/iqdbc/iqpilot/car/hyundai/longitudinal/controller.py deleted file mode 100644 index 78c2546..0000000 --- a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/longitudinal/controller.py +++ /dev/null @@ -1,288 +0,0 @@ -import numpy as np -from dataclasses import dataclass - -from iqdbc.car import structs, DT_CTRL -from iqdbc.car.interfaces import CarStateBase -from iqdbc.car.hyundai.values import CarControllerParams -from iqdbc.iqpilot.car.hyundai.longitudinal.helpers import get_car_config, jerk_limited_integrator, ramp_update -from iqdbc.iqpilot.car.hyundai.values import HyundaiFlagsIQ - -LongCtrlState = structs.CarControl.Actuators.LongControlState - -MIN_JERK = 0.5 -COMFORT_BAND_VAL = 0.01 - -DYNAMIC_LOWER_JERK_BP = [-2.0, -1.5, -1.0, -0.25, -0.1, -0.025, -0.01, -0.005] -DYNAMIC_LOWER_JERK_V = [3.3, 2.5, 2.0, 1.9, 1.8, 1.65, 1.15, 0.5] - - -@dataclass -class LongitudinalState: - desired_accel: float = 0.0 - actual_accel: float = 0.0 - accel_last: float = 0.0 - jerk_upper: float = 0.0 - jerk_lower: float = 0.0 - comfort_band_upper: float = 0.0 - comfort_band_lower: float = 0.0 - stopping: bool = False - - -class LongitudinalController: - """Longitudinal controller which gets injected into CarControllerParams.""" - - def __init__(self, CP: structs.CarParams, CP_IQ: structs.IQCarParams) -> None: - self.CP = CP - self.CP_IQ = CP_IQ - - self.tuning = LongitudinalState() - self.car_config = get_car_config(CP) - self.long_control_state_last = LongCtrlState.off - self.stopping_count = 0 - - self.accel_cmd = 0.0 - self.desired_accel = 0.0 - self.actual_accel = 0.0 - self.accel_last = 0.0 - self.jerk_upper = 0.0 - self.jerk_lower = 0.0 - self.comfort_band_upper = 0.0 - self.comfort_band_lower = 0.0 - self.stopping = False - - @property - def enabled(self) -> bool: - return bool(self.CP_IQ.flags & (HyundaiFlagsIQ.LONG_TUNING_DYNAMIC | HyundaiFlagsIQ.LONG_TUNING_PREDICTIVE)) - - def get_stopping_state(self, actuators: structs.CarControl.Actuators) -> None: - stopping = actuators.longControlState == LongCtrlState.stopping - - # If custom tuning is not enabled, use upstream stopping logic - if not self.enabled: - self.stopping = stopping - self.stopping_count = 0 - return - - # Reset stopping state when not in stopping mode - if not stopping: - self.stopping = False - self.stopping_count = 0 - return - - # When transitioning from off state to stopping - if self.long_control_state_last == LongCtrlState.off: - self.stopping = True - return - - # Keep track of time in stopping state (in control cycles) - if self.stopping_count > 1 / (DT_CTRL * 2): - self.stopping = True - - self.stopping_count += 1 - - @staticmethod - def _calculate_speed_based_jerk_limits(velocity: float, long_control_state: LongCtrlState) -> tuple[float, float]: - """Calculate jerk limits based on vehicle speed according to ISO 15622:2018. - - Args: - velocity: Current vehicle speed (m/s) - long_control_state: Current longitudinal control state - - Returns: - Tuple of (upper_limit, lower_limit) in m/s³ - """ - - # Upper jerk limit varies based on speed and control state - if long_control_state == LongCtrlState.pid: - upper_limit = float(np.interp(velocity, [0.0, 5.0, 20.0], [2.0, 3.0, 1.6])) - else: - upper_limit = 0.5 # Default for non-PID states - - # Lower jerk limit varies based on speed - lower_limit = float(np.interp(velocity, [0.0, 5.0, 20.0], [5.0, 4.0, 2.5])) - - return upper_limit, lower_limit - - def _calculate_lookahead_jerk(self, accel_error: float, velocity: float) -> tuple[float, float]: - """Calculate lookahead jerk needed to reach target acceleration. - - Args: - accel_error: Difference between target and current acceleration (m/s²) - velocity: Current vehicle speed (m/s) - - Returns: - Tuple of (upper_jerk, lower_jerk) in m/s³ - """ - - # Time window to reach target acceleration, varies with speed - future_t_upper = float(np.interp(velocity, self.car_config.lookahead_jerk_bp, self.car_config.lookahead_jerk_upper_v)) - future_t_lower = float(np.interp(velocity, self.car_config.lookahead_jerk_bp, self.car_config.lookahead_jerk_lower_v)) - - # Required jerk to reach target acceleration in lookahead window - j_ego_upper = accel_error / future_t_upper - j_ego_lower = accel_error / future_t_lower - - return j_ego_upper, j_ego_lower - - def _calculate_dynamic_lower_jerk(self, accel_error: float, velocity: float) -> float: - """Calculate dynamic jerk for braking based on acceleration error. - - Used for the dynamic tuning approach (non-predictive). - - Args: - accel_error: Difference between actual and previous acceleration (m/s²) - velocity: Current vehicle speed (m/s) - - Returns: - Dynamic lower jerk limit (m/s³) - """ - - if self.CP.radarUnavailable: - return 5.0 - - if accel_error < 0: - # Scale the brake jerk values based on car config - lower_max = self.car_config.jerk_limits - original_values = np.array(DYNAMIC_LOWER_JERK_V) - scaled_values = original_values * (lower_max / original_values[0]) - - # Interpolate based on acceleration error - dynamic_lower_jerk = float(np.interp(accel_error, DYNAMIC_LOWER_JERK_BP, scaled_values)) - else: - dynamic_lower_jerk = 0.5 - - return dynamic_lower_jerk - - def calculate_jerk(self, CC: structs.CarControl, CS: CarStateBase, long_control_state: LongCtrlState) -> None: - """Calculate appropriate jerk limits for smooth acceleration/deceleration. - - Args: - CC: Car control signals - CS: Car state - long_control_state: Current longitudinal control state - """ - - # If custom tuning is disabled, use upstream fixed values - if not self.enabled: - jerk_limit = 3.0 if long_control_state == LongCtrlState.pid else 1.0 - self.jerk_upper = jerk_limit - self.jerk_lower = 5.0 - return - - velocity = CS.out.vEgo - accel_error = self.accel_cmd - self.accel_last - - # Calculate jerk limits based on speed - upper_speed_factor, lower_speed_factor = self._calculate_speed_based_jerk_limits(velocity, long_control_state) - - # Calculate lookahead jerk - j_ego_upper, j_ego_lower = self._calculate_lookahead_jerk(accel_error, velocity) - - # Calculate lower jerk limit - lower_jerk = max(-j_ego_lower, MIN_JERK) - if self.CP.radarUnavailable: - lower_jerk = 5.0 - - # Final jerk limits with thresholds - desired_jerk_upper = min(max(j_ego_upper, MIN_JERK), upper_speed_factor) - desired_jerk_lower = min(lower_jerk, lower_speed_factor) - - # Calculate dynamic lower jerk for non-predictive tuning - a_ego_blended = float(np.interp(velocity, [1.0, 2.0], [CS.aBasis, CS.out.aEgo])) - dynamic_accel_error = a_ego_blended - self.accel_last - dynamic_lower_jerk = self._calculate_dynamic_lower_jerk(dynamic_accel_error, velocity) - dynamic_desired_lower_jerk = min(dynamic_lower_jerk, lower_speed_factor) - - # Apply jerk limits based on tuning approach - self.jerk_upper = ramp_update(self.jerk_upper, desired_jerk_upper) - - # Predictive tuning uses calculated desired jerk directly - # Dynamic tuning applies a ramped approach for smoother transitions - if self.CP_IQ.flags & HyundaiFlagsIQ.LONG_TUNING_PREDICTIVE: - self.jerk_lower = desired_jerk_lower - else: - self.jerk_lower = ramp_update(self.jerk_lower, dynamic_desired_lower_jerk) - - # Disable jerk when longitudinal control is inactive - if not CC.longActive: - self.jerk_upper = 0.0 - self.jerk_lower = 0.0 - - def calculate_accel(self, CC: structs.CarControl) -> None: - """Calculate commanded acceleration using jerk-limited approach. - - Args: - CC: Car control signals - """ - - # Skip custom processing if tuning is disabled or radar unavailable - if not self.enabled or self.CP.radarUnavailable: - self.desired_accel = self.accel_cmd - self.actual_accel = self.accel_cmd - return - - # Reset acceleration when control is inactive - if not CC.longActive: - self.desired_accel = 0.0 - self.actual_accel = 0.0 - self.accel_last = 0.0 - return - - # Force zero acceleration during stopping - if self.stopping: - self.desired_accel = 0.0 - else: - self.desired_accel = float(np.clip(self.accel_cmd, CarControllerParams.ACCEL_MIN, CarControllerParams.ACCEL_MAX)) - - # Apply jerk-limited integration to get smooth acceleration - self.actual_accel = jerk_limited_integrator(self.desired_accel, self.accel_last, self.jerk_upper, self.jerk_lower) - - self.accel_last = self.actual_accel - - def calculate_comfort_band(self, CC: structs.CarControl) -> None: - if not self.enabled or self.CP.radarUnavailable or not CC.longActive: - self.comfort_band_upper = 0.0 - self.comfort_band_lower = 0.0 - return - - self.comfort_band_upper = COMFORT_BAND_VAL - self.comfort_band_lower = COMFORT_BAND_VAL - - def get_tuning_state(self) -> None: - """Update the tuning state object with current control values. - - External components depend on this state for longitudinal control. - """ - - self.tuning = LongitudinalState( - desired_accel=self.desired_accel, - actual_accel=self.actual_accel, - accel_last=self.accel_last, - jerk_upper=self.jerk_upper, - jerk_lower=self.jerk_lower, - comfort_band_upper=self.comfort_band_upper, - comfort_band_lower=self.comfort_band_lower, - stopping=self.stopping, - ) - - def update(self, CC: structs.CarControl, CS: CarStateBase) -> None: - """Update longitudinal control calculations. - - This is the main entry point called externally. - - Args: - CC: Car control signals including actuators - CS: Car state information - """ - - actuators = CC.actuators - long_control_state = actuators.longControlState - self.accel_cmd = CC.actuators.accel - - self.get_stopping_state(actuators) - self.calculate_jerk(CC, CS, long_control_state) - self.calculate_accel(CC) - self.calculate_comfort_band(CC) - self.get_tuning_state() - - self.long_control_state_last = long_control_state diff --git a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/longitudinal/helpers.py b/iqdbc_repo/iqdbc/iqpilot/car/hyundai/longitudinal/helpers.py deleted file mode 100644 index 3cbe20e..0000000 --- a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/longitudinal/helpers.py +++ /dev/null @@ -1,52 +0,0 @@ -import numpy as np - -from iqdbc.car import structs, DT_CTRL, rate_limit -from iqdbc.car.hyundai.values import HyundaiFlags -from iqdbc.iqpilot.car.hyundai.longitudinal.config import CarTuningConfig, TUNING_CONFIGS, CAR_SPECIFIC_CONFIGS - -JERK_THRESHOLD = 0.1 -JERK_STEP = 0.1 - - -class LongitudinalTuningType: - OFF = 0 - DYNAMIC = 1 - PREDICTIVE = 2 - - -def get_car_config(CP: structs.CarParams) -> CarTuningConfig: - # Get car type flags from specific configs or determine from car flags - car_config = CAR_SPECIFIC_CONFIGS.get(CP.carFingerprint) - # If car is not in specific configs, determine from flags - if car_config is None: - if CP.flags & HyundaiFlags.CANFD: - car_config = TUNING_CONFIGS["CANFD"] - elif CP.flags & HyundaiFlags.EV: - car_config = TUNING_CONFIGS["EV"] - elif CP.flags & HyundaiFlags.HYBRID: - car_config = TUNING_CONFIGS["HYBRID"] - else: - car_config = TUNING_CONFIGS["DEFAULT"] - - return car_config - - -def get_longitudinal_tune(CP: structs.CarParams) -> None: - config = get_car_config(CP) - CP.longitudinalActuatorDelay = config.longitudinal_actuator_delay - - -def jerk_limited_integrator(desired_accel, last_accel, jerk_upper, jerk_lower) -> float: - if desired_accel >= last_accel: - val = jerk_upper * DT_CTRL * 2 - else: - val = jerk_lower * DT_CTRL * 2 - - return rate_limit(desired_accel, last_accel, -val, val) - - -def ramp_update(current, target): - error = target - current - if abs(error) > JERK_THRESHOLD: - return current + float(np.clip(error, -JERK_STEP, JERK_STEP)) - return target diff --git a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/radar_interface_ext.py b/iqdbc_repo/iqdbc/iqpilot/car/hyundai/radar_interface_ext.py deleted file mode 100644 index ff8c9f7..0000000 --- a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/radar_interface_ext.py +++ /dev/null @@ -1,85 +0,0 @@ -from iqdbc.can.parser import CANParser -from iqdbc.car import structs, Bus -from iqdbc.car.hyundai.hyundaicanfd import CanBus -from iqdbc.car.hyundai.values import DBC, HyundaiFlags - -from iqdbc.iqpilot.car.hyundai.escc import EsccRadarInterfaceBase - - -class RadarInterfaceExt(EsccRadarInterfaceBase): - msg_src: str - trigger_msg: int - rcp: CANParser - pts: dict[int, structs.RadarData.RadarPoint] - - def __init__(self, CP: structs.CarParams, CP_IQ: structs.IQCarParams): - EsccRadarInterfaceBase.__init__(self, CP, CP_IQ) - self.CP = CP - self.CP_IQ = CP_IQ - - self.track_id = 0 - - @property - def use_radar_interface_ext(self) -> bool: - return self.use_escc or self.CP.flags & (HyundaiFlags.CAMERA_SCC | HyundaiFlags.CANFD_CAMERA_SCC) - - def get_msg_src(self) -> str | None: - if self.use_escc: - return "ESCC" - if self.CP.flags & (HyundaiFlags.CAMERA_SCC | HyundaiFlags.CANFD_CAMERA_SCC): - return "SCC_CONTROL" if self.CP.flags & HyundaiFlags.CANFD_CAMERA_SCC else "SCC11" - - def get_radar_ext_can_parser(self) -> CANParser: - if self.ESCC.enabled: - lead_src, bus = "ESCC", 0 - elif self.CP.flags & (HyundaiFlags.CAMERA_SCC | HyundaiFlags.CANFD_CAMERA_SCC): - lead_src = "SCC_CONTROL" if self.CP.flags & HyundaiFlags.CANFD_CAMERA_SCC else "SCC11" - bus = CanBus(self.CP).CAM if self.CP.flags & HyundaiFlags.CANFD_CAMERA_SCC else 2 - else: - return None - - messages = [(lead_src, 50)] - return CANParser(DBC[self.CP.carFingerprint][Bus.pt], messages, bus) - - def get_trigger_msg(self, default_trigger_msg) -> int: - if self.ESCC.enabled: - return self.ESCC.trigger_msg - if self.CP.flags & (HyundaiFlags.CAMERA_SCC | HyundaiFlags.CANFD_CAMERA_SCC): - return 0x1A0 if self.CP.flags & HyundaiFlags.CANFD_CAMERA_SCC else 0x420 - return default_trigger_msg - - def initialize_radar_ext(self, default_trigger_msg) -> None: - if self.ESCC.enabled: - self.use_escc = True - - self.rcp = self.get_radar_ext_can_parser() - self.trigger_msg = self.get_trigger_msg(default_trigger_msg) - - def update_ext(self, ret: structs.RadarData) -> structs.RadarData: - if not self.rcp.can_valid: - ret.errors.canError = True - return ret - - for ii in range(1): - msg_src = self.get_msg_src() - msg = self.rcp.vl[msg_src] - - if ii not in self.pts: - self.pts[ii] = structs.RadarData.RadarPoint() - self.pts[ii].trackId = self.track_id - self.track_id += 1 - - valid = msg['ACC_ObjDist'] < 204.6 if self.CP.flags & HyundaiFlags.CANFD_CAMERA_SCC else msg['ACC_ObjStatus'] - if valid: - self.pts[ii].measured = True - self.pts[ii].dRel = msg['ACC_ObjDist'] - self.pts[ii].yRel = float('nan') - self.pts[ii].vRel = msg['ACC_ObjRelSpd'] - self.pts[ii].aRel = float('nan') - self.pts[ii].yvRel = float('nan') - - else: - del self.pts[ii] - - ret.points = list(self.pts.values()) - return ret diff --git a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/values.py b/iqdbc_repo/iqdbc/iqpilot/car/hyundai/values.py deleted file mode 100644 index 672943f..0000000 --- a/iqdbc_repo/iqdbc/iqpilot/car/hyundai/values.py +++ /dev/null @@ -1,25 +0,0 @@ -from enum import IntFlag - - -class HyundaiSafetyFlagsIQ: - DEFAULT = 0 - ESCC = 16 - MAIN_BTN_LONG_TOGGLE = 32 - HAS_LDA_BUTTON = 64 - NON_SCC = 128 - - -class HyundaiFlagsIQ(IntFlag): - ENHANCED_SCC = 1 - HAS_LFA_BUTTON = 2 - MAIN_BTN_LONG_TOGGLE = 2 ** 2 - ENABLE_RADAR_TRACKS_DEPRECATED = 2 ** 3 - LONG_TUNING_DYNAMIC = 2 ** 4 - LONG_TUNING_PREDICTIVE = 2 ** 5 - NON_SCC = 2 ** 6 - NON_SCC_RADAR_FCA = 2 ** 7 - NON_SCC_NO_FCA = 2 ** 8 - SPEED_LIMIT_AVAILABLE = 2 ** 9 - HAS_LKAS12 = 2 ** 10 - - diff --git a/iqdbc_repo/iqdbc/iqpilot/car/interfaces.py b/iqdbc_repo/iqdbc/iqpilot/car/interfaces.py index fce3fa6..c19f68a 100644 --- a/iqdbc_repo/iqdbc/iqpilot/car/interfaces.py +++ b/iqdbc_repo/iqdbc/iqpilot/car/interfaces.py @@ -8,11 +8,7 @@ from collections.abc import Callable from iqdbc.car import structs from iqdbc.car.can_definitions import CanRecvCallable, CanSendCallable -from iqdbc.car.hyundai.values import HyundaiFlags from iqdbc.car.subaru.values import SubaruFlags -from iqdbc.iqpilot.car.hyundai.enable_radar_tracks import enable_radar_tracks as hyundai_enable_radar_tracks -from iqdbc.iqpilot.car.hyundai.longitudinal.helpers import LongitudinalTuningType -from iqdbc.iqpilot.car.hyundai.values import HyundaiFlagsIQ from iqdbc.iqpilot.car.subaru.values_ext import SubaruFlagsIQ, SubaruSafetyFlagsIQ from iqdbc.iqpilot.car.tesla.values import TeslaFlagsIQ from iqdbc.iqpilot.car.toyota.values import ToyotaFlagsIQ @@ -81,7 +77,6 @@ def setup_interfaces(CI, CP: structs.CarParams, CP_IQ: structs.IQCarParams, _initialize_custom_longitudinal_tuning(CI, CP, CP_IQ, params_dict) _initialize_coop_steering(CP, CP_IQ, params_dict) - _initialize_radar_tracks(CP, CP_IQ, can_recv, can_send) _initialize_stop_and_go(CP, CP_IQ, params_dict) _initialize_toyota(CP, CP_IQ, params_dict) @@ -89,16 +84,6 @@ def setup_interfaces(CI, CP: structs.CarParams, CP_IQ: structs.IQCarParams, def _initialize_custom_longitudinal_tuning(CI, CP: structs.CarParams, CP_IQ: structs.IQCarParams, params_dict: dict[str, str]) -> None: - # HKG longitudinal tuning lineage in this port traces to Jason Wen, James - # Vecellio-Grant, and carrotpilot; keep that attribution with this path. - # Hyundai Custom Longitudinal Tuning - if CP.brand == 'hyundai': - hyundai_longitudinal_tuning = int(params_dict.get("HyundaiLongitudinalTuning", 0)) - if hyundai_longitudinal_tuning == LongitudinalTuningType.DYNAMIC: - CP_IQ.flags |= HyundaiFlagsIQ.LONG_TUNING_DYNAMIC.value - if hyundai_longitudinal_tuning == LongitudinalTuningType.PREDICTIVE: - CP_IQ.flags |= HyundaiFlagsIQ.LONG_TUNING_PREDICTIVE.value - _ = CI.get_longitudinal_tuning_iq(CP, CP_IQ) @@ -110,14 +95,6 @@ def _initialize_coop_steering(CP: structs.CarParams, CP_IQ: structs.IQCarParams, CP_IQ.flags |= TeslaFlagsIQ.COOP_STEERING.value -def _initialize_radar_tracks(CP: structs.CarParams, CP_IQ: structs.IQCarParams, - can_recv: CanRecvCallable | None = None, can_send: CanSendCallable | None = None) -> None: - if CP.brand == 'hyundai': - if CP.flags & HyundaiFlags.MANDO_RADAR and (CP.radarUnavailable or CP_IQ.flags & HyundaiFlagsIQ.ENHANCED_SCC): - tracks_enabled = hyundai_enable_radar_tracks(can_recv, can_send, bus=0, addr=0x7d0) - CP.radarUnavailable = not tracks_enabled - - 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 diff --git a/iqdbc_repo/iqdbc/safety/modes/hyundai.h b/iqdbc_repo/iqdbc/safety/modes/hyundai.h index f37d9dc..deaff48 100644 --- a/iqdbc_repo/iqdbc/safety/modes/hyundai.h +++ b/iqdbc_repo/iqdbc/safety/modes/hyundai.h @@ -3,6 +3,8 @@ #include "iqdbc/safety/declarations.h" #include "iqdbc/safety/modes/hyundai_common.h" +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" + #define HYUNDAI_LIMITS(steer, rate_up, rate_down) { \ .max_torque = (steer), \ .max_rate_up = (rate_up), \ @@ -21,96 +23,84 @@ extern const LongitudinalLimits HYUNDAI_LONG_LIMITS; const LongitudinalLimits HYUNDAI_LONG_LIMITS = { - .max_accel = 200, // 1/100 m/s2 - .min_accel = -350, // 1/100 m/s2 - .zero_accel = 0, + .max_accel = 250, // 1/100 m/s2 + .min_accel = -400, // 1/100 m/s2 }; -#define HYUNDAI_COMMON_TX_MSGS(scc_bus) \ - {0x340, 0, 8, .check_relay = true}, /* LKAS11 Bus 0 */ \ - {0x4F1, scc_bus, 4, .check_relay = false}, /* CLU11 Bus 0 (radar-SCC) or 2 (camera-SCC) */ \ - {0x485, 0, 4, .check_relay = true}, /* LFAHDA_MFC Bus 0 */ \ - -#define HYUNDAI_LONG_COMMON_TX_MSGS(scc_bus) \ - HYUNDAI_COMMON_TX_MSGS(scc_bus) \ - {0x420, 0, 8, .check_relay = true}, /* SCC11 Bus 0 */ \ - {0x421, 0, 8, .check_relay = true}, /* SCC12 Bus 0 */ \ - {0x50A, 0, 8, .check_relay = true}, /* SCC13 Bus 0 */ \ - {0x389, 0, 8, .check_relay = true}, /* SCC14 Bus 0 */ \ - {0x4A2, 0, 2, .check_relay = false}, /* FRT_RADAR11 Bus 0 */ \ - -#define HYUNDAI_COMMON_RX_CHECKS(legacy) \ - {.msg = {{0x260, 0, 8, 100U, .max_counter = 3U, .ignore_quality_flag = true}, \ - {0x371, 0, 8, 100U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }}}, \ - {.msg = {{0x386, 0, 8, 100U, .ignore_checksum = (legacy), .ignore_counter = (legacy), .max_counter = (legacy) ? 0U : 15U, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ - {.msg = {{0x394, 0, 8, 100U, .ignore_checksum = (legacy), .ignore_counter = (legacy), .max_counter = (legacy) ? 0U : 7U, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ - {.msg = {{0x251, 0, 8, 50U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ - {.msg = {{0x4F1, 0, 4, 50U, .ignore_checksum = true, .max_counter = 15U, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ - -#define HYUNDAI_SCC11_ADDR_CHECK(scc_bus) \ - {.msg = {{0x420, (scc_bus), 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true, .frequency = 50U}, { 0 }, { 0 }}}, \ - -#define HYUNDAI_SCC12_ADDR_CHECK(scc_bus) \ - {.msg = {{0x421, (scc_bus), 8, 50U, .max_counter = 15U, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ - -#define HYUNDAI_FCEV_GAS_ADDR_CHECK \ - {.msg = {{0x91, 0, 8, 100U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ - -#define HYUNDAI_LDA_BUTTON_ADDR_CHECK \ - {.msg = {{0x391, 0, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true, .frequency = 50U}, { 0 }, { 0 }}}, \ - -#define HYUNDAI_NON_SCC_HEV_ADDR_CHECK \ - {.msg = {{0x595U, 0, 8, 10U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ - -#define HYUNDAI_NON_SCC_EV_ADDR_CHECK \ - {.msg = {{0x592U, 0, 8, 10U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ - static const CanMsg HYUNDAI_TX_MSGS[] = { - HYUNDAI_COMMON_TX_MSGS(0) + {0x340, 0, 8}, // LKAS11 Bus 0 + {0x4F1, 0, 4}, // CLU11 Bus 0 + {0x485, 0, 8}, // LFAHDA_MFC Bus 0 + {593, 2, 8}, // MDPS12, Bus 2 + {1056, 0, 8}, // SCC11, Bus 0 + {1057, 0, 8}, // SCC12, Bus 0 + {1290, 0, 8}, // SCC13, Bus 0 + {905, 0, 8}, // SCC14, Bus 0 + {909, 0, 8}, // FCA11 Bus 0 + {1155, 0, 8}, // FCA12 Bus 0 + {1186, 0, 8}, // FRT_RADAR11, Bus 0 + {1265, 2, 4}, // CLU11, Bus 0, 2 + {0x7D0, 0, 8}, // radar UDS TX addr Bus 0 (for radar disable) // 2000 + {0x7b1, 0, 8}, }; -static bool hyundai_legacy = false; +#define HYUNDAI_COMMON_RX_CHECKS(legacy) \ + {.msg = {{0x260, 0, 8, .max_counter = 3U, .frequency = 100U}, \ + {0x371, 0, 8, .ignore_checksum = true, .ignore_counter = true, .frequency = 100U}, \ + {0x91, 0, 8, .ignore_checksum = true, .ignore_counter = true, .frequency = 100U}}}, \ + {.msg = {{0x386, 0, 8, .ignore_checksum = (legacy), .ignore_counter = (legacy), .max_counter = (legacy) ? 0U : 15U, .frequency = 100U}, { 0 }, { 0 }}}, \ + {.msg = {{0x394, 0, 8, .ignore_checksum = (legacy), .ignore_counter = (legacy), .max_counter = (legacy) ? 0U : 7U, .frequency = 100U}, { 0 }, { 0 }}}, \ -static uint8_t hyundai_get_counter(const CANPacket_t *msg) { +#define HYUNDAI_SCC12_ADDR_CHECK(scc_bus) \ + {.msg = {{0x421, (scc_bus), 8, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}}, \ + +static bool hyundai_legacy = false; +static bool hyundai_cruise_buttons_alt = false; + +static uint8_t hyundai_get_counter(const CANPacket_t *to_push) { + int addr = GET_ADDR(to_push); uint8_t cnt = 0; - if (msg->addr == 0x260U) { - cnt = (msg->data[7] >> 4) & 0x3U; - } else if (msg->addr == 0x386U) { - cnt = ((msg->data[3] >> 6) << 2) | (msg->data[1] >> 6); - } else if (msg->addr == 0x394U) { - cnt = (msg->data[1] >> 5) & 0x7U; - } else if (msg->addr == 0x421U) { - cnt = msg->data[7] & 0xFU; - } else if (msg->addr == 0x4F1U) { - cnt = (msg->data[3] >> 4) & 0xFU; + if (addr == 0x260) { + cnt = (GET_BYTE(to_push, 7) >> 4) & 0x3U; + } else if (addr == 0x386) { + cnt = ((GET_BYTE(to_push, 3) >> 6) << 2) | (GET_BYTE(to_push, 1) >> 6); + } else if (addr == 0x394) { + cnt = (GET_BYTE(to_push, 1) >> 5) & 0x7U; + } else if (addr == 0x421) { + cnt = GET_BYTE(to_push, 7) & 0xFU; + } else if (addr == 0x4F1) { + cnt = (GET_BYTE(to_push, 3) >> 4) & 0xFU; } else { } return cnt; } -static uint32_t hyundai_get_checksum(const CANPacket_t *msg) { +static uint32_t hyundai_get_checksum(const CANPacket_t *to_push) { + int addr = GET_ADDR(to_push); uint8_t chksum = 0; - if (msg->addr == 0x260U) { - chksum = msg->data[7] & 0xFU; - } else if (msg->addr == 0x386U) { - chksum = ((msg->data[7] >> 6) << 2) | (msg->data[5] >> 6); - } else if (msg->addr == 0x394U) { - chksum = msg->data[6] & 0xFU; - } else if (msg->addr == 0x421U) { - chksum = msg->data[7] >> 4; + if (addr == 0x260) { + chksum = GET_BYTE(to_push, 7) & 0xFU; + } else if (addr == 0x386) { + chksum = ((GET_BYTE(to_push, 7) >> 6) << 2) | (GET_BYTE(to_push, 5) >> 6); + } else if (addr == 0x394) { + chksum = GET_BYTE(to_push, 6) & 0xFU; + } else if (addr == 0x421) { + chksum = GET_BYTE(to_push, 7) >> 4; } else { } return chksum; } -static uint32_t hyundai_compute_checksum(const CANPacket_t *msg) { +static uint32_t hyundai_compute_checksum(const CANPacket_t *to_push) { + int addr = GET_ADDR(to_push); + uint8_t chksum = 0; - if (msg->addr == 0x386U) { + if (addr == 0x386) { // count the bits for (int i = 0; i < 8; i++) { - uint8_t b = msg->data[i]; + uint8_t b = GET_BYTE(to_push, i); for (int j = 0; j < 8; j++) { uint8_t bit = 0; // exclude checksum and counter @@ -124,12 +114,12 @@ static uint32_t hyundai_compute_checksum(const CANPacket_t *msg) { } else { // sum of nibbles for (int i = 0; i < 8; i++) { - if ((msg->addr == 0x394U) && (i == 7)) { + if ((addr == 0x394) && (i == 7)) { continue; // exclude } - uint8_t b = msg->data[i]; - if (((msg->addr == 0x260U) && (i == 7)) || ((msg->addr == 0x394U) && (i == 6)) || ((msg->addr == 0x421U) && (i == 7))) { - b &= (msg->addr == 0x421U) ? 0x0FU : 0xF0U; // remove checksum + uint8_t b = GET_BYTE(to_push, i); + if (((addr == 0x260) && (i == 7)) || ((addr == 0x394) && (i == 6)) || ((addr == 0x421) && (i == 7))) { + b &= (addr == 0x421) ? 0x0FU : 0xF0U; // remove checksum } chksum += (b % 16U) + (b / 16U); } @@ -139,127 +129,115 @@ static uint32_t hyundai_compute_checksum(const CANPacket_t *msg) { return chksum; } -static void hyundai_rx_hook(const CANPacket_t *msg) { +static void hyundai_rx_hook(const CANPacket_t *to_push) { + int bus = GET_BUS(to_push); + int addr = GET_ADDR(to_push); // SCC12 is on bus 2 for camera-based SCC cars, bus 0 on all others - if (msg->addr == 0x421U) { - if (((msg->bus == 0U) && !hyundai_camera_scc) || ((msg->bus == 2U) && hyundai_camera_scc)) { + if (addr == 0x421) { + if (((bus == 0) && !hyundai_camera_scc) || ((bus == 2) && hyundai_camera_scc)) { // 2 bits: 13-14 - int cruise_engaged = (GET_BYTES(msg, 0, 4) >> 13) & 0x3U; + int cruise_engaged = (GET_BYTES(to_push, 0, 4) >> 13) & 0x3U; hyundai_common_cruise_state_check(cruise_engaged); } } - if (msg->addr == 0x420U) { - if (((msg->bus == 0U) && !hyundai_camera_scc) || ((msg->bus == 2U) && hyundai_camera_scc)) { - if (!hyundai_longitudinal) { - acc_main_on = GET_BIT(msg, 0U); - } - } - } - - if (msg->bus == 0U) { - if (msg->addr == 0x251U) { - int torque_driver_new = (GET_BYTES(msg, 0, 2) & 0x7ffU) - 1024U; + if (bus == 0) { + if (addr == 0x251) { + int torque_driver_new = (GET_BYTES(to_push, 0, 2) & 0x7ffU) - 1024U; // update array of samples update_sample(&torque_driver, torque_driver_new); } - if (msg->addr == 0x391U) { - aol_button_press = GET_BIT(msg, 4U) ? AOL_BUTTON_PRESSED : AOL_BUTTON_NOT_PRESSED; - } - // ACC steering wheel buttons - if (msg->addr == 0x4F1U) { - int cruise_button = msg->data[0] & 0x7U; - bool main_button = GET_BIT(msg, 3U); + if (addr == 1007) hyundai_cruise_buttons_alt = true; // CASPER_EV: 1007 + if (addr == 1007) { + int cruise_button = (GET_BYTE(to_push, 7) >> 4) & 0x07U; + bool main_button = GET_BIT(to_push, 58U); + hyundai_common_cruise_buttons_check(cruise_button, main_button); + } + else if (addr == 0x4F1 && !hyundai_cruise_buttons_alt) { + int cruise_button = GET_BYTE(to_push, 0) & 0x7U; + bool main_button = GET_BIT(to_push, 3U); hyundai_common_cruise_buttons_check(cruise_button, main_button); } // gas press, different for EV, hybrid, and ICE models - if ((msg->addr == 0x371U) && hyundai_ev_gas_signal) { - gas_pressed = (((msg->data[4] & 0x7FU) << 1) | (msg->data[3] >> 7)) != 0U; - } else if ((msg->addr == 0x371U) && hyundai_hybrid_gas_signal) { - gas_pressed = msg->data[7] != 0U; - } else if ((msg->addr == 0x91U) && hyundai_fcev_gas_signal) { - gas_pressed = msg->data[6] != 0U; - } else if ((msg->addr == 0x260U) && !hyundai_ev_gas_signal && !hyundai_hybrid_gas_signal) { - gas_pressed = (msg->data[7] >> 6) != 0U; + if ((addr == 0x371) && hyundai_ev_gas_signal) { + gas_pressed = (((GET_BYTE(to_push, 4) & 0x7FU) << 1) | GET_BYTE(to_push, 3) >> 7) != 0U; + } else if ((addr == 0x371) && hyundai_hybrid_gas_signal) { + gas_pressed = GET_BYTE(to_push, 7) != 0U; + } else if ((addr == 0x91) && hyundai_fcev_gas_signal) { + gas_pressed = GET_BYTE(to_push, 6) != 0U; + } else if ((addr == 0x260) && !hyundai_ev_gas_signal && !hyundai_hybrid_gas_signal) { + gas_pressed = (GET_BYTE(to_push, 7) >> 6) != 0U; } else { } // sample wheel speed, averaging opposite corners - if (msg->addr == 0x386U) { - uint32_t front_left_speed = GET_BYTES(msg, 0, 2) & 0x3FFFU; - uint32_t rear_right_speed = GET_BYTES(msg, 6, 2) & 0x3FFFU; + if (addr == 0x386) { + uint32_t front_left_speed = GET_BYTES(to_push, 0, 2) & 0x3FFFU; + uint32_t rear_right_speed = GET_BYTES(to_push, 6, 2) & 0x3FFFU; vehicle_moving = (front_left_speed > HYUNDAI_STANDSTILL_THRSLD) || (rear_right_speed > HYUNDAI_STANDSTILL_THRSLD); } - if (msg->addr == 0x394U) { - brake_pressed = ((msg->data[5] >> 5U) & 0x3U) == 0x2U; + if (addr == 0x394) { + brake_pressed = ((GET_BYTE(to_push, 5) >> 5U) & 0x3U) == 0x2U; } - if (msg->addr == 0x592U) { - acc_main_on = GET_BIT(msg, 34U); - bool cruise_engaged = GET_BIT(msg, 35U); - hyundai_common_cruise_state_check(cruise_engaged); - } + bool stock_ecu_detected = (addr == 0x340); - if (msg->addr == 0x595U) { - acc_main_on = GET_BIT(msg, 50U); - bool cruise_engaged = GET_BIT(msg, 51U); - hyundai_common_cruise_state_check(cruise_engaged); - } - - if ((msg->addr == 0x260U) && hyundai_non_scc && !hyundai_ev_gas_signal && !hyundai_hybrid_gas_signal) { - acc_main_on = GET_BIT(msg, 25U); - bool cruise_engaged = GET_BIT(msg, 26U); - hyundai_common_cruise_state_check(cruise_engaged); + // If openpilot is controlling longitudinal we need to ensure the radar is turned off + // Enforce by checking we don't see SCC12 + if (hyundai_longitudinal && (addr == 0x421)) { + stock_ecu_detected = true; } + generic_rx_checks(); + stock_ecu_check(stock_ecu_detected); } - - hyundai_common_reset_acc_main_on_mismatches(); } -static bool hyundai_tx_hook(const CANPacket_t *msg) { - const TorqueSteeringLimits HYUNDAI_STEERING_LIMITS = HYUNDAI_LIMITS(384, 3, 7); - const TorqueSteeringLimits HYUNDAI_STEERING_LIMITS_ALT = HYUNDAI_LIMITS(270, 2, 3); +uint32_t last_ts_lkas11_from_op = 0; +uint32_t last_ts_scc12_from_op = 0; +uint32_t last_ts_scc13_from_op = 0; +uint32_t last_ts_mdps12_from_op = 0; +uint32_t last_ts_fca11_from_op = 0; +uint32_t last_ts_fca12_from_op = 0; +uint32_t last_ts_lfahda_mfc_from_op = 0; + +static bool hyundai_tx_hook(const CANPacket_t *to_send) { + const TorqueSteeringLimits HYUNDAI_STEERING_LIMITS = HYUNDAI_LIMITS(512, 10, 10); + const TorqueSteeringLimits HYUNDAI_STEERING_LIMITS_ALT = HYUNDAI_LIMITS(512, 10, 10); const TorqueSteeringLimits HYUNDAI_STEERING_LIMITS_ALT_2 = HYUNDAI_LIMITS(170, 2, 3); bool tx = true; + int addr = GET_ADDR(to_send); // FCA11: Block any potential actuation - if (msg->addr == 0x38DU) { - int CR_VSM_DecCmd = msg->data[1]; - bool FCA_CmdAct = GET_BIT(msg, 20U); - bool CF_VSM_DecCmdAct = GET_BIT(msg, 31U); + if (addr == 0x38D) { + int CR_VSM_DecCmd = GET_BYTE(to_send, 1); + bool FCA_CmdAct = GET_BIT(to_send, 20U); + bool CF_VSM_DecCmdAct = GET_BIT(to_send, 31U); if ((CR_VSM_DecCmd != 0) || FCA_CmdAct || CF_VSM_DecCmdAct) { tx = false; } } - if (msg->addr == 0x420U) { - acc_main_on_tx = GET_BIT(msg, 0U); - hyundai_common_acc_main_on_sync(); - } - // ACCEL: safety check - if (msg->addr == 0x421U) { - int desired_accel_raw = (((msg->data[4] & 0x7U) << 8) | msg->data[3]) - 1023U; - int desired_accel_val = ((msg->data[5] << 3) | (msg->data[4] >> 5)) - 1023U; + if (addr == 0x421) { + int desired_accel_raw = (((GET_BYTE(to_send, 4) & 0x7U) << 8) | GET_BYTE(to_send, 3)) - 1023U; + int desired_accel_val = ((GET_BYTE(to_send, 5) << 3) | (GET_BYTE(to_send, 4) >> 5)) - 1023U; - int aeb_decel_cmd = msg->data[2]; - bool aeb_req = GET_BIT(msg, 54U); + int aeb_decel_cmd = GET_BYTE(to_send, 2); + bool aeb_req = GET_BIT(to_send, 54U); bool violation = false; violation |= longitudinal_accel_checks(desired_accel_raw, HYUNDAI_LONG_LIMITS); violation |= longitudinal_accel_checks(desired_accel_val, HYUNDAI_LONG_LIMITS); - if (!hyundai_escc) { - violation |= (aeb_decel_cmd != 0); - violation |= aeb_req; - } + violation |= (aeb_decel_cmd != 0); + violation |= aeb_req; if (violation) { tx = false; @@ -267,9 +245,9 @@ static bool hyundai_tx_hook(const CANPacket_t *msg) { } // LKA STEER: safety check - if (msg->addr == 0x340U) { - int desired_torque = ((GET_BYTES(msg, 0, 4) >> 16) & 0x7ffU) - 1024U; - bool steer_req = GET_BIT(msg, 27U); + if (addr == 0x340) { + int desired_torque = ((GET_BYTES(to_send, 0, 4) >> 16) & 0x7ffU) - 1024U; + bool steer_req = GET_BIT(to_send, 27U); const TorqueSteeringLimits limits = hyundai_alt_limits_2 ? HYUNDAI_STEERING_LIMITS_ALT_2 : hyundai_alt_limits ? HYUNDAI_STEERING_LIMITS_ALT : HYUNDAI_STEERING_LIMITS; @@ -280,220 +258,199 @@ static bool hyundai_tx_hook(const CANPacket_t *msg) { } // UDS: Only tester present ("\x02\x3E\x80\x00\x00\x00\x00\x00") allowed on diagnostics address - if (msg->addr == 0x7D0U) { - if ((GET_BYTES(msg, 0, 4) != 0x00803E02U) || (GET_BYTES(msg, 4, 4) != 0x0U)) { + if (addr == 0x7D0) { + if ((GET_BYTES(to_send, 0, 4) != 0x00803E02U) || (GET_BYTES(to_send, 4, 4) != 0x0U)) { tx = false; } } // BUTTONS: used for resume spamming and cruise cancellation - if ((msg->addr == 0x4F1U) && !hyundai_longitudinal) { - int button = msg->data[0] & 0x7U; + if ((addr == 0x4F1) && !hyundai_longitudinal) { + int button = GET_BYTE(to_send, 0) & 0x7U; bool allowed_resume = (button == 1) && controls_allowed; - bool allowed_set = (button == 2) && controls_allowed; - bool allowed_cancel = (button == 4) && cruise_engaged_prev; - if (!(allowed_resume || allowed_set || allowed_cancel)) { + bool allowed_cancel = (button == 4) && (cruise_engaged_prev || controls_allowed); + if (!(allowed_resume || allowed_cancel)) { tx = false; } } + uint32_t now = microsecond_timer_get(); + if(addr == 832) + last_ts_lkas11_from_op = (tx == 0 ? 0 : now); + else if(addr == 1057) + last_ts_scc12_from_op = (tx == 0 ? 0 : now); + else if(addr == 593) + last_ts_mdps12_from_op = (tx == 0 ? 0 : now); + else if (addr == 909) + last_ts_fca11_from_op = (tx == 0 ? 0 : now); + else if (addr == 1155) + last_ts_fca12_from_op = (tx == 0 ? 0 : now); + else if(addr == 1290) + last_ts_scc13_from_op = (tx == 0 ? 0 : now); + else if(addr == 0x485) + last_ts_lfahda_mfc_from_op = (tx == 0 ? 0 : now); return tx; } -static safety_config hyundai_init(uint16_t param) { - static const CanMsg HYUNDAI_LONG_TX_MSGS[] = { - HYUNDAI_LONG_COMMON_TX_MSGS(0) - {0x38D, 0, 8, .check_relay = false}, // FCA11 Bus 0 - {0x483, 0, 8, .check_relay = false}, // FCA12 Bus 0 - {0x7D0, 0, 8, .check_relay = false}, // radar UDS TX addr Bus 0 (for radar disable) - }; +static bool hyundai_fwd_hook(int bus_num, int addr) { + int bus_fwd = -1; - static const CanMsg HYUNDAI_CAMERA_SCC_TX_MSGS[] = { - HYUNDAI_COMMON_TX_MSGS(2) - }; + uint32_t now = microsecond_timer_get(); - static const CanMsg HYUNDAI_CAMERA_SCC_LONG_TX_MSGS[] = { - HYUNDAI_LONG_COMMON_TX_MSGS(2) - }; + // forward cam to ccan and viceversa, except lkas cmd + if (bus_num == 0) { + bus_fwd = 2; - static const CanMsg HYUNDAI_LONG_ESCC_TX_MSGS[] = { - HYUNDAI_LONG_COMMON_TX_MSGS(0) - }; - - hyundai_common_init(param); - hyundai_legacy = false; - - safety_config ret; - if (hyundai_longitudinal) { - // Use CLU11 (buttons) to manage controls allowed instead of SCC cruise state - static RxCheck hyundai_long_rx_checks[] = { - HYUNDAI_COMMON_RX_CHECKS(false) - }; - - static RxCheck hyundai_lda_button_long_rx_checks[] = { - HYUNDAI_COMMON_RX_CHECKS(false) - HYUNDAI_LDA_BUTTON_ADDR_CHECK - }; - - static RxCheck hyundai_fcev_long_rx_checks[] = { - HYUNDAI_COMMON_RX_CHECKS(false) - HYUNDAI_FCEV_GAS_ADDR_CHECK - }; - - static RxCheck hyundai_fcev_lda_button_long_rx_checks[] = { - HYUNDAI_COMMON_RX_CHECKS(false) - HYUNDAI_FCEV_GAS_ADDR_CHECK - HYUNDAI_LDA_BUTTON_ADDR_CHECK - }; - - if (hyundai_fcev_gas_signal) { - if (hyundai_has_lda_button) { - SET_RX_CHECKS(hyundai_fcev_lda_button_long_rx_checks, ret); - } else { - SET_RX_CHECKS(hyundai_fcev_long_rx_checks, ret); - } - } else { - if (hyundai_has_lda_button) { - SET_RX_CHECKS(hyundai_lda_button_long_rx_checks, ret); - } else { - SET_RX_CHECKS(hyundai_long_rx_checks, ret); - } - } - if (hyundai_escc) { - SET_TX_MSGS(HYUNDAI_LONG_ESCC_TX_MSGS, ret); - } else if (hyundai_camera_scc) { - SET_TX_MSGS(HYUNDAI_CAMERA_SCC_LONG_TX_MSGS, ret); - } else { - SET_TX_MSGS(HYUNDAI_LONG_TX_MSGS, ret); - } - - } else if (hyundai_camera_scc) { - static RxCheck hyundai_cam_scc_rx_checks[] = { - HYUNDAI_COMMON_RX_CHECKS(false) - HYUNDAI_SCC12_ADDR_CHECK(2) - HYUNDAI_SCC11_ADDR_CHECK(2) - HYUNDAI_LDA_BUTTON_ADDR_CHECK - }; - - ret = BUILD_SAFETY_CFG(hyundai_cam_scc_rx_checks, HYUNDAI_CAMERA_SCC_TX_MSGS); - } else { - static RxCheck hyundai_rx_checks[] = { - HYUNDAI_COMMON_RX_CHECKS(false) - HYUNDAI_SCC12_ADDR_CHECK(0) - HYUNDAI_SCC11_ADDR_CHECK(0) - }; - - static RxCheck hyundai_lda_button_rx_checks[] = { - HYUNDAI_COMMON_RX_CHECKS(false) - HYUNDAI_SCC12_ADDR_CHECK(0) - HYUNDAI_SCC11_ADDR_CHECK(0) - HYUNDAI_LDA_BUTTON_ADDR_CHECK - }; - - static RxCheck hyundai_fcev_rx_checks[] = { - HYUNDAI_COMMON_RX_CHECKS(false) - HYUNDAI_SCC12_ADDR_CHECK(0) - HYUNDAI_SCC11_ADDR_CHECK(0) - HYUNDAI_FCEV_GAS_ADDR_CHECK - }; - - static RxCheck hyundai_fcev_lda_button_rx_checks[] = { - HYUNDAI_COMMON_RX_CHECKS(false) - HYUNDAI_SCC12_ADDR_CHECK(0) - HYUNDAI_SCC11_ADDR_CHECK(0) - HYUNDAI_FCEV_GAS_ADDR_CHECK - HYUNDAI_LDA_BUTTON_ADDR_CHECK - }; - - static RxCheck hyundai_non_scc_addr_checks[] = { - HYUNDAI_COMMON_RX_CHECKS(false) - }; - - static RxCheck hyundai_non_scc_lda_button_addr_checks[] = { - HYUNDAI_COMMON_RX_CHECKS(false) - HYUNDAI_LDA_BUTTON_ADDR_CHECK - }; - - static RxCheck hyundai_hev_non_scc_addr_checks[] = { - HYUNDAI_COMMON_RX_CHECKS(false) - HYUNDAI_NON_SCC_HEV_ADDR_CHECK - }; - - static RxCheck hyundai_hev_non_scc_lda_button_addr_checks[] = { - HYUNDAI_COMMON_RX_CHECKS(false) - HYUNDAI_NON_SCC_HEV_ADDR_CHECK - HYUNDAI_LDA_BUTTON_ADDR_CHECK - }; - - static RxCheck hyundai_ev_non_scc_addr_checks[] = { - HYUNDAI_COMMON_RX_CHECKS(false) - HYUNDAI_NON_SCC_EV_ADDR_CHECK - }; - - static RxCheck hyundai_ev_non_scc_lda_button_addr_checks[] = { - HYUNDAI_COMMON_RX_CHECKS(false) - HYUNDAI_NON_SCC_EV_ADDR_CHECK - HYUNDAI_LDA_BUTTON_ADDR_CHECK - }; - - SET_TX_MSGS(HYUNDAI_TX_MSGS, ret); - if (hyundai_fcev_gas_signal) { - if (hyundai_has_lda_button) { - SET_RX_CHECKS(hyundai_fcev_lda_button_rx_checks, ret); - } else { - SET_RX_CHECKS(hyundai_fcev_rx_checks, ret); - } - } else if (hyundai_non_scc) { - if (hyundai_ev_gas_signal) { - if (hyundai_has_lda_button) { - SET_RX_CHECKS(hyundai_ev_non_scc_lda_button_addr_checks, ret); - } else { - SET_RX_CHECKS(hyundai_ev_non_scc_addr_checks, ret); - } - } else if (hyundai_hybrid_gas_signal) { - if (hyundai_has_lda_button) { - SET_RX_CHECKS(hyundai_hev_non_scc_lda_button_addr_checks, ret); - } else { - SET_RX_CHECKS(hyundai_hev_non_scc_addr_checks, ret); - } - } else { - if (hyundai_has_lda_button) { - SET_RX_CHECKS(hyundai_non_scc_lda_button_addr_checks, ret); - } else { - SET_RX_CHECKS(hyundai_non_scc_addr_checks, ret); - } - } - } else { - if (hyundai_has_lda_button) { - SET_RX_CHECKS(hyundai_lda_button_rx_checks, ret); - } else { - SET_RX_CHECKS(hyundai_rx_checks, ret); + if(addr == 593) { + if(now - last_ts_mdps12_from_op < 200000) { + bus_fwd = -1; } } } - return ret; + + if (bus_num == 2) { + bool is_lkas_msg = addr == 832; + bool is_lfahda_msg = addr == 1157; + bool is_scc_msg = addr == 1056 || addr == 1057 || addr == 905; + bool is_scc13_msg = addr == 1290; + bool is_fca11_msg = addr == 909; + bool is_fca12_msg = addr == 1155; + + bool block_msg = is_lkas_msg || is_lfahda_msg || is_scc_msg || is_scc13_msg || is_fca11_msg || is_fca12_msg; + if (!block_msg) { + bus_fwd = 0; + } + else { + if(is_lkas_msg) { + if(now - last_ts_lkas11_from_op >= 200000) { + bus_fwd = 0; + } + } + else if(is_lfahda_msg) { + if (now - last_ts_lfahda_mfc_from_op >= 200000) + bus_fwd = 0; + } + else if (is_scc_msg) { + if (now - last_ts_scc12_from_op >= 400000) + bus_fwd = 0; + } + else if (is_scc13_msg) { + if (now - last_ts_scc13_from_op >= 800000) + bus_fwd = 0; + } + else if (is_fca11_msg) { + if (now - last_ts_fca11_from_op >= 400000) + bus_fwd = 0; + } + else if (is_fca12_msg) { + if (now - last_ts_fca12_from_op >= 400000) + bus_fwd = 0; + } + } + } + + return bus_fwd == -1; +} + +/* case + - legacy(on/off) + camera_scc(allways longitudinal on) + longitudinal(scc off) +*/ +static safety_config hyundai_init_carrot(bool legacy_car) { + static const CanMsg HYUNDAI_LONG_TX_MSGS[] = { + {0x340, 0, 8}, // LKAS11 Bus 0 + {0x4F1, 0, 4}, // CLU11 Bus 0 + {0x485, 0, 8}, // LFAHDA_MFC Bus 0 + {0x251, 2, 8}, // MDPS12 Bus 2 + {0x420, 0, 8}, // SCC11 Bus 0 + {0x421, 0, 8}, // SCC12 Bus 0 + {0x50A, 0, 8}, // SCC13 Bus 0 + {0x389, 0, 8}, // SCC14 Bus 0 + {0x4A2, 0, 2}, // FRT_RADAR11 Bus 0 + {0x38D, 0, 8}, // FCA11 Bus 0 + {0x483, 0, 8}, // FCA12 Bus 0 + {0x7D0, 0, 8}, // radar UDS TX addr Bus 0 (for radar disable) + }; + + static const CanMsg HYUNDAI_CAMERA_SCC_TX_MSGS[] = { + {0x340, 0, 8}, // LKAS11 Bus 0 + {0x4F1, 2, 4}, // CLU11 Bus 2 + {0x485, 0, 8}, // LFAHDA_MFC Bus 0 + {593, 2, 8}, // MDPS12, Bus 2 + {1056, 0, 8}, // SCC11, Bus 0 + {1057, 0, 8}, // SCC12, Bus 0 + {1290, 0, 8}, // SCC13, Bus 0 + {905, 0, 8}, // SCC14, Bus 0 + {909, 0, 8}, // FCA11 Bus 0 + {1155, 0, 8}, // FCA12 Bus 0 + {1186, 0, 8}, // FRT_RADAR11, Bus 0 + {0x4F1, 0, 4}, // CLU11 Bus 0 + }; + + safety_config ret; + if (hyundai_camera_scc) { + static RxCheck hyundai_cam_scc_rx_checks[] = { + HYUNDAI_COMMON_RX_CHECKS(false) + HYUNDAI_SCC12_ADDR_CHECK(2) + }; + static RxCheck hyundai_cam_scc_rx_checks_legacy[] = { + HYUNDAI_COMMON_RX_CHECKS(true) + HYUNDAI_SCC12_ADDR_CHECK(2) + }; + if(legacy_car) ret = BUILD_SAFETY_CFG(hyundai_cam_scc_rx_checks_legacy, HYUNDAI_CAMERA_SCC_TX_MSGS); + else ret = BUILD_SAFETY_CFG(hyundai_cam_scc_rx_checks, HYUNDAI_CAMERA_SCC_TX_MSGS); + } + else if (hyundai_longitudinal) { + static RxCheck hyundai_long_rx_checks[] = { + HYUNDAI_COMMON_RX_CHECKS(false) + // Use CLU11 (buttons) to manage controls allowed instead of SCC cruise state + {.msg = {{0x4F1, 0, 4, .ignore_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }} +}, + }; + static RxCheck hyundai_long_rx_checks_legacy[] = { + HYUNDAI_COMMON_RX_CHECKS(true) + // Use CLU11 (buttons) to manage controls allowed instead of SCC cruise state + {.msg = {{0x4F1, 0, 4, .ignore_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }} +}, + }; + + if(legacy_car) ret = BUILD_SAFETY_CFG(hyundai_long_rx_checks_legacy, HYUNDAI_LONG_TX_MSGS); + else ret = BUILD_SAFETY_CFG(hyundai_long_rx_checks, HYUNDAI_LONG_TX_MSGS); + } + else { + static RxCheck hyundai_rx_checks[] = { + HYUNDAI_COMMON_RX_CHECKS(false) + HYUNDAI_SCC12_ADDR_CHECK(0) + }; + static RxCheck hyundai_rx_checks_legacy[] = { + HYUNDAI_COMMON_RX_CHECKS(true) + //HYUNDAI_SCC12_ADDR_CHECK(0) + }; + + if(legacy_car) ret = BUILD_SAFETY_CFG(hyundai_rx_checks_legacy, HYUNDAI_TX_MSGS); + else ret = BUILD_SAFETY_CFG(hyundai_rx_checks, HYUNDAI_TX_MSGS); + } + return ret; +} + + +static safety_config hyundai_init(uint16_t param) { + hyundai_common_init(param); + hyundai_legacy = false; + return hyundai_init_carrot(hyundai_legacy); } static safety_config hyundai_legacy_init(uint16_t param) { - // older hyundai models have less checks due to missing counters and checksums - static RxCheck hyundai_legacy_rx_checks[] = { - HYUNDAI_COMMON_RX_CHECKS(true) - HYUNDAI_SCC12_ADDR_CHECK(0) - HYUNDAI_SCC11_ADDR_CHECK(0) - }; - hyundai_common_init(param); hyundai_legacy = true; - hyundai_longitudinal = false; - hyundai_camera_scc = false; - return BUILD_SAFETY_CFG(hyundai_legacy_rx_checks, HYUNDAI_TX_MSGS); + return hyundai_init_carrot(hyundai_legacy); } const safety_hooks hyundai_hooks = { .init = hyundai_init, .rx = hyundai_rx_hook, .tx = hyundai_tx_hook, + .fwd = hyundai_fwd_hook, .get_counter = hyundai_get_counter, .get_checksum = hyundai_get_checksum, .compute_checksum = hyundai_compute_checksum, @@ -503,6 +460,7 @@ const safety_hooks hyundai_legacy_hooks = { .init = hyundai_legacy_init, .rx = hyundai_rx_hook, .tx = hyundai_tx_hook, + .fwd = hyundai_fwd_hook, .get_counter = hyundai_get_counter, .get_checksum = hyundai_get_checksum, .compute_checksum = hyundai_compute_checksum, diff --git a/iqdbc_repo/iqdbc/safety/modes/hyundai_canfd.h b/iqdbc_repo/iqdbc/safety/modes/hyundai_canfd.h index 9256cee..e3a6cbd 100644 --- a/iqdbc_repo/iqdbc/safety/modes/hyundai_canfd.h +++ b/iqdbc_repo/iqdbc/safety/modes/hyundai_canfd.h @@ -3,149 +3,550 @@ #include "iqdbc/safety/declarations.h" #include "iqdbc/safety/modes/hyundai_common.h" -#define HYUNDAI_CANFD_CRUISE_BUTTON_TX_MSGS(bus) \ - {0x1CF, bus, 8, .check_relay = false}, /* CRUISE_BUTTON */ \ +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#pragma GCC diagnostic ignored "-Wunused-function" -#define HYUNDAI_CANFD_LKA_STEERING_COMMON_TX_MSGS(a_can, e_can) \ - HYUNDAI_CANFD_CRUISE_BUTTON_TX_MSGS(e_can) \ - {0x50, a_can, 16, .check_relay = (a_can) == 0}, /* LKAS */ \ - {0x2A4, a_can, 24, .check_relay = (a_can) == 0}, /* CAM_0x2A4 */ \ +const TorqueSteeringLimits HYUNDAI_CANFD_STEERING_LIMITS = { + .max_torque = 512, //270, + .max_rt_delta = 112, -#define HYUNDAI_CANFD_LKA_STEERING_ALT_COMMON_TX_MSGS(a_can, e_can) \ - HYUNDAI_CANFD_CRUISE_BUTTON_TX_MSGS(e_can) \ - {0x110, a_can, 32, .check_relay = (a_can) == 0}, /* LKAS_ALT */ \ - {0x362, a_can, 32, .check_relay = (a_can) == 0}, /* CAM_0x362 */ \ + .max_rate_up = 2, + .max_rate_down = 3, + .driver_torque_allowance = 250, + .driver_torque_multiplier = 2, + .type = TorqueDriverLimited, -#define HYUNDAI_CANFD_LFA_STEERING_COMMON_TX_MSGS(e_can) \ - {0x12A, e_can, 16, .check_relay = (e_can) == 0}, /* LFA */ \ - {0x1E0, e_can, 16, .check_relay = (e_can) == 0}, /* LFAHDA_CLUSTER */ \ + // the EPS faults when the steering angle is above a certain threshold for too long. to prevent this, + // we allow setting torque actuation bit to 0 while maintaining the requested torque value for two consecutive frames + .min_valid_request_frames = 89, + .max_invalid_request_frames = 2, + .min_valid_request_rt_interval = 810000, // 810ms; a ~10% buffer on cutting every 90 frames + .has_steer_req_tolerance = true, +}; + +const CanMsg HYUNDAI_CANFD_HDA2_TX_MSGS[] = { + {0x50, 0, 16}, // LKAS + {0x1CF, 1, 8}, // CRUISE_BUTTON + {0x2A4, 0, 24}, // CAM_0x2A4 +}; + +const CanMsg HYUNDAI_CANFD_HDA2_ALT_STEERING_TX_MSGS[] = { + {0x110, 0, 32}, // LKAS_ALT + {0x1CF, 1, 8}, // CRUISE_BUTTON + {0x362, 0, 32}, // CAM_0x362 + {0x1AA, 1, 16}, // CRUISE_ALT_BUTTONS , carrot +}; + +const CanMsg HYUNDAI_CANFD_HDA2_LONG_TX_MSGS[] = { + {0x50, 0, 16}, // LKAS + {0x1CF, 0, 8}, // CRUISE_BUTTON + {0x1CF, 1, 8}, // CRUISE_BUTTON + {0x1CF, 2, 8}, // CRUISE_BUTTON + {0x1AA, 0, 16}, // CRUISE_ALT_BUTTONS , carrot + {0x1AA, 1, 16}, // CRUISE_ALT_BUTTONS , carrot + {0x1AA, 2, 16}, // CRUISE_ALT_BUTTONS , carrot + {0x2A4, 0, 24}, // CAM_0x2A4 + {0x51, 0, 32}, // ADRV_0x51 + {0x730, 1, 8}, // tester present for ADAS ECU disable + {0x12A, 1, 16}, // LFA + {0x160, 1, 16}, // ADRV_0x160 + {0x1E0, 1, 16}, // LFAHDA_CLUSTER + {0x1A0, 1, 32}, // CRUISE_INFO + {0x1EA, 1, 32}, // ADRV_0x1ea + {0x200, 1, 8}, // ADRV_0x200 + {0x345, 1, 8}, // ADRV_0x345 + {0x1DA, 1, 32}, // ADRV_0x1da + + {0x12A, 0, 16}, // LFA + {0x1E0, 0, 16}, // LFAHDA_CLUSTER + {0x160, 0, 16}, // ADRV_0x160 + {0x1EA, 0, 32}, // ADRV_0x1ea + {0x200, 0, 8}, // ADRV_0x200 + {0x1A0, 0, 32}, // CRUISE_INFO + {0x345, 0, 8}, // ADRV_0x345 + {0x1DA, 0, 32}, // ADRV_0x1da + + {0x362, 0, 32}, // CAM_0x362 + {0x362, 1, 32}, // CAM_0x362 + {0x2a4, 1, 24}, // CAM_0x2a4 + + {0x110, 0, 32}, // LKAS_ALT (272) + {0x110, 1, 32}, // LKAS_ALT (272) + + {0x50, 1, 16}, // + {0x51, 1, 32}, // + + {353, 0, 32}, // ADRV_353 + {354, 0, 32}, // CORNER_RADAR_HIGHWAY + {512, 0, 8}, // ADRV_0x200 + {1187, 2, 8}, // 4A3 + {1204, 2, 8}, // 4B4 + + {203, 0, 24}, // CB + {373, 2, 24}, // TCS(0x175) + {506, 2, 32}, // CLUSTER_SPEED_LIMIT + {234, 2, 24}, // MDPS + {687, 2, 8}, // STEER_TOUCH_2AF + + {0x4BE, 2, 8}, // NEW_MSG_4BE (may be corner radar enabler x) + {0x4B9, 2, 8}, // NEW_MSG_4B9 (may be corner radar enabler) +}; + +const CanMsg HYUNDAI_CANFD_HDA1_TX_MSGS[] = { + {0x12A, 0, 16}, // LFA + {0x1A0, 0, 32}, // CRUISE_INFO + {0x1CF, 0, 8}, // CRUISE_BUTTON + {0x1CF, 2, 8}, // CRUISE_BUTTON + {0x1E0, 0, 16}, // LFAHDA_CLUSTER + {0x160, 0, 16}, // ADRV_0x160 + {0x7D0, 0, 8}, // tester present for radar ECU disable + {0x1AA, 2, 16}, // CRUISE_ALT_BUTTONS , carrot + {203, 0, 24}, // CB + {373, 2, 24}, // TCS(0x175) + + {353, 0, 32}, // ADRV_353 + {354, 0, 32}, // CORNER_RADAR_HIGHWAY + {512, 0, 8}, // ADRV_0x200 + {1187, 2, 8}, // 4A3 + {1204, 2, 8}, // 4B4 + {373, 2, 24}, // TCS(0x175) + {234, 2, 24}, // MDPS + {687, 2, 8}, // STEER_TOUCH_2AF + +}; -#define HYUNDAI_CANFD_SCC_CONTROL_COMMON_TX_MSGS(e_can, longitudinal) \ - {0x1A0, e_can, 32, .check_relay = (longitudinal)}, /* SCC_CONTROL */ \ // *** Addresses checked in rx hook *** // EV, ICE, HYBRID: ACCELERATOR (0x35), ACCELERATOR_BRAKE_ALT (0x100), ACCELERATOR_ALT (0x105) -#define HYUNDAI_CANFD_COMMON_RX_CHECKS(pt_bus) \ - {.msg = {{0x35, (pt_bus), 32, 100U, .max_counter = 0xffU, .ignore_quality_flag = true}, \ - {0x100, (pt_bus), 32, 100U, .max_counter = 0xffU, .ignore_quality_flag = true}, \ - {0x105, (pt_bus), 32, 100U, .max_counter = 0xffU, .ignore_quality_flag = true}}}, \ - {.msg = {{0x175, (pt_bus), 24, 50U, .max_counter = 0xffU, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ - {.msg = {{0xa0, (pt_bus), 24, 100U, .max_counter = 0xffU, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ - {.msg = {{0xea, (pt_bus), 24, 100U, .max_counter = 0xffU, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ +#define HYUNDAI_CANFD_COMMON_RX_CHECKS(pt_bus) \ + {.msg = {{0x35, (pt_bus), 32, .max_counter = 0xffU, .frequency = 100U}, \ + {0x100, (pt_bus), 32, .max_counter = 0xffU, .frequency = 100U}, \ + {0x105, (pt_bus), 32, .max_counter = 0xffU, .frequency = 100U}}}, \ + {.msg = {{0x175, (pt_bus), 24, .max_counter = 0xffU, .frequency = 50U}, { 0 }, { 0 }}}, \ + {.msg = {{0xa0, (pt_bus), 24, .max_counter = 0xffU, .frequency = 100U}, { 0 }, { 0 }}}, \ + {.msg = {{0xea, (pt_bus), 24, .max_counter = 0xffU, .frequency = 100U}, { 0 }, { 0 }}}, \ -#define HYUNDAI_CANFD_STD_BUTTONS_RX_CHECKS(pt_bus) \ - HYUNDAI_CANFD_COMMON_RX_CHECKS(pt_bus) \ - {.msg = {{0x1cf, (pt_bus), 8, 50U, .ignore_checksum = true, .max_counter = 0xfU, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ +#define HYUNDAI_CANFD_BUTTONS_ADDR_CHECK(pt_bus) \ + {.msg = {{0x1cf, (pt_bus), 8, .ignore_checksum = true, .max_counter = 0xfU, .frequency = 50U}, { 0 }, { 0 }}}, \ -#define HYUNDAI_CANFD_ALT_BUTTONS_RX_CHECKS(pt_bus) \ - HYUNDAI_CANFD_COMMON_RX_CHECKS(pt_bus) \ - {.msg = {{0x1aa, (pt_bus), 16, 50U, .ignore_checksum = true, .max_counter = 0xffU, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ +#define HYUNDAI_CANFD_ALT_BUTTONS_ADDR_CHECK(pt_bus) \ + {.msg = {{0x1aa, (pt_bus), 16, .ignore_checksum = true, .max_counter = 0xffU, .frequency = 50U}, { 0 }, { 0 }}}, \ // SCC_CONTROL (from ADAS unit or camera) -#define HYUNDAI_CANFD_SCC_ADDR_CHECK(scc_bus) \ - {.msg = {{0x1a0, (scc_bus), 32, 50U, .max_counter = 0xffU, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ +#define HYUNDAI_CANFD_SCC_ADDR_CHECK(scc_bus) \ + {.msg = {{0x1a0, (scc_bus), 32, .max_counter = 0xffU, .frequency = 50U}, { 0 }, { 0 }}}, \ -static bool hyundai_canfd_alt_buttons = false; -static bool hyundai_canfd_lka_steering_alt = false; +//static bool hyundai_canfd_alt_buttons = false; +//static bool hyundai_canfd_hda2_alt_steering = false; -static unsigned int hyundai_canfd_get_lka_addr(void) { - return hyundai_canfd_lka_steering_alt ? 0x110U : 0x50U; +// *** Non-HDA2 checks *** +// Camera sends SCC messages on HDA1. +// Both button messages exist on some platforms, so we ensure we track the correct one using flag +RxCheck hyundai_canfd_rx_checks[] = { + HYUNDAI_CANFD_COMMON_RX_CHECKS(0) + HYUNDAI_CANFD_BUTTONS_ADDR_CHECK(0) + HYUNDAI_CANFD_SCC_ADDR_CHECK(2) +}; +RxCheck hyundai_canfd_alt_buttons_rx_checks[] = { + HYUNDAI_CANFD_COMMON_RX_CHECKS(0) + HYUNDAI_CANFD_ALT_BUTTONS_ADDR_CHECK(0) + HYUNDAI_CANFD_SCC_ADDR_CHECK(2) +}; + +// Longitudinal checks for HDA1 +RxCheck hyundai_canfd_long_rx_checks[] = { + HYUNDAI_CANFD_COMMON_RX_CHECKS(0) + HYUNDAI_CANFD_BUTTONS_ADDR_CHECK(0) +}; +RxCheck hyundai_canfd_long_alt_buttons_rx_checks[] = { + HYUNDAI_CANFD_COMMON_RX_CHECKS(0) + HYUNDAI_CANFD_ALT_BUTTONS_ADDR_CHECK(0) +}; + +// Radar sends SCC messages on these cars instead of camera +RxCheck hyundai_canfd_radar_scc_rx_checks[] = { + HYUNDAI_CANFD_COMMON_RX_CHECKS(0) + HYUNDAI_CANFD_BUTTONS_ADDR_CHECK(0) + HYUNDAI_CANFD_SCC_ADDR_CHECK(0) +}; +RxCheck hyundai_canfd_radar_scc_alt_buttons_rx_checks[] = { + HYUNDAI_CANFD_COMMON_RX_CHECKS(0) + HYUNDAI_CANFD_ALT_BUTTONS_ADDR_CHECK(0) + HYUNDAI_CANFD_SCC_ADDR_CHECK(0) +}; + + +// *** HDA2 checks *** +// E-CAN is on bus 1, ADAS unit sends SCC messages on HDA2. +// Does not use the alt buttons message +RxCheck hyundai_canfd_hda2_rx_checks[] = { + HYUNDAI_CANFD_COMMON_RX_CHECKS(1) + HYUNDAI_CANFD_BUTTONS_ADDR_CHECK(1) // TODO: carrot: canival no 0x1cf + HYUNDAI_CANFD_SCC_ADDR_CHECK(1) +}; +RxCheck hyundai_canfd_hda2_rx_checks_scc2[] = { + HYUNDAI_CANFD_COMMON_RX_CHECKS(0) + HYUNDAI_CANFD_BUTTONS_ADDR_CHECK(0) // TODO: carrot: canival no 0x1cf + HYUNDAI_CANFD_SCC_ADDR_CHECK(2) +}; +RxCheck hyundai_canfd_hda2_alt_buttons_rx_checks[] = { + HYUNDAI_CANFD_COMMON_RX_CHECKS(1) + HYUNDAI_CANFD_ALT_BUTTONS_ADDR_CHECK(1) + HYUNDAI_CANFD_SCC_ADDR_CHECK(1) +}; +RxCheck hyundai_canfd_hda2_alt_buttons_rx_checks_scc2[] = { + HYUNDAI_CANFD_COMMON_RX_CHECKS(0) + HYUNDAI_CANFD_ALT_BUTTONS_ADDR_CHECK(0) + HYUNDAI_CANFD_SCC_ADDR_CHECK(2) +}; +RxCheck hyundai_canfd_hda2_long_rx_checks[] = { + HYUNDAI_CANFD_COMMON_RX_CHECKS(1) + HYUNDAI_CANFD_BUTTONS_ADDR_CHECK(1) // TODO: carrot: canival no 0x1cf +}; +RxCheck hyundai_canfd_hda2_long_rx_checks_scc2[] = { + HYUNDAI_CANFD_COMMON_RX_CHECKS(0) + HYUNDAI_CANFD_BUTTONS_ADDR_CHECK(0) +}; +RxCheck hyundai_canfd_hda2_long_alt_buttons_rx_checks[] = { + HYUNDAI_CANFD_COMMON_RX_CHECKS(1) + HYUNDAI_CANFD_ALT_BUTTONS_ADDR_CHECK(1) +}; +RxCheck hyundai_canfd_hda2_long_alt_buttons_rx_checks_scc2[] = { + HYUNDAI_CANFD_COMMON_RX_CHECKS(0) + HYUNDAI_CANFD_ALT_BUTTONS_ADDR_CHECK(0) +}; + + +const int HYUNDAI_PARAM_CANFD_ALT_BUTTONS = 32; +const int HYUNDAI_PARAM_CANFD_HDA2_ALT_STEERING = 128; +bool hyundai_canfd_alt_buttons = false; +bool hyundai_canfd_hda2_alt_steering = false; +bool hyundai_canfd_buffered_fwd = false; + +int hyundai_canfd_hda2_get_lkas_addr(void) { + return hyundai_canfd_hda2_alt_steering ? 0x110 : 0x50; } -static uint8_t hyundai_canfd_get_counter(const CANPacket_t *msg) { +static uint8_t hyundai_canfd_get_counter(const CANPacket_t* to_push) { uint8_t ret = 0; - if (GET_LEN(msg) == 8U) { - ret = msg->data[1] >> 4; - } else { - ret = msg->data[2]; + if (GET_LEN(to_push) == 8U) { + ret = GET_BYTE(to_push, 1) >> 4; + } + else { + ret = GET_BYTE(to_push, 2); } return ret; } -static uint32_t hyundai_canfd_get_checksum(const CANPacket_t *msg) { - uint32_t chksum = msg->data[0] | (msg->data[1] << 8); +static uint32_t hyundai_canfd_get_checksum(const CANPacket_t* to_push) { + uint32_t chksum = GET_BYTE(to_push, 0) | (GET_BYTE(to_push, 1) << 8); return chksum; } -static void hyundai_canfd_rx_hook(const CANPacket_t *msg) { - const unsigned pt_bus = hyundai_canfd_lka_steering ? 1U : 0U; - const unsigned int scc_bus = hyundai_camera_scc ? 2U : pt_bus; +typedef struct { + int addr; + int bus; // forwarding block ��� tx bus: 0 or 2 + int hz; + uint32_t timeout_us; + uint32_t last_tx_us; +} CanfdTxState; - if (msg->bus == pt_bus) { +// forwarding block��: bus 0,2�� ��� +CanfdTxState canfd_tx_states[] = { + {0x50, 0, 100, 0U, 0U}, // 80: LKAS + {0x51, 0, 100, 0U, 0U}, // 81: ADRV_0x51 + {0x110, 0, 100, 0U, 0U}, // 272: LKAS_ALT + {0x12A, 0, 100, 0U, 0U}, // 298: LFA + {0x160, 0, 50, 0U, 0U}, // 352: ADRV_0x160 + {0x161, 0, 20, 0U, 0U}, // 353: ADRV_0x161 + {0x162, 0, 20, 0U, 0U}, // 354: CCNC_0x162 + {0x1A0, 0, 50, 0U, 0U}, // 416: SCC_CONTROL + {0x1DA, 0, 1, 0U, 0U}, // 474: ADRV_0x1da + {0x1E0, 0, 20, 0U, 0U}, // 480: LFAHDA_CLUSTER + {0x1EA, 0, 20, 0U, 0U}, // 490: ADRV_0x1ea + {0x200, 0, 20, 0U, 0U}, // 512: ADRV_0x200 + {0x2A4, 0, 20, 0U, 0U}, // 676: CAM_0x2a4 + {0x345, 0, 5, 0U, 0U}, // 837: ADRV_0x345 + {0x362, 0, 10, 0U, 0U}, // 866: CAM_0x362 + {0x0CB, 0, 100, 0U, 0U}, // 203: LFA_ALT + + {0x175, 2, 50, 0U, 0U}, // 373: TCS + {0x1AA, 2, 50, 0U, 0U}, // 426: CRUISE_ALT_BUTTONS + {0x1CF, 2, 50, 0U, 0U}, // 463: CRUISE_BUTTON + {0x1FA, 2, 10, 0U, 0U}, // 506: CLUSTER_SPEED_LIMIT + {0x0EA, 2, 100, 0U, 0U}, // 234: MDPS + {0x2AF, 2, 10, 0U, 0U}, // 687: STEER_TOUCH_2AF + {0x4A3, 2, 5, 0U, 0U}, // 1187: HDA_INFO_4A3 + {0x4B4, 2, 10, 0U, 0U}, // 1204: NEW_MSG_4B4 + {0x4BE, 2, 10, 0U, 0U}, // 1214: NEW_MSG_4BE + {0x4B9, 2, 10, 0U, 0U}, // 1209: NEW_MSG_4B9 + + {0, 0, 0, 0U, 0U}, +}; + +static CanfdTxState* find_canfd_tx_state(int bus, int addr) { + for (int i = 0; canfd_tx_states[i].addr > 0; i++) { + if ((canfd_tx_states[i].addr == addr) && (canfd_tx_states[i].bus == bus)) { + return &canfd_tx_states[i]; + } + } + return NULL; +} + + +static void hyundai_canfd_set_counter(CANPacket_t* to_push, uint8_t counter) { + if (GET_LEN(to_push) == 8U) { + to_push->data[1] = (to_push->data[1] & 0x0FU) | ((counter & 0x0FU) << 4); + } + else { + to_push->data[2] = counter; + } +} + +static void hyundai_canfd_set_checksum(CANPacket_t* to_push, uint16_t checksum) { + to_push->data[0] = (uint8_t)(checksum & 0xFFU); + to_push->data[1] = (uint8_t)((checksum >> 8U) & 0xFFU); +} + +static void hyundai_canfd_update_checksum(CANPacket_t* to_push) { + to_push->data[0] = 0U; + to_push->data[1] = 0U; + uint32_t checksum = hyundai_common_canfd_compute_checksum(to_push); + hyundai_canfd_set_checksum(to_push, (uint16_t)checksum); +} +static void canfd_apply_counter_and_update_checksum(CANPacket_t* dst, uint8_t counter) { + hyundai_canfd_set_counter(dst, counter); + hyundai_canfd_update_checksum(dst); +} +static void canfd_record_tx_time(int bus, int addr, bool tx) { + CanfdTxState* st = find_canfd_tx_state(bus, addr); + if (st != NULL) { + st->last_tx_us = tx ? microsecond_timer_get() : 0U; + } +} + +static bool canfd_should_block_fwd(int tx_bus, int addr, uint32_t now) { + CanfdTxState* st = find_canfd_tx_state(tx_bus, addr); + if (st == NULL) { + return false; + } + return (now - st->last_tx_us) < st->timeout_us; +} + +#define CANFD_BFWD_MAX_QUEUE 2 +#define CANFD_BFWD_REUSE_MAX 2 + +typedef struct { + int addr; + int dst_bus; + bool enabled; + + bool started; + uint8_t head; + uint8_t tail; + uint8_t count; + + uint8_t reuse_left; + bool has_last_pkt; + CANPacket_t last_pkt; + + CANPacket_t q[CANFD_BFWD_MAX_QUEUE]; +} CanfdBufferedFwd; + +CanfdBufferedFwd canfd_bfwd[] = { + {.addr = 0x1A0, .dst_bus = 0, .enabled = true }, // SCC_CONTROL + {.addr = 0x12A, .dst_bus = 0, .enabled = true }, // LFA + {.addr = 0x0CB, .dst_bus = 0, .enabled = true }, // LFA_ALT + {.addr = 0x0EA, .dst_bus = 2, .enabled = true }, // MDPS + {.addr = 0x1AA, .dst_bus = 2, .enabled = true }, // CRUISE_ALT_BUTTONS + // {.addr = 0x1CF, .dst_bus = 2, .enabled = true }, // CRUISE_BUTTON + {.addr = 0x175, .dst_bus = 2, .enabled = true }, // TCS + { 0 }, +}; + +static void canfd_copy_packet(CANPacket_t* dst, const CANPacket_t* src) { + dst->fd = src->fd; + dst->returned = 0U; + dst->rejected = 0U; + dst->extended = src->extended; + dst->addr = src->addr; + dst->bus = src->bus; + dst->data_len_code = src->data_len_code; + for (uint8_t i = 0U; i < GET_LEN(src); i++) { + dst->data[i] = src->data[i]; + } +} +static CanfdBufferedFwd* canfd_bfwd_find(int addr, int dst_bus) { + for (int i = 0; canfd_bfwd[i].addr > 0; i++) { + if (canfd_bfwd[i].enabled && + (canfd_bfwd[i].addr == addr) && + (canfd_bfwd[i].dst_bus == dst_bus)) { + return &canfd_bfwd[i]; + } + } + return NULL; +} + +static void canfd_bfwd_reset(CanfdBufferedFwd* st) { + st->started = false; + st->head = 0U; + st->tail = 0U; + st->count = 0U; + st->reuse_left = 0U; + st->has_last_pkt = false; + st->last_pkt = (CANPacket_t){0}; +} +static void canfd_bfwd_push(CanfdBufferedFwd* st, const CANPacket_t* pkt) { + if ((st == NULL) || !st->enabled) return; + if (GET_BUS(pkt) != st->dst_bus) return; + + // queue�� �̹� 2���� �̹� �� packet�� ���� + if (st->count >= CANFD_BFWD_MAX_QUEUE) { + return; + } + + canfd_copy_packet(&st->q[st->tail], pkt); + st->tail = (st->tail + 1U) % CANFD_BFWD_MAX_QUEUE; + st->count++; + st->started = true; +} + +static bool canfd_bfwd_pop(CanfdBufferedFwd* st, CANPacket_t* pkt) { + if ((st == NULL) || !st->enabled) { + return false; + } + + if (!st->started || (st->count == 0U)) { + return false; + } + + canfd_copy_packet(pkt, &st->q[st->head]); + st->head = (st->head + 1U) % CANFD_BFWD_MAX_QUEUE; + st->count--; + + // ������ ���� packet ���� + canfd_copy_packet(&st->last_pkt, pkt); + st->has_last_pkt = true; + st->reuse_left = CANFD_BFWD_REUSE_MAX; + + if (st->count == 0U) { + st->started = false; + } + + return true; +} +static bool canfd_bfwd_reuse_last(CanfdBufferedFwd* st, CANPacket_t* pkt) { + if ((st == NULL) || !st->enabled) { + return false; + } + + if (!st->has_last_pkt || (st->reuse_left == 0U)) { + return false; + } + + canfd_copy_packet(pkt, &st->last_pkt); + st->reuse_left--; + + return true; +} + + + + +static void hyundai_canfd_rx_hook(const CANPacket_t *to_push) { + int bus = GET_BUS(to_push); + int addr = GET_ADDR(to_push); + + int pt_bus = hyundai_canfd_hda2 ? 1 : 0; + const int scc_bus = hyundai_camera_scc ? 2 : pt_bus; + + if (hyundai_camera_scc) pt_bus = 0; + + if (bus == pt_bus) { // driver torque - if (msg->addr == 0xeaU) { - int torque_driver_new = ((msg->data[11] & 0x1fU) << 8U) | msg->data[10]; + if (addr == 0xea) { + int torque_driver_new = ((GET_BYTE(to_push, 11) & 0x1fU) << 8U) | GET_BYTE(to_push, 10); torque_driver_new -= 4095; update_sample(&torque_driver, torque_driver_new); } // cruise buttons - const unsigned int button_addr = hyundai_canfd_alt_buttons ? 0x1aaU : 0x1cfU; - if (msg->addr == button_addr) { + const int button_addr = hyundai_canfd_alt_buttons ? 0x1aa : 0x1cf; + if (addr == button_addr) { bool main_button = false; int cruise_button = 0; - if (msg->addr == 0x1cfU) { - cruise_button = msg->data[2] & 0x7U; - main_button = GET_BIT(msg, 19U); - aol_button_press = GET_BIT(msg, 23U) ? AOL_BUTTON_PRESSED : AOL_BUTTON_NOT_PRESSED; + if (addr == 0x1cf) { + cruise_button = GET_BYTE(to_push, 2) & 0x7U; + main_button = GET_BIT(to_push, 19U); } else { - cruise_button = (msg->data[4] >> 4) & 0x7U; - main_button = GET_BIT(msg, 34U); - aol_button_press = GET_BIT(msg, 39U) ? AOL_BUTTON_PRESSED : AOL_BUTTON_NOT_PRESSED; + cruise_button = (GET_BYTE(to_push, 4) >> 4) & 0x7U; + main_button = GET_BIT(to_push, 34U); } hyundai_common_cruise_buttons_check(cruise_button, main_button); } // gas press, different for EV, hybrid, and ICE models - if ((msg->addr == 0x35U) && hyundai_ev_gas_signal) { - gas_pressed = msg->data[5] != 0U; - } else if ((msg->addr == 0x105U) && hyundai_hybrid_gas_signal) { - gas_pressed = GET_BIT(msg, 103U) || (msg->data[13] != 0U) || GET_BIT(msg, 112U); - } else if ((msg->addr == 0x100U) && !hyundai_ev_gas_signal && !hyundai_hybrid_gas_signal) { - gas_pressed = GET_BIT(msg, 176U); + if ((addr == 0x35) && hyundai_ev_gas_signal) { + gas_pressed = GET_BYTE(to_push, 5) != 0U; + } else if ((addr == 0x105) && hyundai_hybrid_gas_signal) { + gas_pressed = GET_BIT(to_push, 103U) || (GET_BYTE(to_push, 13) != 0U) || GET_BIT(to_push, 112U); + } else if ((addr == 0x100) && !hyundai_ev_gas_signal && !hyundai_hybrid_gas_signal) { + gas_pressed = GET_BIT(to_push, 176U); } else { } // brake press - if (msg->addr == 0x175U) { - brake_pressed = GET_BIT(msg, 81U); + if (addr == 0x175) { + brake_pressed = GET_BIT(to_push, 81U); } // vehicle moving - if (msg->addr == 0xa0U) { - uint32_t fl = (GET_BYTES(msg, 8, 2)) & 0x3FFFU; - uint32_t fr = (GET_BYTES(msg, 10, 2)) & 0x3FFFU; - uint32_t rl = (GET_BYTES(msg, 12, 2)) & 0x3FFFU; - uint32_t rr = (GET_BYTES(msg, 14, 2)) & 0x3FFFU; + if (addr == 0xa0) { + uint32_t fl = (GET_BYTES(to_push, 8, 2)) & 0x3FFFU; + uint32_t fr = (GET_BYTES(to_push, 10, 2)) & 0x3FFFU; + uint32_t rl = (GET_BYTES(to_push, 12, 2)) & 0x3FFFU; + uint32_t rr = (GET_BYTES(to_push, 14, 2)) & 0x3FFFU; vehicle_moving = (fl > HYUNDAI_STANDSTILL_THRSLD) || (fr > HYUNDAI_STANDSTILL_THRSLD) || (rl > HYUNDAI_STANDSTILL_THRSLD) || (rr > HYUNDAI_STANDSTILL_THRSLD); // average of all 4 wheel speeds. Conversion: raw * 0.03125 / 3.6 = m/s - UPDATE_VEHICLE_SPEED((fr + rr + rl + fl) / 4.0 * 0.03125 * KPH_TO_MS); + UPDATE_VEHICLE_SPEED((fr + rr + rl + fl) / 4.0 * 0.03125 / 3.6); } } - if (msg->bus == scc_bus) { + if (bus == scc_bus) { // cruise state - if ((msg->addr == 0x1a0U) && !hyundai_longitudinal) { + if ((addr == 0x1a0) && !hyundai_longitudinal) { // 1=enabled, 2=driver override - int cruise_status = ((msg->data[8] >> 4) & 0x7U); + int cruise_status = ((GET_BYTE(to_push, 8) >> 4) & 0x7U); bool cruise_engaged = (cruise_status == 1) || (cruise_status == 2); hyundai_common_cruise_state_check(cruise_engaged); - acc_main_on = GET_BIT(msg, 66U); } } - hyundai_common_reset_acc_main_on_mismatches(); + const int steer_addr = hyundai_canfd_hda2 ? hyundai_canfd_hda2_get_lkas_addr() : 0x12a; + bool stock_ecu_detected = (addr == steer_addr) && (bus == 0); + if (hyundai_longitudinal) { + // on HDA2, ensure ADRV ECU is still knocked out + // on others, ensure accel msg is blocked from camera + const int stock_scc_bus = hyundai_canfd_hda2 ? 1 : 0; + stock_ecu_detected = stock_ecu_detected || ((addr == 0x1a0) && (bus == stock_scc_bus)); + } + generic_rx_checks(); + stock_ecu_check(stock_ecu_detected); + } -static bool hyundai_canfd_tx_hook(const CANPacket_t *msg) { +static bool hyundai_canfd_tx_hook(const CANPacket_t *to_send_const) { + CANPacket_t* to_send = (CANPacket_t*)to_send_const; + const TorqueSteeringLimits HYUNDAI_CANFD_STEERING_LIMITS = { - .max_torque = 270, + .max_torque = 512, .max_rt_delta = 112, - .max_rate_up = 2, - .max_rate_down = 3, + + .max_rate_up = 10, + .max_rate_down = 10, .driver_torque_allowance = 250, .driver_torque_multiplier = 2, .type = TorqueDriverLimited, @@ -159,12 +560,14 @@ static bool hyundai_canfd_tx_hook(const CANPacket_t *msg) { }; bool tx = true; + int addr = GET_ADDR(to_send); + bool violation = false; // steering - const unsigned int steer_addr = (hyundai_canfd_lka_steering && !hyundai_longitudinal) ? hyundai_canfd_get_lka_addr() : 0x12aU; - if (msg->addr == steer_addr) { - int desired_torque = (((msg->data[6] & 0xFU) << 7U) | (msg->data[5] >> 1U)) - 1024U; - bool steer_req = GET_BIT(msg, 52U); + const int steer_addr = (hyundai_canfd_hda2 && !hyundai_longitudinal) ? hyundai_canfd_hda2_get_lkas_addr() : 0x12a; + if (addr == steer_addr) { + int desired_torque = (((GET_BYTE(to_send, 6) & 0xFU) << 7U) | (GET_BYTE(to_send, 5) >> 1U)) - 1024U; + bool steer_req = GET_BIT(to_send, 52U); if (steer_torque_cmd_checks(desired_torque, steer_req, HYUNDAI_CANFD_STEERING_LIMITS)) { tx = false; @@ -172,209 +575,166 @@ static bool hyundai_canfd_tx_hook(const CANPacket_t *msg) { } // cruise buttons check - if (msg->addr == 0x1cfU) { - int button = msg->data[2] & 0x7U; + if (addr == 0x1cf) { + int button = GET_BYTE(to_send, 2) & 0x7U; bool is_cancel = (button == HYUNDAI_BTN_CANCEL); bool is_resume = (button == HYUNDAI_BTN_RESUME); - bool is_set = (button == HYUNDAI_BTN_SET); - bool allowed = (is_cancel && cruise_engaged_prev) || ((is_resume || is_set) && controls_allowed); + bool allowed = (is_cancel && (cruise_engaged_prev || controls_allowed)) || (is_resume && controls_allowed); if (!allowed) { tx = false; } } - // UDS: only tester present ("\x02\x3E\x80\x00\x00\x00\x00\x00") allowed on diagnostics address - if (((msg->addr == 0x730U) && hyundai_canfd_lka_steering) || ((msg->addr == 0x7D0U) && !hyundai_camera_scc)) { - if ((GET_BYTES(msg, 0, 4) != 0x00803E02U) || (GET_BYTES(msg, 4, 4) != 0x0U)) { + if ((addr == 0x730) && hyundai_canfd_hda2) { + if ((GET_BYTES(to_send, 0, 4) != 0x00803E02U) || (GET_BYTES(to_send, 4, 4) != 0x0U)) { tx = false; } } // ACCEL: safety check - if (msg->addr == 0x1a0U) { - int desired_accel_raw = (((msg->data[17] & 0x7U) << 8) | msg->data[16]) - 1023U; - int desired_accel_val = ((msg->data[18] << 4) | (msg->data[17] >> 4)) - 1023U; + if (addr == 0x1a0) { + int desired_accel_raw = (((GET_BYTE(to_send, 17) & 0x7U) << 8) | GET_BYTE(to_send, 16)) - 1023U; + int desired_accel_val = ((GET_BYTE(to_send, 18) << 4) | (GET_BYTE(to_send, 17) >> 4)) - 1023U; - bool violation = false; if (hyundai_longitudinal) { violation |= longitudinal_accel_checks(desired_accel_raw, HYUNDAI_LONG_LIMITS); violation |= longitudinal_accel_checks(desired_accel_val, HYUNDAI_LONG_LIMITS); - } else { + } + else { // only used to cancel on here - const int acc_mode = (msg->data[8] >> 4) & 0x7U; + const int acc_mode = (GET_BYTE(to_send, 8) >> 4) & 0x7U; if (acc_mode != 4) { violation = true; } - if ((desired_accel_raw != 0) || (desired_accel_val != 0)) { violation = true; } } - - if (violation) { - tx = false; - } - - acc_main_on_tx = GET_BIT(msg, 66U); - hyundai_common_acc_main_on_sync(); } + if (violation) { + tx = false; + } + else if (hyundai_canfd_buffered_fwd) { + CanfdBufferedFwd* bfwd = canfd_bfwd_find(addr, GET_BUS(to_send)); + if (bfwd != NULL) { + canfd_bfwd_push(bfwd, to_send); + //tx = false; + return true; + } + } + + canfd_record_tx_time(GET_BUS(to_send), addr, tx); + return tx; } +static bool hyundai_canfd_fwd_hook(int bus_num, int addr) { + uint32_t now = microsecond_timer_get(); + if (bus_num == 0) { + if (canfd_should_block_fwd(2, addr, now)) { + return true; + } + if (addr == 0x4B9) { + return true; + } + return false; + } + return (bus_num != 2) || canfd_should_block_fwd(0, addr, now); +} + static safety_config hyundai_canfd_init(uint16_t param) { - const uint16_t HYUNDAI_PARAM_CANFD_LKA_STEERING_ALT = 128; - const uint16_t HYUNDAI_PARAM_CANFD_ALT_BUTTONS = 32; - static const CanMsg HYUNDAI_CANFD_LKA_STEERING_TX_MSGS[] = { - HYUNDAI_CANFD_LKA_STEERING_COMMON_TX_MSGS(0, 1) - }; + for (int i = 0; canfd_tx_states[i].addr > 0; i++) { + canfd_tx_states[i].timeout_us = (uint32_t)(1000000.0 / canfd_tx_states[i].hz) + 20000U; + canfd_tx_states[i].last_tx_us = 0U; + } - static const CanMsg HYUNDAI_CANFD_LKA_STEERING_ALT_TX_MSGS[] = { - HYUNDAI_CANFD_LKA_STEERING_ALT_COMMON_TX_MSGS(0, 1) - }; - - static const CanMsg HYUNDAI_CANFD_LKA_STEERING_LONG_TX_MSGS[] = { - HYUNDAI_CANFD_LKA_STEERING_COMMON_TX_MSGS(0, 1) - HYUNDAI_CANFD_LFA_STEERING_COMMON_TX_MSGS(1) - HYUNDAI_CANFD_SCC_CONTROL_COMMON_TX_MSGS(1, true) - {0x51, 0, 32, .check_relay = false}, // ADRV_0x51 - {0x730, 1, 8, .check_relay = false}, // tester present for ADAS ECU disable - {0x160, 1, 16, .check_relay = false}, // ADRV_0x160 - {0x1EA, 1, 32, .check_relay = false}, // ADRV_0x1ea - {0x200, 1, 8, .check_relay = false}, // ADRV_0x200 - {0x345, 1, 8, .check_relay = false}, // ADRV_0x345 - {0x1DA, 1, 32, .check_relay = false}, // ADRV_0x1da - }; - - static const CanMsg HYUNDAI_CANFD_LFA_STEERING_TX_MSGS[] = { - HYUNDAI_CANFD_CRUISE_BUTTON_TX_MSGS(2) - HYUNDAI_CANFD_LFA_STEERING_COMMON_TX_MSGS(0) - HYUNDAI_CANFD_SCC_CONTROL_COMMON_TX_MSGS(0, false) - }; - - // ADRV_0x160 is checked for radar liveness - static const CanMsg HYUNDAI_CANFD_LFA_STEERING_LONG_TX_MSGS[] = { - HYUNDAI_CANFD_CRUISE_BUTTON_TX_MSGS(2) - HYUNDAI_CANFD_LFA_STEERING_COMMON_TX_MSGS(0) - HYUNDAI_CANFD_SCC_CONTROL_COMMON_TX_MSGS(0, true) - {0x160, 0, 16, .check_relay = true}, // ADRV_0x160 - {0x7D0, 0, 8, .check_relay = false}, // tester present for radar ECU disable - }; - - // ADRV_0x160 is checked for relay malfunction -#define HYUNDAI_CANFD_LFA_STEERING_CAMERA_SCC_TX_MSGS(longitudinal) \ - HYUNDAI_CANFD_CRUISE_BUTTON_TX_MSGS(2) \ - HYUNDAI_CANFD_LFA_STEERING_COMMON_TX_MSGS(0) \ - HYUNDAI_CANFD_SCC_CONTROL_COMMON_TX_MSGS(0, (longitudinal)) \ - {0x160, 0, 16, .check_relay = (longitudinal)}, /* ADRV_0x160 */ \ + for (int i = 0; canfd_bfwd[i].addr > 0; i++) { + canfd_bfwd_reset(&canfd_bfwd[i]); + } hyundai_common_init(param); gen_crc_lookup_table_16(0x1021, hyundai_canfd_crc_lut); hyundai_canfd_alt_buttons = GET_FLAG(param, HYUNDAI_PARAM_CANFD_ALT_BUTTONS); - hyundai_canfd_lka_steering_alt = GET_FLAG(param, HYUNDAI_PARAM_CANFD_LKA_STEERING_ALT); + hyundai_canfd_hda2_alt_steering = GET_FLAG(param, HYUNDAI_PARAM_CANFD_HDA2_ALT_STEERING); + hyundai_canfd_buffered_fwd = hyundai_camera_scc; + // no long for radar-SCC HDA1 yet + //if (!hyundai_canfd_hda2 && !hyundai_camera_scc) { + // hyundai_longitudinal = false; + //} safety_config ret; if (hyundai_longitudinal) { - if (hyundai_canfd_lka_steering) { - static RxCheck hyundai_canfd_lka_steering_long_rx_checks[] = { - HYUNDAI_CANFD_STD_BUTTONS_RX_CHECKS(1) - }; - - ret = BUILD_SAFETY_CFG(hyundai_canfd_lka_steering_long_rx_checks, HYUNDAI_CANFD_LKA_STEERING_LONG_TX_MSGS); - + if (hyundai_canfd_hda2) { + if (hyundai_canfd_alt_buttons) { // carrot : for CANIVAL 4TH HDA2 + if (hyundai_camera_scc) ret = BUILD_SAFETY_CFG(hyundai_canfd_hda2_long_alt_buttons_rx_checks_scc2, HYUNDAI_CANFD_HDA2_LONG_TX_MSGS); + else ret = BUILD_SAFETY_CFG(hyundai_canfd_hda2_long_alt_buttons_rx_checks, HYUNDAI_CANFD_HDA2_LONG_TX_MSGS); + } + else { + if (hyundai_camera_scc) ret = BUILD_SAFETY_CFG(hyundai_canfd_hda2_long_rx_checks_scc2, HYUNDAI_CANFD_HDA2_LONG_TX_MSGS); + else ret = BUILD_SAFETY_CFG(hyundai_canfd_hda2_long_rx_checks, HYUNDAI_CANFD_HDA2_LONG_TX_MSGS); + } } else { - // Longitudinal checks for LFA steering - static RxCheck hyundai_canfd_long_rx_checks[] = { - HYUNDAI_CANFD_STD_BUTTONS_RX_CHECKS(0) - }; - - static RxCheck hyundai_canfd_alt_buttons_long_rx_checks[] = { - HYUNDAI_CANFD_ALT_BUTTONS_RX_CHECKS(0) - }; - - static CanMsg hyundai_canfd_lfa_steering_camera_scc_tx_msgs[] = { - HYUNDAI_CANFD_LFA_STEERING_CAMERA_SCC_TX_MSGS(true) - }; - - if (hyundai_canfd_alt_buttons) { - SET_RX_CHECKS(hyundai_canfd_alt_buttons_long_rx_checks, ret); - } else { - SET_RX_CHECKS(hyundai_canfd_long_rx_checks, ret); - } - - if (hyundai_camera_scc) { - SET_TX_MSGS(hyundai_canfd_lfa_steering_camera_scc_tx_msgs, ret); - } else { - SET_TX_MSGS(HYUNDAI_CANFD_LFA_STEERING_LONG_TX_MSGS, ret); - } + ret = hyundai_canfd_alt_buttons ? BUILD_SAFETY_CFG(hyundai_canfd_long_alt_buttons_rx_checks, HYUNDAI_CANFD_HDA1_TX_MSGS) : \ + BUILD_SAFETY_CFG(hyundai_canfd_long_rx_checks, HYUNDAI_CANFD_HDA1_TX_MSGS); } - } else { - if (hyundai_canfd_lka_steering) { - // *** LKA steering checks *** - // E-CAN is on bus 1, SCC messages are sent on cars with ADRV ECU. - // Does not use the alt buttons message - static RxCheck hyundai_canfd_lka_steering_rx_checks[] = { - HYUNDAI_CANFD_STD_BUTTONS_RX_CHECKS(1) - HYUNDAI_CANFD_SCC_ADDR_CHECK(1) + if (hyundai_canfd_hda2 && hyundai_camera_scc) { + if (hyundai_canfd_alt_buttons) { // carrot : for CANIVAL 4TH HDA2 + ret = hyundai_canfd_hda2_alt_steering ? BUILD_SAFETY_CFG(hyundai_canfd_hda2_alt_buttons_rx_checks_scc2, HYUNDAI_CANFD_HDA2_LONG_TX_MSGS) : \ + BUILD_SAFETY_CFG(hyundai_canfd_hda2_alt_buttons_rx_checks_scc2, HYUNDAI_CANFD_HDA2_LONG_TX_MSGS); + } + else { + ret = hyundai_canfd_hda2_alt_steering ? BUILD_SAFETY_CFG(hyundai_canfd_hda2_rx_checks_scc2, HYUNDAI_CANFD_HDA2_LONG_TX_MSGS) : \ + BUILD_SAFETY_CFG(hyundai_canfd_hda2_rx_checks_scc2, HYUNDAI_CANFD_HDA2_LONG_TX_MSGS); + } + }else if (hyundai_canfd_hda2) { + if (hyundai_canfd_alt_buttons) { // carrot : for CANIVAL 4TH HDA2 + ret = hyundai_canfd_hda2_alt_steering ? BUILD_SAFETY_CFG(hyundai_canfd_hda2_alt_buttons_rx_checks, HYUNDAI_CANFD_HDA2_LONG_TX_MSGS) : \ + BUILD_SAFETY_CFG(hyundai_canfd_hda2_alt_buttons_rx_checks, HYUNDAI_CANFD_HDA2_LONG_TX_MSGS); + } + else { + ret = hyundai_canfd_hda2_alt_steering ? BUILD_SAFETY_CFG(hyundai_canfd_hda2_rx_checks, HYUNDAI_CANFD_HDA2_LONG_TX_MSGS) : \ + BUILD_SAFETY_CFG(hyundai_canfd_hda2_rx_checks, HYUNDAI_CANFD_HDA2_LONG_TX_MSGS); + } + } else if (!hyundai_camera_scc) { + static RxCheck hyundai_canfd_radar_scc_alt_buttons_rx_checks[] = { + HYUNDAI_CANFD_COMMON_RX_CHECKS(0) + HYUNDAI_CANFD_ALT_BUTTONS_ADDR_CHECK(0) + HYUNDAI_CANFD_SCC_ADDR_CHECK(0) }; - SET_RX_CHECKS(hyundai_canfd_lka_steering_rx_checks, ret); - if (hyundai_canfd_lka_steering_alt) { - SET_TX_MSGS(HYUNDAI_CANFD_LKA_STEERING_ALT_TX_MSGS, ret); - } else { - SET_TX_MSGS(HYUNDAI_CANFD_LKA_STEERING_TX_MSGS, ret); - } - - } else if (!hyundai_camera_scc) { // Radar sends SCC messages on these cars instead of camera static RxCheck hyundai_canfd_radar_scc_rx_checks[] = { - HYUNDAI_CANFD_STD_BUTTONS_RX_CHECKS(0) + HYUNDAI_CANFD_COMMON_RX_CHECKS(0) + HYUNDAI_CANFD_BUTTONS_ADDR_CHECK(0) HYUNDAI_CANFD_SCC_ADDR_CHECK(0) }; - static RxCheck hyundai_canfd_alt_buttons_radar_scc_rx_checks[] = { - HYUNDAI_CANFD_ALT_BUTTONS_RX_CHECKS(0) - HYUNDAI_CANFD_SCC_ADDR_CHECK(0) - }; - - SET_TX_MSGS(HYUNDAI_CANFD_LFA_STEERING_TX_MSGS, ret); - - if (hyundai_canfd_alt_buttons) { - SET_RX_CHECKS(hyundai_canfd_alt_buttons_radar_scc_rx_checks, ret); - } else { - SET_RX_CHECKS(hyundai_canfd_radar_scc_rx_checks, ret); - } - + ret = hyundai_canfd_alt_buttons ? BUILD_SAFETY_CFG(hyundai_canfd_radar_scc_alt_buttons_rx_checks, HYUNDAI_CANFD_HDA1_TX_MSGS) : \ + BUILD_SAFETY_CFG(hyundai_canfd_radar_scc_rx_checks, HYUNDAI_CANFD_HDA1_TX_MSGS); } else { - // *** LFA steering checks *** - // Camera sends SCC messages on LFA steering cars. + // *** Non-HDA2 checks *** + static RxCheck hyundai_canfd_alt_buttons_rx_checks[] = { + HYUNDAI_CANFD_COMMON_RX_CHECKS(0) + HYUNDAI_CANFD_ALT_BUTTONS_ADDR_CHECK(0) + HYUNDAI_CANFD_SCC_ADDR_CHECK(2) + }; + + // Camera sends SCC messages on HDA1. // Both button messages exist on some platforms, so we ensure we track the correct one using flag static RxCheck hyundai_canfd_rx_checks[] = { - HYUNDAI_CANFD_STD_BUTTONS_RX_CHECKS(0) + HYUNDAI_CANFD_COMMON_RX_CHECKS(0) + HYUNDAI_CANFD_BUTTONS_ADDR_CHECK(0) HYUNDAI_CANFD_SCC_ADDR_CHECK(2) }; - static RxCheck hyundai_canfd_alt_buttons_rx_checks[] = { - HYUNDAI_CANFD_ALT_BUTTONS_RX_CHECKS(0) - HYUNDAI_CANFD_SCC_ADDR_CHECK(2) - }; - - static CanMsg hyundai_canfd_lfa_steering_camera_scc_tx_msgs[] = { - HYUNDAI_CANFD_LFA_STEERING_CAMERA_SCC_TX_MSGS(false) - }; - - SET_TX_MSGS(hyundai_canfd_lfa_steering_camera_scc_tx_msgs, ret); - - if (hyundai_canfd_alt_buttons) { - SET_RX_CHECKS(hyundai_canfd_alt_buttons_rx_checks, ret); - } else { - SET_RX_CHECKS(hyundai_canfd_rx_checks, ret); - } + ret = hyundai_canfd_alt_buttons ? BUILD_SAFETY_CFG(hyundai_canfd_alt_buttons_rx_checks, HYUNDAI_CANFD_HDA1_TX_MSGS) : \ + BUILD_SAFETY_CFG(hyundai_canfd_rx_checks, HYUNDAI_CANFD_HDA1_TX_MSGS); } } @@ -385,6 +745,7 @@ const safety_hooks hyundai_canfd_hooks = { .init = hyundai_canfd_init, .rx = hyundai_canfd_rx_hook, .tx = hyundai_canfd_tx_hook, + .fwd = hyundai_canfd_fwd_hook, .get_counter = hyundai_canfd_get_counter, .get_checksum = hyundai_canfd_get_checksum, .compute_checksum = hyundai_common_canfd_compute_checksum, diff --git a/iqdbc_repo/iqdbc/safety/modes/hyundai_common.h b/iqdbc_repo/iqdbc/safety/modes/hyundai_common.h index 8d16f08..2cbb2c8 100644 --- a/iqdbc_repo/iqdbc/safety/modes/hyundai_common.h +++ b/iqdbc_repo/iqdbc/safety/modes/hyundai_common.h @@ -2,11 +2,20 @@ #include "iqdbc/safety/declarations.h" +#define GET_ADDR(msg) ((msg)->addr) +#define GET_BUS(msg) ((msg)->bus) +#define GET_BYTE(msg, b) ((msg)->data[(b)]) + +static int cruise_main_prev = 0; + +static void generic_rx_checks(void); +static void stock_ecu_check(bool stock_ecu_detected); + extern uint16_t hyundai_canfd_crc_lut[256]; uint16_t hyundai_canfd_crc_lut[256]; static const uint8_t HYUNDAI_PREV_BUTTON_SAMPLES = 8; // roughly 160 ms - + // extern const uint32_t HYUNDAI_STANDSTILL_THRSLD; const uint32_t HYUNDAI_STANDSTILL_THRSLD = 12; // 0.375 kph @@ -17,13 +26,6 @@ enum { HYUNDAI_BTN_CANCEL = 4, }; -enum { - HYUNDAI_PARAM_IQ_ESCC = 16, - HYUNDAI_PARAM_IQ_MAIN_BTN_LONG_TOGGLE = 32, - HYUNDAI_PARAM_IQ_HAS_LDA_BUTTON = 64, - HYUNDAI_PARAM_IQ_NON_SCC = 128, -}; - // common state extern bool hyundai_ev_gas_signal; bool hyundai_ev_gas_signal = false; @@ -37,8 +39,8 @@ bool hyundai_longitudinal = false; extern bool hyundai_camera_scc; bool hyundai_camera_scc = false; -extern bool hyundai_canfd_lka_steering; -bool hyundai_canfd_lka_steering = false; +extern bool hyundai_canfd_hda2; +bool hyundai_canfd_hda2 = false; extern bool hyundai_alt_limits; bool hyundai_alt_limits = false; @@ -49,57 +51,29 @@ bool hyundai_fcev_gas_signal = false; extern bool hyundai_alt_limits_2; bool hyundai_alt_limits_2 = false; -// ESCC -extern bool hyundai_escc; -bool hyundai_escc = false; - -extern bool hyundai_main_btn_long_toggle; -bool hyundai_main_btn_long_toggle = false; - -extern bool hyundai_has_lda_button; -bool hyundai_has_lda_button = false; - -extern bool hyundai_non_scc; -bool hyundai_non_scc = false; - static uint8_t hyundai_last_button_interaction; // button messages since the user pressed an enable button -static bool main_button_prev; -static bool acc_main_on_prev; -static bool acc_main_on_tx; -static uint32_t acc_main_on_mismatches; - void hyundai_common_init(uint16_t param) { - const uint16_t HYUNDAI_PARAM_EV_GAS = 1; - const uint16_t HYUNDAI_PARAM_HYBRID_GAS = 2; - const uint16_t HYUNDAI_PARAM_CAMERA_SCC = 8; - const uint16_t HYUNDAI_PARAM_CANFD_LKA_STEERING = 16; - const uint16_t HYUNDAI_PARAM_ALT_LIMITS = 64; // TODO: shift this down with the rest of the common flags - const uint16_t HYUNDAI_PARAM_FCEV_GAS = 256; - const uint16_t HYUNDAI_PARAM_ALT_LIMITS_2 = 512; + const int HYUNDAI_PARAM_EV_GAS = 1; + const int HYUNDAI_PARAM_HYBRID_GAS = 2; + const int HYUNDAI_PARAM_CAMERA_SCC = 8; + const int HYUNDAI_PARAM_CANFD_HDA2 = 16; + const int HYUNDAI_PARAM_ALT_LIMITS = 64; // TODO: shift this down with the rest of the common flags + const int HYUNDAI_PARAM_FCEV_GAS = 256; + const int HYUNDAI_PARAM_ALT_LIMITS_2 = 512; hyundai_ev_gas_signal = GET_FLAG(param, HYUNDAI_PARAM_EV_GAS); hyundai_hybrid_gas_signal = !hyundai_ev_gas_signal && GET_FLAG(param, HYUNDAI_PARAM_HYBRID_GAS); hyundai_camera_scc = GET_FLAG(param, HYUNDAI_PARAM_CAMERA_SCC); - hyundai_canfd_lka_steering = GET_FLAG(param, HYUNDAI_PARAM_CANFD_LKA_STEERING); + hyundai_canfd_hda2 = GET_FLAG(param, HYUNDAI_PARAM_CANFD_HDA2); hyundai_alt_limits = GET_FLAG(param, HYUNDAI_PARAM_ALT_LIMITS); hyundai_fcev_gas_signal = GET_FLAG(param, HYUNDAI_PARAM_FCEV_GAS); hyundai_alt_limits_2 = GET_FLAG(param, HYUNDAI_PARAM_ALT_LIMITS_2); - hyundai_escc = GET_FLAG(current_safety_param_iq, HYUNDAI_PARAM_IQ_ESCC); - hyundai_main_btn_long_toggle = GET_FLAG(current_safety_param_iq, HYUNDAI_PARAM_IQ_MAIN_BTN_LONG_TOGGLE); - hyundai_has_lda_button = GET_FLAG(current_safety_param_iq, HYUNDAI_PARAM_IQ_HAS_LDA_BUTTON); - hyundai_non_scc = GET_FLAG(current_safety_param_iq, HYUNDAI_PARAM_IQ_NON_SCC); - hyundai_last_button_interaction = HYUNDAI_PREV_BUTTON_SAMPLES; - main_button_prev = false; - acc_main_on_prev = false; - acc_main_on_tx = false; - acc_main_on_mismatches = 0U; - #ifdef ALLOW_DEBUG - const uint16_t HYUNDAI_PARAM_LONGITUDINAL = 4; + const int HYUNDAI_PARAM_LONGITUDINAL = 4; hyundai_longitudinal = GET_FLAG(param, HYUNDAI_PARAM_LONGITUDINAL); #else hyundai_longitudinal = false; @@ -112,19 +86,27 @@ void hyundai_common_cruise_state_check(const bool cruise_engaged) { // enter controls on rising edge of ACC and recent user button press, exit controls when ACC off if (!hyundai_longitudinal) { - if (cruise_engaged && !cruise_engaged_prev && (hyundai_last_button_interaction < HYUNDAI_PREV_BUTTON_SAMPLES)) { + hyundai_last_button_interaction = 0U; // carrot + //if (cruise_engaged && !cruise_engaged_prev && (hyundai_last_button_interaction < HYUNDAI_PREV_BUTTON_SAMPLES)) { + if (cruise_engaged) { controls_allowed = true; } if (!cruise_engaged) { controls_allowed = false; + } cruise_engaged_prev = cruise_engaged; } } void hyundai_common_cruise_buttons_check(const int cruise_button, const bool main_button) { - if ((cruise_button == HYUNDAI_BTN_RESUME) || (cruise_button == HYUNDAI_BTN_SET) || (cruise_button == HYUNDAI_BTN_CANCEL) || main_button) { + if(main_button && main_button != cruise_main_prev) { + acc_main_on = !acc_main_on; + } + cruise_main_prev = main_button; + if ((cruise_button == HYUNDAI_BTN_RESUME) || (cruise_button == HYUNDAI_BTN_SET) || (cruise_button == HYUNDAI_BTN_CANCEL) || + (main_button)) { hyundai_last_button_interaction = 0U; } else { hyundai_last_button_interaction = SAFETY_MIN(hyundai_last_button_interaction + 1U, HYUNDAI_PREV_BUTTON_SAMPLES); @@ -141,66 +123,38 @@ void hyundai_common_cruise_buttons_check(const int cruise_button, const bool mai // exit controls on cancel press if (cruise_button == HYUNDAI_BTN_CANCEL) { controls_allowed = false; - } - // toggle main cruise state on rising edge of main cruise button - if (main_button && !main_button_prev && hyundai_main_btn_long_toggle) { - acc_main_on = !acc_main_on; } cruise_button_prev = cruise_button; - main_button_prev = main_button; } } -uint32_t hyundai_common_canfd_compute_checksum(const CANPacket_t *msg) { - int len = GET_LEN(msg); - uint32_t address = msg->addr; +uint32_t hyundai_common_canfd_compute_checksum(const CANPacket_t *to_push) { + int len = GET_LEN(to_push); + uint32_t address = GET_ADDR(to_push); uint16_t crc = 0; for (int i = 2; i < len; i++) { - crc = (crc << 8U) ^ hyundai_canfd_crc_lut[(crc >> 8U) ^ msg->data[i]]; + crc = (crc << 8U) ^ hyundai_canfd_crc_lut[(crc >> 8U) ^ GET_BYTE(to_push, i)]; } - // Add address to crc crc = (crc << 8U) ^ hyundai_canfd_crc_lut[(crc >> 8U) ^ ((address >> 0U) & 0xFFU)]; crc = (crc << 8U) ^ hyundai_canfd_crc_lut[(crc >> 8U) ^ ((address >> 8U) & 0xFFU)]; - if (len == 24) { + if (len == 8) { + crc ^= 0x5f29U; + } + else if (len == 16) { + crc ^= 0x041dU; + } + else if (len == 24) { crc ^= 0x819dU; - } else if (len == 32) { + } + else if (len == 32) { crc ^= 0x9f5bU; - } else { - } return crc; } - -// reset mismatches on rising edge of acc_main_on to avoid rare race conditions when using non-PCM main cruise state -void hyundai_common_reset_acc_main_on_mismatches(void) { - if (acc_main_on && !acc_main_on_prev) { - acc_main_on_mismatches = 0U; - } - - acc_main_on_prev = acc_main_on; -} - -// exit lateral controls allowed if iqpilot and panda main cruise states are desynced -void hyundai_common_acc_main_on_sync(void) { - if (acc_main_on && !acc_main_on_tx) { - acc_main_on_mismatches += 1U; - - if (acc_main_on_mismatches >= 3U) { // desync by 3 frames - acc_main_on = false; - aol_exit_controls(AOL_DISENGAGE_REASON_NON_PCM_ACC_MAIN_DESYNC); - } - } else { - acc_main_on_mismatches = 0U; - } -} - -uint32_t get_acc_main_on_mismatches(void) { - return acc_main_on_mismatches; -} diff --git a/iqdbc_repo/iqdbc/safety/tests/hyundai_common.py b/iqdbc_repo/iqdbc/safety/tests/hyundai_common.py index cceb125..b5ea09d 100644 --- a/iqdbc_repo/iqdbc/safety/tests/hyundai_common.py +++ b/iqdbc_repo/iqdbc/safety/tests/hyundai_common.py @@ -1,296 +1,46 @@ -import unittest - -from iqdbc.iqpilot.car.hyundai.values import HyundaiSafetyFlagsIQ -import iqdbc.safety.tests.common as common from iqdbc.safety.tests.libsafety import libsafety_py -from iqdbc.safety.tests.common import make_msg -class Buttons: - NONE = 0 - RESUME = 1 - SET = 2 - CANCEL = 4 +def packet(addr: int, bus: int, length: int, updates: dict[int, int] | None = None): + data = bytearray(length) + for index, value in (updates or {}).items(): + data[index] = value + return libsafety_py.make_CANPacket(addr, bus, data) -PREV_BUTTON_SAMPLES = 8 -ENABLE_BUTTONS = (Buttons.RESUME, Buttons.SET, Buttons.CANCEL) +def classic_steer(torque: int, request: bool = True): + value = torque + 1024 + word = (value << 16) | (int(request) << 27) + return packet(0x340, 0, 8, {i: (word >> (8 * i)) & 0xFF for i in range(4)}) -class HyundaiButtonBase: - BUTTONS_TX_BUS = 0 # tx on this bus, rx on 0 - SCC_BUS = 0 # rx on this bus - - def test_button_sends(self): - """ - RES, SET and CANCEL buttons are allowed - - RES and SET allowed while controls allowed - - CANCEL allowed while cruise is enabled - """ - self.safety.set_controls_allowed(0) - self.assertFalse(self._tx(self._button_msg(Buttons.RESUME, bus=self.BUTTONS_TX_BUS))) - self.assertFalse(self._tx(self._button_msg(Buttons.SET, bus=self.BUTTONS_TX_BUS))) - - self.safety.set_controls_allowed(1) - self.assertTrue(self._tx(self._button_msg(Buttons.RESUME, bus=self.BUTTONS_TX_BUS))) - self.assertTrue(self._tx(self._button_msg(Buttons.SET, bus=self.BUTTONS_TX_BUS))) - - for enabled in (True, False): - self._rx(self._pcm_status_msg(enabled)) - self.assertEqual(enabled, self._tx(self._button_msg(Buttons.CANCEL, bus=self.BUTTONS_TX_BUS))) - - def test_enable_control_allowed_from_cruise(self): - """ - Hyundai non-longitudinal only enables on PCM rising edge and recent button press. Tests PCM enabling with: - - disallowed: No buttons - - disallowed: Buttons that don't enable cruise - - allowed: Buttons that do enable cruise - - allowed: Main button with all above combinations - """ - for main_button in (0, 1): - for btn in range(8): - for _ in range(PREV_BUTTON_SAMPLES): # reset - self._rx(self._button_msg(Buttons.NONE)) - - self._rx(self._pcm_status_msg(False)) - self.assertFalse(self.safety.get_controls_allowed()) - self._rx(self._button_msg(btn, main_button=main_button)) - self._rx(self._pcm_status_msg(True)) - controls_allowed = btn in ENABLE_BUTTONS or main_button - self.assertEqual(controls_allowed, self.safety.get_controls_allowed()) - - def test_sampling_cruise_buttons(self): - """ - Test that we allow controls on recent button press, but not as button leaves sliding window - """ - self._rx(self._button_msg(Buttons.SET)) - for i in range(2 * PREV_BUTTON_SAMPLES): - self._rx(self._pcm_status_msg(False)) - self.assertFalse(self.safety.get_controls_allowed()) - self._rx(self._pcm_status_msg(True)) - controls_allowed = i < PREV_BUTTON_SAMPLES - self.assertEqual(controls_allowed, self.safety.get_controls_allowed()) - self._rx(self._button_msg(Buttons.NONE)) +def canfd_steer(addr: int, length: int, torque: int, request: bool = True): + value = torque + 1024 + return packet(addr, 0, length, { + 5: (value & 0x7F) << 1, + 6: ((value >> 7) & 0xF) | (int(request) << 4), + }) -class HyundaiLongitudinalBase(common.LongitudinalAccelSafetyTest): +def classic_accel(accel: int, *, aeb_decel: int = 0, aeb_request: bool = False): + value = accel + 1023 + return packet(0x421, 0, 8, { + 2: aeb_decel, + 3: value & 0xFF, + 4: ((value >> 8) & 0x7) | ((value & 0x7) << 5), + 5: (value >> 3) & 0xFF, + 6: int(aeb_request) << 6, + }) - DISABLED_ECU_UDS_MSG: tuple[int, int] - DISABLED_ECU_ACTUATION_MSG: tuple[int, int] - @classmethod - def setUpClass(cls): - if cls.__name__ == "HyundaiLongitudinalBase": - cls.safety = None - raise unittest.SkipTest +def canfd_accel(accel: int, *, acc_mode: int = 0, bus: int = 0): + value = accel + 1023 + return packet(0x1A0, bus, 32, { + 8: (acc_mode & 0x7) << 4, + 16: value & 0xFF, + 17: ((value >> 8) & 0x7) | ((value & 0xF) << 4), + 18: (value >> 4) & 0xFF, + }) - # override these tests from CarSafetyTest, hyundai longitudinal uses button enable - def test_disable_control_allowed_from_cruise(self): - pass - def test_enable_control_allowed_from_cruise(self): - pass - - def test_sampling_cruise_buttons(self): - pass - - def test_cruise_engaged_prev(self): - pass - - def test_button_sends(self): - pass - - def _pcm_status_msg(self, enable): - raise Exception - - def _accel_msg(self, accel, aeb_req=False, aeb_decel=0): - raise NotImplementedError - - def _acc_state_msg(self, enable): - raise NotImplementedError - - def _tx_acc_state_msg(self, enable): - raise NotImplementedError - - def test_pcm_main_cruise_state_availability(self): - pass - - def test_set_resume_buttons(self): - """ - SET and RESUME enter controls allowed on their falling edge. - """ - for btn_prev in range(8): - for btn_cur in range(8): - self._rx(self._button_msg(Buttons.NONE)) - self.safety.set_controls_allowed(0) - for _ in range(10): - self._rx(self._button_msg(btn_prev)) - self.assertFalse(self.safety.get_controls_allowed()) - - # should enter controls allowed on falling edge and not transitioning to cancel - should_enable = btn_cur != btn_prev and \ - btn_cur != Buttons.CANCEL and \ - btn_prev in (Buttons.RESUME, Buttons.SET) - - self._rx(self._button_msg(btn_cur)) - self.assertEqual(should_enable, self.safety.get_controls_allowed()) - - def test_cancel_button(self): - self.safety.set_controls_allowed(1) - self._rx(self._button_msg(Buttons.CANCEL)) - self.assertFalse(self.safety.get_controls_allowed()) - - def test_main_cruise_button(self): - """Test that main cruise button correctly toggles acc_main_on state""" - default_safety_mode = self.safety.get_current_safety_mode() - default_safety_param = self.safety.get_current_safety_param() - default_safety_param_iq = self.safety.get_current_safety_param_iq() - - for enable_aol in (True, False): - with self.subTest("enable_aol", aol_enabled=enable_aol): - for main_cruise_toggleable in (True, False): - with self.subTest("main_cruise_toggleable", main_cruise_toggleable=main_cruise_toggleable): - main_cruise_toggleable_flag = HyundaiSafetyFlagsIQ.MAIN_BTN_LONG_TOGGLE if main_cruise_toggleable else 0 - self.safety.set_current_safety_param_iq(default_safety_param_iq | main_cruise_toggleable_flag) - self.safety.set_safety_hooks(default_safety_mode, default_safety_param) - - # Test initial state - self.safety.set_aol_params(enable_aol, False, False) - - self.assertFalse(self.safety.get_acc_main_on()) - - self._rx(self._main_cruise_button_msg(0)) - self._rx(self._main_cruise_button_msg(1)) - self.assertEqual(enable_aol and main_cruise_toggleable, self.safety.get_controls_allowed_lat()) - - self._rx(self._main_cruise_button_msg(0)) - self.assertEqual(enable_aol and main_cruise_toggleable, self.safety.get_controls_allowed_lat()) - - self._rx(self._main_cruise_button_msg(1)) - self.assertFalse(self.safety.get_controls_allowed_lat()) - - for _ in range(10): - self._rx(self._main_cruise_button_msg(1)) - self.assertFalse(self.safety.get_controls_allowed_lat()) - self.safety.set_current_safety_param_iq(default_safety_param_iq) - - def test_acc_main_sync_mismatches_reset(self): - """Test that acc_main_on_mismatches resets properly on rising edge of main button""" - default_safety_mode = self.safety.get_current_safety_mode() - default_safety_param = self.safety.get_current_safety_param() - default_safety_param_iq = self.safety.get_current_safety_param_iq() - - for enable_aol in (True, False): - with self.subTest("enable_aol", aol_enabled=enable_aol): - main_cruise_toggleable_flag = HyundaiSafetyFlagsIQ.MAIN_BTN_LONG_TOGGLE - self.safety.set_current_safety_param_iq(default_safety_param_iq | main_cruise_toggleable_flag) - self.safety.set_safety_hooks(default_safety_mode, default_safety_param) - - self.safety.set_aol_params(enable_aol, False, False) - - # Initial state - self._rx(self._main_cruise_button_msg(0)) - self.assertFalse(self.safety.get_acc_main_on()) - - # Set up mismatch condition - self._rx(self._main_cruise_button_msg(1)) # Press button - acc_main_on = True - self._rx(self._main_cruise_button_msg(0)) # Release button - self._tx(self._tx_acc_state_msg(False)) # acc_main_on_tx = False - self.assertTrue(self.safety.get_acc_main_on()) - self.assertEqual(1, self.safety.get_acc_main_on_mismatches()) - - # Rising edge of acc_main_on should reset - self._rx(self._main_cruise_button_msg(1)) # Press button again - self._rx(self._main_cruise_button_msg(0)) # Release button - self._tx(self._tx_acc_state_msg(False)) # acc_main_on_tx = False - self.assertFalse(self.safety.get_acc_main_on()) - self.assertEqual(0, self.safety.get_acc_main_on_mismatches()) - self.safety.set_current_safety_param_iq(default_safety_param_iq) - - def test_acc_main_sync_mismatch_counter(self): - """Test mismatch counter behavior and disengagement""" - default_safety_mode = self.safety.get_current_safety_mode() - default_safety_param = self.safety.get_current_safety_param() - default_safety_param_iq = self.safety.get_current_safety_param_iq() - - for enable_aol in (True, False): - with self.subTest("enable_aol", aol_enabled=enable_aol): - main_cruise_toggleable_flag = HyundaiSafetyFlagsIQ.MAIN_BTN_LONG_TOGGLE - self.safety.set_current_safety_param_iq(default_safety_param_iq | main_cruise_toggleable_flag) - self.safety.set_safety_hooks(default_safety_mode, default_safety_param) - - self.safety.set_aol_params(enable_aol, False, False) - self.safety.set_controls_allowed_lat(True) - - # Start with matched states - self._rx(self._main_cruise_button_msg(0)) - self._tx(self._tx_acc_state_msg(False)) - self.assertEqual(0, self.safety.get_acc_main_on_mismatches()) - - # Create mismatch by enabling acc_main_on - self._rx(self._main_cruise_button_msg(1)) # Press button - self._rx(self._main_cruise_button_msg(0)) # Release button - self._tx(self._tx_acc_state_msg(False)) # acc_main_on_tx stays false - self.assertTrue(self.safety.get_acc_main_on()) - self.assertEqual(1, self.safety.get_acc_main_on_mismatches()) - - # Second mismatch - self._tx(self._tx_acc_state_msg(False)) - self.assertTrue(self.safety.get_acc_main_on()) - self.assertEqual(2, self.safety.get_acc_main_on_mismatches()) - - # Third mismatch should trigger disengagement - self._tx(self._tx_acc_state_msg(False)) - self.assertFalse(self.safety.get_acc_main_on()) - self.assertFalse(self.safety.get_controls_allowed_lat()) - # Counter should reset after disengagement - self._tx(self._tx_acc_state_msg(False)) - self.assertEqual(0, self.safety.get_acc_main_on_mismatches()) - self.safety.set_current_safety_param_iq(default_safety_param_iq) - - def test_acc_main_sync_mismatch_recovery(self): - default_safety_mode = self.safety.get_current_safety_mode() - default_safety_param = self.safety.get_current_safety_param() - default_safety_param_iq = self.safety.get_current_safety_param_iq() - - """Test that mismatch counter resets when states resync""" - for enable_aol in (True, False): - with self.subTest("enable_aol", aol_enabled=enable_aol): - main_cruise_toggleable_flag = HyundaiSafetyFlagsIQ.MAIN_BTN_LONG_TOGGLE - self.safety.set_current_safety_param_iq(default_safety_param_iq | main_cruise_toggleable_flag) - self.safety.set_safety_hooks(default_safety_mode, default_safety_param) - - self.safety.set_aol_params(enable_aol, False, False) - - # Create initial mismatch - self._rx(self._main_cruise_button_msg(1)) # Press button - self._rx(self._main_cruise_button_msg(0)) # Release button - self._tx(self._tx_acc_state_msg(False)) # acc_main_on_tx = False - self.assertEqual(1, self.safety.get_acc_main_on_mismatches()) - - # Sync states - self._tx(self._tx_acc_state_msg(True)) # Match acc_main_on_tx to acc_main_on - self.assertEqual(0, self.safety.get_acc_main_on_mismatches()) - self.safety.set_current_safety_param_iq(default_safety_param_iq) - - def test_tester_present_allowed(self, ecu_disable: bool = True): - """ - Ensure tester present diagnostic message is allowed to keep ECU knocked out - for longitudinal control. - """ - - addr, bus = self.DISABLED_ECU_UDS_MSG - for should_tx, msg in ((True, b"\x02\x3E\x80\x00\x00\x00\x00\x00"), - (False, b"\x03\xAA\xAA\x00\x00\x00\x00\x00")): - tester_present = libsafety_py.make_CANPacket(addr, bus, msg) - self.assertEqual(should_tx and ecu_disable, self._tx(tester_present)) - - def test_disabled_ecu_alive(self): - """ - If the ECU knockout failed, make sure the relay malfunction is shown - """ - - addr, bus = self.DISABLED_ECU_ACTUATION_MSG - self.assertFalse(self.safety.get_relay_malfunction()) - self._rx(make_msg(bus, addr, 8)) - self.assertTrue(self.safety.get_relay_malfunction()) +TESTER_PRESENT = bytes.fromhex("023e800000000000") diff --git a/iqdbc_repo/iqdbc/safety/tests/test_hyundai.py b/iqdbc_repo/iqdbc/safety/tests/test_hyundai.py old mode 100755 new mode 100644 index dff2645..398d03a --- a/iqdbc_repo/iqdbc/safety/tests/test_hyundai.py +++ b/iqdbc_repo/iqdbc/safety/tests/test_hyundai.py @@ -1,569 +1,107 @@ -#!/usr/bin/env python3 -from parameterized import parameterized_class -import random -import unittest +import pytest from iqdbc.car.hyundai.values import HyundaiSafetyFlags from iqdbc.car.structs import CarParams +from iqdbc.safety.tests.hyundai_common import TESTER_PRESENT, classic_accel, classic_steer, packet from iqdbc.safety.tests.libsafety import libsafety_py -import iqdbc.safety.tests.common as common -from iqdbc.safety.tests.common import CANPackerSafety -from iqdbc.safety.tests.hyundai_common import HyundaiButtonBase, HyundaiLongitudinalBase -from iqdbc.iqpilot.car.hyundai.values import HyundaiSafetyFlagsIQ -# LDA button availability -LDA_BUTTON = [ - {"SAFETY_PARAM_IQ": HyundaiSafetyFlagsIQ.DEFAULT}, - {"SAFETY_PARAM_IQ": HyundaiSafetyFlagsIQ.HAS_LDA_BUTTON}, -] - -# All combinations of non-SCC HEV/PHEV/EV cars -_ALL_NON_SCC_HEV_EV_COMBOS = [ - # Hybrid - {"PCM_STATUS_MSG": ("E_CRUISE_CONTROL", "CRUISE_LAMP_S"), - "ACC_STATE_MSG": ("E_CRUISE_CONTROL", "CRUISE_LAMP_M"), - "GAS_MSG": ("E_EMS11", "CR_Vcu_AccPedDep_Pos"), - "SAFETY_PARAM": HyundaiSafetyFlags.HYBRID_GAS}, - # EV - {"PCM_STATUS_MSG": ("LABEL11", "CC_ACT"), - "ACC_STATE_MSG": ("LABEL11", "CC_React"), - "GAS_MSG": ("E_EMS11", "Accel_Pedal_Pos"), - "SAFETY_PARAM": HyundaiSafetyFlags.EV_GAS}, -] -ALL_NON_SCC_HEV_EV_COMBOS = [{**p, **lda} for lda in LDA_BUTTON for p in _ALL_NON_SCC_HEV_EV_COMBOS] - - -# 4 bit checkusm used in some hyundai messages -# lives outside the can packer because we never send this msg -def checksum(msg): - addr, dat, bus = msg - - chksum = 0 - if addr == 0x386: - for i, b in enumerate(dat): - for j in range(8): - # exclude checksum and counter bits - if (i != 1 or j < 6) and (i != 3 or j < 6) and (i != 5 or j < 6) and (i != 7 or j < 6): - bit = (b >> j) & 1 - else: - bit = 0 - chksum += bit - chksum = (chksum ^ 9) & 0xF - ret = bytearray(dat) - ret[5] |= (chksum & 0x3) << 6 - ret[7] |= (chksum & 0xc) << 4 - else: - for i, b in enumerate(dat): - if addr in [0x260, 0x421] and i == 7: - b &= 0x0F if addr == 0x421 else 0xF0 - elif addr == 0x394 and i == 6: - b &= 0xF0 - elif addr == 0x394 and i == 7: - continue - chksum += sum(divmod(b, 16)) - chksum = (16 - chksum) % 16 - ret = bytearray(dat) - ret[6 if addr == 0x394 else 7] |= chksum << (4 if addr == 0x421 else 0) - - return addr, ret, bus - - -@parameterized_class(LDA_BUTTON) -class TestHyundaiSafety(HyundaiButtonBase, common.CarSafetyTest, common.DriverTorqueSteeringSafetyTest, common.SteerRequestCutSafetyTest): - TX_MSGS = [[0x340, 0], [0x4F1, 0], [0x485, 0]] - STANDSTILL_THRESHOLD = 12 # 0.375 kph - RELAY_MALFUNCTION_ADDRS = {0: (0x340, 0x485)} # LKAS11 - FWD_BLACKLISTED_ADDRS = {2: [0x340, 0x485]} - - MAX_RATE_UP = 3 - MAX_RATE_DOWN = 7 - MAX_TORQUE_LOOKUP = [0], [384] - MAX_RT_DELTA = 112 - DRIVER_TORQUE_ALLOWANCE = 50 - DRIVER_TORQUE_FACTOR = 2 - - # Safety around steering req bit - MIN_VALID_STEERING_FRAMES = 89 - MAX_INVALID_STEERING_FRAMES = 2 - - cnt_gas = 0 - cnt_speed = 0 - cnt_brake = 0 - cnt_cruise = 0 - cnt_button = 0 - - SAFETY_PARAM_IQ: int = 0 - - @classmethod - def setUpClass(cls): - if cls.__name__ == "TestHyundaiSafety": - cls.safety = None - raise unittest.SkipTest - - def setUp(self): - self.packer = CANPackerSafety("hyundai_kia_generic") - self.safety = libsafety_py.libsafety - self.safety.set_current_safety_param_iq(self.SAFETY_PARAM_IQ) - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, 0) - self.safety.init_tests() - - def _button_msg(self, buttons, main_button=0, bus=0): - values = {"CF_Clu_CruiseSwState": buttons, "CF_Clu_CruiseSwMain": main_button, "CF_Clu_AliveCnt1": self.cnt_button} - self.__class__.cnt_button += 1 - return self.packer.make_can_msg_safety("CLU11", bus, values) - - def _user_gas_msg(self, gas): - values = {"CF_Ems_AclAct": gas, "AliveCounter": self.cnt_gas % 4} - self.__class__.cnt_gas += 1 - return self.packer.make_can_msg_safety("EMS16", 0, values, fix_checksum=checksum) - - def _user_brake_msg(self, brake): - values = {"DriverOverride": 2 if brake else random.choice((0, 1, 3)), - "AliveCounterTCS": self.cnt_brake % 8} - self.__class__.cnt_brake += 1 - return self.packer.make_can_msg_safety("TCS13", 0, values, fix_checksum=checksum) - - def _speed_msg(self, speed): - # safety doesn't scale, so undo the scaling - values = {"WHL_SPD_%s" % s: speed * 0.03125 for s in ["FL", "FR", "RL", "RR"]} - values["WHL_SPD_AliveCounter_LSB"] = (self.cnt_speed % 16) & 0x3 - values["WHL_SPD_AliveCounter_MSB"] = (self.cnt_speed % 16) >> 2 - self.__class__.cnt_speed += 1 - return self.packer.make_can_msg_safety("WHL_SPD11", 0, values, fix_checksum=checksum) - - def _pcm_status_msg(self, enable): - values = {"ACCMode": enable, "CR_VSM_Alive": self.cnt_cruise % 16} - self.__class__.cnt_cruise += 1 - return self.packer.make_can_msg_safety("SCC12", self.SCC_BUS, values, fix_checksum=checksum) - - def _torque_driver_msg(self, torque): - values = {"CR_Mdps_StrColTq": torque} - return self.packer.make_can_msg_safety("MDPS12", 0, values) - - def _torque_cmd_msg(self, torque, steer_req=1): - values = {"CR_Lkas_StrToqReq": torque, "CF_Lkas_ActToi": steer_req} - return self.packer.make_can_msg_safety("LKAS11", 0, values) - - def _acc_state_msg(self, enable): - values = {"MainMode_ACC": enable} - return self.packer.make_can_msg_safety("SCC11", self.SCC_BUS, values) - - def _lkas_button_msg(self, enabled): - if self.SAFETY_PARAM_IQ & HyundaiSafetyFlagsIQ.HAS_LDA_BUTTON: - values = {"LDA_BTN": enabled} - return self.packer.make_can_msg_safety("BCM_PO_11", 0, values) - else: - raise NotImplementedError - - def _main_cruise_button_msg(self, enabled): - return self._button_msg(0, enabled) - - def test_pcm_main_cruise_state_availability(self): - """Test that ACC main state is correctly set when receiving 0x420 message, toggling HYUNDAI_LONG flag""" - prior_safety_mode = self.safety.get_current_safety_mode() - prior_safety_param = self.safety.get_current_safety_param() - - for hyundai_longitudinal in (True, False): - with self.subTest("hyundai_longitudinal", hyundai_longitudinal=hyundai_longitudinal): - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, 0 if hyundai_longitudinal else HyundaiSafetyFlags.LONG) - for should_turn_acc_main_on in (True, False): - with self.subTest("acc_main_on", should_turn_acc_main_on=should_turn_acc_main_on): - self._rx(self._acc_state_msg(should_turn_acc_main_on)) # Send the ACC state message - expected_acc_main = should_turn_acc_main_on and hyundai_longitudinal # ACC main should only be set if hyundai_longitudinal is True - self.assertEqual(expected_acc_main, self.safety.get_acc_main_on()) - self.safety.set_safety_hooks(prior_safety_mode, prior_safety_param) - - def test_enable_control_allowed_with_aol_button(self): - default_safety_mode = self.safety.get_current_safety_mode() - default_safety_param = self.safety.get_current_safety_param() - default_safety_param_iq = self.safety.get_current_safety_param_iq() - """Toggle AOL with AOL button""" - try: - self._lkas_button_msg(False) - except NotImplementedError as err: - raise unittest.SkipTest("Skipping test because LDA button is not supported") from err - - try: - for enable_aol in (True, False): - with self.subTest("enable_aol", aol_enabled=enable_aol): - for has_lda_button_param in (True, False): - with self.subTest("has_lda_button", has_lda_button_param=has_lda_button_param): - has_lda_button = HyundaiSafetyFlagsIQ.HAS_LDA_BUTTON if has_lda_button_param else 0 - self.safety.set_current_safety_param_iq(has_lda_button) - self.safety.set_safety_hooks(default_safety_mode, default_safety_param) - - self.safety.set_aol_params(enable_aol, False, False) - self.assertEqual(enable_aol, self.safety.get_enable_aol()) - - self._rx(self._lkas_button_msg(True)) - self._rx(self._speed_msg(0)) - self._rx(self._lkas_button_msg(False)) - self._rx(self._speed_msg(0)) - self.assertEqual(enable_aol and has_lda_button_param, self.safety.get_controls_allowed_lat()) - finally: - self.safety.set_current_safety_param_iq(default_safety_param_iq) - - -@parameterized_class(LDA_BUTTON) -class TestHyundaiSafetyAltLimits(TestHyundaiSafety): - MAX_RATE_UP = 2 - MAX_RATE_DOWN = 3 - MAX_TORQUE_LOOKUP = [0], [270] - - @classmethod - def setUpClass(cls): - if cls.__name__ == "TestHyundaiSafetyAltLimits": - cls.safety = None - raise unittest.SkipTest - - def setUp(self): - self.packer = CANPackerSafety("hyundai_kia_generic") - self.safety = libsafety_py.libsafety - self.safety.set_current_safety_param_iq(self.SAFETY_PARAM_IQ) - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, HyundaiSafetyFlags.ALT_LIMITS) - self.safety.init_tests() - - -@parameterized_class(LDA_BUTTON) -class TestHyundaiSafetyAltLimits2(TestHyundaiSafety): - MAX_RATE_UP = 2 - MAX_RATE_DOWN = 3 - MAX_TORQUE_LOOKUP = [0], [170] - - @classmethod - def setUpClass(cls): - if cls.__name__ == "TestHyundaiSafetyAltLimits2": - cls.safety = None - raise unittest.SkipTest - - def setUp(self): - self.packer = CANPackerSafety("hyundai_kia_generic") - self.safety = libsafety_py.libsafety - self.safety.set_current_safety_param_iq(self.SAFETY_PARAM_IQ) - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, HyundaiSafetyFlags.ALT_LIMITS_2) - self.safety.init_tests() - - -@parameterized_class(LDA_BUTTON) -class TestHyundaiSafetyCameraSCC(TestHyundaiSafety): - BUTTONS_TX_BUS = 2 # tx on 2, rx on 0 - SCC_BUS = 2 # rx on 2 - - @classmethod - def setUpClass(cls): - if cls.__name__ == "TestHyundaiSafetyCameraSCC": - cls.safety = None - raise unittest.SkipTest - - def setUp(self): - self.packer = CANPackerSafety("hyundai_kia_generic") - self.safety = libsafety_py.libsafety - self.safety.set_current_safety_param_iq(self.SAFETY_PARAM_IQ) - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, HyundaiSafetyFlags.CAMERA_SCC) - self.safety.init_tests() - - def test_pcm_main_cruise_state_availability(self): - """ - Test that ACC main state is correctly set when receiving 0x420 message. - For camera SCC, ACC main should always be on when receiving 0x420 message - """ - - for should_turn_acc_main_on in (True, False): - with self.subTest("acc_main_on", should_turn_acc_main_on=should_turn_acc_main_on): - self._rx(self._acc_state_msg(should_turn_acc_main_on)) - self.assertEqual(should_turn_acc_main_on, self.safety.get_acc_main_on()) - - -@parameterized_class(LDA_BUTTON) -class TestHyundaiSafetyFCEV(TestHyundaiSafety): - @classmethod - def setUpClass(cls): - if cls.__name__ == "TestHyundaiSafetyFCEV": - cls.safety = None - raise unittest.SkipTest - - def setUp(self): - self.packer = CANPackerSafety("hyundai_kia_generic") - self.safety = libsafety_py.libsafety - self.safety.set_current_safety_param_iq(self.SAFETY_PARAM_IQ) - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, HyundaiSafetyFlags.FCEV_GAS) - self.safety.init_tests() - - def _user_gas_msg(self, gas): - values = {"ACCELERATOR_PEDAL": gas} - return self.packer.make_can_msg_safety("FCEV_ACCELERATOR", 0, values) - - -class TestHyundaiLegacySafety(TestHyundaiSafety): - def setUp(self): - self.packer = CANPackerSafety("hyundai_kia_generic") - self.safety = libsafety_py.libsafety - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundaiLegacy, 0) - self.safety.init_tests() - - -class TestHyundaiLegacySafetyEV(TestHyundaiSafety): - def setUp(self): - self.packer = CANPackerSafety("hyundai_kia_generic") - self.safety = libsafety_py.libsafety - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundaiLegacy, HyundaiSafetyFlags.EV_GAS) - self.safety.init_tests() - - def _user_gas_msg(self, gas): - values = {"Accel_Pedal_Pos": gas} - return self.packer.make_can_msg_safety("E_EMS11", 0, values, fix_checksum=checksum) - - -class TestHyundaiLegacySafetyHEV(TestHyundaiSafety): - def setUp(self): - self.packer = CANPackerSafety("hyundai_kia_generic") - self.safety = libsafety_py.libsafety - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundaiLegacy, HyundaiSafetyFlags.HYBRID_GAS) - self.safety.init_tests() - - def _user_gas_msg(self, gas): - values = {"CR_Vcu_AccPedDep_Pos": gas} - return self.packer.make_can_msg_safety("E_EMS11", 0, values, fix_checksum=checksum) - - -@parameterized_class(LDA_BUTTON) -class TestHyundaiLongitudinalSafety(HyundaiLongitudinalBase, TestHyundaiSafety): - TX_MSGS = [[0x340, 0], [0x4F1, 0], [0x485, 0], [0x420, 0], [0x421, 0], [0x50A, 0], [0x389, 0], [0x4A2, 0], [0x38D, 0], [0x483, 0], [0x7D0, 0]] - - FWD_BLACKLISTED_ADDRS = {2: [0x340, 0x485, 0x421, 0x420, 0x50A, 0x389]} - - RELAY_MALFUNCTION_ADDRS = {0: (0x340, 0x485, 0x421, 0x420, 0x50A, 0x389)} # LKAS11, LFAHDA_MFC, SCC12, SCC11, SCC13, SCC14 - - DISABLED_ECU_UDS_MSG = (0x7D0, 0) - DISABLED_ECU_ACTUATION_MSG = (0x421, 0) - - @classmethod - def setUpClass(cls): - if cls.__name__ == "TestHyundaiLongitudinalSafety": - cls.safety = None - raise unittest.SkipTest - - def setUp(self): - self.packer = CANPackerSafety("hyundai_kia_generic") - self.safety = libsafety_py.libsafety - self.safety.set_current_safety_param_iq(self.SAFETY_PARAM_IQ) - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, HyundaiSafetyFlags.LONG) - self.safety.init_tests() - - def _accel_msg(self, accel, aeb_req=False, aeb_decel=0): - values = { - "aReqRaw": accel, - "aReqValue": accel, - "AEB_CmdAct": int(aeb_req), - "CR_VSM_DecCmd": aeb_decel, - } - return self.packer.make_can_msg_safety("SCC12", self.SCC_BUS, values) - - def _fca11_msg(self, idx=0, vsm_aeb_req=False, fca_aeb_req=False, aeb_decel=0): - values = { - "CR_FCA_Alive": idx % 0xF, - "FCA_Status": 2, - "CR_VSM_DecCmd": aeb_decel, - "CF_VSM_DecCmdAct": int(vsm_aeb_req), - "FCA_CmdAct": int(fca_aeb_req), - } - return self.packer.make_can_msg_safety("FCA11", 0, values) - - def _tx_acc_state_msg(self, enable): - values = {"MainMode_ACC": enable} - return self.packer.make_can_msg_safety("SCC11", 0, values) - - def test_no_aeb_fca11(self): - self.assertTrue(self._tx(self._fca11_msg())) - self.assertFalse(self._tx(self._fca11_msg(vsm_aeb_req=True))) - self.assertFalse(self._tx(self._fca11_msg(fca_aeb_req=True))) - self.assertFalse(self._tx(self._fca11_msg(aeb_decel=1.0))) - - def test_no_aeb_scc12(self): - self.assertTrue(self._tx(self._accel_msg(0))) - self.assertFalse(self._tx(self._accel_msg(0, aeb_req=True))) - self.assertFalse(self._tx(self._accel_msg(0, aeb_decel=1.0))) - - -class TestHyundaiLongitudinalSafetyCameraSCC(HyundaiLongitudinalBase, TestHyundaiSafety): - TX_MSGS = [[0x340, 0], [0x4F1, 2], [0x485, 0], [0x420, 0], [0x421, 0], [0x50A, 0], [0x389, 0], [0x4A2, 0]] - - FWD_BLACKLISTED_ADDRS = {2: [0x340, 0x485, 0x420, 0x421, 0x50A, 0x389]} - RELAY_MALFUNCTION_ADDRS = {0: (0x340, 0x485, 0x421, 0x420, 0x50A, 0x389)} # LKAS11, LFAHDA_MFC, SCC12, SCC11, SCC13, SCC14 - - def setUp(self): - self.packer = CANPackerSafety("hyundai_kia_generic") - self.safety = libsafety_py.libsafety - self.safety.set_current_safety_param_iq(HyundaiSafetyFlagsIQ.HAS_LDA_BUTTON) - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, HyundaiSafetyFlags.LONG | HyundaiSafetyFlags.CAMERA_SCC) - self.safety.init_tests() - - def _accel_msg(self, accel, aeb_req=False, aeb_decel=0): - values = { - "aReqRaw": accel, - "aReqValue": accel, - "AEB_CmdAct": int(aeb_req), - "CR_VSM_DecCmd": aeb_decel, - } - return self.packer.make_can_msg_safety("SCC12", self.SCC_BUS, values) - - def _tx_acc_state_msg(self, enable): - values = {"MainMode_ACC": enable} - return self.packer.make_can_msg_safety("SCC11", self.SCC_BUS, values) - - def test_no_aeb_scc12(self): - self.assertTrue(self._tx(self._accel_msg(0))) - self.assertFalse(self._tx(self._accel_msg(0, aeb_req=True))) - self.assertFalse(self._tx(self._accel_msg(0, aeb_decel=1.0))) - - def test_tester_present_allowed(self): - pass - - def test_disabled_ecu_alive(self): - pass - - -@parameterized_class(LDA_BUTTON) -class TestHyundaiSafetyFCEVLong(TestHyundaiLongitudinalSafety, TestHyundaiSafetyFCEV): - @classmethod - def setUpClass(cls): - if cls.__name__ == "TestHyundaiSafetyFCEVLong": - cls.safety = None - raise unittest.SkipTest - - def setUp(self): - self.packer = CANPackerSafety("hyundai_kia_generic") - self.safety = libsafety_py.libsafety - self.safety.set_current_safety_param_iq(self.SAFETY_PARAM_IQ) - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, HyundaiSafetyFlags.FCEV_GAS | HyundaiSafetyFlags.LONG) - self.safety.init_tests() - - -@parameterized_class(LDA_BUTTON) -class TestHyundaiLongitudinalESCCSafety(HyundaiLongitudinalBase, TestHyundaiSafety): - TX_MSGS = [[0x340, 0], [0x4F1, 0], [0x485, 0], [0x420, 0], [0x421, 0], [0x50A, 0], [0x389, 0]] - - FWD_BLACKLISTED_ADDRS = {2: [0x340, 0x485, 0x420, 0x421, 0x50A, 0x389]} - RELAY_MALFUNCTION_ADDRS = {0: (0x340, 0x485, 0x420, 0x421, 0x50A, 0x389)} # LKAS11, LFAHDA_MFC, SCC12, SCC11, SCC13, SCC14 - - @classmethod - def setUpClass(cls): - if cls.__name__ == "TestHyundaiLongitudinalESCCSafety": - cls.safety = None - raise unittest.SkipTest - - def setUp(self): - self.packer = CANPackerSafety("hyundai_kia_generic") - self.safety = libsafety_py.libsafety - self.safety.set_current_safety_param_iq(HyundaiSafetyFlagsIQ.ESCC | self.SAFETY_PARAM_IQ) - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, HyundaiSafetyFlags.LONG) - self.safety.init_tests() - - def _accel_msg(self, accel, aeb_req=False, aeb_decel=0): - values = { - "aReqRaw": accel, - "aReqValue": accel, - } - return self.packer.make_can_msg_safety("SCC12", self.SCC_BUS, values) - - def _tx_acc_state_msg(self, enable): - values = {"MainMode_ACC": enable} - return self.packer.make_can_msg_safety("SCC11", 0, values) - - def test_tester_present_allowed(self): - pass - - def test_disabled_ecu_alive(self): - pass - - -@parameterized_class(LDA_BUTTON) -class TestHyundaiNonSCCSafety(TestHyundaiSafety): - - @classmethod - def setUpClass(cls): - if cls.__name__ == "TestHyundaiNonSCCSafety": - cls.safety = None - raise unittest.SkipTest - - def setUp(self): - self.packer = CANPackerSafety("hyundai_kia_generic") - self.safety = libsafety_py.libsafety - self.safety.set_current_safety_param_iq(HyundaiSafetyFlagsIQ.NON_SCC | self.SAFETY_PARAM_IQ) - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, 0) - self.safety.init_tests() - - def _pcm_status_msg(self, enable): - values = {"CRUISE_LAMP_S": enable, "AliveCounter": self.cnt_gas % 4} - self.__class__.cnt_gas += 1 - return self.packer.make_can_msg_safety("EMS16", 0, values, fix_checksum=checksum) - - def _acc_state_msg(self, enable): - values = {"CRUISE_LAMP_M": enable, "AliveCounter": self.cnt_gas % 4} - self.__class__.cnt_gas += 1 - return self.packer.make_can_msg_safety("EMS16", 0, values, fix_checksum=checksum) - - def _user_gas_msg(self, gas: float, controls_allowed: bool = True): - values = {"CF_Ems_AclAct": gas, "CRUISE_LAMP_M": 1, "CRUISE_LAMP_S": controls_allowed, "AliveCounter": self.cnt_gas % 4} - self.__class__.cnt_gas += 1 - return self.packer.make_can_msg_safety("EMS16", 0, values, fix_checksum=checksum) - - def test_allow_engage_with_gas_pressed(self): - self._rx(self._user_gas_msg(1, self.safety.get_controls_allowed())) - self.safety.set_controls_allowed(True) - self._rx(self._user_gas_msg(1, self.safety.get_controls_allowed())) - self.assertTrue(self.safety.get_controls_allowed()) - self._rx(self._user_gas_msg(1, self.safety.get_controls_allowed())) - self.assertTrue(self.safety.get_controls_allowed()) - - def test_no_disengage_on_gas(self): - self._rx(self._user_gas_msg(0, self.safety.get_controls_allowed())) - self.safety.set_controls_allowed(True) - self._rx(self._user_gas_msg(self.GAS_PRESSED_THRESHOLD + 1, self.safety.get_controls_allowed())) - # Test we allow lateral, but not longitudinal - self.assertTrue(self.safety.get_controls_allowed()) - self.assertFalse(self.safety.get_longitudinal_brake_allowed()) - self.assertTrue(self.safety.get_longitudinal_gas_allowed()) - # Make sure we can re-gain longitudinal actuation - self._rx(self._user_gas_msg(0, self.safety.get_controls_allowed())) - self.assertTrue(self.safety.get_longitudinal_brake_allowed()) - self.assertTrue(self.safety.get_longitudinal_gas_allowed()) - - -@parameterized_class(ALL_NON_SCC_HEV_EV_COMBOS) -class TestHyundaiNonSCCSafety_HEV_EV(TestHyundaiSafety): - - PCM_STATUS_MSG = ("", "") - ACC_STATE_MSG = ("", "") - GAS_MSG = ("", "") - SAFETY_PARAM = 0 - - @classmethod - def setUpClass(cls): - if cls.__name__ == "TestHyundaiNonSCCSafety_HEV_EV": - cls.safety = None - raise unittest.SkipTest - - def setUp(self): - self.packer = CANPackerSafety("hyundai_kia_generic") - self.safety = libsafety_py.libsafety - self.safety.set_current_safety_param_iq(HyundaiSafetyFlagsIQ.NON_SCC | self.SAFETY_PARAM_IQ) - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, self.SAFETY_PARAM) - self.safety.init_tests() - - def _pcm_status_msg(self, enable): - values = {self.PCM_STATUS_MSG[1]: enable} - return self.packer.make_can_msg_safety(self.PCM_STATUS_MSG[0], 0, values) - - def _acc_state_msg(self, enable): - values = {self.ACC_STATE_MSG[1]: enable} - return self.packer.make_can_msg_safety(self.ACC_STATE_MSG[0], 0, values) - - def _user_gas_msg(self, gas): - values = {self.GAS_MSG[1]: gas} - return self.packer.make_can_msg_safety(self.GAS_MSG[0], 0, values, fix_checksum=checksum) - - -if __name__ == "__main__": - unittest.main() +@pytest.fixture +def safety(): + return libsafety_py.libsafety + + +@pytest.mark.parametrize("mode", (CarParams.SafetyModel.hyundai, CarParams.SafetyModel.hyundaiLegacy)) +@pytest.mark.parametrize("param", ( + 0, + HyundaiSafetyFlags.EV_GAS, + HyundaiSafetyFlags.HYBRID_GAS, + HyundaiSafetyFlags.LONG, + HyundaiSafetyFlags.CAMERA_SCC, + HyundaiSafetyFlags.ALT_LIMITS, + HyundaiSafetyFlags.FCEV_GAS, + HyundaiSafetyFlags.ALT_LIMITS_2, +)) +def test_classic_safety_configurations_initialize(safety, mode, param): + assert safety.set_safety_hooks(mode, param) == 0 + safety.init_tests() + assert safety.get_current_safety_param() == param + + +@pytest.mark.parametrize("mode", (CarParams.SafetyModel.hyundai, CarParams.SafetyModel.hyundaiLegacy)) +def test_classic_tx_whitelist_and_steering_limits(safety, mode): + safety.set_safety_hooks(mode, 0) + safety.init_tests() + + assert not safety.safety_tx_hook(packet(0x123, 0, 8)) + assert not safety.safety_tx_hook(packet(0x340, 1, 8)) + + safety.set_controls_allowed(False) + assert safety.safety_tx_hook(classic_steer(0, False)) + assert not safety.safety_tx_hook(classic_steer(1)) + + safety.set_controls_allowed(True) + assert safety.safety_tx_hook(classic_steer(10)) + safety.set_desired_torque_last(512) + safety.set_rt_torque_last(512) + assert safety.safety_tx_hook(classic_steer(512)) + assert not safety.safety_tx_hook(classic_steer(513)) + assert not safety.safety_tx_hook(classic_steer(-513)) + + +def test_classic_alt_limits_2(safety): + safety.set_safety_hooks(CarParams.SafetyModel.hyundai, HyundaiSafetyFlags.ALT_LIMITS_2) + safety.init_tests() + safety.set_controls_allowed(True) + safety.set_desired_torque_last(170) + safety.set_rt_torque_last(170) + assert safety.safety_tx_hook(classic_steer(170)) + assert not safety.safety_tx_hook(classic_steer(171)) + + +def test_classic_longitudinal_accel_and_aeb_guards(safety): + safety.set_safety_hooks(CarParams.SafetyModel.hyundai, HyundaiSafetyFlags.LONG) + safety.init_tests() + + safety.set_controls_allowed(False) + assert safety.safety_tx_hook(classic_accel(0)) + assert not safety.safety_tx_hook(classic_accel(1)) + + safety.set_controls_allowed(True) + for accel in (-400, 0, 250): + assert safety.safety_tx_hook(classic_accel(accel)) + for accel in (-401, 251): + assert not safety.safety_tx_hook(classic_accel(accel)) + assert not safety.safety_tx_hook(classic_accel(0, aeb_decel=1)) + assert not safety.safety_tx_hook(classic_accel(0, aeb_request=True)) + + assert safety.safety_tx_hook(packet(0x38D, 0, 8)) + assert not safety.safety_tx_hook(packet(0x38D, 0, 8, {1: 1})) + assert not safety.safety_tx_hook(packet(0x38D, 0, 8, {2: 1 << 4})) + assert not safety.safety_tx_hook(packet(0x38D, 0, 8, {3: 1 << 7})) + + +def test_classic_buttons(safety): + safety.set_safety_hooks(CarParams.SafetyModel.hyundai, 0) + safety.init_tests() + + safety.set_controls_allowed(False) + assert not safety.safety_tx_hook(packet(0x4F1, 0, 4, {0: 1})) + assert not safety.safety_tx_hook(packet(0x4F1, 0, 4, {0: 2})) + assert not safety.safety_tx_hook(packet(0x4F1, 0, 4, {0: 4})) + + safety.set_controls_allowed(True) + assert safety.safety_tx_hook(packet(0x4F1, 0, 4, {0: 1})) + assert not safety.safety_tx_hook(packet(0x4F1, 0, 4, {0: 2})) + assert safety.safety_tx_hook(packet(0x4F1, 0, 4, {0: 4})) + + safety.set_controls_allowed(False) + safety.set_cruise_engaged_prev(True) + assert safety.safety_tx_hook(packet(0x4F1, 0, 4, {0: 4})) + + +def test_classic_diagnostic_payload_is_restricted(safety): + safety.set_safety_hooks(CarParams.SafetyModel.hyundai, HyundaiSafetyFlags.LONG) + safety.init_tests() + assert safety.safety_tx_hook(packet(0x7D0, 0, 8, dict(enumerate(TESTER_PRESENT)))) + assert not safety.safety_tx_hook(packet(0x7D0, 0, 8, {0: 3, 1: 0x22})) diff --git a/iqdbc_repo/iqdbc/safety/tests/test_hyundai_canfd.py b/iqdbc_repo/iqdbc/safety/tests/test_hyundai_canfd.py old mode 100755 new mode 100644 index fbdf2dd..b0c0f27 --- a/iqdbc_repo/iqdbc/safety/tests/test_hyundai_canfd.py +++ b/iqdbc_repo/iqdbc/safety/tests/test_hyundai_canfd.py @@ -1,312 +1,104 @@ -#!/usr/bin/env python3 -from parameterized import parameterized_class -import unittest +import pytest from iqdbc.car.hyundai.values import HyundaiSafetyFlags from iqdbc.car.structs import CarParams +from iqdbc.safety.tests.hyundai_common import TESTER_PRESENT, canfd_accel, canfd_steer, packet from iqdbc.safety.tests.libsafety import libsafety_py -import iqdbc.safety.tests.common as common -from iqdbc.safety.tests.common import CANPackerSafety -from iqdbc.safety.tests.hyundai_common import HyundaiButtonBase, HyundaiLongitudinalBase -# All combinations of radar/camera-SCC and gas/hybrid/EV cars -ALL_GAS_EV_HYBRID_COMBOS = [ - # Radar SCC - {"GAS_MSG": ("ACCELERATOR_BRAKE_ALT", "ACCELERATOR_PEDAL_PRESSED"), "SCC_BUS": 0, "SAFETY_PARAM": 0}, - {"GAS_MSG": ("ACCELERATOR", "ACCELERATOR_PEDAL"), "SCC_BUS": 0, "SAFETY_PARAM": HyundaiSafetyFlags.EV_GAS}, - {"GAS_MSG": ("ACCELERATOR_ALT", "ACCELERATOR_PEDAL"), "SCC_BUS": 0, "SAFETY_PARAM": HyundaiSafetyFlags.HYBRID_GAS}, - # Camera SCC - {"GAS_MSG": ("ACCELERATOR_BRAKE_ALT", "ACCELERATOR_PEDAL_PRESSED"), "SCC_BUS": 2, "SAFETY_PARAM": HyundaiSafetyFlags.CAMERA_SCC}, - {"GAS_MSG": ("ACCELERATOR", "ACCELERATOR_PEDAL"), "SCC_BUS": 2, "SAFETY_PARAM": HyundaiSafetyFlags.EV_GAS | HyundaiSafetyFlags.CAMERA_SCC}, - {"GAS_MSG": ("ACCELERATOR_ALT", "ACCELERATOR_PEDAL"), "SCC_BUS": 2, "SAFETY_PARAM": HyundaiSafetyFlags.HYBRID_GAS | HyundaiSafetyFlags.CAMERA_SCC}, -] - -class TestHyundaiCanfdBase(HyundaiButtonBase, common.CarSafetyTest, common.DriverTorqueSteeringSafetyTest, common.SteerRequestCutSafetyTest): - - TX_MSGS = [[0x50, 0], [0x1CF, 1], [0x2A4, 0]] - STANDSTILL_THRESHOLD = 12 # 0.375 kph - FWD_BLACKLISTED_ADDRS = {2: [0x50, 0x2a4]} - - MAX_RATE_UP = 2 - MAX_RATE_DOWN = 3 - MAX_TORQUE_LOOKUP = [0], [270] - - MAX_RT_DELTA = 112 - - DRIVER_TORQUE_ALLOWANCE = 250 - DRIVER_TORQUE_FACTOR = 2 - - # Safety around steering req bit - MIN_VALID_STEERING_FRAMES = 89 - MAX_INVALID_STEERING_FRAMES = 2 - - PT_BUS = 0 - SCC_BUS = 2 - STEER_BUS = 0 - STEER_MSG = "" - GAS_MSG = ("", "") - BUTTONS_TX_BUS = 1 - - def _torque_driver_msg(self, torque): - values = {"STEERING_COL_TORQUE": torque} - return self.packer.make_can_msg_safety("MDPS", self.PT_BUS, values) - - def _torque_cmd_msg(self, torque, steer_req=1): - values = {"TORQUE_REQUEST": torque, "STEER_REQ": steer_req} - return self.packer.make_can_msg_safety(self.STEER_MSG, self.STEER_BUS, values) - - def _speed_msg(self, speed): - values = {f"WHL_Spd{pos}Val": speed * 0.03125 for pos in ["FL", "FR", "RL", "RR"]} - return self.packer.make_can_msg_safety("WHEEL_SPEEDS", self.PT_BUS, values) - - def _user_brake_msg(self, brake): - values = {"DriverBraking": brake} - return self.packer.make_can_msg_safety("TCS", self.PT_BUS, values) - - def _user_gas_msg(self, gas): - values = {self.GAS_MSG[1]: gas} - return self.packer.make_can_msg_safety(self.GAS_MSG[0], self.PT_BUS, values) - - def _pcm_status_msg(self, enable): - values = {"ACCMode": 1 if enable else 0} - return self.packer.make_can_msg_safety("SCC_CONTROL", self.SCC_BUS, values) - - def _button_msg(self, buttons, main_button=0, bus=None): - if bus is None: - bus = self.PT_BUS - values = { - "CRUISE_BUTTONS": buttons, - "ADAPTIVE_CRUISE_MAIN_BTN": main_button, - } - return self.packer.make_can_msg_safety("CRUISE_BUTTONS", bus, values) - - def _acc_state_msg(self, enable): - values = {"MainMode_ACC": enable} - return self.packer.make_can_msg_safety("SCC_CONTROL", self.SCC_BUS, values) - - def _lkas_button_msg(self, enabled): - values = {"LDA_BTN": enabled} - return self.packer.make_can_msg_safety("CRUISE_BUTTONS", self.PT_BUS, values) - - def _main_cruise_button_msg(self, enabled): - return self._button_msg(0, enabled) - - -class TestHyundaiCanfdLFASteeringBase(TestHyundaiCanfdBase): - - TX_MSGS = [[0x12A, 0], [0x1A0, 1], [0x1CF, 0], [0x1E0, 0]] - RELAY_MALFUNCTION_ADDRS = {0: (0x12A, 0x1E0)} # LFA, LFAHDA_CLUSTER - FWD_BLACKLISTED_ADDRS = {2: [0x12A, 0x1E0]} - - STEER_MSG = "LFA" - BUTTONS_TX_BUS = 2 - SAFETY_PARAM: int - - @classmethod - def setUpClass(cls): - super().setUpClass() - if cls.__name__ in ("TestHyundaiCanfdLFASteering", "TestHyundaiCanfdLFASteeringAltButtons"): - cls.packer = None - cls.safety = None - raise unittest.SkipTest - - def setUp(self): - self.packer = CANPackerSafety("hyundai_canfd_generated") - self.safety = libsafety_py.libsafety - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundaiCanfd, self.SAFETY_PARAM) - self.safety.init_tests() - - -@parameterized_class(ALL_GAS_EV_HYBRID_COMBOS) -class TestHyundaiCanfdLFASteering(TestHyundaiCanfdLFASteeringBase): - pass - - -class TestHyundaiCanfdLFASteeringAltButtonsBase(TestHyundaiCanfdLFASteeringBase): - - SAFETY_PARAM: int - - def setUp(self): - self.packer = CANPackerSafety("hyundai_canfd_generated") - self.safety = libsafety_py.libsafety - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundaiCanfd, HyundaiSafetyFlags.CANFD_ALT_BUTTONS | self.SAFETY_PARAM) - self.safety.init_tests() - - def _button_msg(self, buttons, main_button=0, bus=1): - values = { - "CRUISE_BUTTONS": buttons, - "ADAPTIVE_CRUISE_MAIN_BTN": main_button, - } - return self.packer.make_can_msg_safety("CRUISE_BUTTONS_ALT", self.PT_BUS, values) - - def _lkas_button_msg(self, enabled): - values = {"LDA_BTN": enabled} - return self.packer.make_can_msg_safety("CRUISE_BUTTONS_ALT", self.PT_BUS, values) - - def _acc_cancel_msg(self, cancel, accel=0): - values = {"ACCMode": 4 if cancel else 0, "aReqRaw": accel, "aReqValue": accel} - return self.packer.make_can_msg_safety("SCC_CONTROL", self.PT_BUS, values) - - def test_button_sends(self): - """ - No button send allowed with alt buttons. - """ - for enabled in (True, False): - for btn in range(8): - self.safety.set_controls_allowed(enabled) - self.assertFalse(self._tx(self._button_msg(btn))) - - def test_acc_cancel(self): - # FIXME: the CANFD_ALT_BUTTONS cars are the only ones that use SCC_CONTROL to cancel, why can't we use buttons? - for enabled in (True, False): - self.safety.set_controls_allowed(enabled) - self.assertTrue(self._tx(self._acc_cancel_msg(True))) - self.assertFalse(self._tx(self._acc_cancel_msg(True, accel=1))) - self.assertFalse(self._tx(self._acc_cancel_msg(False))) - - -@parameterized_class(ALL_GAS_EV_HYBRID_COMBOS) -class TestHyundaiCanfdLFASteeringAltButtons(TestHyundaiCanfdLFASteeringAltButtonsBase): - pass - - -class TestHyundaiCanfdLKASteeringEV(TestHyundaiCanfdBase): - - TX_MSGS = [[0x50, 0], [0x1CF, 1], [0x2A4, 0]] - RELAY_MALFUNCTION_ADDRS = {0: (0x50, 0x2a4)} # LKAS, CAM_0x2A4 - FWD_BLACKLISTED_ADDRS = {2: [0x50, 0x2a4]} - - PT_BUS = 1 - SCC_BUS = 1 - STEER_MSG = "LKAS" - GAS_MSG = ("ACCELERATOR", "ACCELERATOR_PEDAL") - - def setUp(self): - self.packer = CANPackerSafety("hyundai_canfd_generated") - self.safety = libsafety_py.libsafety - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundaiCanfd, HyundaiSafetyFlags.CANFD_LKA_STEERING | HyundaiSafetyFlags.EV_GAS) - self.safety.init_tests() - - -# TODO: Handle ICE and HEV configurations once we see cars that use the new messages -class TestHyundaiCanfdLKASteeringAltEV(TestHyundaiCanfdBase): - - TX_MSGS = [[0x110, 0], [0x1CF, 1], [0x362, 0]] - RELAY_MALFUNCTION_ADDRS = {0: (0x110, 0x362)} # LKAS_ALT, CAM_0x362 - FWD_BLACKLISTED_ADDRS = {2: [0x110, 0x362]} - - PT_BUS = 1 - SCC_BUS = 1 - STEER_MSG = "LKAS_ALT" - GAS_MSG = ("ACCELERATOR", "ACCELERATOR_PEDAL") - - def setUp(self): - self.packer = CANPackerSafety("hyundai_canfd_generated") - self.safety = libsafety_py.libsafety - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundaiCanfd, HyundaiSafetyFlags.CANFD_LKA_STEERING | HyundaiSafetyFlags.EV_GAS | - HyundaiSafetyFlags.CANFD_LKA_STEERING_ALT) - self.safety.init_tests() - - -class TestHyundaiCanfdLKASteeringLongEV(HyundaiLongitudinalBase, TestHyundaiCanfdLKASteeringEV): - - TX_MSGS = [[0x50, 0], [0x1CF, 1], [0x2A4, 0], [0x51, 0], [0x730, 1], [0x12a, 1], [0x160, 1], - [0x1e0, 1], [0x1a0, 1], [0x1ea, 1], [0x200, 1], [0x345, 1], [0x1da, 1]] - - RELAY_MALFUNCTION_ADDRS = {0: (0x50, 0x2a4), 1: (0x1a0,)} # LKAS, CAM_0x2A4, SCC_CONTROL - - DISABLED_ECU_UDS_MSG = (0x730, 1) - DISABLED_ECU_ACTUATION_MSG = (0x1a0, 1) - - STEER_MSG = "LFA" - GAS_MSG = ("ACCELERATOR", "ACCELERATOR_PEDAL") - STEER_BUS = 1 - - def setUp(self): - self.packer = CANPackerSafety("hyundai_canfd_generated") - self.safety = libsafety_py.libsafety - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundaiCanfd, HyundaiSafetyFlags.CANFD_LKA_STEERING | - HyundaiSafetyFlags.LONG | HyundaiSafetyFlags.EV_GAS) - self.safety.init_tests() - - def _accel_msg(self, accel, aeb_req=False, aeb_decel=0): - values = { - "aReqRaw": accel, - "aReqValue": accel, - } - return self.packer.make_can_msg_safety("SCC_CONTROL", self.PT_BUS, values) - - def _tx_acc_state_msg(self, enable): - values = {"MainMode_ACC": enable} - return self.packer.make_can_msg_safety("SCC_CONTROL", self.PT_BUS, values) - - -# Tests longitudinal for ICE, hybrid, EV cars with LFA steering -class TestHyundaiCanfdLFASteeringLongBase(HyundaiLongitudinalBase, TestHyundaiCanfdLFASteeringBase): - - FWD_BLACKLISTED_ADDRS = {2: [0x12a, 0x1e0, 0x1a0, 0x160]} - - RELAY_MALFUNCTION_ADDRS = {0: (0x12A, 0x1E0, 0x1a0, 0x160)} # LFA, LFAHDA_CLUSTER, SCC_CONTROL, ADRV_0x160 - - DISABLED_ECU_UDS_MSG = (0x7D0, 0) - DISABLED_ECU_ACTUATION_MSG = (0x1a0, 0) - - @classmethod - def setUpClass(cls): - if cls.__name__ == "TestHyundaiCanfdLFASteeringLongBase": - cls.safety = None - raise unittest.SkipTest - - def setUp(self): - self.packer = CANPackerSafety("hyundai_canfd_generated") - self.safety = libsafety_py.libsafety - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundaiCanfd, HyundaiSafetyFlags.LONG | self.SAFETY_PARAM) - self.safety.init_tests() - - def _accel_msg(self, accel, aeb_req=False, aeb_decel=0): - values = { - "aReqRaw": accel, - "aReqValue": accel, - } - return self.packer.make_can_msg_safety("SCC_CONTROL", self.PT_BUS, values) - - def _tx_acc_state_msg(self, enable): - values = {"MainMode_ACC": enable} - return self.packer.make_can_msg_safety("SCC_CONTROL", self.PT_BUS, values) - - # no knockout - def test_tester_present_allowed(self): - pass - - -@parameterized_class(ALL_GAS_EV_HYBRID_COMBOS) -class TestHyundaiCanfdLFASteeringLong(TestHyundaiCanfdLFASteeringLongBase): - @classmethod - def setUpClass(cls): - if cls.__name__ == "TestHyundaiCanfdLFASteeringLong": - cls.safety = None - raise unittest.SkipTest - - -@parameterized_class(ALL_GAS_EV_HYBRID_COMBOS) -class TestHyundaiCanfdLFASteeringLongAltButtons(TestHyundaiCanfdLFASteeringLongBase, TestHyundaiCanfdLFASteeringAltButtonsBase): - @classmethod - def setUpClass(cls): - if cls.__name__ == "TestHyundaiCanfdLFASteeringLongAltButtons": - cls.safety = None - raise unittest.SkipTest - - def setUp(self): - self.packer = CANPackerSafety("hyundai_canfd_generated") - self.safety = libsafety_py.libsafety - self.safety.set_safety_hooks(CarParams.SafetyModel.hyundaiCanfd, HyundaiSafetyFlags.LONG | HyundaiSafetyFlags.CANFD_ALT_BUTTONS | self.SAFETY_PARAM) - self.safety.init_tests() - - def test_acc_cancel(self): - # Alt buttons does not use SCC_CONTROL to cancel if longitudinal - pass - - -if __name__ == "__main__": - unittest.main() +@pytest.fixture +def safety(): + return libsafety_py.libsafety + + +@pytest.mark.parametrize("param", ( + 0, + HyundaiSafetyFlags.EV_GAS, + HyundaiSafetyFlags.HYBRID_GAS, + HyundaiSafetyFlags.LONG, + HyundaiSafetyFlags.CAMERA_SCC, + HyundaiSafetyFlags.CANFD_LKA_STEERING, + HyundaiSafetyFlags.CANFD_ALT_BUTTONS, + HyundaiSafetyFlags.CANFD_LKA_STEERING | HyundaiSafetyFlags.CANFD_LKA_STEERING_ALT, + HyundaiSafetyFlags.CANFD_LKA_STEERING | HyundaiSafetyFlags.LONG, + HyundaiSafetyFlags.CANFD_LKA_STEERING | HyundaiSafetyFlags.LONG | HyundaiSafetyFlags.CANFD_ALT_BUTTONS, +)) +def test_canfd_safety_configurations_initialize(safety, param): + assert safety.set_safety_hooks(CarParams.SafetyModel.hyundaiCanfd, param) == 0 + safety.init_tests() + assert safety.get_current_safety_param() == param + + +@pytest.mark.parametrize(("param", "addr", "length"), ( + (0, 0x12A, 16), + (HyundaiSafetyFlags.CANFD_LKA_STEERING, 0x50, 16), + (HyundaiSafetyFlags.CANFD_LKA_STEERING | HyundaiSafetyFlags.CANFD_LKA_STEERING_ALT, 0x110, 32), + (HyundaiSafetyFlags.CANFD_LKA_STEERING | HyundaiSafetyFlags.LONG, 0x12A, 16), +)) +def test_canfd_steering_limits(safety, param, addr, length): + safety.set_safety_hooks(CarParams.SafetyModel.hyundaiCanfd, param) + safety.init_tests() + + safety.set_controls_allowed(False) + assert safety.safety_tx_hook(canfd_steer(addr, length, 0, False)) + assert not safety.safety_tx_hook(canfd_steer(addr, length, 1)) + + safety.set_controls_allowed(True) + assert safety.safety_tx_hook(canfd_steer(addr, length, 10)) + safety.set_desired_torque_last(512) + safety.set_rt_torque_last(512) + assert safety.safety_tx_hook(canfd_steer(addr, length, 512)) + assert not safety.safety_tx_hook(canfd_steer(addr, length, 513)) + assert not safety.safety_tx_hook(canfd_steer(addr, length, -513)) + + +def test_canfd_tx_whitelist_and_buttons(safety): + safety.set_safety_hooks(CarParams.SafetyModel.hyundaiCanfd, 0) + safety.init_tests() + assert not safety.safety_tx_hook(packet(0x123, 0, 8)) + assert not safety.safety_tx_hook(packet(0x12A, 1, 16)) + + safety.set_controls_allowed(False) + assert not safety.safety_tx_hook(packet(0x1CF, 0, 8, {2: 1})) + assert not safety.safety_tx_hook(packet(0x1CF, 0, 8, {2: 2})) + assert not safety.safety_tx_hook(packet(0x1CF, 0, 8, {2: 4})) + + safety.set_controls_allowed(True) + assert safety.safety_tx_hook(packet(0x1CF, 0, 8, {2: 1})) + assert not safety.safety_tx_hook(packet(0x1CF, 0, 8, {2: 2})) + assert safety.safety_tx_hook(packet(0x1CF, 0, 8, {2: 4})) + + safety.set_controls_allowed(False) + safety.set_cruise_engaged_prev(True) + assert safety.safety_tx_hook(packet(0x1CF, 0, 8, {2: 4})) + + +def test_canfd_stock_longitudinal_only_allows_cancel(safety): + safety.set_safety_hooks(CarParams.SafetyModel.hyundaiCanfd, 0) + safety.init_tests() + assert safety.safety_tx_hook(canfd_accel(0, acc_mode=4)) + assert not safety.safety_tx_hook(canfd_accel(1, acc_mode=4)) + assert not safety.safety_tx_hook(canfd_accel(0, acc_mode=0)) + + +def test_canfd_longitudinal_accel_limits(safety): + safety.set_safety_hooks(CarParams.SafetyModel.hyundaiCanfd, HyundaiSafetyFlags.LONG) + safety.init_tests() + + safety.set_controls_allowed(False) + assert safety.safety_tx_hook(canfd_accel(0)) + assert not safety.safety_tx_hook(canfd_accel(1)) + + safety.set_controls_allowed(True) + for accel in (-400, 0, 250): + assert safety.safety_tx_hook(canfd_accel(accel)) + for accel in (-401, 251): + assert not safety.safety_tx_hook(canfd_accel(accel)) + + +def test_canfd_hda2_diagnostic_payload_is_restricted(safety): + param = HyundaiSafetyFlags.CANFD_LKA_STEERING | HyundaiSafetyFlags.LONG + safety.set_safety_hooks(CarParams.SafetyModel.hyundaiCanfd, param) + safety.init_tests() + assert safety.safety_tx_hook(packet(0x730, 1, 8, dict(enumerate(TESTER_PRESENT)))) + assert not safety.safety_tx_hook(packet(0x730, 1, 8, {0: 3, 1: 0x22})) diff --git a/iqdbc_repo/iqdbc/safety/tests/test_hyundai_controller.py b/iqdbc_repo/iqdbc/safety/tests/test_hyundai_controller.py new file mode 100644 index 0000000..71c14b5 --- /dev/null +++ b/iqdbc_repo/iqdbc/safety/tests/test_hyundai_controller.py @@ -0,0 +1,39 @@ +import pytest + +from iqdbc.car import gen_empty_fingerprint, structs +from iqdbc.car.hyundai.interface import CarInterface +from iqdbc.car.hyundai.values import CAR +from iqdbc.safety.tests.libsafety import libsafety_py + + +@pytest.mark.parametrize("candidate", list(CAR), ids=lambda candidate: candidate.value) +@pytest.mark.parametrize("alpha_long", (False, True), ids=("stock_long", "openpilot_long")) +def test_controller_frames_match_configured_safety(candidate, alpha_long, monkeypatch, tmp_path): + """Run real controller output through the safety configuration selected for every HKG platform.""" + monkeypatch.setenv("PARAMS_ROOT", str(tmp_path / candidate.value)) + fingerprint = gen_empty_fingerprint() + cp = CarInterface.get_params(candidate, fingerprint, [], alpha_long, False, False) + cp_iq = CarInterface.get_params_iq(cp, candidate, fingerprint, [], alpha_long, False, False) + interface = CarInterface(cp, cp_iq) + interface.update([]) + + safety_config = cp.safetyConfigs[-1] + safety = libsafety_py.libsafety + assert safety.set_safety_hooks(safety_config.safetyModel.raw, safety_config.safetyParam) == 0 + safety.init_tests() + safety.set_controls_allowed(True) + + control = structs.CarControl.new_message() + control.enabled = True + control.latActive = True + control.longActive = alpha_long + control.actuators.torque = 0.01 + control.actuators.accel = 0.0 + + for frame in range(20): + _, can_sends = interface.apply(control.as_reader(), structs.IQCarControl()) + assert isinstance(can_sends, list) + for address, data, bus in can_sends: + packet = libsafety_py.make_CANPacket(address, bus, data) + rejection = f"{candidate.value} frame {frame}: safety rejected address={address:#x} bus={bus} data={data.hex()}" + assert safety.safety_tx_hook(packet), rejection diff --git a/iqpilot/iq_maps/road_data/road_daemon.py b/iqpilot/iq_maps/road_data/road_daemon.py index 5f5ed13..0e358da 100644 --- a/iqpilot/iq_maps/road_data/road_daemon.py +++ b/iqpilot/iq_maps/road_data/road_daemon.py @@ -1,11 +1,6 @@ """ Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos """ -# DISCLAIMER: This code is intended principally for development and debugging purposes. -# Although it provides a standalone entry point to the program, users should refer -# to the actual implementations for consumption. Usage outside of development scenarios -# is not advised and could lead to unpredictable results. - import threading import traceback @@ -13,26 +8,27 @@ from openpilot.common.realtime import Ratekeeper, config_realtime_process from openpilot.iqpilot.iq_maps.road_data import debug_road_data from openpilot.iqpilot.iq_maps.road_data.iq_road_layer import IQRoadLayer +ROAD_LAYER_HZ = 1 +ROAD_LAYER_CORES = [0, 1, 2, 3] -def excepthook(args): - debug_road_data(f'IQ maps threading exception:\n{args}') + +def _log_thread_exception(args) -> None: + debug_road_data(f"IQ maps threading exception:\n{args}") traceback.print_exception(args.exc_type, args.exc_value, args.exc_traceback) -def live_map_data_iq_thread(): - config_realtime_process([0, 1, 2, 3], 5) - - live_map_iq = IQRoadLayer() - rk = Ratekeeper(1, print_delay_threshold=None) - +def run() -> None: + config_realtime_process(ROAD_LAYER_CORES, 5) + layer = IQRoadLayer() + rk = Ratekeeper(ROAD_LAYER_HZ, print_delay_threshold=None) while True: - live_map_iq.step() + layer.step() rk.keep_time() -def main(): - threading.excepthook = excepthook - live_map_data_iq_thread() +def main() -> None: + threading.excepthook = _log_thread_exception + run() if __name__ == "__main__": diff --git a/iqpilot/iq_maps/vendor_mapd_installer.py b/iqpilot/iq_maps/vendor_mapd_installer.py index 69e9f4f..a76bcb9 100755 --- a/iqpilot/iq_maps/vendor_mapd_installer.py +++ b/iqpilot/iq_maps/vendor_mapd_installer.py @@ -1,21 +1,25 @@ #!/usr/bin/env python3 -import hashlib """ Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos + +Installs the `mapd` binary by Jacob Pfeifer (github.com/pfeiferj/mapd) — the binary is his work. """ +import hashlib import logging import os import stat import time import traceback -import requests from pathlib import Path from urllib.request import urlopen +import requests + from cereal import messaging +from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params -from openpilot.system.hardware.hw import Paths from openpilot.common.spinner import Spinner +from openpilot.system.hardware.hw import Paths from openpilot.system.version import is_prebuilt from openpilot.iqpilot.iq_maps import VENDOR_MAPD_BIN_DIR, VENDOR_MAPD_PATH import openpilot.system.sentry as sentry @@ -23,17 +27,28 @@ import openpilot.system.sentry as sentry VENDOR_RELEASE_TAG = "v2.0.6" VENDOR_RELEASE_URL = f"https://github.com/pfeiferj/mapd/releases/download/{VENDOR_RELEASE_TAG}/mapd" +_VERSION_PARAM = "MapdVersion" +_HASH_FILE = os.path.join(BASEDIR, "iqpilot", "iq_maps", "tests", "mapd_hash") +_DOWNLOAD_TIMEOUT_S = 60 +_MAX_DOWNLOAD_TRIES = 5 + + +def get_file_hash(path: str) -> str: + """Hex SHA-256 of a file's contents.""" + with open(path, "rb") as handle: + return hashlib.file_digest(handle, "sha256").hexdigest() + def stamp_vendor_version(version: str, params: Params | None = None) -> None: - if params is None: - params = Params() - - params.put("MapdVersion", version) + (params or Params()).put(_VERSION_PARAM, version) -def _expected_vendor_hash_path() -> str: - from openpilot.common.basedir import BASEDIR - return os.path.join(BASEDIR, "iqpilot", "iq_maps", "tests", "mapd_hash") +def _pinned_hash() -> str: + try: + with open(_HASH_FILE) as f: + return f.read().strip() + except OSError: + return "" class VendorMapdInstaller: @@ -41,98 +56,74 @@ class VendorMapdInstaller: self._spinner = spinner_ref self._params = Params() - def fetch(self) -> None: - self.ensure_directories_exist() - self._download_file() - stamp_vendor_version(VENDOR_RELEASE_TAG, self._params) + def get_installed_version(self) -> str: + return str(self._params.get(_VERSION_PARAM) or "") - def check_and_download(self) -> None: - if self.download_needed(): - self.fetch() + @staticmethod + def ensure_directories_exist() -> None: + for d in (Paths.mapd_root(), VENDOR_MAPD_BIN_DIR): + os.makedirs(d, exist_ok=True) def download_needed(self) -> bool: if not os.path.exists(VENDOR_MAPD_PATH): return True if self.get_installed_version() != VENDOR_RELEASE_TAG: return True - return not self._binary_hash_matches() - - @staticmethod - def _binary_hash_matches() -> bool: + pinned = _pinned_hash() + if not pinned: + return False try: - hash_path = _expected_vendor_hash_path() - with open(hash_path) as f: - expected = f.read().strip() - except Exception: - return True - if not expected: - return True - try: - return get_file_hash(VENDOR_MAPD_PATH) == expected - except Exception: + return get_file_hash(VENDOR_MAPD_PATH) != pinned + except OSError: return True - @staticmethod - def ensure_directories_exist() -> None: - if not os.path.exists(Paths.mapd_root()): - os.makedirs(Paths.mapd_root()) - if not os.path.exists(VENDOR_MAPD_BIN_DIR): - os.makedirs(VENDOR_MAPD_BIN_DIR) + def check_and_download(self) -> None: + if self.download_needed(): + self.fetch() - @staticmethod - def _safe_write_and_set_executable(file_path: Path, content: bytes) -> None: - with open(file_path, 'wb') as output: - output.write(content) - output.flush() - os.fsync(output.fileno()) - current_permissions = stat.S_IMODE(os.lstat(file_path).st_mode) - os.chmod(file_path, current_permissions | stat.S_IEXEC) + def fetch(self) -> None: + self.ensure_directories_exist() + if self._pull_binary(): + stamp_vendor_version(VENDOR_RELEASE_TAG, self._params) - def _download_file(self, num_retries=5) -> None: - temp_file = Path(VENDOR_MAPD_PATH + ".tmp") - download_timeout = 60 - for cnt in range(num_retries): + def _pull_binary(self) -> bool: + scratch = Path(f"{VENDOR_MAPD_PATH}.tmp") + for attempt in range(1, _MAX_DOWNLOAD_TRIES + 1): try: - response = requests.get(VENDOR_RELEASE_URL, stream=True, timeout=download_timeout) - response.raise_for_status() - self._safe_write_and_set_executable(temp_file, response.content) - temp_file.replace(VENDOR_MAPD_PATH) - return - except requests.exceptions.ReadTimeout: - self._spinner.update(f"ReadTimeout caught. Timeout is [{download_timeout}]. Retrying download... [{cnt}]") - time.sleep(0.5) + resp = requests.get(VENDOR_RELEASE_URL, stream=True, timeout=_DOWNLOAD_TIMEOUT_S) + resp.raise_for_status() + with open(scratch, "wb") as out: + out.write(resp.content) + out.flush() + os.fsync(out.fileno()) + mode = stat.S_IMODE(os.lstat(scratch).st_mode) + os.chmod(scratch, mode | stat.S_IEXEC) + scratch.replace(VENDOR_MAPD_PATH) + return True except requests.exceptions.RequestException as e: - self._spinner.update(f"RequestException caught: {e}. Retrying download... [{cnt}]") + self._spinner.update(f"mapd download failed ({e}); retry {attempt}/{_MAX_DOWNLOAD_TRIES}") time.sleep(0.5) - - # Delete temp file if the process was not successful. - if temp_file.exists(): - temp_file.unlink() - logging.error("Failed to download file after all retries") - - def get_installed_version(self) -> str: - return str(self._params.get("MapdVersion") or "") + scratch.unlink(missing_ok=True) + logging.error("mapd binary download failed after %d attempts", _MAX_DOWNLOAD_TRIES) + return False def wait_for_internet_connection(self, return_on_failure: bool = False) -> bool: - max_retries = 10 - for retries in range(max_retries + 1): - self._spinner.update(f"Waiting for internet connection... [{retries}/{max_retries}]") + attempts = 10 + for i in range(attempts + 1): + self._spinner.update(f"Waiting for internet connection... [{i}/{attempts}]") time.sleep(2) try: - _ = urlopen('https://sentry.io', timeout=10) + urlopen("https://sentry.io", timeout=10) return True - except Exception as e: - print(f'Wait for internet failed: {e}') - if return_on_failure and retries == max_retries: + except Exception as e: # noqa: BLE001 + print(f"Wait for internet failed: {e}") + if return_on_failure and i == attempts: return False - return False def non_prebuilt_install(self) -> None: - sm = messaging.SubMaster(['deviceState']) - metered = sm['deviceState'].networkMetered - - if metered: + sm = messaging.SubMaster(["deviceState"]) + if sm["deviceState"].networkMetered: self._spinner.update("Can't proceed with mapd install since network is metered!") time.sleep(5) return @@ -149,14 +140,11 @@ class VendorMapdInstaller: time.sleep(0.1) self.check_and_download() self._spinner.close() - - except Exception: + except Exception: # noqa: BLE001 for i in range(6): - self._spinner.update("Failed to download OSM maps won't work until properly downloaded!" + - "Try again manually rebooting. " + - f"Boot will continue in {5 - i}s...") + self._spinner.update("Failed to download OSM maps won't work until properly downloaded!" + f"Try again manually rebooting. Boot will continue in {5 - i}s...") time.sleep(1) - sentry.init(sentry.SentryProject.SELFDRIVE) traceback.print_exc() sentry.capture_exception() @@ -164,18 +152,12 @@ class VendorMapdInstaller: if __name__ == "__main__": spinner = Spinner() - install_manager = VendorMapdInstaller(spinner) - install_manager.ensure_directories_exist() + installer = VendorMapdInstaller(spinner) + installer.ensure_directories_exist() if is_prebuilt(): - debug_msg = f"[DEBUG] This is prebuilt, no vendor mapd install required. VERSION: [{VENDOR_RELEASE_TAG}], Param [{install_manager.get_installed_version()}]" - spinner.update(debug_msg) + spinner.update(f"[DEBUG] Prebuilt build; no vendor mapd install required. " + f"VERSION: [{VENDOR_RELEASE_TAG}], Param [{installer.get_installed_version()}]") stamp_vendor_version(VENDOR_RELEASE_TAG) else: spinner.update(f"Checking if vendor mapd is installed and valid. Prebuilt [{is_prebuilt()}]") - install_manager.non_prebuilt_install() - - -def get_file_hash(path: str) -> str: - """Hex SHA-256 of a file's contents.""" - with open(path, "rb") as handle: - return hashlib.file_digest(handle, "sha256").hexdigest() + installer.non_prebuilt_install() diff --git a/iqpilot/selfdrive/iqmodeld/models/split_model_constants.py b/iqpilot/selfdrive/iqmodeld/models/split_model_constants.py index 5165d6b..a088fe7 100644 --- a/iqpilot/selfdrive/iqmodeld/models/split_model_constants.py +++ b/iqpilot/selfdrive/iqmodeld/models/split_model_constants.py @@ -1,3 +1,4 @@ +# openpilot model I/O constants (comma.ai, MIT — see LICENSE) import numpy as np @@ -14,7 +15,7 @@ class SplitModelConstants: LEAD_T_OFFSETS = [0., 2., 4.] META_T_IDXS = [2., 4., 6., 8., 10.] - # model inputs constants + # split-model temporal / history run parameters MODEL_FREQ = 20 HISTORY_FREQ = 5 HISTORY_LEN_SECONDS = 5 diff --git a/launch_env.sh b/launch_env.sh index b1803f0..1ca9150 100755 --- a/launch_env.sh +++ b/launch_env.sh @@ -23,7 +23,7 @@ if [ -z "$AGNOS_VERSION" ]; then case "$DEVICE_MODEL" in *) - export AGNOS_VERSION="IQ.OS 4.5" + export AGNOS_VERSION="IQ.OS 4.8" ;; esac fi diff --git a/system/hardware/tici/agnos.json b/system/hardware/tici/agnos.json index 45f31ff..582f604 100644 --- a/system/hardware/tici/agnos.json +++ b/system/hardware/tici/agnos.json @@ -78,17 +78,17 @@ }, { "name": "system", - "url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/system-036bb0bcf945115c6488efadcdb56a42192201290a5fe4572ac7b46549146c79.img.xz", - "hash": "a0bf6d22e1134fc6c47158d63901c06324ea3b3808ed2fec35801a888cf3d526", - "hash_raw": "036bb0bcf945115c6488efadcdb56a42192201290a5fe4572ac7b46549146c79", + "url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/system-756453317d208f873d44e14e9429d466c90cdcee70de52fede0bfdd6f6571c7b.img.xz", + "hash": "654de83dd64190701c5a9dc7297fb569ba106cc63217725893920df6b8c9eaa0", + "hash_raw": "756453317d208f873d44e14e9429d466c90cdcee70de52fede0bfdd6f6571c7b", "size": 6291456000, "sparse": true, "full_check": false, "has_ab": true, - "ondevice_hash": "9a08b97618dceceed48205ec674330bb97c7f76487a6cca2f68288aaa42aaf8e", + "ondevice_hash": "8269bd017b18a1a4fd5e093b96efa181fd803e200fa92364fe9307f25445f596", "alt": { - "hash": "036bb0bcf945115c6488efadcdb56a42192201290a5fe4572ac7b46549146c79", - "url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/system-036bb0bcf945115c6488efadcdb56a42192201290a5fe4572ac7b46549146c79.img", + "hash": "756453317d208f873d44e14e9429d466c90cdcee70de52fede0bfdd6f6571c7b", + "url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/system-756453317d208f873d44e14e9429d466c90cdcee70de52fede0bfdd6f6571c7b.img", "size": 6291456000 } } diff --git a/system/hardware/tici/agnos.json.sig b/system/hardware/tici/agnos.json.sig index 87abc87..2a4b9e7 100644 --- a/system/hardware/tici/agnos.json.sig +++ b/system/hardware/tici/agnos.json.sig @@ -1 +1 @@ -Xmaq5VKDz8zpg4uJI4cTwgkgKp+HzFlL+5pzHfWvJXqVSNnlOZ/H5dNzm2MScLgzjnxcRYxferbIXjTyZKrzAw== +6ZRxEduDaLm1coUVvI/0QAZtmbf+tY0TWMZtaEaxV7I2fKFfGPG/6oOizuFsmd/SSQls84kap9MwKDEc8XfIDA== diff --git a/system/hardware/tici/agnos_tici_15_1.json b/system/hardware/tici/agnos_tici_15_1.json index 323348f..2acf2e7 100644 --- a/system/hardware/tici/agnos_tici_15_1.json +++ b/system/hardware/tici/agnos_tici_15_1.json @@ -67,17 +67,17 @@ }, { "name": "system", - "url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/system-036bb0bcf945115c6488efadcdb56a42192201290a5fe4572ac7b46549146c79.img.xz", - "hash": "a0bf6d22e1134fc6c47158d63901c06324ea3b3808ed2fec35801a888cf3d526", - "hash_raw": "036bb0bcf945115c6488efadcdb56a42192201290a5fe4572ac7b46549146c79", + "url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/system-756453317d208f873d44e14e9429d466c90cdcee70de52fede0bfdd6f6571c7b.img.xz", + "hash": "654de83dd64190701c5a9dc7297fb569ba106cc63217725893920df6b8c9eaa0", + "hash_raw": "756453317d208f873d44e14e9429d466c90cdcee70de52fede0bfdd6f6571c7b", "size": 6291456000, "sparse": true, "full_check": false, "has_ab": true, - "ondevice_hash": "9a08b97618dceceed48205ec674330bb97c7f76487a6cca2f68288aaa42aaf8e", + "ondevice_hash": "8269bd017b18a1a4fd5e093b96efa181fd803e200fa92364fe9307f25445f596", "alt": { - "hash": "036bb0bcf945115c6488efadcdb56a42192201290a5fe4572ac7b46549146c79", - "url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/system-036bb0bcf945115c6488efadcdb56a42192201290a5fe4572ac7b46549146c79.img", + "hash": "756453317d208f873d44e14e9429d466c90cdcee70de52fede0bfdd6f6571c7b", + "url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/system-756453317d208f873d44e14e9429d466c90cdcee70de52fede0bfdd6f6571c7b.img", "size": 6291456000 } } diff --git a/system/hardware/tici/agnos_tici_15_1.json.sig b/system/hardware/tici/agnos_tici_15_1.json.sig index f6d2b41..db7a65e 100644 --- a/system/hardware/tici/agnos_tici_15_1.json.sig +++ b/system/hardware/tici/agnos_tici_15_1.json.sig @@ -1 +1 @@ -IeObYseNfOAYVt6hNKkFMX+RmBAQBU9iiwbox8y6sUdZZs7ZdrUqWJ1ou6yxxsx2JCkgOCQk8z9yT5frz5CeDg== ++gqhJbKMr9i9lW7WrtKebqKXlM0Asr/i7ZodOzIAHzAgzGEvPCWbfco2jo0/jO7O2UzZwKJUl/WzHlsOtJvnCw== diff --git a/system/ui/lib/emoji.py b/system/ui/lib/emoji.py index 37228e2..17f99d4 100644 --- a/system/ui/lib/emoji.py +++ b/system/ui/lib/emoji.py @@ -33,10 +33,19 @@ EMOJI_REGEX = re.compile( flags=re.UNICODE ) +_emoji_font_loaded = False + def _load_emoji_font() -> ImageFont.FreeTypeFont | None: - global _emoji_font - if _emoji_font is None: - _emoji_font = ImageFont.truetype(str(FONT_DIR.joinpath("NotoColorEmoji.ttf")), 109) + global _emoji_font, _emoji_font_loaded + if not _emoji_font_loaded: + _emoji_font_loaded = True + try: + # FONT_DIR is an importlib.resources path. Inside the setup zipapp it points into the archive, + # so str() yields a path through the .zip that PIL can't open ("cannot open resource"). Read + # the bytes and hand PIL a file object so it works both on disk and inside the zipapp. + _emoji_font = ImageFont.truetype(io.BytesIO(FONT_DIR.joinpath("NotoColorEmoji.ttf").read_bytes()), 109) + except Exception: + _emoji_font = None # never crash the whole UI over an emoji glyph return _emoji_font def find_emoji(text): @@ -44,12 +53,15 @@ def find_emoji(text): def emoji_tex(emoji): if emoji not in _cache: + font = _load_emoji_font() + if font is None: + return None img = Image.new("RGBA", (128, 128), (0, 0, 0, 0)) draw = ImageDraw.Draw(img) - draw.text((0, 0), emoji, font=_load_emoji_font(), embedded_color=True) + draw.text((0, 0), emoji, font=font, embedded_color=True) with io.BytesIO() as buffer: img.save(buffer, format="PNG") l = buffer.tell() buffer.seek(0) _cache[emoji] = rl.load_texture_from_image(rl.load_image_from_memory(".png", buffer.getvalue(), l)) - return _cache[emoji] + return _cache.get(emoji) diff --git a/system/ui/mici_setup.py b/system/ui/mici_setup.py index a371ac6..afbb9d6 100755 --- a/system/ui/mici_setup.py +++ b/system/ui/mici_setup.py @@ -50,6 +50,8 @@ INSTALLER_URL_PATH = "/tmp/installer_url" # "/" maps to a GitHub fork. IQ.OS uses the DRM "magic" compositor, not Wayland, # so comma's downloaded installers (installer.comma.ai) crash on launch; clone the fork directly. GITHUB_FORK_URL = "https://github.com/{user}/openpilot.git" +# IQ.Pilot lives on the IQ Lvbs git server; github.com/IQLvbs is DMCA'd and dead. +GIT_URL_OVERRIDES = {"IQLvbs": "https://git.konn3kt.com/IQ.Lvbs/IQ.Pilot.git"} CONTINUE = """#!/usr/bin/env bash @@ -756,7 +758,7 @@ class Setup(Widget): pass def _fork_install_thread(self, user: str, branch: str): - git_url = GITHUB_FORK_URL.format(user=user) + git_url = GIT_URL_OVERRIDES.get(user) or GITHUB_FORK_URL.format(user=user) label = f"{user}/{branch}" try: subprocess.run(["rm", "-rf", TMP_INSTALL_PATH], check=False) @@ -774,7 +776,8 @@ class Setup(Widget): subprocess.run(["git", "-C", TMP_INSTALL_PATH, "submodule", "update", "--init"], check=False) run_cmd(["rm", "-f", VALID_CACHE_PATH]) - run_cmd(["rm", "-rf", INSTALL_PATH]) + # sudo: a prior *run* install can leave root-owned .pyc here that a comma-user rm can't delete. + run_cmd(["sudo", "rm", "-rf", INSTALL_PATH]) run_cmd(["mv", TMP_INSTALL_PATH, INSTALL_PATH]) self._ble_progress("installing", 90) @@ -882,6 +885,11 @@ class Setup(Widget): # AGNOS might try to execute the installer before this process exits. # Therefore, important to close the fd before renaming the installer. os.close(fd) + # comma's ELF installer does `rm -rf /data/openpilot` as the comma user and asserts it + # succeeds; a prior *run* install leaves root-owned __pycache__ .pyc it can't delete, so it + # aborts before continue.sh and bounces back to setup. Clear the old tree first (sudo) so the + # installer's rm succeeds. + subprocess.run(["sudo", "rm", "-rf", INSTALL_PATH], check=False) os.rename(tmpfile, INSTALLER_DESTINATION_PATH) with open(INSTALLER_URL_PATH, "w") as f: diff --git a/system/ui/tici_setup.py b/system/ui/tici_setup.py index 6eda8e3..2a33bc4 100755 --- a/system/ui/tici_setup.py +++ b/system/ui/tici_setup.py @@ -51,6 +51,8 @@ INSTALLER_DESTINATION_PATH = "/tmp/installer" INSTALLER_URL_PATH = "/tmp/installer_url" GITHUB_FORK_URL = "https://github.com/{user}/openpilot.git" +# IQ.Pilot lives on the IQ Lvbs git server; github.com/IQLvbs is DMCA'd and dead. +GIT_URL_OVERRIDES = {"IQLvbs": "https://git.konn3kt.com/IQ.Lvbs/IQ.Pilot.git"} CONTINUE = """#!/usr/bin/env bash @@ -589,7 +591,7 @@ class Setup(Widget): pass def _fork_install_thread(self, user: str, branch: str): - git_url = GITHUB_FORK_URL.format(user=user) + git_url = GIT_URL_OVERRIDES.get(user) or GITHUB_FORK_URL.format(user=user) label = f"{user}/{branch}" fail_msg = "Ensure the entered URL is valid, and the device's internet connection is good." try: @@ -609,7 +611,8 @@ class Setup(Widget): subprocess.run(["git", "-C", TMP_INSTALL_PATH, "submodule", "update", "--init"], check=False) run_cmd(["rm", "-f", VALID_CACHE_PATH]) - run_cmd(["rm", "-rf", INSTALL_PATH]) + # sudo: a prior *run* install can leave root-owned .pyc here that a comma-user rm can't delete. + run_cmd(["sudo", "rm", "-rf", INSTALL_PATH]) run_cmd(["mv", TMP_INSTALL_PATH, INSTALL_PATH]) self._ble_progress("installing", 90) @@ -718,6 +721,11 @@ class Setup(Widget): # AGNOS might try to execute the installer before this process exits. # Therefore, important to close the fd before renaming the installer. os.close(fd) + # comma's ELF installer does `rm -rf /data/openpilot` as the comma user and asserts it + # succeeds; a prior *run* install leaves root-owned __pycache__ .pyc it can't delete, so it + # aborts before continue.sh and bounces back to setup. Clear the old tree first (sudo) so the + # installer's rm succeeds. + subprocess.run(["sudo", "rm", "-rf", INSTALL_PATH], check=False) os.rename(tmpfile, INSTALLER_DESTINATION_PATH) with open(INSTALLER_URL_PATH, "w") as f: diff --git a/system/ui/widgets/label.py b/system/ui/widgets/label.py index e7fe6af..b368e04 100644 --- a/system/ui/widgets/label.py +++ b/system/ui/widgets/label.py @@ -406,7 +406,8 @@ class Label(Widget): line_pos.x += width_before.x tex = emoji_tex(emoji) - rl.draw_texture_ex(tex, line_pos, 0.0, self._font_size / tex.height * FONT_SCALE, self._text_color) + if tex is not None: + rl.draw_texture_ex(tex, line_pos, 0.0, self._font_size / tex.height * FONT_SCALE, self._text_color) line_pos.x += self._font_size * FONT_SCALE prev_index = end rl.draw_text_ex(self._font, text[prev_index:], line_pos, self._font_size, 0, self._text_color) @@ -849,8 +850,9 @@ class UnifiedLabel(Widget): # Draw emoji tex = emoji_tex(emoji) - emoji_scale = self._font_size / tex.height * FONT_SCALE - rl.draw_texture_ex(tex, line_pos, 0.0, emoji_scale, self._text_color) + if tex is not None: + emoji_scale = self._font_size / tex.height * FONT_SCALE + rl.draw_texture_ex(tex, line_pos, 0.0, emoji_scale, self._text_color) # Emoji width is font_size * FONT_SCALE (as per measure_text_cached) line_pos.x += self._font_size * FONT_SCALE prev_index = end