mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-09-04 07:03:44 +08:00
Compare commits
779 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 08b519ca77 | |||
| 449cb11938 | |||
| 3d4c625deb | |||
| dff446fe5e | |||
| 75577ecfca | |||
| 41bca45bdd | |||
| 3ebc6b9903 | |||
| 5e13c2d61b | |||
| d646413db3 | |||
| d0fc9f9f46 | |||
| eef1d0513e | |||
| 401319431a | |||
| 6f49c1cfc9 | |||
| 9f2f79a652 | |||
| 4d9df8b147 | |||
| 138e4cca06 | |||
| 5d32cccaf1 | |||
| 764417845f | |||
| 3fb2bcdcee | |||
| d8ac4dc57a | |||
| 2620f9f9bd | |||
| 16e561c5b5 | |||
| 6420724913 | |||
| 388662ceb0 | |||
| b5286ec678 | |||
| aa9eeae40e | |||
| d426054dec | |||
| b22babb0b5 | |||
| 147b9df247 | |||
| 02a45f13a2 | |||
| 5f256e60d9 | |||
| b6964f0142 | |||
| 83c3ee8e26 | |||
| 7926c2183d | |||
| 7d39054b6c | |||
| 79fa8bd566 | |||
| ae82751776 | |||
| 0911d9c208 | |||
| 465ac2651a | |||
| 4486dc2f14 | |||
| f546a3e07a | |||
| 3acff1e3d7 | |||
| f198977141 | |||
| dc62d0e27a | |||
| 6b1ad03acf | |||
| ebb096a956 | |||
| 11b2987c50 | |||
| ec0ab9d300 | |||
| f501a4de37 | |||
| 63f8828c01 | |||
| aa1d691304 | |||
| ac95896551 | |||
| 443c35228d | |||
| 4d281c22d7 | |||
| 6c1ec6798f | |||
| 386a6f9216 | |||
| c02bb05113 | |||
| 695573c057 | |||
| f0d8de490c | |||
| 7bfe5ab830 | |||
| f07d588534 | |||
| a0aa48f82a | |||
| 3c852bdbb0 | |||
| f5ba6362ce | |||
| 2d93c29890 | |||
| c0b8f1cb01 | |||
| e19aed96da | |||
| f6d7442c05 | |||
| 8bcf4c7abf | |||
| f85bfb277b | |||
| b2602bc4e7 | |||
| 3e176f3884 | |||
| f79ab05fa5 | |||
| 5b47ff584a | |||
| af2e153e52 | |||
| b619371441 | |||
| e3bfb66ded | |||
| 328f2d9ff7 | |||
| 227b5cf82a | |||
| adb5058cb8 | |||
| 3c655e79a9 | |||
| 032f085500 | |||
| 5882bd23ba | |||
| 78aba03b4f | |||
| 2c002755c7 | |||
| b3c417ce05 | |||
| 00fc6d8158 | |||
| 81d20d304f | |||
| d683da24ea | |||
| 4509316877 | |||
| 47ccab65d9 | |||
| 979b297652 | |||
| 6a17743513 | |||
| e20ea5d0d1 | |||
| f20b256473 | |||
| a88da4071f | |||
| 9437efe93b | |||
| b7393ad04a | |||
| 1da3008676 | |||
| 7446b96939 | |||
| 145bf39587 | |||
| 31f00eaff7 | |||
| b381cc0c4a | |||
| 903631ee53 | |||
| f8d47139a3 | |||
| 89753b6194 | |||
| 0b9298e363 | |||
| fcf4d75c76 | |||
| 4db69dae3b | |||
| c82cc2ed9f | |||
| f30a8ea20e | |||
| 1a3b243233 | |||
| 68cef2d360 | |||
| 60aa4aad49 | |||
| 5c4f6ff353 | |||
| c1857824b7 | |||
| 468ba323fc | |||
| dfd9b54bf5 | |||
| b00888c858 | |||
| 0a89eaf255 | |||
| 931877feb9 | |||
| 71f35601d7 | |||
| 9eb5768d2a | |||
| 2ef545b987 | |||
| 83cec26dea | |||
| 0122e4069b | |||
| f857a55f59 | |||
| 05140149fb | |||
| 6a64493512 | |||
| 9c1d39b859 | |||
| ffab4a8321 | |||
| 71c1d79807 | |||
| 36d0c074f1 | |||
| 6dccb85b96 | |||
| d11ecaf457 | |||
| b302637e4d | |||
| e28f72c661 | |||
| 2db8d95905 | |||
| db5922db43 | |||
| 96f5819c6a | |||
| cfd221b89c | |||
| 013f8579d7 | |||
| 2b53b59bee | |||
| 33f6d69a32 | |||
| 58e919c264 | |||
| 17e5542b1b | |||
| e1458d4723 | |||
| 06f9e43e4e | |||
| f8e03a9fc5 | |||
| 7c6741a93e | |||
| 4b3372d006 | |||
| 9a9e7cd1e9 | |||
| 1d9fdc25ca | |||
| 05db925e93 | |||
| 2bd080821b | |||
| 651726bbb5 | |||
| 6eabec436d | |||
| 56d6a6ee47 | |||
| e9f4c6316c | |||
| 284dbddd8a | |||
| 0068d7a698 | |||
| f63ee3375a | |||
| 05e9dfd5d0 | |||
| 269562e73a | |||
| 3cefd789e5 | |||
| d477735c92 | |||
| 66893b27ae | |||
| e0d9e05f9f | |||
| 73f64ac754 | |||
| 5130168067 | |||
| 04a2530ace | |||
| 297358741a | |||
| 41b10d0184 | |||
| 49f061eee4 | |||
| d8090be19d | |||
| d78902d73b | |||
| a0cf285394 | |||
| a531309e4f | |||
| 459d7c4099 | |||
| d47be80928 | |||
| 25903a0d1a | |||
| 75bd7ea3a0 | |||
| 74a2d0119e | |||
| 4f0264d07e | |||
| c201bef873 | |||
| 8e10e6adc1 | |||
| 4078e6fcfa | |||
| 80c97d0e80 | |||
| 525e57a26e | |||
| def1979aca | |||
| 5d9b55adcb | |||
| 21805a5454 | |||
| 50e1c1d376 | |||
| ef956fb54e | |||
| 944f0f087d | |||
| 68c6a1f189 | |||
| c4ef78afc9 | |||
| 526f8e0075 | |||
| a62e7b50d7 | |||
| e33213187e | |||
| bbbb4d1cf6 | |||
| 17c1499100 | |||
| 00772a6aeb | |||
| 76c930e33b | |||
| 7177b312f4 | |||
| d3cfea6a8a | |||
| 6e7b197e8a | |||
| 3719f97866 | |||
| 161ecbc1ab | |||
| b567d9fc90 | |||
| 33744deb61 | |||
| 225dfb6678 | |||
| 0593e53b04 | |||
| 4c3b2e9206 | |||
| 230ed14ece | |||
| 5c00729cfe | |||
| f95dbf83c4 | |||
| f6ab7849e8 | |||
| 6d52355bdd | |||
| 757c82c1e7 | |||
| 1a56ccbd9e | |||
| f15e6f86c7 | |||
| 5e8e40c5c3 | |||
| 13d0973528 | |||
| b10afc8379 | |||
| 00fdbd9c6f | |||
| 17cef8f164 | |||
| 730ba6e14d | |||
| 604a5ec3d1 | |||
| f2e6fddee9 | |||
| cb4ebf85a6 | |||
| 60e1615553 | |||
| 83e8064044 | |||
| a143e6ee93 | |||
| 6f57861420 | |||
| 5ef9fbda99 | |||
| 1fe6a5011a | |||
| 14b2e4dbc8 | |||
| 42d164f285 | |||
| 032bf899e0 | |||
| 1f470c8da5 | |||
| 3f6ccd104e | |||
| 4ccfc1c00c | |||
| 7a54b630fc | |||
| 22ee337762 | |||
| d84a6a95c1 | |||
| ddf95f3e45 | |||
| 008958360c | |||
| c0e9507313 | |||
| d54b6b0794 | |||
| ec485d078a | |||
| d97a4fdd65 | |||
| 12e9e1982c | |||
| f73af2211d | |||
| 603f9b56f9 | |||
| 101c354f3e | |||
| c2e2c24e8c | |||
| 21ba6ab7cd | |||
| 23a8240688 | |||
| fa8616b7ce | |||
| d1b4bfe8e9 | |||
| 8526563cf6 | |||
| c3ad1ba7dc | |||
| e245ac8332 | |||
| 74ff7bdf97 | |||
| 096dbfb701 | |||
| ad2382da53 | |||
| 2118eb17e0 | |||
| 8a5cef0f86 | |||
| 6ed117a131 | |||
| e78537c4aa | |||
| cdfd5d1d66 | |||
| 8e1caf8fe4 | |||
| c3ee472b19 | |||
| 16521d354e | |||
| 5ffa73368a | |||
| b290167194 | |||
| ebdb85ff06 | |||
| ede63179c1 | |||
| ada0ce8855 | |||
| 682b4b5c92 | |||
| 1bf2717626 | |||
| cbf7f35c85 | |||
| 8c41d92e89 | |||
| 097c6e4eb1 | |||
| e1c3d1e929 | |||
| bd9d65e92c | |||
| decf859858 | |||
| dcde24f667 | |||
| 4f471fc38c | |||
| ca737c0d40 | |||
| f1f065a77a | |||
| f64d6e6a73 | |||
| c56f7d0c20 | |||
| a367ee458c | |||
| 187318b500 | |||
| acf32365be | |||
| d7ef213792 | |||
| 6bd48c28e8 | |||
| d938c9daa6 | |||
| 1d3cd32e56 | |||
| 61f5c9e7ef | |||
| 0315fe483a | |||
| 7f6adc7a7f | |||
| d4d06e5561 | |||
| 98f856a548 | |||
| d8528595b3 | |||
| 0e5a5c527e | |||
| 2c9b8a8a2f | |||
| 47ba1544d3 | |||
| 425ba0faf4 | |||
| 5485e275fc | |||
| 724e3b200c | |||
| a59f46c7b2 | |||
| 3fe7d9b90a | |||
| 9e3ab90bdd | |||
| 8e69eb32fd | |||
| 7ec6fa5c0e | |||
| 83444c3499 | |||
| 57ac82d148 | |||
| 89d8b1cb1b | |||
| 6eba716ff8 | |||
| 42d3cf42d8 | |||
| 06f6ff66a8 | |||
| cd1d13e456 | |||
| b02a10b4de | |||
| 518b0f0345 | |||
| 3c9721be9b | |||
| a9b20d2c32 | |||
| 01b606b92a | |||
| 32117d43bc | |||
| 332dfdf099 | |||
| f7634ec761 | |||
| 98a913693d | |||
| 2250920c8a | |||
| cdd8a0b2df | |||
| d326365ee4 | |||
| bc413a844f | |||
| 76e5806575 | |||
| a527614604 | |||
| 63817ce7db | |||
| eac56eea22 | |||
| 8f95c92891 | |||
| dd870ef29c | |||
| a149d2624a | |||
| 06adeb71fd | |||
| bbbfc46601 | |||
| 48d6adab46 | |||
| a611653837 | |||
| 8b3ce51325 | |||
| cee5cf4471 | |||
| d51bd65695 | |||
| 5d5a04416a | |||
| 9798511e2e | |||
| b5223b6e23 | |||
| 1f33a35c5b | |||
| 4c2acfc55c | |||
| 73eac7d282 | |||
| 2a38c61f10 | |||
| 38abe7704e | |||
| 474c4ff01e | |||
| d50e0ebd4f | |||
| dc8d47bb50 | |||
| 3e63820cc0 | |||
| d21e13ba8f | |||
| 6334045800 | |||
| c82952da4c | |||
| dad4f928cd | |||
| 0d3330c501 | |||
| ab447ef306 | |||
| 62afc81810 | |||
| 934c484896 | |||
| 290efba471 | |||
| 3aa1436ff4 | |||
| 034992a3e8 | |||
| 8de5f51971 | |||
| a8af7ad960 | |||
| 9affcc8378 | |||
| a6a7475e7a | |||
| 22463e8323 | |||
| ac56cce888 | |||
| 6dd4d74ca0 | |||
| 428d47c918 | |||
| 1b9d7c5cd7 | |||
| 2691ee89e5 | |||
| 2833fdc54d | |||
| dbe927c629 | |||
| 4ef68730a2 | |||
| 2175217e9b | |||
| d89371c518 | |||
| 6d4089feb7 | |||
| 686f09658e | |||
| 517a07d1de | |||
| 493f377d21 | |||
| 10c1e61ffc | |||
| 7b9b7461bc | |||
| 165c960e52 | |||
| a44635ea6b | |||
| e8959fa3b7 | |||
| 56a47318a0 | |||
| 7de5bdc557 | |||
| 7e9e6c9f67 | |||
| d304d14342 | |||
| b5753daa17 | |||
| b55a55e4b4 | |||
| c9184018de | |||
| 6e454d801b | |||
| 300bdcaf16 | |||
| fa02a2baa8 | |||
| 32e2f0bccc | |||
| 8436e41731 | |||
| 205e4b3a43 | |||
| 042cdeda03 | |||
| 6277ecee4e | |||
| 0078eb477c | |||
| c8a1fb3895 | |||
| f65be7b584 | |||
| 7fbab917fa | |||
| a4a1d98f14 | |||
| 122672cd45 | |||
| fb1bfd16eb | |||
| 2eb88f4b6e | |||
| 5b06fb4968 | |||
| f8c251001f | |||
| 28d03e95d3 | |||
| 762ced4157 | |||
| b9a83f5873 | |||
| e8f526f6b8 | |||
| a0dc562f9a | |||
| 07adabd70d | |||
| 34ca49517f | |||
| 749235cda2 | |||
| 515f28fcbd | |||
| eaa5a9ad83 | |||
| 640187f350 | |||
| 3932dd9fe2 | |||
| f0e3414d1f | |||
| ba9f216931 | |||
| 4e711173e0 | |||
| 8f945fb6fe | |||
| ec6bf08a65 | |||
| 0351e7d817 | |||
| 7eae0e9670 | |||
| 8ef7e55e74 | |||
| 0d2f0b6825 | |||
| 6370abd73a | |||
| 8640f06054 | |||
| 779b42d8ea | |||
| f5f846f5b6 | |||
| d8b6e43a0d | |||
| b72042042f | |||
| bd6dced538 | |||
| 66245a5a2e | |||
| d4a3bc0f5c | |||
| fcc5cc359e | |||
| aa381d4d97 | |||
| bc3f215764 | |||
| daf0f84bc9 | |||
| b945d4c021 | |||
| 9f1066ce83 | |||
| 370654637a | |||
| fb854cecd3 | |||
| 713ce294cc | |||
| 7450b9de9a | |||
| 5b2b053afd | |||
| 88be0e6387 | |||
| cc5c95705d | |||
| d16d72afc6 | |||
| 6230d08c0f | |||
| 48af4d2f7f | |||
| d773ad9025 | |||
| 894eae7090 | |||
| 28fcba8471 | |||
| 0cff67bda8 | |||
| f0eeec955f | |||
| 9b28c7bd52 | |||
| ef400a9b3f | |||
| d4b3c3c3b0 | |||
| c57c05886c | |||
| 80f465616a | |||
| 4e70755895 | |||
| 5b41566e4e | |||
| 2141e5a5b1 | |||
| d51dd02d10 | |||
| bb3ed894b1 | |||
| d4c911f58c | |||
| fc87af4da1 | |||
| 7cd02e0c40 | |||
| db8d38e85f | |||
| 2c7e6e72c5 | |||
| 85dd1cbe7e | |||
| 665f538533 | |||
| 28a4de1c9e | |||
| 42eef3f21c | |||
| ce86d9d05a | |||
| b70d0941c9 | |||
| 8d7ba284d7 | |||
| 71b577cbc2 | |||
| cc40a28562 | |||
| 104ae74901 | |||
| 2e45e57287 | |||
| 10843b2f6e | |||
| eb3eb116eb | |||
| b34e968f91 | |||
| 3701079265 | |||
| 1a713fe3e2 | |||
| 6d92a8e5ad | |||
| 01df304f88 | |||
| 7a76325e67 | |||
| c3d1f727c0 | |||
| 94e60c5d70 | |||
| 43143e7a1f | |||
| f2b14c7ac0 | |||
| d5c0fea948 | |||
| a51b1fd78f | |||
| 8b7c2b5f36 | |||
| 0eab89c8d9 | |||
| 7b124faad2 | |||
| 4ac7fcaf5c | |||
| f265aa3f7b | |||
| 11044975c5 | |||
| 27f73a6f08 | |||
| 3e5bb853cb | |||
| 2f0864e215 | |||
| 8376ba7c97 | |||
| c928e27033 | |||
| 5f52120d7a | |||
| cab8457f47 | |||
| 8453f6b4eb | |||
| 03cf613e4c | |||
| ce44830b22 | |||
| 3ae3c5361e | |||
| d3dd2545a9 | |||
| 29cb892e1a | |||
| a106e222ca | |||
| 6ccc984dab | |||
| cce803e888 | |||
| 9427041200 | |||
| 6bae55ac8e | |||
| d8b9bf5529 | |||
| 4c07ea96e7 | |||
| fcf1bf2f3c | |||
| e3c377df34 | |||
| 28141e3074 | |||
| 25c5722372 | |||
| d699f26ded | |||
| 9ccd61e8cf | |||
| fccd46fef5 | |||
| 1863259a58 | |||
| c001d2b184 | |||
| 03ebfd2c69 | |||
| 94141aebb1 | |||
| 71ee4ab2a3 | |||
| dfb5acddf5 | |||
| 33d7e977b4 | |||
| c6708e716f | |||
| 5a7ec6b154 | |||
| d935514f78 | |||
| 8f3f9cf6c7 | |||
| 4013a70e9d | |||
| 3e363cf7a3 | |||
| 9f13e71a0a | |||
| 28ea8d0c09 | |||
| d0c877f591 | |||
| b5ebc6474e | |||
| cb151bb9aa | |||
| e943d2afd2 | |||
| 8556708cd6 | |||
| 6fa509cc88 | |||
| 8e7ce87be8 | |||
| 5d8137b30a | |||
| 368cb1a6f6 | |||
| ba460bbb7b | |||
| a6ffaaa781 | |||
| d4cfd34291 | |||
| b0334c2ae5 | |||
| 6a19e82bb2 | |||
| 5693de7d8d | |||
| 20fa52f5df | |||
| cb540160e4 | |||
| be1fda1504 | |||
| 0c3bd608d9 | |||
| 258b4c6048 | |||
| 8b23fd8c03 | |||
| eb7d4212fd | |||
| 73485ba76c | |||
| 1ea2143e01 | |||
| 20235f027d | |||
| 55ad1fd0fd | |||
| 5a2117892c | |||
| d8e4d75656 | |||
| 77db3e506c | |||
| acd15fcba7 | |||
| 00539e1dc2 | |||
| fb98b8cb29 | |||
| fc88f70ebd | |||
| 6233e7b2c0 | |||
| 0144a691b9 | |||
| 37a6c62e6e | |||
| ca09e50081 | |||
| 8098b9fa53 | |||
| 5564d133b3 | |||
| 6e3bf42c97 | |||
| f94babe509 | |||
| 45eead8dcd | |||
| fcd39be875 | |||
| a609716520 | |||
| a0ae06022c | |||
| c9cf8cfdf6 | |||
| 3d4e1f2d48 | |||
| ca74743eac | |||
| fb031a3c57 | |||
| 4bad6f6f79 | |||
| 7e1b3769d7 | |||
| 4a98785aa3 | |||
| d305071351 | |||
| 653009185e | |||
| 57bfc691bf | |||
| 7e4f8d4154 | |||
| 361f692d53 | |||
| f81099af79 | |||
| 1d982da86e | |||
| c306fc7cfd | |||
| b49c21e5aa | |||
| 44b2df59da | |||
| c8c3a814ea | |||
| 46c3592563 | |||
| 6534ce356a | |||
| e4dfbd1a60 | |||
| e9a2c925ed | |||
| 57292f09bf | |||
| e577502f4b | |||
| 7b0c0784ed | |||
| 96dcfa4287 | |||
| 6046a84e95 | |||
| 1884087590 | |||
| 637c3c820c | |||
| 4f47f8cb0a | |||
| e38668b3cb | |||
| 9dbf5db9ec | |||
| e47a836d2d | |||
| 6c0ee59a3e | |||
| a0f4028aaa | |||
| beb7e5bf6b | |||
| f88ef7ecc2 | |||
| 6cc8e9b86a | |||
| a999f28270 | |||
| 2a3d2744af | |||
| 804316e40c | |||
| bdde8907bf | |||
| 85ab7557e9 | |||
| 3d2b959db7 | |||
| 889cd3db1a | |||
| 4916143a5d | |||
| 1153010f85 | |||
| 0cbd8013b2 | |||
| a425a9c11a | |||
| 987de36f54 | |||
| f2fbd3f97c | |||
| 30245e7d34 | |||
| 3aa2801ce7 | |||
| bc3c245aa5 | |||
| cdb266cba2 | |||
| e4e416bfb3 | |||
| 39414ee2e4 | |||
| a08fe79cef | |||
| 33508d42ef | |||
| 110bd8b295 | |||
| 622720f730 | |||
| 4bdf55f6a0 | |||
| 9e2448b3d5 | |||
| 2ccd6e35b7 | |||
| 71b5cd8594 | |||
| 3bcd062eb7 | |||
| 6a4b508864 | |||
| 6e48d7dc12 | |||
| d849ac120b | |||
| 4243a5b055 | |||
| 8d9e97fdcd | |||
| 1457b902ac | |||
| 8ab1b723ae | |||
| 2fb5fbf3ad | |||
| cbe6eb077e | |||
| 831a8f27e5 | |||
| 46d19999ce | |||
| e27badccef | |||
| 07cf72d573 | |||
| 8bda3d5be1 | |||
| cdc2b7a3ed | |||
| c7bc46ec8e | |||
| dc1b9fc790 | |||
| 275f8966b2 | |||
| 5b1445bb5f | |||
| 0b1a94914b | |||
| 3317d545be | |||
| a630533b44 | |||
| cb82059d67 | |||
| e08745d519 | |||
| 7e76fa9b41 | |||
| b72570df40 | |||
| 95ee3a818b | |||
| 72992743a4 | |||
| 8eefbacc48 | |||
| 4531edad1e | |||
| 0af6ca7d37 | |||
| ac4ffb4a7e | |||
| 641f1dc238 | |||
| 650cb03b60 | |||
| cefcc41bca | |||
| 957fe8af75 | |||
| d98ae2b94b | |||
| 12a984b26d | |||
| 9cd81e89f6 | |||
| 677545cc23 | |||
| 2f02c93b3b | |||
| 7f314d9f28 | |||
| 6ea41a0329 | |||
| c33e8094e8 | |||
| f0b23a40fe | |||
| b65158cd97 | |||
| b6794d72d3 | |||
| ea2aa532af | |||
| 5bbe5f1daf | |||
| 1afb6b3978 | |||
| 9e03465520 | |||
| 06e267cef2 | |||
| b79527a217 | |||
| fa85c848f6 | |||
| 0e08829188 | |||
| 1363a5b044 | |||
| 60406cb982 | |||
| 152c39044f | |||
| 6c392185be | |||
| c7a5c880cc | |||
| 0510e87530 | |||
| c9734c9b1a | |||
| 66e04d4a45 | |||
| c1577d2536 | |||
| 23b354d47e | |||
| 5c9888a0d7 | |||
| 74cf048f94 | |||
| 0eb8d0cfdc | |||
| 9ddf5d31b4 | |||
| 7da4359dd0 | |||
| 032b2a1fde | |||
| 08df283511 | |||
| ae3792c683 | |||
| 9d2149d495 | |||
| 5234a121f9 | |||
| 706c65a70d | |||
| 04bee88dd2 | |||
| 072928ec96 | |||
| 03ec0b2c60 | |||
| 294e301000 | |||
| 74e4dd4c44 | |||
| f40881657c | |||
| 4bb15dded4 | |||
| 5eb7e8f02b | |||
| ef5ece17eb | |||
| 1339ca02c4 | |||
| d5e40d3bdf | |||
| 97c20744d3 | |||
| 30786472cb | |||
| af185f8491 | |||
| 2a5cb66b9a | |||
| 82eae95add | |||
| 85b33d8819 | |||
| e4fc9b6912 | |||
| a44cde63a5 | |||
| d93039698c | |||
| 3a1ca3fb81 | |||
| 28e51ebfea | |||
| 1c2627e1ae | |||
| b4dc28a45e | |||
| c8a9eb5464 | |||
| 11be793c3a | |||
| ce989294ab | |||
| a21520fa8f | |||
| e5751388d4 |
@@ -0,0 +1,6 @@
|
|||||||
|
github: firestar5683
|
||||||
|
patreon: firestar4430
|
||||||
|
custom:
|
||||||
|
- "https://cash.app/$domkthompson"
|
||||||
|
- "https://account.venmo.com/u/firestar4430"
|
||||||
|
- "https://www.paypal.com/paypalme/firestar4430"
|
||||||
@@ -34,7 +34,7 @@ runs:
|
|||||||
- name: setup github cache
|
- name: setup github cache
|
||||||
id: gha-cache
|
id: gha-cache
|
||||||
if: ${{ !contains(runner.name, 'nsc') && inputs.save != 'false' }}
|
if: ${{ !contains(runner.name, 'nsc') && inputs.save != 'false' }}
|
||||||
uses: 'actions/cache@v4'
|
uses: 'actions/cache@v5'
|
||||||
with:
|
with:
|
||||||
path: ${{ inputs.path }}
|
path: ${{ inputs.path }}
|
||||||
key: ${{ inputs.key }}
|
key: ${{ inputs.key }}
|
||||||
@@ -43,7 +43,7 @@ runs:
|
|||||||
- name: setup github cache
|
- name: setup github cache
|
||||||
id: gha-cache-ro
|
id: gha-cache-ro
|
||||||
if: ${{ !contains(runner.name, 'nsc') && inputs.save == 'false' }}
|
if: ${{ !contains(runner.name, 'nsc') && inputs.save == 'false' }}
|
||||||
uses: 'actions/cache/restore@v4'
|
uses: 'actions/cache/restore@v5'
|
||||||
with:
|
with:
|
||||||
path: ${{ inputs.path }}
|
path: ${{ inputs.path }}
|
||||||
key: ${{ inputs.key }}
|
key: ${{ inputs.key }}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ runs:
|
|||||||
${{ env.RUN }} "rm -rf /tmp/scons_cache/* && \
|
${{ env.RUN }} "rm -rf /tmp/scons_cache/* && \
|
||||||
scons -j$(nproc) --cache-populate"
|
scons -j$(nproc) --cache-populate"
|
||||||
- name: Save scons cache
|
- name: Save scons cache
|
||||||
uses: actions/cache/save@v4
|
uses: actions/cache/save@v5
|
||||||
if: github.ref == 'refs/heads/master'
|
if: github.ref == 'refs/heads/master'
|
||||||
with:
|
with:
|
||||||
path: .ci_cache/scons_cache
|
path: .ci_cache/scons_cache
|
||||||
|
|||||||
@@ -23,11 +23,6 @@ on:
|
|||||||
type: boolean
|
type: boolean
|
||||||
default: true
|
default: true
|
||||||
required: false
|
required: false
|
||||||
build_ui:
|
|
||||||
description: "Build UI (selfdrive/ui)"
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
required: false
|
|
||||||
build_params:
|
build_params:
|
||||||
description: "Build params Python extension"
|
description: "Build params Python extension"
|
||||||
type: boolean
|
type: boolean
|
||||||
@@ -88,7 +83,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Checkout target branch
|
- name: Checkout target branch
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
ref: ${{ env.BUILD_BRANCH }}
|
ref: ${{ env.BUILD_BRANCH }}
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -156,7 +151,6 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
TARGETS=()
|
TARGETS=()
|
||||||
[[ "${{ inputs.build_ui }}" == "true" ]] && TARGETS+=("selfdrive/ui/ui")
|
|
||||||
[[ "${{ inputs.build_params }}" == "true" ]] && TARGETS+=("common/params_pyx.so")
|
[[ "${{ inputs.build_params }}" == "true" ]] && TARGETS+=("common/params_pyx.so")
|
||||||
[[ "${{ inputs.build_cereal }}" == "true" ]] && TARGETS+=("cereal/messaging/bridge")
|
[[ "${{ inputs.build_cereal }}" == "true" ]] && TARGETS+=("cereal/messaging/bridge")
|
||||||
if [[ "${{ inputs.build_panda }}" == "true" ]]; then
|
if [[ "${{ inputs.build_panda }}" == "true" ]]; then
|
||||||
@@ -184,8 +178,8 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ${#TARGETS[@]} -eq 0 ]]; then
|
if [[ ${#TARGETS[@]} -eq 0 ]]; then
|
||||||
echo "No partial targets selected; defaulting to UI + panda"
|
echo "No partial targets selected; defaulting to panda"
|
||||||
TARGETS=("selfdrive/ui/ui" "panda/board/obj/panda.bin.signed")
|
TARGETS=("panda/board/obj/panda.bin.signed")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Running partial build for targets: ${TARGETS[*]}"
|
echo "Running partial build for targets: ${TARGETS[*]}"
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Checkout target branch
|
- name: Checkout target branch
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
ref: ${{ env.BUILD_BRANCH }}
|
ref: ${{ env.BUILD_BRANCH }}
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|||||||
@@ -17,17 +17,17 @@ jobs:
|
|||||||
publish:
|
publish:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: Log in to GHCR
|
- name: Log in to GHCR
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Build and push runner image
|
- name: Build and push runner image
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v7
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: tools/truenas_github_runner/Dockerfile
|
file: tools/truenas_github_runner/Dockerfile
|
||||||
|
|||||||
+1
-3
@@ -21,6 +21,7 @@ compiledmodels/
|
|||||||
/docs_site/
|
/docs_site/
|
||||||
|
|
||||||
*.mp4
|
*.mp4
|
||||||
|
!docs/assets/speed-limit-vision-demo*.mp4
|
||||||
*.dylib
|
*.dylib
|
||||||
*.DSYM
|
*.DSYM
|
||||||
*.d
|
*.d
|
||||||
@@ -53,9 +54,6 @@ cereal/gen
|
|||||||
selfdrive/ui/translations/tmp
|
selfdrive/ui/translations/tmp
|
||||||
selfdrive/car/tests/cars_dump
|
selfdrive/car/tests/cars_dump
|
||||||
system/camerad/test/ae_gray_test
|
system/camerad/test/ae_gray_test
|
||||||
selfdrive/ui/ui.macos
|
|
||||||
selfdrive/ui/ui.larch64
|
|
||||||
|
|
||||||
.coverage*
|
.coverage*
|
||||||
coverage.xml
|
coverage.xml
|
||||||
htmlcov
|
htmlcov
|
||||||
|
|||||||
Vendored
+1
-16
@@ -11,14 +11,6 @@
|
|||||||
"tools/sim/run_bridge.py"
|
"tools/sim/run_bridge.py"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "cpp_process",
|
|
||||||
"type": "pickString",
|
|
||||||
"description": "Select the process to debug",
|
|
||||||
"options": [
|
|
||||||
"selfdrive/ui/ui"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "args",
|
"id": "args",
|
||||||
"description": "Arguments to pass to the process",
|
"description": "Arguments to pass to the process",
|
||||||
@@ -40,13 +32,6 @@
|
|||||||
"justMyCode": true,
|
"justMyCode": true,
|
||||||
"args": "${input:args}"
|
"args": "${input:args}"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "C++: openpilot Process",
|
|
||||||
"type": "cppdbg",
|
|
||||||
"request": "launch",
|
|
||||||
"program": "${workspaceFolder}/${input:cpp_process}",
|
|
||||||
"cwd": "${workspaceFolder}"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "Attach LLDB to Replay drive",
|
"name": "Attach LLDB to Replay drive",
|
||||||
"type": "lldb",
|
"type": "lldb",
|
||||||
@@ -82,4 +67,4 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
+52
-118
@@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
import importlib
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
@@ -37,10 +38,6 @@ AddOption('--coverage',
|
|||||||
action='store_true',
|
action='store_true',
|
||||||
help='build with test coverage options')
|
help='build with test coverage options')
|
||||||
|
|
||||||
AddOption('--clazy',
|
|
||||||
action='store_true',
|
|
||||||
help='build with clazy')
|
|
||||||
|
|
||||||
AddOption('--ccflags',
|
AddOption('--ccflags',
|
||||||
action='store',
|
action='store',
|
||||||
type='string',
|
type='string',
|
||||||
@@ -132,6 +129,41 @@ elif arch == "aarch64" and AGNOS:
|
|||||||
arch = "larch64"
|
arch = "larch64"
|
||||||
assert arch in ["larch64", "aarch64", "x86_64", "Darwin"]
|
assert arch in ["larch64", "aarch64", "x86_64", "Darwin"]
|
||||||
|
|
||||||
|
# AGNOS 19.6 ships native dependencies as versioned Python packages. Link
|
||||||
|
# Cap'n Proto statically from that managed package so release binaries don't
|
||||||
|
# depend on the removed libcapnp-1.0.2.so system library.
|
||||||
|
try:
|
||||||
|
capnproto = importlib.import_module("capnproto")
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
capnproto = None
|
||||||
|
try:
|
||||||
|
ffmpeg = importlib.import_module("ffmpeg")
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
ffmpeg = None
|
||||||
|
|
||||||
|
capnproto_include_dirs = [capnproto.INCLUDE_DIR] if capnproto is not None else []
|
||||||
|
capnproto_lib_dirs = [capnproto.LIB_DIR] if capnproto is not None else []
|
||||||
|
ffmpeg_include_dirs = [ffmpeg.INCLUDE_DIR] if ffmpeg is not None else []
|
||||||
|
ffmpeg_lib_dirs = [ffmpeg.LIB_DIR] if ffmpeg is not None else []
|
||||||
|
|
||||||
|
# Cross-builds install managed dependencies in /work/.venv-linux-arm64, but
|
||||||
|
# comma devices expose the same packages from /usr/local/venv. Never embed the
|
||||||
|
# host/container mount path in release binaries.
|
||||||
|
ffmpeg_runtime_lib_dirs = ffmpeg_lib_dirs
|
||||||
|
if arch == "larch64" and ffmpeg is not None:
|
||||||
|
ffmpeg_runtime_lib_dirs = [os.path.join("/usr/local/venv", os.path.relpath(ffmpeg.LIB_DIR, sys.prefix))]
|
||||||
|
|
||||||
|
# The managed native-dependency packages keep their tools inside the package
|
||||||
|
# instead of installing them into /usr/local/venv/bin. cereal invokes capnpc
|
||||||
|
# directly while SConscript files are evaluated, so make the packaged tools
|
||||||
|
# discoverable to both SCons actions and configure-time subprocesses.
|
||||||
|
dependency_bin_dirs = [
|
||||||
|
package.BIN_DIR for package in (capnproto, ffmpeg)
|
||||||
|
if package is not None and os.path.isdir(package.BIN_DIR)
|
||||||
|
]
|
||||||
|
if dependency_bin_dirs:
|
||||||
|
os.environ["PATH"] = os.pathsep.join([*dependency_bin_dirs, os.environ["PATH"]])
|
||||||
|
|
||||||
# Homebrew llvm can shadow Apple clang and break macOS SDK header resolution.
|
# Homebrew llvm can shadow Apple clang and break macOS SDK header resolution.
|
||||||
# Use the system toolchain explicitly on macOS for reliable local builds.
|
# Use the system toolchain explicitly on macOS for reliable local builds.
|
||||||
cc = '/usr/bin/clang' if arch == "Darwin" else 'clang'
|
cc = '/usr/bin/clang' if arch == "Darwin" else 'clang'
|
||||||
@@ -273,7 +305,10 @@ env = Environment(
|
|||||||
"-Wno-vla-cxx-extension",
|
"-Wno-vla-cxx-extension",
|
||||||
] + cflags + ccflags,
|
] + cflags + ccflags,
|
||||||
|
|
||||||
CPPPATH=cpppath + [
|
# Managed dependencies must precede the compatibility sysroot. The sysroot
|
||||||
|
# can intentionally retain legacy libraries for C3 support, but new release
|
||||||
|
# binaries must link against the versions shipped in the managed venv.
|
||||||
|
CPPPATH=capnproto_include_dirs + ffmpeg_include_dirs + cpppath + [
|
||||||
"#",
|
"#",
|
||||||
"#third_party/acados/include",
|
"#third_party/acados/include",
|
||||||
"#third_party/acados/include/blasfeo/include",
|
"#third_party/acados/include/blasfeo/include",
|
||||||
@@ -292,11 +327,11 @@ env = Environment(
|
|||||||
RANLIB=ranlib,
|
RANLIB=ranlib,
|
||||||
LINKFLAGS=ldflags,
|
LINKFLAGS=ldflags,
|
||||||
|
|
||||||
RPATH=rpath,
|
RPATH=ffmpeg_runtime_lib_dirs + rpath,
|
||||||
|
|
||||||
CFLAGS=["-std=gnu11"] + cflags,
|
CFLAGS=["-std=gnu11"] + cflags,
|
||||||
CXXFLAGS=["-std=c++1z"] + cxxflags,
|
CXXFLAGS=["-std=c++1z"] + cxxflags,
|
||||||
LIBPATH=libpath + [
|
LIBPATH=capnproto_lib_dirs + ffmpeg_lib_dirs + libpath + [
|
||||||
"#msgq_repo",
|
"#msgq_repo",
|
||||||
"#third_party",
|
"#third_party",
|
||||||
"#selfdrive/pandad",
|
"#selfdrive/pandad",
|
||||||
@@ -354,116 +389,7 @@ else:
|
|||||||
np_version = SCons.Script.Value(np.__version__)
|
np_version = SCons.Script.Value(np.__version__)
|
||||||
Export('envCython', 'np_version')
|
Export('envCython', 'np_version')
|
||||||
|
|
||||||
# Qt build environment
|
Export('env', 'arch', 'real_arch')
|
||||||
qt_env = env.Clone()
|
|
||||||
qt_modules = ["Widgets", "Gui", "Core", "Network", "Concurrent", "DBus", "Xml"]
|
|
||||||
|
|
||||||
qt_libs = []
|
|
||||||
if arch == "Darwin":
|
|
||||||
qt_env['QTDIR'] = f"{brew_prefix}/opt/qt@5"
|
|
||||||
qt_dirs = [
|
|
||||||
os.path.join(qt_env['QTDIR'], "include"),
|
|
||||||
]
|
|
||||||
qt_dirs += [f"{qt_env['QTDIR']}/include/Qt{m}" for m in qt_modules]
|
|
||||||
qt_env["LINKFLAGS"] += ["-F" + os.path.join(qt_env['QTDIR'], "lib")]
|
|
||||||
qt_env["FRAMEWORKS"] += [f"Qt{m}" for m in qt_modules] + ["OpenGL"]
|
|
||||||
qt_env.AppendENVPath('PATH', os.path.join(qt_env['QTDIR'], "bin"))
|
|
||||||
else:
|
|
||||||
if arch == "larch64":
|
|
||||||
qt_env.PrependENVPath('PATH', Dir("#third_party/qt5/larch64/bin/").abspath)
|
|
||||||
# For laptop/device builds that mount an AGNOS sysroot, always prefer Qt
|
|
||||||
# headers from that sysroot to keep headers/libs ABI-matched (Qt 5.12.x).
|
|
||||||
if arch == "larch64" and os.environ.get("SP_TICI_SYSROOT"):
|
|
||||||
qt_install_prefix = tici_libpath("/usr")
|
|
||||||
qt_install_headers = tici_libpath("/usr/include/aarch64-linux-gnu/qt5")
|
|
||||||
else:
|
|
||||||
qmake = os.environ.get("SP_QMAKE", "qmake")
|
|
||||||
qt_install_prefix = subprocess.check_output([qmake, '-query', 'QT_INSTALL_PREFIX'], encoding='utf8').strip()
|
|
||||||
qt_install_headers = subprocess.check_output([qmake, '-query', 'QT_INSTALL_HEADERS'], encoding='utf8').strip()
|
|
||||||
|
|
||||||
qt_env['QTDIR'] = qt_install_prefix
|
|
||||||
qt_dirs = [
|
|
||||||
f"{qt_install_headers}",
|
|
||||||
]
|
|
||||||
|
|
||||||
qt_gui_path = os.path.join(qt_install_headers, "QtGui")
|
|
||||||
qt_gui_dirs = [d for d in os.listdir(qt_gui_path) if os.path.isdir(os.path.join(qt_gui_path, d))]
|
|
||||||
qt_dirs += [f"{qt_install_headers}/QtGui/{qt_gui_dirs[0]}/QtGui", ] if qt_gui_dirs else []
|
|
||||||
qt_dirs += [f"{qt_install_headers}/Qt{m}" for m in qt_modules]
|
|
||||||
|
|
||||||
qt_libs = [f"Qt5{m}" for m in qt_modules]
|
|
||||||
if arch == "larch64":
|
|
||||||
qt_libs += ["GLESv2", "wayland-client"]
|
|
||||||
elif arch != "Darwin":
|
|
||||||
qt_libs += ["GL"]
|
|
||||||
qt_env['QT3DIR'] = qt_env['QTDIR']
|
|
||||||
qt_env.Tool('qt3')
|
|
||||||
if arch == "larch64" and os.environ.get("SP_TICI_SYSROOT"):
|
|
||||||
qt_tool_bin = tici_libpath("/usr/lib/qt5/bin")
|
|
||||||
qt_tool_root = tici_libpath("/")
|
|
||||||
qt_arm_moc = os.path.join(qt_tool_bin, "moc")
|
|
||||||
qt_arm_uic = os.path.join(qt_tool_bin, "uic")
|
|
||||||
qt_arm_rcc = os.path.join(qt_tool_bin, "rcc")
|
|
||||||
qt_host_bin = os.environ.get("SP_QT_HOST_BIN", "/usr/lib/qt5/bin")
|
|
||||||
qt_host_moc = os.environ.get("SP_QT_HOST_MOC", os.path.join(qt_host_bin, "moc"))
|
|
||||||
qt_host_uic = os.environ.get("SP_QT_HOST_UIC", os.path.join(qt_host_bin, "uic"))
|
|
||||||
qt_host_rcc = os.environ.get("SP_QT_HOST_RCC", "rcc")
|
|
||||||
if platform.machine() in ("aarch64", "arm64"):
|
|
||||||
if "SP_QT_HOST_MOC" in os.environ:
|
|
||||||
qt_env['QT3_MOC'] = qt_host_moc
|
|
||||||
elif os.path.isfile(qt_arm_moc):
|
|
||||||
qt_env['QT3_MOC'] = qt_arm_moc
|
|
||||||
if "SP_QT_HOST_UIC" in os.environ:
|
|
||||||
qt_env['QT3_UIC'] = qt_host_uic
|
|
||||||
elif os.path.isfile(qt_arm_uic):
|
|
||||||
qt_env['QT3_UIC'] = qt_arm_uic
|
|
||||||
if "SP_QT_HOST_RCC" in os.environ:
|
|
||||||
qt_env['SP_QT_RCC'] = qt_host_rcc
|
|
||||||
elif os.path.isfile(qt_arm_rcc):
|
|
||||||
qt_env['SP_QT_RCC'] = qt_arm_rcc
|
|
||||||
else:
|
|
||||||
qt_qemu = shutil.which("qemu-aarch64-static") or shutil.which("qemu-aarch64")
|
|
||||||
|
|
||||||
if qt_qemu and os.path.isfile(qt_arm_moc):
|
|
||||||
qt_env['QT3_MOC'] = f"{qt_qemu} -L {qt_tool_root} {qt_arm_moc}"
|
|
||||||
else:
|
|
||||||
qt_env['QT3_MOC'] = qt_host_moc
|
|
||||||
|
|
||||||
if qt_qemu and os.path.isfile(qt_arm_uic):
|
|
||||||
qt_env['QT3_UIC'] = f"{qt_qemu} -L {qt_tool_root} {qt_arm_uic}"
|
|
||||||
else:
|
|
||||||
qt_env['QT3_UIC'] = qt_host_uic
|
|
||||||
|
|
||||||
if qt_qemu and os.path.isfile(qt_arm_rcc):
|
|
||||||
qt_env['SP_QT_RCC'] = f"{qt_qemu} -L {qt_tool_root} {qt_arm_rcc}"
|
|
||||||
else:
|
|
||||||
qt_env['SP_QT_RCC'] = qt_host_rcc
|
|
||||||
|
|
||||||
qt_env['CPPPATH'] += qt_dirs + ["#third_party/qrcode"]
|
|
||||||
qt_flags = [
|
|
||||||
"-D_REENTRANT",
|
|
||||||
"-DQT_NO_DEBUG",
|
|
||||||
"-DQT_WIDGETS_LIB",
|
|
||||||
"-DQT_GUI_LIB",
|
|
||||||
"-DQT_CORE_LIB",
|
|
||||||
"-DQT_MESSAGELOGCONTEXT",
|
|
||||||
]
|
|
||||||
qt_env['CXXFLAGS'] += qt_flags
|
|
||||||
qt_env['LIBPATH'] += ['#selfdrive/ui', ]
|
|
||||||
qt_env['LIBS'] = qt_libs
|
|
||||||
|
|
||||||
if GetOption("clazy"):
|
|
||||||
checks = [
|
|
||||||
"level0",
|
|
||||||
"level1",
|
|
||||||
"no-range-loop",
|
|
||||||
"no-non-pod-global-static",
|
|
||||||
]
|
|
||||||
qt_env['CXX'] = 'clazy'
|
|
||||||
qt_env['ENV']['CLAZY_IGNORE_DIRS'] = qt_dirs[0]
|
|
||||||
qt_env['ENV']['CLAZY_CHECKS'] = ','.join(checks)
|
|
||||||
|
|
||||||
Export('env', 'qt_env', 'arch', 'real_arch')
|
|
||||||
|
|
||||||
# Build common module
|
# Build common module
|
||||||
SConscript(['common/SConscript'])
|
SConscript(['common/SConscript'])
|
||||||
@@ -484,7 +410,15 @@ SConscript(['opendbc_repo/SConscript'], exports={'env': env_swaglog})
|
|||||||
SConscript(['cereal/SConscript'])
|
SConscript(['cereal/SConscript'])
|
||||||
|
|
||||||
Import('socketmaster', 'msgq')
|
Import('socketmaster', 'msgq')
|
||||||
messaging = [socketmaster, msgq, 'capnp', 'kj',]
|
if capnproto is not None:
|
||||||
|
messaging = [
|
||||||
|
socketmaster,
|
||||||
|
msgq,
|
||||||
|
File(os.path.join(capnproto.LIB_DIR, "libcapnp.a")),
|
||||||
|
File(os.path.join(capnproto.LIB_DIR, "libkj.a")),
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
messaging = [socketmaster, msgq, 'capnp', 'kj']
|
||||||
Export('messaging')
|
Export('messaging')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,4 +3,107 @@
|
|||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
exec "${ROOT_DIR}/scripts/laptop_device_build.sh" build "$@"
|
original_args=("$@")
|
||||||
|
|
||||||
|
shortcut_targets=()
|
||||||
|
passthrough_args=()
|
||||||
|
shortcut_includes_panda=0
|
||||||
|
panda_generated_files=(
|
||||||
|
"panda/board/obj/gitversion.h"
|
||||||
|
"panda/board/obj/version"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_panda_targets() {
|
||||||
|
local variants=(
|
||||||
|
panda
|
||||||
|
panda_h7
|
||||||
|
panda_remote
|
||||||
|
panda_h7_remote
|
||||||
|
panda_hkg_remote
|
||||||
|
panda_h7_hkg_remote
|
||||||
|
panda_can_ignition_only
|
||||||
|
panda_h7_can_ignition_only
|
||||||
|
panda_remote_can_ignition_only
|
||||||
|
panda_h7_remote_can_ignition_only
|
||||||
|
panda_hkg_remote_can_ignition_only
|
||||||
|
panda_h7_hkg_remote_can_ignition_only
|
||||||
|
panda_jungle_h7
|
||||||
|
body_h7
|
||||||
|
)
|
||||||
|
|
||||||
|
local variant
|
||||||
|
for variant in "${variants[@]}"; do
|
||||||
|
shortcut_targets+=("panda/board/obj/${variant}.bin.signed")
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--params|-params|-param)
|
||||||
|
shortcut_targets+=("common/params_pyx.so")
|
||||||
|
;;
|
||||||
|
--panda|-panda)
|
||||||
|
shortcut_includes_panda=1
|
||||||
|
add_panda_targets
|
||||||
|
;;
|
||||||
|
--cereal|-cereal)
|
||||||
|
shortcut_targets+=(
|
||||||
|
"cereal/libcereal.a"
|
||||||
|
"cereal/libsocketmaster.a"
|
||||||
|
"cereal/messaging/bridge"
|
||||||
|
"cereal/services.h"
|
||||||
|
)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if [[ "$1" =~ ^[0-9]+$ ]]; then
|
||||||
|
passthrough_args+=("-j$1")
|
||||||
|
else
|
||||||
|
passthrough_args+=("$1")
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "${#shortcut_targets[@]}" -gt 0 ]]; then
|
||||||
|
scons_args=("--no-scrub")
|
||||||
|
scons_args+=("${shortcut_targets[@]}")
|
||||||
|
if [[ "${#passthrough_args[@]}" -gt 0 ]]; then
|
||||||
|
scons_args+=("${passthrough_args[@]}")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${shortcut_includes_panda}" -eq 1 ]]; then
|
||||||
|
exec "${ROOT_DIR}/scripts/laptop_device_build.sh" scons "${scons_args[@]}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
tmpdir="$(mktemp -d)"
|
||||||
|
for path in "${panda_generated_files[@]}"; do
|
||||||
|
if [[ -e "${ROOT_DIR}/${path}" ]]; then
|
||||||
|
cp -p "${ROOT_DIR}/${path}" "${tmpdir}/${path//\//__}"
|
||||||
|
else
|
||||||
|
touch "${tmpdir}/${path//\//__}.missing"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if "${ROOT_DIR}/scripts/laptop_device_build.sh" scons "${scons_args[@]}"; then
|
||||||
|
status=0
|
||||||
|
else
|
||||||
|
status=$?
|
||||||
|
fi
|
||||||
|
|
||||||
|
for path in "${panda_generated_files[@]}"; do
|
||||||
|
if [[ -e "${tmpdir}/${path//\//__}.missing" ]]; then
|
||||||
|
rm -f "${ROOT_DIR}/${path}"
|
||||||
|
else
|
||||||
|
cp -p "${tmpdir}/${path//\//__}" "${ROOT_DIR}/${path}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
rm -rf "${tmpdir}"
|
||||||
|
exit "${status}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${#original_args[@]}" -gt 0 ]]; then
|
||||||
|
exec "${ROOT_DIR}/scripts/laptop_device_build.sh" build "${original_args[@]}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "${ROOT_DIR}/scripts/laptop_device_build.sh" build
|
||||||
|
|||||||
+11
-3
@@ -1,3 +1,5 @@
|
|||||||
|
import subprocess
|
||||||
|
|
||||||
Import('env', 'common', 'msgq')
|
Import('env', 'common', 'msgq')
|
||||||
|
|
||||||
cereal_dir = Dir('.')
|
cereal_dir = Dir('.')
|
||||||
@@ -5,9 +7,15 @@ gen_dir = Dir('gen')
|
|||||||
|
|
||||||
# Build cereal
|
# Build cereal
|
||||||
schema_files = ['log.capnp', 'car.capnp', 'legacy.capnp', 'custom.capnp']
|
schema_files = ['log.capnp', 'car.capnp', 'legacy.capnp', 'custom.capnp']
|
||||||
env.Command([f'gen/cpp/{s}.c++' for s in schema_files] + [f'gen/cpp/{s}.h' for s in schema_files],
|
schema_outputs = env.Command([f'gen/cpp/{s}.c++' for s in schema_files] + [f'gen/cpp/{s}.h' for s in schema_files],
|
||||||
schema_files,
|
schema_files,
|
||||||
f"capnpc --src-prefix={cereal_dir.path} $SOURCES -o c++:{gen_dir.path}/cpp/")
|
f"capnpc --src-prefix={cereal_dir.path} $SOURCES -o c++:{gen_dir.path}/cpp/")
|
||||||
|
|
||||||
|
# capnpc embeds an exact compiler-version guard in every generated C++ header.
|
||||||
|
# Include the tool version in the dependency signature so SCons cannot reuse
|
||||||
|
# generated headers from a cache populated by another AGNOS/toolchain version.
|
||||||
|
capnp_compiler_version = subprocess.check_output(['capnpc', '--version'], encoding='utf-8').strip()
|
||||||
|
env.Depends(schema_outputs, env.Value(capnp_compiler_version))
|
||||||
|
|
||||||
cereal = env.Library('cereal', [f'gen/cpp/{s}.c++' for s in schema_files])
|
cereal = env.Library('cereal', [f'gen/cpp/{s}.c++' for s in schema_files])
|
||||||
|
|
||||||
|
|||||||
+27
-1
@@ -98,6 +98,7 @@ struct StarPilotCarState @0xf35cc4560bbf6ec2 {
|
|||||||
teslaCCNotArmed @27 :Bool; # lateral engaged but DI_cruiseState != STANDBY/ENABLED
|
teslaCCNotArmed @27 :Bool; # lateral engaged but DI_cruiseState != STANDBY/ENABLED
|
||||||
accelHardCruise @28 :Bool; # current/releasing accel cruise button came from GM hard-press signal
|
accelHardCruise @28 :Bool; # current/releasing accel cruise button came from GM hard-press signal
|
||||||
decelHardCruise @29 :Bool; # current/releasing decel cruise button came from GM hard-press signal
|
decelHardCruise @29 :Bool; # current/releasing decel cruise button came from GM hard-press signal
|
||||||
|
pulseAndGlide @30 :Bool; # developer-only wheel-button pulse-and-glide mode is enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
struct StarPilotDeviceState @0xda96579883444c35 {
|
struct StarPilotDeviceState @0xda96579883444c35 {
|
||||||
@@ -219,11 +220,27 @@ struct StarPilotPlan @0xf98d843bfd7004a3 {
|
|||||||
disableThrottle @35 :Bool;
|
disableThrottle @35 :Bool;
|
||||||
trackingLead @36 :Bool;
|
trackingLead @36 :Bool;
|
||||||
stopSignConfirmed @37 :Bool;
|
stopSignConfirmed @37 :Bool;
|
||||||
|
pulseGlideCoasting @38 :Bool; # developer-only P&G phase for on-road status UI
|
||||||
|
# Curve Speed Controller diagnostics, for tuning and rollout validation
|
||||||
|
cscOverridden @39 :Bool; # driver cancelled this curve with RES+
|
||||||
|
cscLearnedLatAccel @40 :Float32; # learned comfort at the current curvature, before margin
|
||||||
|
cscBindingDistance @41 :Float32; # distance to the horizon point setting the target, m
|
||||||
|
approachStopLength @42 :Float32; # pre-commit distance to a detected stop, m; 0 when off
|
||||||
}
|
}
|
||||||
|
|
||||||
struct StarPilotRadarState @0xb86e6369214c01c8 {
|
struct StarPilotRadarState @0xb86e6369214c01c8 {
|
||||||
leadLeft @0 :LeadData;
|
leadLeft @0 :LeadData;
|
||||||
leadRight @1 :LeadData;
|
leadRight @1 :LeadData;
|
||||||
|
adjacentStopped @2 :AdjacentStopped;
|
||||||
|
|
||||||
|
# A vehicle in an adjacent lane that was observed MOVING and then came to rest.
|
||||||
|
# Distinct from leadLeft/leadRight, which are moving-target-only by design.
|
||||||
|
struct AdjacentStopped {
|
||||||
|
status @0 :Bool;
|
||||||
|
dRel @1 :Float32;
|
||||||
|
yRel @2 :Float32;
|
||||||
|
radarTrackId @3 :Int32 = -1;
|
||||||
|
}
|
||||||
|
|
||||||
struct LeadData {
|
struct LeadData {
|
||||||
dRel @0 :Float32;
|
dRel @0 :Float32;
|
||||||
@@ -253,6 +270,7 @@ struct StarPilotSelfdriveState @0xf416ec09499d9d19 {
|
|||||||
alertSize @3 :AlertSize;
|
alertSize @3 :AlertSize;
|
||||||
alertType @4 :Text;
|
alertType @4 :Text;
|
||||||
alertSound @5 :Car.CarControl.HUDControl.AudibleAlert;
|
alertSound @5 :Car.CarControl.HUDControl.AudibleAlert;
|
||||||
|
vEgo @6 :Float32;
|
||||||
|
|
||||||
enum AlertStatus {
|
enum AlertStatus {
|
||||||
normal @0;
|
normal @0;
|
||||||
@@ -282,7 +300,15 @@ struct StarPilotLateralManeuverPlanDEPRECATED @0xcb9fd56c7057593a {
|
|||||||
desiredCurvature @0 :Float32; # 1/m
|
desiredCurvature @0 :Float32; # 1/m
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CustomReserved11 @0xc2243c65e0340384 {
|
struct StarPilotLateralState @0xc2243c65e0340384 {
|
||||||
|
active @0 :Bool;
|
||||||
|
frictionThreshold @1 :Float32;
|
||||||
|
frictionScale @2 :Float32;
|
||||||
|
feedforward @3 :Float32;
|
||||||
|
frictionJerk @4 :Float32;
|
||||||
|
frictionJerkDeadzone @5 :Float32;
|
||||||
|
lowSpeedFactor @6 :Float32;
|
||||||
|
unwindDetected @7 :Bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CustomReserved12 @0x9ccdc8676701b412 {
|
struct CustomReserved12 @0x9ccdc8676701b412 {
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
+61
-7
@@ -130,8 +130,13 @@ struct OnroadEvent @0xc4fa6047f024e718 {
|
|||||||
userBookmark @95;
|
userBookmark @95;
|
||||||
excessiveActuation @96;
|
excessiveActuation @96;
|
||||||
audioFeedback @97;
|
audioFeedback @97;
|
||||||
|
bigModelLoading @100;
|
||||||
|
bigModelFailed @102;
|
||||||
|
|
||||||
soundsUnavailableDEPRECATED @47;
|
soundsUnavailableDEPRECATED @47;
|
||||||
|
stockLkasDEPRECATED @98;
|
||||||
|
lateralManeuverDEPRECATED @99;
|
||||||
|
bigModelReadyDEPRECATED @101;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -467,6 +472,10 @@ struct CanData {
|
|||||||
struct DeviceState @0xa4d8b5af2aa492eb {
|
struct DeviceState @0xa4d8b5af2aa492eb {
|
||||||
deviceType @45 :InitData.DeviceType;
|
deviceType @45 :InitData.DeviceType;
|
||||||
|
|
||||||
|
# usb
|
||||||
|
chestnutPresent @51 :Bool;
|
||||||
|
usbState @52 :UsbState;
|
||||||
|
|
||||||
networkType @22 :NetworkType;
|
networkType @22 :NetworkType;
|
||||||
networkInfo @31 :NetworkInfo;
|
networkInfo @31 :NetworkInfo;
|
||||||
networkStrength @24 :NetworkStrength;
|
networkStrength @24 :NetworkStrength;
|
||||||
@@ -498,7 +507,8 @@ struct DeviceState @0xa4d8b5af2aa492eb {
|
|||||||
pmicTempC @39 :List(Float32);
|
pmicTempC @39 :List(Float32);
|
||||||
intakeTempC @46 :Float32;
|
intakeTempC @46 :Float32;
|
||||||
exhaustTempC @47 :Float32;
|
exhaustTempC @47 :Float32;
|
||||||
caseTempC @48 :Float32;
|
gnssTempC @48 :Float32;
|
||||||
|
bottomSocTempC @50 :Float32;
|
||||||
maxTempC @44 :Float32; # max of other temps, used to control fan
|
maxTempC @44 :Float32; # max of other temps, used to control fan
|
||||||
thermalZones @38 :List(ThermalZone);
|
thermalZones @38 :List(ThermalZone);
|
||||||
thermalStatus @14 :ThermalStatus;
|
thermalStatus @14 :ThermalStatus;
|
||||||
@@ -512,10 +522,10 @@ struct DeviceState @0xa4d8b5af2aa492eb {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum ThermalStatus {
|
enum ThermalStatus {
|
||||||
green @0;
|
ok @0;
|
||||||
yellow @1;
|
warmDEPRECATED @1;
|
||||||
red @2;
|
overheated @2;
|
||||||
danger @3;
|
critical @3;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum NetworkType {
|
enum NetworkType {
|
||||||
@@ -731,6 +741,41 @@ struct PeripheralState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct UsbState {
|
||||||
|
devices @0 :List(Device);
|
||||||
|
|
||||||
|
struct Device {
|
||||||
|
busnum @0 :UInt8;
|
||||||
|
devnum @1 :UInt8;
|
||||||
|
vendorId @2 :UInt16;
|
||||||
|
productId @3 :UInt16;
|
||||||
|
speedMbps @4 :UInt16;
|
||||||
|
manufacturer @6 :Text;
|
||||||
|
product @5 :Text;
|
||||||
|
linkErrorCount @7 :UInt16;
|
||||||
|
usb3Lane @8 :Usb3Lane;
|
||||||
|
|
||||||
|
enum Usb3Lane {
|
||||||
|
unknown @0;
|
||||||
|
a @1;
|
||||||
|
b @2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ChestnutState {
|
||||||
|
tempC @0 :Float32;
|
||||||
|
memoryTempC @1 :Float32;
|
||||||
|
powerDrawW @2 :Float32;
|
||||||
|
powerLimitW @3 :Float32;
|
||||||
|
gpuUsagePercent @4 :UInt8;
|
||||||
|
gpuClockMhz @5 :UInt16;
|
||||||
|
fanSpeedRpm @6 :UInt16;
|
||||||
|
pcieLtssm @7 :UInt8;
|
||||||
|
supplyVoltage @8 :UInt16; # mV
|
||||||
|
supplyCurrent @9 :Int16; # mA
|
||||||
|
}
|
||||||
|
|
||||||
struct RadarState @0x9a185389d6fdd05f {
|
struct RadarState @0x9a185389d6fdd05f {
|
||||||
mdMonoTime @6 :UInt64;
|
mdMonoTime @6 :UInt64;
|
||||||
carStateMonoTime @11 :UInt64;
|
carStateMonoTime @11 :UInt64;
|
||||||
@@ -1282,6 +1327,11 @@ struct LongitudinalPlan @0xe00b5b3eba12876c {
|
|||||||
|
|
||||||
solverExecutionTime @35 :Float32;
|
solverExecutionTime @35 :Float32;
|
||||||
|
|
||||||
|
leadTrajectoryX0 @40 :List(Float32);
|
||||||
|
leadTrajectoryV0 @41 :List(Float32);
|
||||||
|
leadTrajectoryX1 @42 :List(Float32);
|
||||||
|
leadTrajectoryV1 @43 :List(Float32);
|
||||||
|
|
||||||
enum LongitudinalPlanSource {
|
enum LongitudinalPlanSource {
|
||||||
cruise @0;
|
cruise @0;
|
||||||
lead0 @1;
|
lead0 @1;
|
||||||
@@ -2192,6 +2242,7 @@ struct DriverStateV2 {
|
|||||||
rightBlinkProb @8 :Float32;
|
rightBlinkProb @8 :Float32;
|
||||||
sunglassesProb @9 :Float32;
|
sunglassesProb @9 :Float32;
|
||||||
phoneProb @13 :Float32;
|
phoneProb @13 :Float32;
|
||||||
|
sleepProb @14 :Float32;
|
||||||
notReadyProbDEPRECATED @12 :List(Float32);
|
notReadyProbDEPRECATED @12 :List(Float32);
|
||||||
occludedProbDEPRECATED @10 :Float32;
|
occludedProbDEPRECATED @10 :Float32;
|
||||||
readyProbDEPRECATED @11 :List(Float32);
|
readyProbDEPRECATED @11 :List(Float32);
|
||||||
@@ -2263,7 +2314,8 @@ struct DriverMonitoringStateDEPRECATED @0xb83cda094a1da284 {
|
|||||||
|
|
||||||
struct DriverMonitoringState {
|
struct DriverMonitoringState {
|
||||||
lockout @0 :Bool;
|
lockout @0 :Bool;
|
||||||
lockoutRecoveryPercent @11 :Int8;
|
lockoutCount @15 :Int8;
|
||||||
|
lockoutMinutesRemaining @11 :Int8;
|
||||||
alert3Count @12 :Int8;
|
alert3Count @12 :Int8;
|
||||||
noResponseCount @13 :Int8;
|
noResponseCount @13 :Int8;
|
||||||
noResponseForceDecel @14 :Bool;
|
noResponseForceDecel @14 :Bool;
|
||||||
@@ -2685,6 +2737,7 @@ struct Event {
|
|||||||
procLog @33 :ProcLog;
|
procLog @33 :ProcLog;
|
||||||
clocks @35 :Clocks;
|
clocks @35 :Clocks;
|
||||||
deviceState @6 :DeviceState;
|
deviceState @6 :DeviceState;
|
||||||
|
chestnutState @152 :ChestnutState;
|
||||||
logMessage @18 :Text;
|
logMessage @18 :Text;
|
||||||
errorLogMessage @85 :Text;
|
errorLogMessage @85 :Text;
|
||||||
|
|
||||||
@@ -2704,6 +2757,7 @@ struct Event {
|
|||||||
userBookmark @93 :UserBookmark;
|
userBookmark @93 :UserBookmark;
|
||||||
bookmarkButton @148 :UserBookmark;
|
bookmarkButton @148 :UserBookmark;
|
||||||
audioFeedback @149 :AudioFeedback;
|
audioFeedback @149 :AudioFeedback;
|
||||||
|
visionSpeedLimitBookmark @153 :UserBookmark;
|
||||||
|
|
||||||
lateralManeuverPlan @150 :LateralManeuverPlan;
|
lateralManeuverPlan @150 :LateralManeuverPlan;
|
||||||
# *********** debug ***********
|
# *********** debug ***********
|
||||||
@@ -2740,7 +2794,7 @@ struct Event {
|
|||||||
starpilotSelfdriveState @115 :Custom.StarPilotSelfdriveState;
|
starpilotSelfdriveState @115 :Custom.StarPilotSelfdriveState;
|
||||||
customReserved9 @116 :Custom.CustomReserved9;
|
customReserved9 @116 :Custom.CustomReserved9;
|
||||||
starpilotLateralManeuverPlanDEPRECATED @136 :Custom.StarPilotLateralManeuverPlanDEPRECATED;
|
starpilotLateralManeuverPlanDEPRECATED @136 :Custom.StarPilotLateralManeuverPlanDEPRECATED;
|
||||||
customReserved11 @137 :Custom.CustomReserved11;
|
starpilotLateralState @137 :Custom.StarPilotLateralState;
|
||||||
customReserved12 @138 :Custom.CustomReserved12;
|
customReserved12 @138 :Custom.CustomReserved12;
|
||||||
customReserved13 @139 :Custom.CustomReserved13;
|
customReserved13 @139 :Custom.CustomReserved13;
|
||||||
customReserved14 @140 :Custom.CustomReserved14;
|
customReserved14 @140 :Custom.CustomReserved14;
|
||||||
|
|||||||
@@ -268,6 +268,7 @@ class SubMaster:
|
|||||||
class PubMaster:
|
class PubMaster:
|
||||||
def __init__(self, services: List[str]):
|
def __init__(self, services: List[str]):
|
||||||
self.sock = {}
|
self.sock = {}
|
||||||
|
self._zmq_readers_settled = set()
|
||||||
for s in services:
|
for s in services:
|
||||||
self.sock[s] = pub_sock(s)
|
self.sock[s] = pub_sock(s)
|
||||||
|
|
||||||
@@ -277,6 +278,13 @@ class PubMaster:
|
|||||||
self.sock[s].send(dat)
|
self.sock[s].send(dat)
|
||||||
|
|
||||||
def wait_for_readers_to_update(self, s: str, timeout: int, dt: float = 0.05) -> bool:
|
def wait_for_readers_to_update(self, s: str, timeout: int, dt: float = 0.05) -> bool:
|
||||||
|
if "ZMQ" in os.environ:
|
||||||
|
if s not in self._zmq_readers_settled:
|
||||||
|
time.sleep(min(timeout, 1.0))
|
||||||
|
self._zmq_readers_settled.add(s)
|
||||||
|
elif dt >= 0.05:
|
||||||
|
time.sleep(min(timeout, 1.0))
|
||||||
|
return True
|
||||||
for _ in range(int(timeout*(1./dt))):
|
for _ in range(int(timeout*(1./dt))):
|
||||||
if self.sock[s].all_readers_updated():
|
if self.sock[s].all_readers_updated():
|
||||||
return True
|
return True
|
||||||
|
|||||||
Binary file not shown.
@@ -12,6 +12,7 @@ static std::map<std::string, service> services = {
|
|||||||
{ "temperatureSensor", {"temperatureSensor", true, 2.000000, 200, 256000}},
|
{ "temperatureSensor", {"temperatureSensor", true, 2.000000, 200, 256000}},
|
||||||
{ "gpsNMEA", {"gpsNMEA", true, 9.000000, -1, 256000}},
|
{ "gpsNMEA", {"gpsNMEA", true, 9.000000, -1, 256000}},
|
||||||
{ "deviceState", {"deviceState", true, 2.000000, 1, 256000}},
|
{ "deviceState", {"deviceState", true, 2.000000, 1, 256000}},
|
||||||
|
{ "chestnutState", {"chestnutState", true, 10.000000, 10, 256000}},
|
||||||
{ "touch", {"touch", true, 20.000000, 1, 256000}},
|
{ "touch", {"touch", true, 20.000000, 1, 256000}},
|
||||||
{ "can", {"can", true, 100.000000, 2053, 10485760}},
|
{ "can", {"can", true, 100.000000, 2053, 10485760}},
|
||||||
{ "controlsState", {"controlsState", true, 100.000000, 10, 2097152}},
|
{ "controlsState", {"controlsState", true, 100.000000, 10, 2097152}},
|
||||||
@@ -68,6 +69,7 @@ static std::map<std::string, service> services = {
|
|||||||
{ "rawAudioData", {"rawAudioData", false, 20.000000, -1, 256000}},
|
{ "rawAudioData", {"rawAudioData", false, 20.000000, -1, 256000}},
|
||||||
{ "bookmarkButton", {"bookmarkButton", true, 0.000000, 1, 256000}},
|
{ "bookmarkButton", {"bookmarkButton", true, 0.000000, 1, 256000}},
|
||||||
{ "audioFeedback", {"audioFeedback", true, 0.000000, 1, 256000}},
|
{ "audioFeedback", {"audioFeedback", true, 0.000000, 1, 256000}},
|
||||||
|
{ "visionSpeedLimitBookmark", {"visionSpeedLimitBookmark", false, 0.000000, 1, 256000}},
|
||||||
{ "roadEncodeData", {"roadEncodeData", false, 20.000000, -1, 10485760}},
|
{ "roadEncodeData", {"roadEncodeData", false, 20.000000, -1, 10485760}},
|
||||||
{ "driverEncodeData", {"driverEncodeData", false, 20.000000, -1, 10485760}},
|
{ "driverEncodeData", {"driverEncodeData", false, 20.000000, -1, 10485760}},
|
||||||
{ "wideRoadEncodeData", {"wideRoadEncodeData", false, 20.000000, -1, 10485760}},
|
{ "wideRoadEncodeData", {"wideRoadEncodeData", false, 20.000000, -1, 10485760}},
|
||||||
@@ -82,6 +84,7 @@ static std::map<std::string, service> services = {
|
|||||||
{ "livestreamRoadEncodeData", {"livestreamRoadEncodeData", false, 20.000000, -1, 2097152}},
|
{ "livestreamRoadEncodeData", {"livestreamRoadEncodeData", false, 20.000000, -1, 2097152}},
|
||||||
{ "livestreamDriverEncodeData", {"livestreamDriverEncodeData", false, 20.000000, -1, 2097152}},
|
{ "livestreamDriverEncodeData", {"livestreamDriverEncodeData", false, 20.000000, -1, 2097152}},
|
||||||
{ "customReserved9", {"customReserved9", true, 0.000000, 1, 256000}},
|
{ "customReserved9", {"customReserved9", true, 0.000000, 1, 256000}},
|
||||||
|
{ "starpilotLateralState", {"starpilotLateralState", true, 100.000000, 10, 256000}},
|
||||||
{ "customReservedRawData0", {"customReservedRawData0", true, 0.000000, -1, 256000}},
|
{ "customReservedRawData0", {"customReservedRawData0", true, 0.000000, -1, 256000}},
|
||||||
{ "customReservedRawData1", {"customReservedRawData1", true, 0.000000, -1, 256000}},
|
{ "customReservedRawData1", {"customReservedRawData1", true, 0.000000, -1, 256000}},
|
||||||
{ "customReservedRawData2", {"customReservedRawData2", true, 0.000000, -1, 256000}},
|
{ "customReservedRawData2", {"customReservedRawData2", true, 0.000000, -1, 256000}},
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ _services: dict[str, tuple] = {
|
|||||||
"temperatureSensor": (True, 2., 200),
|
"temperatureSensor": (True, 2., 200),
|
||||||
"gpsNMEA": (True, 9.),
|
"gpsNMEA": (True, 9.),
|
||||||
"deviceState": (True, 2., 1),
|
"deviceState": (True, 2., 1),
|
||||||
|
"chestnutState": (True, 10., 10),
|
||||||
"touch": (True, 20., 1),
|
"touch": (True, 20., 1),
|
||||||
"can": (True, 100., 2053, QueueSize.BIG), # decimation gives ~3 msgs in a full segment
|
"can": (True, 100., 2053, QueueSize.BIG), # decimation gives ~3 msgs in a full segment
|
||||||
"controlsState": (True, 100., 10, QueueSize.MEDIUM),
|
"controlsState": (True, 100., 10, QueueSize.MEDIUM),
|
||||||
@@ -85,6 +86,7 @@ _services: dict[str, tuple] = {
|
|||||||
"rawAudioData": (False, 20.),
|
"rawAudioData": (False, 20.),
|
||||||
"bookmarkButton": (True, 0., 1),
|
"bookmarkButton": (True, 0., 1),
|
||||||
"audioFeedback": (True, 0., 1),
|
"audioFeedback": (True, 0., 1),
|
||||||
|
"visionSpeedLimitBookmark": (False, 0., 1),
|
||||||
"roadEncodeData": (False, 20., None, QueueSize.BIG),
|
"roadEncodeData": (False, 20., None, QueueSize.BIG),
|
||||||
"driverEncodeData": (False, 20., None, QueueSize.BIG),
|
"driverEncodeData": (False, 20., None, QueueSize.BIG),
|
||||||
"wideRoadEncodeData": (False, 20., None, QueueSize.BIG),
|
"wideRoadEncodeData": (False, 20., None, QueueSize.BIG),
|
||||||
@@ -101,6 +103,7 @@ _services: dict[str, tuple] = {
|
|||||||
"livestreamRoadEncodeData": (False, 20., None, QueueSize.MEDIUM),
|
"livestreamRoadEncodeData": (False, 20., None, QueueSize.MEDIUM),
|
||||||
"livestreamDriverEncodeData": (False, 20., None, QueueSize.MEDIUM),
|
"livestreamDriverEncodeData": (False, 20., None, QueueSize.MEDIUM),
|
||||||
"customReserved9": (True, 0., 1),
|
"customReserved9": (True, 0., 1),
|
||||||
|
"starpilotLateralState": (True, 100., 10),
|
||||||
"customReservedRawData0": (True, 0.),
|
"customReservedRawData0": (True, 0.),
|
||||||
"customReservedRawData1": (True, 0.),
|
"customReservedRawData1": (True, 0.),
|
||||||
"customReservedRawData2": (True, 0.),
|
"customReservedRawData2": (True, 0.),
|
||||||
|
|||||||
+69
-1
@@ -1,5 +1,8 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import io
|
||||||
import math
|
import math
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
CHUNK_SIZE = 45 * 1024 * 1024 # 45MB, under GitHub's 50MB limit
|
CHUNK_SIZE = 45 * 1024 * 1024 # 45MB, under GitHub's 50MB limit
|
||||||
@@ -13,9 +16,16 @@ def get_manifest_path(name):
|
|||||||
return f"{name}.chunkmanifest"
|
return f"{name}.chunkmanifest"
|
||||||
|
|
||||||
|
|
||||||
|
def _chunk_paths(path, num_chunks):
|
||||||
|
return [get_manifest_path(path)] + [get_chunk_name(path, i, num_chunks) for i in range(num_chunks)]
|
||||||
|
|
||||||
|
|
||||||
def get_chunk_paths(path, file_size):
|
def get_chunk_paths(path, file_size):
|
||||||
num_chunks = math.ceil(file_size / CHUNK_SIZE)
|
num_chunks = math.ceil(file_size / CHUNK_SIZE)
|
||||||
return [get_manifest_path(path)] + [get_chunk_name(path, i, num_chunks) for i in range(num_chunks)]
|
return _chunk_paths(path, num_chunks)
|
||||||
|
|
||||||
|
|
||||||
|
get_chunk_targets = get_chunk_paths
|
||||||
|
|
||||||
|
|
||||||
def chunk_file(path, targets):
|
def chunk_file(path, targets):
|
||||||
@@ -31,6 +41,59 @@ def chunk_file(path, targets):
|
|||||||
os.remove(path)
|
os.remove(path)
|
||||||
|
|
||||||
|
|
||||||
|
def get_existing_chunks(path):
|
||||||
|
if os.path.isfile(path):
|
||||||
|
return [path]
|
||||||
|
manifest_path = get_manifest_path(path)
|
||||||
|
if os.path.isfile(manifest_path):
|
||||||
|
num_chunks = int(Path(manifest_path).read_text().strip())
|
||||||
|
return _chunk_paths(path, num_chunks)
|
||||||
|
raise FileNotFoundError(path)
|
||||||
|
|
||||||
|
|
||||||
|
def file_chunked_exists(path) -> bool:
|
||||||
|
return os.path.isfile(path) or os.path.isfile(get_manifest_path(path))
|
||||||
|
|
||||||
|
|
||||||
|
class ChunkStream(io.RawIOBase):
|
||||||
|
def __init__(self, paths):
|
||||||
|
self._paths = iter(paths)
|
||||||
|
self._file = None
|
||||||
|
|
||||||
|
def readable(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def readinto(self, buffer):
|
||||||
|
count = 0
|
||||||
|
view = memoryview(buffer)
|
||||||
|
while count < len(buffer):
|
||||||
|
if self._file is None:
|
||||||
|
path = next(self._paths, None)
|
||||||
|
if path is None:
|
||||||
|
break
|
||||||
|
self._file = open(path, "rb")
|
||||||
|
bytes_read = self._file.readinto(view[count:])
|
||||||
|
if not bytes_read:
|
||||||
|
self._file.close()
|
||||||
|
self._file = None
|
||||||
|
continue
|
||||||
|
count += bytes_read
|
||||||
|
return count
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
if self._file is not None:
|
||||||
|
self._file.close()
|
||||||
|
self._file = None
|
||||||
|
super().close()
|
||||||
|
|
||||||
|
|
||||||
|
def open_file_chunked(path):
|
||||||
|
chunks = get_existing_chunks(path)
|
||||||
|
if chunks and chunks[0] == get_manifest_path(path):
|
||||||
|
chunks = chunks[1:]
|
||||||
|
return io.BufferedReader(ChunkStream(chunks))
|
||||||
|
|
||||||
|
|
||||||
def read_file_chunked(path):
|
def read_file_chunked(path):
|
||||||
manifest_path = get_manifest_path(path)
|
manifest_path = get_manifest_path(path)
|
||||||
if os.path.isfile(manifest_path):
|
if os.path.isfile(manifest_path):
|
||||||
@@ -39,3 +102,8 @@ def read_file_chunked(path):
|
|||||||
if os.path.isfile(path):
|
if os.path.isfile(path):
|
||||||
return Path(path).read_bytes()
|
return Path(path).read_bytes()
|
||||||
raise FileNotFoundError(path)
|
raise FileNotFoundError(path)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
file_path = sys.argv[1]
|
||||||
|
chunk_file(file_path, get_chunk_targets(file_path, os.path.getsize(file_path)))
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ from openpilot.common.params import Params
|
|||||||
|
|
||||||
|
|
||||||
def get_gps_location_service(params: Params) -> str:
|
def get_gps_location_service(params: Params) -> str:
|
||||||
if params.get_bool("UbloxAvailable"):
|
if params.get_bool("UbloxAvailable") or params.get_bool("CarGpsAvailable"):
|
||||||
return "gpsLocationExternal"
|
return "gpsLocationExternal"
|
||||||
else:
|
else:
|
||||||
return "gpsLocation"
|
return "gpsLocation"
|
||||||
|
|||||||
Binary file not shown.
+5
-1
@@ -99,7 +99,7 @@ Params::Params(const std::string &path, bool memory) {
|
|||||||
if (memory) {
|
if (memory) {
|
||||||
params_folder = Path::shm_path() + "/params";
|
params_folder = Path::shm_path() + "/params";
|
||||||
} else {
|
} else {
|
||||||
cache_path = "/cache/params" + params_prefix + "/";
|
cache_path = Path::params_cache() + params_prefix + "/";
|
||||||
params_folder = path;
|
params_folder = path;
|
||||||
}
|
}
|
||||||
params_path = ensure_params_path(params_prefix, params_folder);
|
params_path = ensure_params_path(params_prefix, params_folder);
|
||||||
@@ -309,6 +309,10 @@ int Params::getTuningLevel(const std::string &key) {
|
|||||||
return keys[key].tuning_level;
|
return keys[key].tuning_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ParamSettingsTier Params::getSettingsTier(const std::string &key) {
|
||||||
|
return keys[key].settings_tier;
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<std::string> Params::getStockValue(const std::string &key) {
|
std::optional<std::string> Params::getStockValue(const std::string &key) {
|
||||||
ParamKeyAttributes &attributes = keys[key];
|
ParamKeyAttributes &attributes = keys[key];
|
||||||
if (attributes.stock_value) {
|
if (attributes.stock_value) {
|
||||||
|
|||||||
@@ -33,6 +33,11 @@ enum ParamKeyType {
|
|||||||
BYTES = 6
|
BYTES = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ParamSettingsTier {
|
||||||
|
SETTINGS_SIMPLE = 0,
|
||||||
|
SETTINGS_ADVANCED = 1,
|
||||||
|
};
|
||||||
|
|
||||||
struct ParamKeyAttributes {
|
struct ParamKeyAttributes {
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
ParamKeyType type;
|
ParamKeyType type;
|
||||||
@@ -42,6 +47,9 @@ struct ParamKeyAttributes {
|
|||||||
std::optional<std::string> stock_value = std::nullopt;
|
std::optional<std::string> stock_value = std::nullopt;
|
||||||
|
|
||||||
int tuning_level = 0;
|
int tuning_level = 0;
|
||||||
|
|
||||||
|
// Controls settings-page visibility only. It does not gate the param's runtime behavior.
|
||||||
|
ParamSettingsTier settings_tier = SETTINGS_ADVANCED;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Params {
|
class Params {
|
||||||
@@ -112,6 +120,8 @@ public:
|
|||||||
|
|
||||||
int getTuningLevel(const std::string &key);
|
int getTuningLevel(const std::string &key);
|
||||||
|
|
||||||
|
ParamSettingsTier getSettingsTier(const std::string &key);
|
||||||
|
|
||||||
std::optional<std::string> getStockValue(const std::string &key);
|
std::optional<std::string> getStockValue(const std::string &key);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -4,6 +4,27 @@ from enum import IntEnum, IntFlag
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
SETTINGS_SIMPLE = 0
|
||||||
|
SETTINGS_ADVANCED = 1
|
||||||
|
|
||||||
|
|
||||||
|
def _load_settings_tiers() -> dict[str, int]:
|
||||||
|
params_keys = Path(__file__).with_name("params_keys.h")
|
||||||
|
if not params_keys.exists():
|
||||||
|
return {}
|
||||||
|
|
||||||
|
tiers = {}
|
||||||
|
for line in params_keys.read_text(encoding="utf-8", errors="ignore").splitlines():
|
||||||
|
if not line.lstrip().startswith('{"'):
|
||||||
|
continue
|
||||||
|
parts = line.split('"')
|
||||||
|
if len(parts) >= 2:
|
||||||
|
tiers[parts[1]] = SETTINGS_SIMPLE if "SETTINGS_SIMPLE" in line else SETTINGS_ADVANCED
|
||||||
|
return tiers
|
||||||
|
|
||||||
|
|
||||||
|
_SETTINGS_TIERS = _load_settings_tiers()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from openpilot.common.params_pyx import Params as _Params, ParamKeyFlag, ParamKeyType, UnknownKeyName
|
from openpilot.common.params_pyx import Params as _Params, ParamKeyFlag, ParamKeyType, UnknownKeyName
|
||||||
except Exception:
|
except Exception:
|
||||||
@@ -180,6 +201,9 @@ except Exception:
|
|||||||
def get_tuning_level(self, key):
|
def get_tuning_level(self, key):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
def get_settings_tier(self, key):
|
||||||
|
return _SETTINGS_TIERS.get(self.check_key(key), SETTINGS_ADVANCED)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
assert _Params
|
assert _Params
|
||||||
assert ParamKeyFlag
|
assert ParamKeyFlag
|
||||||
@@ -187,6 +211,12 @@ else:
|
|||||||
assert UnknownKeyName
|
assert UnknownKeyName
|
||||||
|
|
||||||
class Params(_Params):
|
class Params(_Params):
|
||||||
|
def get_settings_tier(self, key):
|
||||||
|
try:
|
||||||
|
return super().get_settings_tier(key)
|
||||||
|
except AttributeError:
|
||||||
|
return _SETTINGS_TIERS.get(self.check_key(key), SETTINGS_ADVANCED)
|
||||||
|
|
||||||
def get(self, key, block=False, return_default=False, encoding=None, default=None):
|
def get(self, key, block=False, return_default=False, encoding=None, default=None):
|
||||||
try:
|
try:
|
||||||
value = super().get(key, block=block, return_default=return_default)
|
value = super().get(key, block=block, return_default=return_default)
|
||||||
|
|||||||
+307
-210
@@ -8,7 +8,7 @@
|
|||||||
inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
||||||
{"AccessToken", {CLEAR_ON_MANAGER_START | DONT_LOG, STRING}},
|
{"AccessToken", {CLEAR_ON_MANAGER_START | DONT_LOG, STRING}},
|
||||||
{"AdbEnabled", {PERSISTENT, BOOL}},
|
{"AdbEnabled", {PERSISTENT, BOOL}},
|
||||||
{"AlwaysAllowUploads", {PERSISTENT, BOOL, "0"}},
|
{"AlwaysAllowUploads", {PERSISTENT, BOOL, "0", std::nullopt, 0, SETTINGS_SIMPLE}},
|
||||||
{"AlwaysOnDM", {PERSISTENT, BOOL}},
|
{"AlwaysOnDM", {PERSISTENT, BOOL}},
|
||||||
{"ApiCache_Device", {PERSISTENT, STRING}},
|
{"ApiCache_Device", {PERSISTENT, STRING}},
|
||||||
{"AssistNowToken", {PERSISTENT, STRING}},
|
{"AssistNowToken", {PERSISTENT, STRING}},
|
||||||
@@ -16,10 +16,14 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"AthenadUploadQueue", {PERSISTENT, JSON}},
|
{"AthenadUploadQueue", {PERSISTENT, JSON}},
|
||||||
{"AthenadRecentlyViewedRoutes", {PERSISTENT, STRING}},
|
{"AthenadRecentlyViewedRoutes", {PERSISTENT, STRING}},
|
||||||
{"BootCount", {PERSISTENT, INT}},
|
{"BootCount", {PERSISTENT, INT}},
|
||||||
|
{"BluetoothAudioAddress", {PERSISTENT, STRING}},
|
||||||
|
{"BluetoothAudioTestActive", {CLEAR_ON_MANAGER_START | DONT_LOG, BOOL}},
|
||||||
|
{"BluetoothEnabled", {PERSISTENT, BOOL, "0"}},
|
||||||
{"CalibrationParams", {PERSISTENT, BYTES}},
|
{"CalibrationParams", {PERSISTENT, BYTES}},
|
||||||
{"CameraDebugExpGain", {CLEAR_ON_MANAGER_START, STRING}},
|
{"CameraDebugExpGain", {CLEAR_ON_MANAGER_START, STRING}},
|
||||||
{"CameraDebugExpTime", {CLEAR_ON_MANAGER_START, STRING}},
|
{"CameraDebugExpTime", {CLEAR_ON_MANAGER_START, STRING}},
|
||||||
{"CarBatteryCapacity", {PERSISTENT, INT}},
|
{"CarBatteryCapacity", {PERSISTENT, INT}},
|
||||||
|
{"CarGpsAvailable", {CLEAR_ON_MANAGER_START, BOOL}},
|
||||||
{"CarParams", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, BYTES}},
|
{"CarParams", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, BYTES}},
|
||||||
{"CarParamsCache", {CLEAR_ON_MANAGER_START, BYTES}},
|
{"CarParamsCache", {CLEAR_ON_MANAGER_START, BYTES}},
|
||||||
{"CarParamsPersistent", {PERSISTENT, BYTES}},
|
{"CarParamsPersistent", {PERSISTENT, BYTES}},
|
||||||
@@ -36,14 +40,16 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"DoReboot", {CLEAR_ON_MANAGER_START, BOOL}},
|
{"DoReboot", {CLEAR_ON_MANAGER_START, BOOL}},
|
||||||
{"DoShutdown", {CLEAR_ON_MANAGER_START, BOOL}},
|
{"DoShutdown", {CLEAR_ON_MANAGER_START, BOOL}},
|
||||||
{"DoUninstall", {CLEAR_ON_MANAGER_START, BOOL}},
|
{"DoUninstall", {CLEAR_ON_MANAGER_START, BOOL}},
|
||||||
|
{"DoUserReboot", {CLEAR_ON_MANAGER_START, BOOL}},
|
||||||
{"DriverTooDistracted", {CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON, BOOL}},
|
{"DriverTooDistracted", {CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON, BOOL}},
|
||||||
|
{"DriverLockoutCount", {CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON, INT, "0"}},
|
||||||
{"EcuDisableFailed", {CLEAR_ON_MANAGER_START, BOOL}},
|
{"EcuDisableFailed", {CLEAR_ON_MANAGER_START, BOOL}},
|
||||||
{"AlphaLongitudinalEnabled", {PERSISTENT, BOOL}},
|
{"AlphaLongitudinalEnabled", {PERSISTENT, BOOL}},
|
||||||
{"ExperimentalLongitudinalEnabled", {PERSISTENT, BOOL}},
|
{"ExperimentalLongitudinalEnabled", {PERSISTENT, BOOL}},
|
||||||
{"ExperimentalMode", {PERSISTENT, BOOL}},
|
{"ExperimentalMode", {PERSISTENT, BOOL}},
|
||||||
{"ExperimentalModeConfirmed", {PERSISTENT, BOOL}},
|
{"ExperimentalModeConfirmed", {PERSISTENT, BOOL}},
|
||||||
{"PersistChillState", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"PersistChillState", {PERSISTENT, BOOL, "0", "0", 1}},
|
||||||
{"PersistExperimentalState", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"PersistExperimentalState", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"PersistedCCStatus", {PERSISTENT, INT, "0", "0"}},
|
{"PersistedCCStatus", {PERSISTENT, INT, "0", "0"}},
|
||||||
{"PersistedCEStatus", {PERSISTENT, INT, "0", "0"}},
|
{"PersistedCEStatus", {PERSISTENT, INT, "0", "0"}},
|
||||||
{"FirmwareQueryDone", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, BOOL}},
|
{"FirmwareQueryDone", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, BOOL}},
|
||||||
@@ -56,26 +62,32 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"GithubUsername", {PERSISTENT, STRING}},
|
{"GithubUsername", {PERSISTENT, STRING}},
|
||||||
{"GitRemote", {PERSISTENT, STRING}},
|
{"GitRemote", {PERSISTENT, STRING}},
|
||||||
{"GsmApn", {PERSISTENT, STRING}},
|
{"GsmApn", {PERSISTENT, STRING}},
|
||||||
{"GsmMetered", {PERSISTENT, BOOL, "1"}},
|
{"GsmMetered", {PERSISTENT, BOOL, "1", std::nullopt, 0, SETTINGS_SIMPLE}},
|
||||||
{"GsmRoaming", {PERSISTENT, BOOL}},
|
{"GsmRoaming", {PERSISTENT, BOOL}},
|
||||||
{"HardwareSerial", {PERSISTENT, STRING}},
|
{"HardwareSerial", {PERSISTENT, STRING}},
|
||||||
{"HasAcceptedTerms", {PERSISTENT, STRING, "0"}},
|
{"HasAcceptedTerms", {PERSISTENT, STRING, "0"}},
|
||||||
|
// Internal kill switch; the platform verification allowlist remains the hard safety gate.
|
||||||
|
{"HondaBoschARadar", {PERSISTENT, BOOL, "1"}},
|
||||||
{"HondaGasFactorParams", {PERSISTENT, FLOAT}},
|
{"HondaGasFactorParams", {PERSISTENT, FLOAT}},
|
||||||
|
{"HondaLateralPidKiScale", {PERSISTENT, FLOAT, "1.0", "1.0", 3}},
|
||||||
|
{"HondaLateralPidKpScale", {PERSISTENT, FLOAT, "1.0", "1.0", 3}},
|
||||||
{"HondaWindFactorParams", {PERSISTENT, FLOAT}},
|
{"HondaWindFactorParams", {PERSISTENT, FLOAT}},
|
||||||
{"InstallDate", {PERSISTENT, TIME}},
|
{"InstallDate", {PERSISTENT, TIME}},
|
||||||
{"IsDriverViewEnabled", {CLEAR_ON_MANAGER_START, BOOL}},
|
{"IsDriverViewEnabled", {CLEAR_ON_MANAGER_START, BOOL}},
|
||||||
{"IsEngaged", {PERSISTENT, BOOL}},
|
{"IsEngaged", {PERSISTENT, BOOL}},
|
||||||
{"IsLdwEnabled", {PERSISTENT, BOOL}},
|
{"IsLdwEnabled", {PERSISTENT, BOOL}},
|
||||||
|
{"IsLiveStreaming", {CLEAR_ON_MANAGER_START, BOOL}},
|
||||||
{"IsMetric", {PERSISTENT, BOOL}},
|
{"IsMetric", {PERSISTENT, BOOL}},
|
||||||
{"IsOffroad", {CLEAR_ON_MANAGER_START, BOOL}},
|
{"IsOffroad", {CLEAR_ON_MANAGER_START, BOOL}},
|
||||||
{"IsOnroad", {PERSISTENT, BOOL}},
|
{"IsOnroad", {PERSISTENT, BOOL}},
|
||||||
{"IsRHD", {PERSISTENT, BOOL}},
|
{"IsRHD", {PERSISTENT, BOOL, std::nullopt, std::nullopt, 0, SETTINGS_SIMPLE}},
|
||||||
{"IsRhdDetected", {PERSISTENT, BOOL}},
|
{"IsRhdDetected", {PERSISTENT, BOOL}},
|
||||||
{"IsRHDOverride", {PERSISTENT, BOOL}},
|
{"IsRHDOverride", {PERSISTENT, BOOL}},
|
||||||
{"IsReleaseBranch", {CLEAR_ON_MANAGER_START, BOOL}},
|
{"IsReleaseBranch", {CLEAR_ON_MANAGER_START, BOOL}},
|
||||||
{"IsTakingSnapshot", {CLEAR_ON_MANAGER_START, BOOL}},
|
{"IsTakingSnapshot", {CLEAR_ON_MANAGER_START, BOOL}},
|
||||||
{"IsTestedBranch", {CLEAR_ON_MANAGER_START, BOOL}},
|
{"IsTestedBranch", {CLEAR_ON_MANAGER_START, BOOL}},
|
||||||
{"JoystickDebugMode", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, BOOL}},
|
{"JoystickDebugMode", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, BOOL}},
|
||||||
|
{"JoystickControlDevice", {PERSISTENT, STRING}},
|
||||||
{"LanguageSetting", {PERSISTENT, STRING, "main_en"}},
|
{"LanguageSetting", {PERSISTENT, STRING, "main_en"}},
|
||||||
{"LastAthenaPingTime", {CLEAR_ON_MANAGER_START, INT}},
|
{"LastAthenaPingTime", {CLEAR_ON_MANAGER_START, INT}},
|
||||||
{"LastGPSPosition", {PERSISTENT, STRING}},
|
{"LastGPSPosition", {PERSISTENT, STRING}},
|
||||||
@@ -90,6 +102,8 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"LiveDelay", {PERSISTENT, BYTES}},
|
{"LiveDelay", {PERSISTENT, BYTES}},
|
||||||
{"LiveParameters", {PERSISTENT, JSON}},
|
{"LiveParameters", {PERSISTENT, JSON}},
|
||||||
{"LiveParametersV2", {PERSISTENT, BYTES}},
|
{"LiveParametersV2", {PERSISTENT, BYTES}},
|
||||||
|
{"LivestreamEncoderBitrate", {CLEAR_ON_MANAGER_START | DONT_LOG, INT}},
|
||||||
|
{"LivestreamRequestKeyframe", {CLEAR_ON_MANAGER_START | DONT_LOG, BOOL}},
|
||||||
{"LiveTorqueParameters", {PERSISTENT | DONT_LOG, BYTES}},
|
{"LiveTorqueParameters", {PERSISTENT | DONT_LOG, BYTES}},
|
||||||
{"LateralManeuverMode", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, BOOL}},
|
{"LateralManeuverMode", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, BOOL}},
|
||||||
{"LocationFilterInitialState", {PERSISTENT, BYTES}},
|
{"LocationFilterInitialState", {PERSISTENT, BYTES}},
|
||||||
@@ -121,6 +135,14 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"RecordAudioFeedback", {PERSISTENT, BOOL, "0"}},
|
{"RecordAudioFeedback", {PERSISTENT, BOOL, "0"}},
|
||||||
{"RecordFront", {PERSISTENT, BOOL}},
|
{"RecordFront", {PERSISTENT, BOOL}},
|
||||||
{"RecordFrontLock", {PERSISTENT, BOOL}}, // for the internal fleet
|
{"RecordFrontLock", {PERSISTENT, BOOL}}, // for the internal fleet
|
||||||
|
{"SentryModeEnabled", {PERSISTENT, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
|
{"SentryModeCapture", {CLEAR_ON_MANAGER_START, BOOL}},
|
||||||
|
{"SentryModeLastEvent", {PERSISTENT, JSON, "{}", "{}"}},
|
||||||
|
{"SentryModeNtfyUrl", {PERSISTENT, STRING}},
|
||||||
|
{"SentryModeSensitivity", {PERSISTENT, FLOAT, "0.04", "0.04", 0, SETTINGS_SIMPLE}},
|
||||||
|
{"SentryModeStatus", {CLEAR_ON_MANAGER_START | DONT_LOG, JSON}},
|
||||||
|
{"SentryModeWarningTime", {PERSISTENT, FLOAT, "1.0", "1.0", 0, SETTINGS_SIMPLE}},
|
||||||
|
{"SentryModeWebhook", {PERSISTENT, STRING}},
|
||||||
{"SecOCKey", {PERSISTENT | DONT_LOG, STRING}},
|
{"SecOCKey", {PERSISTENT | DONT_LOG, STRING}},
|
||||||
{"ShowDebugInfo", {PERSISTENT, BOOL}},
|
{"ShowDebugInfo", {PERSISTENT, BOOL}},
|
||||||
{"ShowAllToggles", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"ShowAllToggles", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
@@ -144,15 +166,19 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"UpdaterLastFetchTime", {PERSISTENT, TIME}},
|
{"UpdaterLastFetchTime", {PERSISTENT, TIME}},
|
||||||
{"UptimeOffroad", {PERSISTENT, FLOAT, "0.0"}},
|
{"UptimeOffroad", {PERSISTENT, FLOAT, "0.0"}},
|
||||||
{"UptimeOnroad", {PERSISTENT, FLOAT, "0.0"}},
|
{"UptimeOnroad", {PERSISTENT, FLOAT, "0.0"}},
|
||||||
|
{"UsbGpuActive", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, BOOL}},
|
||||||
|
{"UsbGpuCompiled", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, BOOL}},
|
||||||
|
{"UsbGpuLoading", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, BOOL}},
|
||||||
|
{"UsbGpuPresent", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, BOOL}},
|
||||||
{"Version", {PERSISTENT, STRING}},
|
{"Version", {PERSISTENT, STRING}},
|
||||||
|
|
||||||
// StarPilot variables
|
// StarPilot variables
|
||||||
{"AccelerationPath", {PERSISTENT, BOOL, "1", "0", 2}},
|
{"AccelerationPath", {PERSISTENT, BOOL, "1", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"AccelerationProfile", {PERSISTENT, INT, "0", "0", 0}},
|
{"AccelerationProfile", {PERSISTENT, INT, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"AdjacentLeadsUI", {PERSISTENT, BOOL, "1", "0", 3}},
|
{"AdjacentLeadsUI", {PERSISTENT, BOOL, "1", "0", 3}},
|
||||||
{"AdjacentPath", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"AdjacentPath", {PERSISTENT, BOOL, "0", "0", 3, SETTINGS_SIMPLE}},
|
||||||
{"AdjacentPathMetrics", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"AdjacentPathMetrics", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"AdvancedCustomUI", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"AdvancedCustomUI", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"AdvancedLateralTune", {PERSISTENT, BOOL, "1", "0", 2}},
|
{"AdvancedLateralTune", {PERSISTENT, BOOL, "1", "0", 2}},
|
||||||
{"AdvancedLongitudinalTune", {PERSISTENT, BOOL, "1", "0", 3}},
|
{"AdvancedLongitudinalTune", {PERSISTENT, BOOL, "1", "0", 3}},
|
||||||
{"AggressiveFollow", {PERSISTENT, FLOAT, "1.25", "1.25", 2}},
|
{"AggressiveFollow", {PERSISTENT, FLOAT, "1.25", "1.25", 2}},
|
||||||
@@ -162,13 +188,14 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"AggressiveJerkDeceleration", {PERSISTENT, FLOAT, "50.0", "50.0", 3}},
|
{"AggressiveJerkDeceleration", {PERSISTENT, FLOAT, "50.0", "50.0", 3}},
|
||||||
{"AggressiveJerkSpeed", {PERSISTENT, FLOAT, "50.0", "50.0", 3}},
|
{"AggressiveJerkSpeed", {PERSISTENT, FLOAT, "50.0", "50.0", 3}},
|
||||||
{"AggressiveJerkSpeedDecrease", {PERSISTENT, FLOAT, "50.0", "50.0", 3}},
|
{"AggressiveJerkSpeedDecrease", {PERSISTENT, FLOAT, "50.0", "50.0", 3}},
|
||||||
{"AlertVolumeControl", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"AlertVolumeControl", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"AllowImpossibleAcceleration", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"AllowImpossibleAcceleration", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"AlwaysOnLateral", {PERSISTENT, BOOL, "1", "0", 0}},
|
{"AlwaysOnLateral", {PERSISTENT, BOOL, "1", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"AlwaysOnLateralLKAS", {PERSISTENT, BOOL, "1", "0", 2}},
|
{"AlwaysOnLateralLKAS", {PERSISTENT, BOOL, "1", "0", 2}},
|
||||||
{"ApiCache_DriveStats", {PERSISTENT, JSON, "{}", "{}"}},
|
{"ApiCache_DriveStats", {PERSISTENT, JSON, "{}", "{}"}},
|
||||||
{"AutomaticallyDownloadModels", {PERSISTENT, BOOL, "1", "0", 1}},
|
{"AutomaticallyDownloadModels", {PERSISTENT, BOOL, "1", "0", 1}},
|
||||||
{"AutomaticUpdates", {PERSISTENT, BOOL, "1", "1", 0}},
|
{"AutomaticUpdates", {PERSISTENT, BOOL, "1", "1", 0}},
|
||||||
|
{"AllowGpuModelDownloadWithoutGpu", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
||||||
{"AvailableModelNames", {PERSISTENT, STRING, "", "", 1}},
|
{"AvailableModelNames", {PERSISTENT, STRING, "", "", 1}},
|
||||||
{"AvailableModelSeries", {PERSISTENT, STRING, "", "", 1}},
|
{"AvailableModelSeries", {PERSISTENT, STRING, "", "", 1}},
|
||||||
{"AvailableModels", {PERSISTENT, STRING, "", "", 1}},
|
{"AvailableModels", {PERSISTENT, STRING, "", "", 1}},
|
||||||
@@ -177,30 +204,31 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"BootLogo", {PERSISTENT, STRING, "starpilot", "stock", 0}},
|
{"BootLogo", {PERSISTENT, STRING, "starpilot", "stock", 0}},
|
||||||
{"BuildMetadata", {PERSISTENT, STRING, "", "", 0}},
|
{"BuildMetadata", {PERSISTENT, STRING, "", "", 0}},
|
||||||
{"BlindSpotMetrics", {PERSISTENT, BOOL, "1", "0", 3}},
|
{"BlindSpotMetrics", {PERSISTENT, BOOL, "1", "0", 3}},
|
||||||
{"BlindSpotPath", {PERSISTENT, BOOL, "1", "0", 1}},
|
{"BlindSpotPath", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"BelowSteerSpeedVolume", {PERSISTENT, INT, "101", "101", 2}},
|
{"BelowSteerSpeedVolume", {PERSISTENT, INT, "101", "101", 2, SETTINGS_SIMPLE}},
|
||||||
{"BorderMetrics", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"BorderMetrics", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"BorderWidth", {PERSISTENT, FLOAT, "100.0", "100.0", 2}},
|
{"BorderWidth", {PERSISTENT, FLOAT, "100.0", "100.0", 2, SETTINGS_SIMPLE}},
|
||||||
{"CalibratedLateralAcceleration", {PERSISTENT, FLOAT, "2.0", "2.0", 2}},
|
{"CalibratedLateralAcceleration", {PERSISTENT, FLOAT, "2.0", "2.0", 2}},
|
||||||
{"CalibrationProgress", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
{"CalibrationProgress", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
{"CameraOffset", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
{"CameraOffset", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
{"CameraView", {PERSISTENT, INT, "3", "0", 2}},
|
{"CameraView", {PERSISTENT, INT, "2", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"CancelDownloadMaps", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
{"CancelDownloadMaps", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
||||||
{"DisableWideRoad", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"DisableWideRoad", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"CancelModelDownload", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
{"CancelModelDownload", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
||||||
{"CancelThemeDownload", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
{"CancelThemeDownload", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
||||||
{"CarMake", {PERSISTENT, STRING, "mock", "mock", 0}},
|
{"CarMake", {PERSISTENT, STRING, "mock", "mock", 0, SETTINGS_SIMPLE}},
|
||||||
{"CarModel", {PERSISTENT, STRING, "MOCK", "MOCK", 0}},
|
{"CarModel", {PERSISTENT, STRING, "MOCK", "MOCK", 0, SETTINGS_SIMPLE}},
|
||||||
{"CarModelName", {PERSISTENT, STRING, "", "", 0}},
|
{"CarModelName", {PERSISTENT, STRING, "", "", 0}},
|
||||||
{"CECurves", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"CECurves", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"CECurvesLead", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"CECurvesLead", {PERSISTENT, BOOL, "0", "0", 1}},
|
||||||
{"CELead", {PERSISTENT, BOOL, "1", "0", 1}},
|
{"CELead", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"CEModelStopTime", {PERSISTENT, FLOAT, "7.0", "0.0", 2}},
|
{"CEModelStopTime", {PERSISTENT, FLOAT, "7.7", "0.0", 2, SETTINGS_SIMPLE}},
|
||||||
|
{"CEOpenRoad", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"CESignalLaneDetection", {PERSISTENT, BOOL, "1", "0", 2}},
|
{"CESignalLaneDetection", {PERSISTENT, BOOL, "1", "0", 2}},
|
||||||
{"CESignalSpeed", {PERSISTENT, FLOAT, "0.0", "0.0", 2}},
|
{"CESignalSpeed", {PERSISTENT, FLOAT, "0.0", "0.0", 2, SETTINGS_SIMPLE}},
|
||||||
{"CESlowerLead", {PERSISTENT, BOOL, "1", "0", 1}},
|
{"CESlowerLead", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"CESpeed", {PERSISTENT, FLOAT, "0.0", "0.0", 1}},
|
{"CESpeed", {PERSISTENT, FLOAT, "0.0", "0.0", 1, SETTINGS_SIMPLE}},
|
||||||
{"CESpeedLead", {PERSISTENT, FLOAT, "0.0", "0.0", 1}},
|
{"CESpeedLead", {PERSISTENT, FLOAT, "0.0", "0.0", 1, SETTINGS_SIMPLE}},
|
||||||
{"CCMLead", {PERSISTENT, BOOL, "1", "0", 1}},
|
{"CCMLead", {PERSISTENT, BOOL, "1", "0", 1}},
|
||||||
{"CCMLaunchAssist", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"CCMLaunchAssist", {PERSISTENT, BOOL, "0", "0", 1}},
|
||||||
{"CCMSetSpeedMargin", {PERSISTENT, FLOAT, "3.0", "0.0", 1}},
|
{"CCMSetSpeedMargin", {PERSISTENT, FLOAT, "3.0", "0.0", 1}},
|
||||||
@@ -208,19 +236,20 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"CCMSpeedLead", {PERSISTENT, FLOAT, "35.0", "0.0", 1}},
|
{"CCMSpeedLead", {PERSISTENT, FLOAT, "35.0", "0.0", 1}},
|
||||||
{"CCStatus", {CLEAR_ON_OFFROAD_TRANSITION, INT, "0", "0"}},
|
{"CCStatus", {CLEAR_ON_OFFROAD_TRANSITION, INT, "0", "0"}},
|
||||||
{"CEStatus", {CLEAR_ON_OFFROAD_TRANSITION, INT, "0", "0"}},
|
{"CEStatus", {CLEAR_ON_OFFROAD_TRANSITION, INT, "0", "0"}},
|
||||||
{"CEStopLights", {PERSISTENT, BOOL, "1", "0", 1}},
|
{"CEStopLights", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"CEStoppedLead", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"CEStoppedLead", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"ClusterOffset", {PERSISTENT, FLOAT, "1.0", "1.0", 2}},
|
{"ClusterOffset", {PERSISTENT, FLOAT, "1.0", "1.0", 2, SETTINGS_SIMPLE}},
|
||||||
{"ColorScheme", {PERSISTENT, STRING, "stock", "stock", 0}},
|
{"ColorScheme", {PERSISTENT, STRING, "stock", "stock", 0}},
|
||||||
{"ColorToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
{"ColorToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
||||||
{"BootLogoToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
{"BootLogoToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
||||||
{"Compass", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"Compass", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"CommunityFavorites", {PERSISTENT, STRING, "", "", 1}},
|
{"CommunityFavorites", {PERSISTENT, STRING, "", "", 1}},
|
||||||
{"ConditionalChill", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"ConditionalChill", {PERSISTENT, BOOL, "0", "0", 1}},
|
||||||
{"ConditionalExperimental", {PERSISTENT, BOOL, "1", "0", 1}},
|
{"ConditionalExperimental", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"CurvatureData", {PERSISTENT | DONT_LOG, JSON, "{}", "{}"}},
|
{"CurvatureData", {PERSISTENT | DONT_LOG, JSON, "{}", "{}"}},
|
||||||
{"CurveSpeedController", {PERSISTENT, BOOL, "1", "0", 1}},
|
{"CurveSpeedController", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"CustomAlerts", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"CurveSpeedControllerNoLead", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}},
|
||||||
|
{"CustomAlerts", {PERSISTENT, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"CustomAccelProfile", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"CustomAccelProfile", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"CustomAccelProfileInitialized", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"CustomAccelProfileInitialized", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"CustomAccelProfile0MPH", {PERSISTENT, FLOAT, "3.0", "3.0", 3}},
|
{"CustomAccelProfile0MPH", {PERSISTENT, FLOAT, "3.0", "3.0", 3}},
|
||||||
@@ -230,10 +259,10 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"CustomAccelProfile45MPH", {PERSISTENT, FLOAT, "1.0", "1.0", 3}},
|
{"CustomAccelProfile45MPH", {PERSISTENT, FLOAT, "1.0", "1.0", 3}},
|
||||||
{"CustomAccelProfile56MPH", {PERSISTENT, FLOAT, "0.8", "0.8", 3}},
|
{"CustomAccelProfile56MPH", {PERSISTENT, FLOAT, "0.8", "0.8", 3}},
|
||||||
{"CustomAccelProfile89MPH", {PERSISTENT, FLOAT, "0.6", "0.6", 3}},
|
{"CustomAccelProfile89MPH", {PERSISTENT, FLOAT, "0.6", "0.6", 3}},
|
||||||
{"CustomCruise", {PERSISTENT, FLOAT, "1.0", "1.0", 2}},
|
{"CustomCruise", {PERSISTENT, FLOAT, "1.0", "1.0", 2, SETTINGS_SIMPLE}},
|
||||||
{"CustomCruiseLong", {PERSISTENT, FLOAT, "5.0", "5.0", 2}},
|
{"CustomCruiseLong", {PERSISTENT, FLOAT, "5.0", "5.0", 2, SETTINGS_SIMPLE}},
|
||||||
{"CustomPersonalities", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"CustomPersonalities", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||||
{"CancelButtonControl", {PERSISTENT, INT, "1", "0", 2}},
|
{"CancelButtonControl", {PERSISTENT, INT, "1", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"CancelButtonControlsMigrated", {PERSISTENT, BOOL, "0", "0"}},
|
{"CancelButtonControlsMigrated", {PERSISTENT, BOOL, "0", "0"}},
|
||||||
{"AOLLKASMigratedToButtonControl", {PERSISTENT, BOOL, "0", "0"}},
|
{"AOLLKASMigratedToButtonControl", {PERSISTENT, BOOL, "0", "0"}},
|
||||||
{"TrafficPersonalityProfile", {PERSISTENT, BOOL, "1", "1", 2}},
|
{"TrafficPersonalityProfile", {PERSISTENT, BOOL, "1", "1", 2}},
|
||||||
@@ -241,9 +270,9 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"StandardPersonalityProfile", {PERSISTENT, BOOL, "1", "1", 2}},
|
{"StandardPersonalityProfile", {PERSISTENT, BOOL, "1", "1", 2}},
|
||||||
{"RelaxedPersonalityProfile", {PERSISTENT, BOOL, "1", "1", 2}},
|
{"RelaxedPersonalityProfile", {PERSISTENT, BOOL, "1", "1", 2}},
|
||||||
{"CustomThemes", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"CustomThemes", {PERSISTENT, BOOL, "0", "0", 0}},
|
||||||
{"CustomUI", {PERSISTENT, BOOL, "1", "0", 1}},
|
{"CustomUI", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"DebugMode", {CLEAR_ON_OFFROAD_TRANSITION, BOOL, "0", "0"}},
|
{"DebugMode", {CLEAR_ON_OFFROAD_TRANSITION, BOOL, "0", "0"}},
|
||||||
{"DecelerationProfile", {PERSISTENT, INT, "1", "0", 2}},
|
{"DecelerationProfile", {PERSISTENT, INT, "1", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"DeveloperMetrics", {PERSISTENT, BOOL, "1", "0", 3}},
|
{"DeveloperMetrics", {PERSISTENT, BOOL, "1", "0", 3}},
|
||||||
{"DeveloperSidebar", {PERSISTENT, BOOL, "1", "0", 3}},
|
{"DeveloperSidebar", {PERSISTENT, BOOL, "1", "0", 3}},
|
||||||
{"DeveloperSidebarMetric1", {PERSISTENT, INT, "1", "0", 3}},
|
{"DeveloperSidebarMetric1", {PERSISTENT, INT, "1", "0", 3}},
|
||||||
@@ -254,14 +283,15 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"DeveloperSidebarMetric6", {PERSISTENT, INT, "6", "0", 3}},
|
{"DeveloperSidebarMetric6", {PERSISTENT, INT, "6", "0", 3}},
|
||||||
{"DeveloperSidebarMetric7", {PERSISTENT, INT, "7", "0", 3}},
|
{"DeveloperSidebarMetric7", {PERSISTENT, INT, "7", "0", 3}},
|
||||||
{"DeveloperUI", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"DeveloperUI", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
|
{"GalaxyDeveloperMode", {PERSISTENT | DONT_LOG, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"DeveloperWidgets", {PERSISTENT, BOOL, "1", "0", 3}},
|
{"DeveloperWidgets", {PERSISTENT, BOOL, "1", "0", 3}},
|
||||||
{"DeviceManagement", {PERSISTENT, BOOL, "1", "0", 1}},
|
{"DeviceManagement", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"DeviceShutdown", {PERSISTENT, INT, "9", "33", 1}},
|
{"DeviceShutdown", {PERSISTENT, INT, "6", "6", 1, SETTINGS_SIMPLE}},
|
||||||
{"DisableOnroadUploads", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"DisableOnroadUploads", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"DisableOpenpilotLongitudinal", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"DisableOpenpilotLongitudinal", {PERSISTENT, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"DiscordUsername", {PERSISTENT, STRING, "", "", 0}},
|
{"DiscordUsername", {PERSISTENT, STRING, "", "", 0}},
|
||||||
{"DisengageVolume", {PERSISTENT, INT, "101", "101", 2}},
|
{"DisengageVolume", {PERSISTENT, INT, "101", "101", 2, SETTINGS_SIMPLE}},
|
||||||
{"DistanceButtonControl", {PERSISTENT, INT, "1", "0", 2}},
|
{"DistanceButtonControl", {PERSISTENT, INT, "1", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"DistanceIconPack", {PERSISTENT, STRING, "stock", "stock", 0}},
|
{"DistanceIconPack", {PERSISTENT, STRING, "stock", "stock", 0}},
|
||||||
{"DistanceIconToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
{"DistanceIconToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
||||||
{"DownloadableBootLogos", {PERSISTENT, STRING, "", ""}},
|
{"DownloadableBootLogos", {PERSISTENT, STRING, "", ""}},
|
||||||
@@ -273,121 +303,149 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"DownloadableWheels", {PERSISTENT, STRING, "", ""}},
|
{"DownloadableWheels", {PERSISTENT, STRING, "", ""}},
|
||||||
{"DownloadAllModels", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
{"DownloadAllModels", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
||||||
{"DownloadMaps", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
{"DownloadMaps", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
||||||
{"DriverCamera", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"DriverCamera", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"Model", {PERSISTENT, STRING, "sc2", "sc2", 1}},
|
{"Model", {PERSISTENT, STRING, "rdf43", "rdf43", 1}},
|
||||||
{"ModelVersion", {PERSISTENT, STRING, "v11", "v11", 1}},
|
{"ModelVersion", {PERSISTENT, STRING, "v15", "v15", 1}},
|
||||||
{"DrivingModel", {PERSISTENT, STRING, "sc2", "sc2", 1}},
|
{"DrivingModel", {PERSISTENT, STRING, "rdf43", "rdf43", 1}},
|
||||||
{"DrivingModelName", {PERSISTENT, STRING, "South Carolina", "South Carolina", 1}},
|
{"DrivingModelName", {PERSISTENT, STRING, "Regret Driven Framework V4", "Regret Driven Framework V4", 1}},
|
||||||
{"DrivingModelVersion", {PERSISTENT, STRING, "v11", "v11", 1}},
|
{"DrivingModelVersion", {PERSISTENT, STRING, "v15", "v15", 1}},
|
||||||
{"DynamicPathWidth", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"DynamicPathWidth", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"DynamicPedalsOnUI", {PERSISTENT, BOOL, "1", "0", 1}},
|
{"DynamicPedalsOnUI", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"EngageVolume", {PERSISTENT, INT, "101", "101", 2}},
|
{"EngageVolume", {PERSISTENT, INT, "101", "101", 2, SETTINGS_SIMPLE}},
|
||||||
{"EVTuning", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"EVTuning", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"Fahrenheit", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"Fahrenheit", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"FlashPanda", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
{"FlashPanda", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
||||||
{"GMDashSpoofOffsets", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"GMDashSpoofOffsets", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"GMPedalLongitudinal", {PERSISTENT, BOOL, "1", "1", 2}},
|
{"GMPedalLongitudinal", {PERSISTENT, BOOL, "1", "1", 2, SETTINGS_SIMPLE}},
|
||||||
{"IgnoreIgnitionLine", {PERSISTENT, BOOL, "0", "0"}},
|
{"HKGRemoteStartBootsComma", {PERSISTENT, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"LongPitch", {PERSISTENT, BOOL, "1", "0", 2}},
|
{"IgnoreIgnitionLine", {PERSISTENT, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"RemoteStartBootsComma", {PERSISTENT, BOOL, "0", "0"}},
|
{"LongPitch", {PERSISTENT, BOOL, "1", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"RemapCancelToDistance", {PERSISTENT, BOOL, "0", "0"}},
|
{"RemoteStartBootsComma", {PERSISTENT, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"NAPAdaptiveAccel", {PERSISTENT, BOOL, "1", "1"}},
|
{"RemapCancelToDistance", {PERSISTENT, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
|
{"NAPAdaptiveAccel", {PERSISTENT, BOOL, "1", "1", 0, SETTINGS_SIMPLE}},
|
||||||
{"NAPFollowDistance", {PERSISTENT, INT, "4", "4"}},
|
{"NAPFollowDistance", {PERSISTENT, INT, "4", "4"}},
|
||||||
{"NAPForcePreAP", {PERSISTENT, BOOL, "0", "0"}},
|
{"NAPForcePreAP", {PERSISTENT, BOOL, "0", "0"}},
|
||||||
{"NAPPedalEnabled", {PERSISTENT, BOOL, "0", "0"}},
|
{"NAPPedalEnabled", {PERSISTENT, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"NAPPedalCanBus", {PERSISTENT, INT, "2", "2"}},
|
{"NAPPedalCanBus", {PERSISTENT, INT, "2", "2", 0, SETTINGS_SIMPLE}},
|
||||||
{"NAPPedalCalibDone", {PERSISTENT, BOOL, "0", "0"}},
|
{"NAPPedalCalibDone", {PERSISTENT, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"NAPPedalCalibMin", {PERSISTENT, FLOAT, "-3.0", "-3.0"}},
|
{"NAPPedalCalibMin", {PERSISTENT, FLOAT, "-3.0", "-3.0"}},
|
||||||
{"NAPPedalCalibMax", {PERSISTENT, FLOAT, "99.6", "99.6"}},
|
{"NAPPedalCalibMax", {PERSISTENT, FLOAT, "99.6", "99.6"}},
|
||||||
{"NAPPedalCalibFactor", {PERSISTENT, FLOAT, "1.0", "1.0"}},
|
{"NAPPedalCalibFactor", {PERSISTENT, FLOAT, "1.0", "1.0", 0, SETTINGS_SIMPLE}},
|
||||||
{"NAPPedalCalibZero", {PERSISTENT, FLOAT, "0.0", "0.0"}},
|
{"NAPPedalCalibZero", {PERSISTENT, FLOAT, "0.0", "0.0", 0, SETTINGS_SIMPLE}},
|
||||||
{"NAPPedalProfile", {PERSISTENT, INT, "4", "4"}},
|
{"NAPPedalProfile", {PERSISTENT, INT, "4", "4"}},
|
||||||
{"NAPRadarBehindNosecone", {PERSISTENT, BOOL, "0", "0"}},
|
{"NAPRadarBehindNosecone", {PERSISTENT, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"NAPRadarEnabled", {PERSISTENT, BOOL, "0", "0"}},
|
{"NAPRadarEnabled", {PERSISTENT, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"NAPRadarOffset", {PERSISTENT, FLOAT, "0.0", "0.0"}},
|
{"NAPRadarOffset", {PERSISTENT, FLOAT, "0.0", "0.0", 0, SETTINGS_SIMPLE}},
|
||||||
{"ForceAutoTune", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"ForceAutoTune", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"ForceAutoTuneOff", {PERSISTENT, BOOL, "1", "0", 2}},
|
{"ForceAutoTuneOff", {PERSISTENT, BOOL, "1", "0", 2}},
|
||||||
{"ForceFingerprint", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"ForceFingerprint", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"ForceOffroad", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
{"ForceOffroad", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
||||||
{"ForceOnroad", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
{"ForceOnroad", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
||||||
{"ForceStops", {PERSISTENT, BOOL, "1", "0", 2}},
|
{"ForceStops", {PERSISTENT, BOOL, "1", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"ForceStopDistanceOffset", {PERSISTENT, INT, "0", "0", 2}},
|
{"ForceStopDistanceOffset", {PERSISTENT, INT, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"ForceStandstill", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"ForceStandstill", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
|
{"FordLKASButtonControlMigrated", {PERSISTENT, BOOL, "0", "0"}},
|
||||||
{"ForceTorqueController", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"ForceTorqueController", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"FPSCounter", {PERSISTENT, BOOL, "1", "0", 3}},
|
{"FordAngleBlend", {PERSISTENT, FLOAT, "0.5", "0.5", 2}},
|
||||||
|
{"FordAngleHighSpeedDamping", {PERSISTENT, FLOAT, "1.0", "1.0", 2}},
|
||||||
|
{"FordAngleHighSpeedFactor", {PERSISTENT, FLOAT, "1.0", "1.0", 2}},
|
||||||
|
{"FordAngleLaneChangeFactor", {PERSISTENT, FLOAT, "1.0", "1.0", 2}},
|
||||||
|
{"FordAngleLowSpeedFactor", {PERSISTENT, FLOAT, "1.0", "1.0", 2}},
|
||||||
|
{"FordCurvatureBlendHigh", {PERSISTENT, FLOAT, "0.4", "0.4", 2}},
|
||||||
|
{"FordCurvatureBlendLow", {PERSISTENT, FLOAT, "0.4", "0.4", 2}},
|
||||||
|
{"FordCurvatureLaneChangeFactor", {PERSISTENT, FLOAT, "0.85", "0.85", 2}},
|
||||||
|
{"FordHandsFreeCluster", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||||
|
{"FordHumanTurnDetection", {PERSISTENT, BOOL, "1", "1", 2}},
|
||||||
|
{"FordLateralMode", {PERSISTENT, INT, "1", "1", 2}},
|
||||||
|
{"FLMActiveOverrides", {PERSISTENT, JSON, "{}", "{}", 2}},
|
||||||
|
{"FLMActiveProfileId", {PERSISTENT, STRING, "", "", 2}},
|
||||||
|
{"FLMSubmittedTune", {CLEAR_ON_MANAGER_START, JSON, "{}", "{}"}},
|
||||||
|
{"FLMTrialBaseline", {PERSISTENT | DONT_LOG, JSON, "{}", "{}"}},
|
||||||
|
{"FLMTrialApplied", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||||
|
{"FPSCounter", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"GalaxyDashboardStats", {PERSISTENT | DONT_LOG, JSON, "{}", "{}"}},
|
{"GalaxyDashboardStats", {PERSISTENT | DONT_LOG, JSON, "{}", "{}"}},
|
||||||
{"StarPilotApiToken", {PERSISTENT | DONT_LOG, STRING, "", "", 0}},
|
{"StarPilotApiToken", {PERSISTENT | DONT_LOG, STRING, "", "", 0}},
|
||||||
{"StarPilotCarParams", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, BYTES, "", ""}},
|
{"StarPilotCarParams", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, BYTES, "", ""}},
|
||||||
{"StarPilotCarParamsPersistent", {PERSISTENT, BYTES, "", ""}},
|
{"StarPilotCarParamsPersistent", {PERSISTENT, BYTES, "", ""}},
|
||||||
{"StarPilotDongleId", {PERSISTENT | DONT_LOG, STRING, "", "", 0}},
|
{"StarPilotDongleId", {PERSISTENT | DONT_LOG, STRING, "", "", 0}},
|
||||||
{"StarPilotFavoriteSlots", {PERSISTENT, JSON, "[]", "[]", 1}},
|
{"StarPilotFavoriteSlots", {PERSISTENT, JSON, "[]", "[]", 1}},
|
||||||
|
{"ControllerActionSlots", {PERSISTENT, JSON, "[]", "[]", 1}},
|
||||||
|
{"WheelControlLearnSlot", {CLEAR_ON_MANAGER_START | DONT_LOG, INT}},
|
||||||
|
{"WheelControlMappings", {PERSISTENT, JSON, "[]", "[]", 1}},
|
||||||
|
{"WheelControlStatus", {CLEAR_ON_MANAGER_START | DONT_LOG, JSON, "{}", "{}"}},
|
||||||
|
{"WheelControlTestActive", {CLEAR_ON_MANAGER_START | DONT_LOG, BOOL}},
|
||||||
|
{"WheelControlsEnabled", {PERSISTENT, BOOL, "0"}},
|
||||||
{"StarPilotStats", {PERSISTENT | DONT_LOG, JSON, "{}", "{}"}},
|
{"StarPilotStats", {PERSISTENT | DONT_LOG, JSON, "{}", "{}"}},
|
||||||
{"StarPilotTogglesUpdated", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
{"StarPilotTogglesUpdated", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
||||||
{"FrogsGoMoosTweak", {PERSISTENT, BOOL, "1", "0", 2}},
|
{"GoatScream", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"GoatScream", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"GoatScreamCriticalAlerts", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"GoatScreamCriticalAlerts", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"GreenLightAlert", {PERSISTENT, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"GreenLightAlert", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"HideAlerts", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"HideAlerts", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"HideChangingLanesBanner", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"HideChangingLanesBanner", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"HideDistanceProfileBanner", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"HideDistanceProfileBanner", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"HideTurningBanner", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"HideTurningBanner", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"HideDMIcon", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"HideDMIcon", {PERSISTENT, BOOL, "0", "0", 2}},
|
|
||||||
{"HideLeadMarker", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"HideLeadMarker", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||||
{"HideMaxSpeed", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"HideMaxSpeed", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"HideSpeed", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"HideSpeed", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"HideSpeedLimit", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"HideSpeedLimit", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"HideSteeringWheel", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"HideSteeringWheel", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"HigherBitrate", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"HigherBitrate", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"HolidayThemes", {PERSISTENT, BOOL, "1", "0", 0}},
|
{"HolidayThemes", {PERSISTENT, BOOL, "1", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"HumanAcceleration", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"HumanLaneChanges", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"CoastUpToLeads", {PERSISTENT, BOOL, "1", "1", 2}},
|
|
||||||
{"PrioritizeSmoothFollowing", {PERSISTENT, BOOL, "0", "0", 2}},
|
|
||||||
{"HumanLaneChanges", {PERSISTENT, BOOL, "0", "0", 2}},
|
|
||||||
{"IconPack", {PERSISTENT, STRING, "stock", "stock", 0}},
|
{"IconPack", {PERSISTENT, STRING, "stock", "stock", 0}},
|
||||||
{"IconToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
{"IconToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
||||||
{"IncreasedStoppedDistance", {PERSISTENT, FLOAT, "0.0", "0.0", 1}},
|
{"IncreasedStoppedDistance", {PERSISTENT, FLOAT, "0.0", "0.0", 1, SETTINGS_SIMPLE}},
|
||||||
{"IncreasedStoppedDistanceLowVisibility", {PERSISTENT, FLOAT, "0.0", "0.0", 2}},
|
{"IncreasedStoppedDistanceLowVisibility", {PERSISTENT, FLOAT, "0.0", "0.0", 2, SETTINGS_SIMPLE}},
|
||||||
{"IncreasedStoppedDistanceRain", {PERSISTENT, FLOAT, "0.0", "0.0", 2}},
|
{"IncreasedStoppedDistanceRain", {PERSISTENT, FLOAT, "0.0", "0.0", 2, SETTINGS_SIMPLE}},
|
||||||
{"IncreasedStoppedDistanceRainStorm", {PERSISTENT, FLOAT, "0.0", "0.0", 2}},
|
{"IncreasedStoppedDistanceRainStorm", {PERSISTENT, FLOAT, "0.0", "0.0", 2, SETTINGS_SIMPLE}},
|
||||||
{"IncreasedStoppedDistanceSnow", {PERSISTENT, FLOAT, "0.0", "0.0", 2}},
|
{"IncreasedStoppedDistanceSnow", {PERSISTENT, FLOAT, "0.0", "0.0", 2, SETTINGS_SIMPLE}},
|
||||||
{"RedneckCruise", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"RedneckCruise", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"IncreaseFollowingLowVisibility", {PERSISTENT, FLOAT, "0.0", "0.0", 2}},
|
{"IncreaseFollowingLowVisibility", {PERSISTENT, FLOAT, "0.0", "0.0", 2, SETTINGS_SIMPLE}},
|
||||||
{"IncreaseFollowingRain", {PERSISTENT, FLOAT, "0.0", "0.0", 2}},
|
{"IncreaseFollowingRain", {PERSISTENT, FLOAT, "0.0", "0.0", 2, SETTINGS_SIMPLE}},
|
||||||
{"IncreaseFollowingRainStorm", {PERSISTENT, FLOAT, "0.0", "0.0", 2}},
|
{"IncreaseFollowingRainStorm", {PERSISTENT, FLOAT, "0.0", "0.0", 2, SETTINGS_SIMPLE}},
|
||||||
{"IncreaseFollowingSnow", {PERSISTENT, FLOAT, "0.0", "0.0", 2}},
|
{"IncreaseFollowingSnow", {PERSISTENT, FLOAT, "0.0", "0.0", 2, SETTINGS_SIMPLE}},
|
||||||
{"IncreaseThermalLimits", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"IncreaseThermalLimits", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"IssueReported", {CLEAR_ON_MANAGER_START, JSON, "{}", "{}"}},
|
{"IssueReported", {CLEAR_ON_MANAGER_START, JSON, "{}", "{}"}},
|
||||||
{"KonikDongleId", {PERSISTENT, STRING, "", "", 0}},
|
{"KonikDongleId", {PERSISTENT, STRING, "", "", 0}},
|
||||||
{"KonikMinutes", {PERSISTENT, INT, "0", "0", 0}},
|
{"KonikMinutes", {PERSISTENT, INT, "0", "0", 0}},
|
||||||
{"LaneChanges", {PERSISTENT, BOOL, "1", "1", 0}},
|
{"LaneCentering", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||||
{"LaneChangeSmoothing", {PERSISTENT, INT, "10", "10", 1}},
|
{"LaneCenteringPauseOnSignal", {PERSISTENT, BOOL, "1", "1", 2}},
|
||||||
{"LaneChangeTime", {PERSISTENT, FLOAT, "1.0", "0.0", 1}},
|
{"LaneCenteringE2EAuthority", {PERSISTENT, FLOAT, "1.0", "1.0", 3}},
|
||||||
{"LaneDetectionWidth", {PERSISTENT, FLOAT, "0.0", "0.0", 1}},
|
{"LaneCenterOffset", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
{"LaneLinesColor", {PERSISTENT, STRING, "", "", 2}},
|
{"LaneChanges", {PERSISTENT, BOOL, "1", "1", 0, SETTINGS_SIMPLE}},
|
||||||
{"LaneLinesWidth", {PERSISTENT, FLOAT, "4.0", "2.0", 2}},
|
{"LaneChangeCloseGap", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}},
|
||||||
|
{"LaneChangeCloseGapSeconds", {PERSISTENT, FLOAT, "0.6", "0.6", 1, SETTINGS_SIMPLE}},
|
||||||
|
{"LaneChangeSmoothing", {PERSISTENT, INT, "5", "10", 1, SETTINGS_SIMPLE}},
|
||||||
|
{"LaneChangeTime", {PERSISTENT, FLOAT, "1.0", "0.0", 1, SETTINGS_SIMPLE}},
|
||||||
|
{"LaneDetectionWidth", {PERSISTENT, FLOAT, "0.0", "0.0", 1, SETTINGS_SIMPLE}},
|
||||||
|
{"LaneLinesColor", {PERSISTENT, STRING, "", "", 2, SETTINGS_SIMPLE}},
|
||||||
|
{"LaneLinesWidth", {PERSISTENT, FLOAT, "4.0", "2.0", 2, SETTINGS_SIMPLE}},
|
||||||
{"LastMapsUpdate", {PERSISTENT, STRING, "", ""}},
|
{"LastMapsUpdate", {PERSISTENT, STRING, "", ""}},
|
||||||
|
{"MapsDownloadProgress", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
||||||
|
{"MapsDownloadSizeCache", {PERSISTENT, STRING, "{}", "{}"}},
|
||||||
{"LateralTune", {PERSISTENT, BOOL, "1", "0", 1}},
|
{"LateralTune", {PERSISTENT, BOOL, "1", "0", 1}},
|
||||||
{"LeadDepartingAlert", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"LeadDepartingAlert", {PERSISTENT, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"LeadDetectionThreshold", {PERSISTENT, INT, "35", "50", 3}},
|
{"LeadDetectionThreshold", {PERSISTENT, INT, "35", "50", 3}},
|
||||||
{"LeadIndicator", {PERSISTENT, BOOL, "1", "1", 2}},
|
{"LeadIndicator", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"LeadInfo", {PERSISTENT, BOOL, "1", "0", 3}},
|
{"LeadInfo", {PERSISTENT, BOOL, "1", "0", 3}},
|
||||||
{"LKASButtonControl", {PERSISTENT, INT, "5", "0", 2}},
|
{"LKASButtonControl", {PERSISTENT, INT, "5", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"LockDoors", {PERSISTENT, BOOL, "1", "0", 0}},
|
{"LockDoors", {PERSISTENT, BOOL, "1", "0", 0}},
|
||||||
{"LockDoorsTimer", {PERSISTENT, INT, "0", "0", 0}},
|
{"LockDoorsTimer", {PERSISTENT, INT, "0", "0", 0}},
|
||||||
{"LongCancelButtonControl", {PERSISTENT, INT, "5", "0", 2}},
|
{"LongCancelButtonControl", {PERSISTENT, INT, "5", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"LongDistanceButtonControl", {PERSISTENT, INT, "5", "0", 2}},
|
{"LongDistanceButtonControl", {PERSISTENT, INT, "5", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"LongModeButtonControl", {PERSISTENT, INT, "0", "0", 2}},
|
{"LongModeButtonControl", {PERSISTENT, INT, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"LongStarButtonControl", {PERSISTENT, INT, "0", "0", 2}},
|
{"LongStarButtonControl", {PERSISTENT, INT, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"LongitudinalActuatorDelay", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
{"LongitudinalActuatorDelay", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
{"LongitudinalActuatorDelayStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
{"LongitudinalActuatorDelayStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
{"LateralManeuverStatus", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, JSON, "{}", "{}"}},
|
{"LateralManeuverStatus", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, JSON, "{}", "{}"}},
|
||||||
{"LongitudinalManeuverPaddleMode", {PERSISTENT, STRING, "auto", "auto"}},
|
{"LongitudinalManeuverPaddleMode", {PERSISTENT, STRING, "auto", "auto"}},
|
||||||
{"LongitudinalManeuverStatus", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, JSON, "{}", "{}"}},
|
{"LongitudinalManeuverStatus", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, JSON, "{}", "{}"}},
|
||||||
{"LongitudinalTune", {PERSISTENT, BOOL, "1", "0", 0}},
|
{"LongitudinalTune", {PERSISTENT, BOOL, "1", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"LoudBlindspotAlert", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"LoudBlindspotAlert", {PERSISTENT, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"LoudBlindspotAlertWhenDisengaged", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"LoudBlindspotAlertWhenDisengaged", {PERSISTENT, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"LowVoltageShutdown", {PERSISTENT, FLOAT, "11.8", "11.8", 3}},
|
{"LowVoltageShutdown", {PERSISTENT, FLOAT, "11.8", "11.8", 3, SETTINGS_SIMPLE}},
|
||||||
{"MainCruiseButtonControl", {PERSISTENT, INT, "0", "0", 2}},
|
{"MainCruiseButtonControl", {PERSISTENT, INT, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"ManualUpdateInitiated", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
{"ManualUpdateInitiated", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
||||||
{"AMapKey1", {PERSISTENT | DONT_LOG, STRING, "", "", 0}},
|
{"AMapKey1", {PERSISTENT | DONT_LOG, STRING, "", "", 0}},
|
||||||
{"AMapKey2", {PERSISTENT | DONT_LOG, STRING, "", "", 0}},
|
{"AMapKey2", {PERSISTENT | DONT_LOG, STRING, "", "", 0}},
|
||||||
@@ -399,12 +457,14 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"MapboxSecretKey", {PERSISTENT | DONT_LOG, STRING, "", "", 0}},
|
{"MapboxSecretKey", {PERSISTENT | DONT_LOG, STRING, "", "", 0}},
|
||||||
{"MapDeceleration", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"MapDeceleration", {PERSISTENT, BOOL, "0", "0", 1}},
|
||||||
{"MapdSettings", {PERSISTENT, JSON, "{}", "{}"}},
|
{"MapdSettings", {PERSISTENT, JSON, "{}", "{}"}},
|
||||||
{"MapGears", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"MapGears", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"MapsSelected", {PERSISTENT, STRING, "", "", 0}},
|
{"MapsSelected", {PERSISTENT, STRING, "", "", 0}},
|
||||||
{"MapSpeedLimit", {CLEAR_ON_MANAGER_START, FLOAT, "0.0", "0.0"}},
|
{"MapSpeedLimit", {CLEAR_ON_MANAGER_START, FLOAT, "0.0", "0.0"}},
|
||||||
{"NavDesiresAllowed", {PERSISTENT, BOOL, "1", "0", 2}},
|
{"NavDesiresAllowed", {PERSISTENT, BOOL, "1", "0", 2}},
|
||||||
|
{"NavLanePositioningAllowed", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||||
{"NavLongitudinalAllowed", {PERSISTENT, BOOL, "1", "0", 2}},
|
{"NavLongitudinalAllowed", {PERSISTENT, BOOL, "1", "0", 2}},
|
||||||
{"ClearNavOnOffroad", {PERSISTENT, BOOL, "1", "1", 2}},
|
{"ClearNavOnOffroad", {PERSISTENT, BOOL, "1", "1", 2, SETTINGS_SIMPLE}},
|
||||||
|
{"ClearNavOnOffroadTimeoutMinutes", {PERSISTENT, INT, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"NavDestination", {PERSISTENT | CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
{"NavDestination", {PERSISTENT | CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
||||||
{"NavInstructionCollapsed", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, BOOL, "0", "0"}},
|
{"NavInstructionCollapsed", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, BOOL, "0", "0"}},
|
||||||
{"NavInstructionState", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, JSON, "{}", "{}"}},
|
{"NavInstructionState", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, JSON, "{}", "{}"}},
|
||||||
@@ -416,29 +476,33 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"VisionSpeedLimitLastEvent", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
{"VisionSpeedLimitLastEvent", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
||||||
{"VisionSpeedLimitStatus", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
{"VisionSpeedLimitStatus", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
||||||
{"VisionSpeedLimitStream", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
{"VisionSpeedLimitStream", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
||||||
|
{"VisionSpeedLimitSupportCount", {CLEAR_ON_MANAGER_START, INT, "0", "0"}},
|
||||||
|
{"VisionSpeedLimitSupportSpeed", {CLEAR_ON_MANAGER_START, FLOAT, "0.0", "0.0"}},
|
||||||
{"MaxDesiredAcceleration", {PERSISTENT, FLOAT, "4.0", "2.0", 2}},
|
{"MaxDesiredAcceleration", {PERSISTENT, FLOAT, "4.0", "2.0", 2}},
|
||||||
{"MinimumBackupSize", {PERSISTENT, INT, "0", "0"}},
|
{"MinimumBackupSize", {PERSISTENT, INT, "0", "0"}},
|
||||||
{"MinimumLaneChangeSpeed", {PERSISTENT, FLOAT, "20.0", "20.0", 2}},
|
{"MinimumLaneChangeSpeed", {PERSISTENT, FLOAT, "20.0", "20.0", 2, SETTINGS_SIMPLE}},
|
||||||
{"ModeButtonControl", {PERSISTENT, INT, "0", "0", 2}},
|
{"ModeButtonControl", {PERSISTENT, INT, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"ModelDownloadProgress", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
{"ModelDownloadProgress", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
||||||
{"ModelDrivesAndScores", {PERSISTENT, JSON, "{}", "{}"}},
|
{"ModelDrivesAndScores", {PERSISTENT, JSON, "{}", "{}"}},
|
||||||
{"ModelReleasedDates", {PERSISTENT, STRING, "", "", 1}},
|
{"ModelReleasedDates", {PERSISTENT, STRING, "", "", 1}},
|
||||||
{"ModelRandomizer", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"ModelRandomizer", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||||
|
{"LatSmoothSeconds", {PERSISTENT, FLOAT, "0.1", "0.1", 3}},
|
||||||
|
{"LongSmoothSeconds", {PERSISTENT, FLOAT, "0.3", "0.3", 3}},
|
||||||
{"ModelSortMode", {PERSISTENT, STRING, "alphabetical", "alphabetical", 1}},
|
{"ModelSortMode", {PERSISTENT, STRING, "alphabetical", "alphabetical", 1}},
|
||||||
{"ModelToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
{"ModelToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
||||||
{"ModelUI", {PERSISTENT, BOOL, "1", "0", 2}},
|
{"ModelUI", {PERSISTENT, BOOL, "1", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"ModelVersions", {PERSISTENT, STRING, "", "", 1}},
|
{"ModelVersions", {PERSISTENT, STRING, "", "", 1}},
|
||||||
{"ModelManifestVersion", {PERSISTENT, STRING, "", "", 1}},
|
{"ModelManifestVersion", {PERSISTENT, STRING, "", "", 1}},
|
||||||
{"NavigationUI", {PERSISTENT, BOOL, "1", "0", 1}},
|
{"NavigationUI", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"NNFF", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"NNFF", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||||
{"NNFFLite", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"NNFFLite", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||||
{"NostalgiaMode", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"NostalgiaMode", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"NNFFModelName", {CLEAR_ON_MANAGER_START, STRING, "", "", 0}},
|
{"NNFFModelName", {CLEAR_ON_MANAGER_START, STRING, "", "", 0}},
|
||||||
{"NoLogging", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"NoLogging", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"NoUploads", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"NoUploads", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"NudgelessLaneChange", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"NudgelessLaneChange", {PERSISTENT, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"NudgelessLaneChangeOnlyWhenEngaged", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"NudgelessLaneChangeOnlyWhenEngaged", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"NumericalTemp", {PERSISTENT, BOOL, "1", "0", 3}},
|
{"NumericalTemp", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"Offset1", {PERSISTENT, FLOAT, "5.0", "0.0", 0}},
|
{"Offset1", {PERSISTENT, FLOAT, "5.0", "0.0", 0}},
|
||||||
{"Offset2", {PERSISTENT, FLOAT, "5.0", "0.0", 0}},
|
{"Offset2", {PERSISTENT, FLOAT, "5.0", "0.0", 0}},
|
||||||
{"Offset3", {PERSISTENT, FLOAT, "5.0", "0.0", 0}},
|
{"Offset3", {PERSISTENT, FLOAT, "5.0", "0.0", 0}},
|
||||||
@@ -446,45 +510,57 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"Offset5", {PERSISTENT, FLOAT, "10.0", "0.0", 0}},
|
{"Offset5", {PERSISTENT, FLOAT, "10.0", "0.0", 0}},
|
||||||
{"Offset6", {PERSISTENT, FLOAT, "10.0", "0.0", 0}},
|
{"Offset6", {PERSISTENT, FLOAT, "10.0", "0.0", 0}},
|
||||||
{"Offset7", {PERSISTENT, FLOAT, "10.0", "0.0", 0}},
|
{"Offset7", {PERSISTENT, FLOAT, "10.0", "0.0", 0}},
|
||||||
{"OneLaneChange", {PERSISTENT, BOOL, "1", "0", 2}},
|
{"OneLaneChange", {PERSISTENT, BOOL, "1", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"OnroadDistanceButton", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"OnroadDistanceButton", {PERSISTENT, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"OnroadDistanceButtonPressed", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
{"OnroadDistanceButtonPressed", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
||||||
|
{"FavoriteVirtualAccelCruiseCounter", {CLEAR_ON_MANAGER_START, INT, "0", "0"}},
|
||||||
|
{"FavoriteVirtualDecelCruiseCounter", {CLEAR_ON_MANAGER_START, INT, "0", "0"}},
|
||||||
|
{"FavoriteTrafficModeCounter", {CLEAR_ON_MANAGER_START, INT, "0", "0"}},
|
||||||
{"WheelButtonBookmarkCounter", {CLEAR_ON_MANAGER_START, INT, "0", "0"}},
|
{"WheelButtonBookmarkCounter", {CLEAR_ON_MANAGER_START, INT, "0", "0"}},
|
||||||
|
{"WheelControlAOLCounter", {CLEAR_ON_MANAGER_START, INT, "0", "0"}},
|
||||||
|
{"WheelControlForceCoastCounter", {CLEAR_ON_MANAGER_START, INT, "0", "0"}},
|
||||||
|
{"WheelControlPulseGlideCounter", {CLEAR_ON_MANAGER_START, INT, "0", "0"}},
|
||||||
{"openpilotMinutes", {PERSISTENT, INT, "0", "0", 0}},
|
{"openpilotMinutes", {PERSISTENT, INT, "0", "0", 0}},
|
||||||
{"OverpassRequests", {PERSISTENT, JSON, "{}", "{}"}},
|
{"OverpassRequests", {PERSISTENT, JSON, "{}", "{}"}},
|
||||||
{"PathColor", {PERSISTENT, STRING, "", "", 2}},
|
{"PathColor", {PERSISTENT, STRING, "", "", 2, SETTINGS_SIMPLE}},
|
||||||
{"PathEdgesColor", {PERSISTENT, STRING, "", "", 2}},
|
{"PathEdgesColor", {PERSISTENT, STRING, "", "", 2, SETTINGS_SIMPLE}},
|
||||||
{"PathEdgeWidth", {PERSISTENT, FLOAT, "20.0", "0.0", 2}},
|
{"PathEdgeWidth", {PERSISTENT, FLOAT, "20.0", "0.0", 2, SETTINGS_SIMPLE}},
|
||||||
{"PathWidth", {PERSISTENT, FLOAT, "6.1", "5.9", 2}},
|
{"PathWidth", {PERSISTENT, FLOAT, "6.1", "5.9", 2, SETTINGS_SIMPLE}},
|
||||||
{"PauseAOLOnBrake", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"PauseAOLOnBrake", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"PauseLateralOnSignal", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"PauseLateralOnSignal", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"PauseLateralSpeed", {PERSISTENT, FLOAT, "0.0", "0.0", 1}},
|
{"PauseLateralSpeed", {PERSISTENT, FLOAT, "0.0", "0.0", 1, SETTINGS_SIMPLE}},
|
||||||
{"LateralResumeDelay", {PERSISTENT, FLOAT, "0.0", "0.0", 1}},
|
{"LateralResumeDelay", {PERSISTENT, FLOAT, "0.0", "0.0", 1, SETTINGS_SIMPLE}},
|
||||||
{"PedalsOnUI", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"PedalsOnUI", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}},
|
||||||
|
{"PIPPreviewEnabled", {PERSISTENT, BOOL, "0", "0", 1}},
|
||||||
|
{"PIPPreviewMask", {PERSISTENT, JSON, "{\"width\":1928,\"height\":1208,\"center_left\":[315,548],\"center_right\":[1571,539],\"crop_size\":580}", "{\"width\":1928,\"height\":1208,\"center_left\":[315,548],\"center_right\":[1571,539],\"crop_size\":580}", 2}},
|
||||||
|
{"PIPPreviewShowOnBlinker", {PERSISTENT, BOOL, "0", "0", 1}},
|
||||||
|
{"PIPPreviewShowOnBSM", {PERSISTENT, BOOL, "0", "0", 1}},
|
||||||
|
{"PIPPreviewInvert", {PERSISTENT, BOOL, "0", "0", 1}},
|
||||||
{"GalaxyPaired", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"GalaxyPaired", {PERSISTENT, BOOL, "0", "0", 0}},
|
||||||
{"GalaxyUploadPending", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"GalaxyUploadPending", {PERSISTENT, BOOL, "0", "0", 0}},
|
||||||
{"PreferredSchedule", {PERSISTENT, INT, "2", "0", 0}},
|
{"PreferredSchedule", {PERSISTENT, INT, "2", "0", 0}},
|
||||||
{"PreviousSpeedLimit", {PERSISTENT, FLOAT, "0.0", "0.0"}},
|
{"PreviousSpeedLimit", {PERSISTENT, FLOAT, "0.0", "0.0"}},
|
||||||
{"PromptDistractedVolume", {PERSISTENT, INT, "101", "101", 2}},
|
{"PromptDistractedVolume", {PERSISTENT, INT, "101", "101", 2, SETTINGS_SIMPLE}},
|
||||||
{"PromptVolume", {PERSISTENT, INT, "101", "101", 2}},
|
{"PromptVolume", {PERSISTENT, INT, "101", "101", 2, SETTINGS_SIMPLE}},
|
||||||
{"QOLLateral", {PERSISTENT, BOOL, "1", "0", 1}},
|
{"PulseGlideSpeedDelta", {PERSISTENT, FLOAT, "5.0", "5.0", 3}},
|
||||||
{"QOLLongitudinal", {PERSISTENT, BOOL, "1", "0", 1}},
|
{"QOLLateral", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"QOLVisuals", {PERSISTENT, BOOL, "1", "0", 0}},
|
{"QOLLongitudinal", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"RadarTakeoffs", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"QOLVisuals", {PERSISTENT, BOOL, "1", "0", 0, SETTINGS_SIMPLE}},
|
||||||
|
{"RadarTakeoffs", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"RadarTracksUI", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"RadarTracksUI", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"RainbowPath", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"RainbowPath", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"RandomEvents", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"RandomEvents", {PERSISTENT, BOOL, "0", "0", 1}},
|
||||||
{"RandomThemes", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"RandomThemes", {PERSISTENT, BOOL, "0", "0", 1}},
|
||||||
{"RandomThemesHolidays", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"RandomThemesHolidays", {PERSISTENT, BOOL, "0", "0", 1}},
|
||||||
{"ReduceAccelerationLowVisibility", {PERSISTENT, INT, "0", "0", 2}},
|
{"ReduceAccelerationLowVisibility", {PERSISTENT, INT, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"ReduceAccelerationRain", {PERSISTENT, INT, "0", "0", 2}},
|
{"ReduceAccelerationRain", {PERSISTENT, INT, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"ReduceAccelerationRainStorm", {PERSISTENT, INT, "0", "0", 2}},
|
{"ReduceAccelerationRainStorm", {PERSISTENT, INT, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"ReduceAccelerationSnow", {PERSISTENT, INT, "0", "0", 2}},
|
{"ReduceAccelerationSnow", {PERSISTENT, INT, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"ReduceLateralAccelerationLowVisibility", {PERSISTENT, INT, "0", "0", 2}},
|
{"ReduceLateralAccelerationLowVisibility", {PERSISTENT, INT, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"ReduceLateralAccelerationRain", {PERSISTENT, INT, "0", "0", 2}},
|
{"ReduceLateralAccelerationRain", {PERSISTENT, INT, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"ReduceLateralAccelerationRainStorm", {PERSISTENT, INT, "0", "0", 2}},
|
{"ReduceLateralAccelerationRainStorm", {PERSISTENT, INT, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"ReduceLateralAccelerationSnow", {PERSISTENT, INT, "0", "0", 2}},
|
{"ReduceLateralAccelerationSnow", {PERSISTENT, INT, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"RefuseVolume", {PERSISTENT, INT, "101", "101", 2}},
|
{"RefuseVolume", {PERSISTENT, INT, "101", "101", 2, SETTINGS_SIMPLE}},
|
||||||
{"RelaxedFollow", {PERSISTENT, FLOAT, "1.6", "1.6", 2}},
|
{"RelaxedFollow", {PERSISTENT, FLOAT, "1.6", "1.6", 2}},
|
||||||
{"RelaxedFollowHigh", {PERSISTENT, FLOAT, "1.4", "1.4", 2}},
|
{"RelaxedFollowHigh", {PERSISTENT, FLOAT, "1.4", "1.4", 2}},
|
||||||
{"RelaxedJerkAcceleration", {PERSISTENT, FLOAT, "100.0", "100.0", 3}},
|
{"RelaxedJerkAcceleration", {PERSISTENT, FLOAT, "100.0", "100.0", 3}},
|
||||||
@@ -492,44 +568,46 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"RelaxedJerkDeceleration", {PERSISTENT, FLOAT, "100.0", "100.0", 3}},
|
{"RelaxedJerkDeceleration", {PERSISTENT, FLOAT, "100.0", "100.0", 3}},
|
||||||
{"RelaxedJerkSpeed", {PERSISTENT, FLOAT, "100.0", "100.0", 3}},
|
{"RelaxedJerkSpeed", {PERSISTENT, FLOAT, "100.0", "100.0", 3}},
|
||||||
{"RelaxedJerkSpeedDecrease", {PERSISTENT, FLOAT, "100.0", "100.0", 3}},
|
{"RelaxedJerkSpeedDecrease", {PERSISTENT, FLOAT, "100.0", "100.0", 3}},
|
||||||
{"ReverseCruise", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"RivianAngleControl", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
|
{"RivianAngleSaturated", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, BOOL, "0", "0"}},
|
||||||
|
{"RivianToiRecoveryFailed", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, BOOL, "0", "0"}},
|
||||||
{"RecoveryPower", {PERSISTENT, FLOAT, "1.0", "1.0", 2}},
|
{"RecoveryPower", {PERSISTENT, FLOAT, "1.0", "1.0", 2}},
|
||||||
{"RoadEdgesWidth", {PERSISTENT, FLOAT, "2.0", "2.0", 2}},
|
{"RoadEdgesWidth", {PERSISTENT, FLOAT, "2.0", "2.0", 2, SETTINGS_SIMPLE}},
|
||||||
{"RoadNameUI", {PERSISTENT, BOOL, "1", "0", 1}},
|
{"RoadNameUI", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"RotatingWheel", {PERSISTENT, BOOL, "1", "0", 1}},
|
{"RotatingWheel", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"ScreenBrightness", {PERSISTENT, INT, "101", "101", 2}},
|
{"ScreenBrightness", {PERSISTENT, INT, "101", "101", 2, SETTINGS_SIMPLE}},
|
||||||
{"ScreenBrightnessOnroad", {PERSISTENT, INT, "101", "101", 2}},
|
{"ScreenBrightnessOnroad", {PERSISTENT, INT, "101", "101", 2, SETTINGS_SIMPLE}},
|
||||||
{"ScreenManagement", {PERSISTENT, BOOL, "1", "0", 1}},
|
{"ScreenManagement", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"ScreenRecorder", {PERSISTENT, BOOL, "1", "0", 2}},
|
{"ScreenRecorder", {PERSISTENT, BOOL, "1", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"ScreenTimeout", {PERSISTENT, INT, "30", "30", 2}},
|
{"ScreenTimeout", {PERSISTENT, INT, "30", "30", 2, SETTINGS_SIMPLE}},
|
||||||
{"ScreenTimeoutOnroad", {PERSISTENT, INT, "30", "10", 2}},
|
{"ScreenTimeoutOnroad", {PERSISTENT, INT, "30", "10", 2, SETTINGS_SIMPLE}},
|
||||||
{"SecOCKeys", {PERSISTENT | DONT_LOG, STRING, "", "", 0}},
|
{"SecOCKeys", {PERSISTENT | DONT_LOG, STRING, "", "", 0}},
|
||||||
{"SafeMode", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"SafeMode", {PERSISTENT, BOOL, "0", "0", 0}},
|
||||||
{"SafeModeBackup", {PERSISTENT, JSON, "{}", "{}"}},
|
{"SafeModeBackup", {PERSISTENT, JSON, "{}", "{}"}},
|
||||||
{"SetSpeedLimit", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"SetSpeedLimit", {PERSISTENT, BOOL, "0", "0", 1}},
|
||||||
{"SetSpeedOffset", {PERSISTENT, FLOAT, "0.0", "0.0", 2}},
|
{"SetSpeedOffset", {PERSISTENT, FLOAT, "0.0", "0.0", 2, SETTINGS_SIMPLE}},
|
||||||
{"ShowCEMStatus", {PERSISTENT, BOOL, "1", "0", 2}},
|
{"ShowCEMStatus", {PERSISTENT, BOOL, "1", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"ShowCCMStatus", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"ShowCCMStatus", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||||
{"ShowCPU", {PERSISTENT, BOOL, "1", "0", 3}},
|
{"ShowCPU", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"ShowCSCStatus", {PERSISTENT, BOOL, "1", "0", 2}},
|
{"ShowCSCStatus", {PERSISTENT, BOOL, "1", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"ShowGPU", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"ShowGPU", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"ShowIP", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"ShowIP", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"ShowMemoryUsage", {PERSISTENT, BOOL, "1", "0", 3}},
|
{"ShowMemoryUsage", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"ShowModeStatusBanner", {PERSISTENT, BOOL, "1", "0", 2}},
|
{"ShowModeStatusBanner", {PERSISTENT, BOOL, "1", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"ShownToggleDescriptions", {PERSISTENT, JSON, "{}", "{}"}},
|
{"ShownToggleDescriptions", {PERSISTENT, JSON, "{}", "{}"}},
|
||||||
{"ShowSLCOffset", {PERSISTENT, BOOL, "1", "0", 0}},
|
{"ShowSLCOffset", {PERSISTENT, BOOL, "1", "0", 0}},
|
||||||
{"ShowSpeedLimits", {PERSISTENT, BOOL, "1", "0", 1}},
|
{"ShowSpeedLimits", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"ShowSteering", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"ShowSteering", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"ShowStoppingPoint", {PERSISTENT, BOOL, "1", "0", 3}},
|
{"ShowStoppingPoint", {PERSISTENT, BOOL, "1", "0", 3}},
|
||||||
{"ShowStoppingPointMetrics", {PERSISTENT, BOOL, "1", "0", 3}},
|
{"ShowStoppingPointMetrics", {PERSISTENT, BOOL, "1", "0", 3}},
|
||||||
{"ShowStorageLeft", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"ShowStorageLeft", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"ShowStorageUsed", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"ShowStorageUsed", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"SidebarMetrics", {PERSISTENT, BOOL, "1", "0", 3}},
|
{"SidebarMetrics", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"SidebarOpen", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"SidebarOpen", {PERSISTENT, BOOL, "0", "0", 0}},
|
||||||
{"SignalAnimation", {PERSISTENT, STRING, "stock", "stock", 0}},
|
{"SignalAnimation", {PERSISTENT, STRING, "stock", "stock", 0}},
|
||||||
{"SignalMetrics", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"SignalMetrics", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"SignalToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
{"SignalToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
||||||
{"SimpleMode", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"SimpleMode", {PERSISTENT, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"SLCAbbreviatedSources", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"SLCAbbreviatedSources", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"SLCActiveSourcesOnly", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"SLCActiveSourcesOnly", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"SLCConfirmation", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"SLCConfirmation", {PERSISTENT, BOOL, "0", "0", 0}},
|
||||||
@@ -538,18 +616,18 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"SLCFallback", {PERSISTENT, INT, "2", "0", 1}},
|
{"SLCFallback", {PERSISTENT, INT, "2", "0", 1}},
|
||||||
{"SLCLookaheadHigher", {PERSISTENT, INT, "0", "0", 2}},
|
{"SLCLookaheadHigher", {PERSISTENT, INT, "0", "0", 2}},
|
||||||
{"SLCLookaheadLower", {PERSISTENT, INT, "0", "0", 2}},
|
{"SLCLookaheadLower", {PERSISTENT, INT, "0", "0", 2}},
|
||||||
{"SLCMapboxFiller", {PERSISTENT, BOOL, "1", "0", 1}},
|
{"SLCMapboxFiller", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"SLCOverride", {PERSISTENT, INT, "1", "0", 1}},
|
{"SLCOverride", {PERSISTENT, INT, "1", "0", 1}},
|
||||||
{"SLCPriority", {PERSISTENT, STRING, "", "", 2}},
|
{"SLCPriority", {PERSISTENT, STRING, "", "", 2}},
|
||||||
{"SLCPriority1", {PERSISTENT, STRING, "Map Data", "Map Data", 2}},
|
{"SLCPriority1", {PERSISTENT, STRING, "Vision", "Map Data", 2}},
|
||||||
{"SLCPriority2", {PERSISTENT, STRING, "Dashboard", "Dashboard", 2}},
|
{"SLCPriority2", {PERSISTENT, STRING, "Map Data", "Dashboard", 2}},
|
||||||
{"SNGHack", {PERSISTENT, BOOL, "1", "0", 2}},
|
{"SNGHack", {PERSISTENT, BOOL, "1", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"SoundPack", {PERSISTENT, STRING, "stock", "stock", 0}},
|
{"SoundPack", {PERSISTENT, STRING, "stock", "stock", 0}},
|
||||||
{"SoundToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
{"SoundToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
||||||
{"SLCAdoptSpeedLimit", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
{"SLCAdoptSpeedLimit", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
||||||
{"SLCForceCruiseSpeed", {CLEAR_ON_MANAGER_START, FLOAT, "0.0", "0.0"}},
|
{"SLCForceCruiseSpeed", {CLEAR_ON_MANAGER_START, FLOAT, "0.0", "0.0"}},
|
||||||
{"SpeedLimitAccepted", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
{"SpeedLimitAccepted", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
||||||
{"SpeedLimitChangedAlert", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"SpeedLimitChangedAlert", {PERSISTENT, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"SpeedLimitController", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"SpeedLimitController", {PERSISTENT, BOOL, "0", "0", 0}},
|
||||||
{"SpeedLimitFiller", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"SpeedLimitFiller", {PERSISTENT, BOOL, "0", "0", 0}},
|
||||||
{"SpeedLimits", {PERSISTENT | DONT_LOG, JSON, "[]", "[]"}},
|
{"SpeedLimits", {PERSISTENT | DONT_LOG, JSON, "[]", "[]"}},
|
||||||
@@ -557,7 +635,9 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"SpeedLimitSources", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"SpeedLimitSources", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"VisionSpeedLimitAutoBookmark", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"VisionSpeedLimitAutoBookmark", {PERSISTENT, BOOL, "0", "0", 0}},
|
||||||
{"VisionSpeedLimitAutoPreserveSegment", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"VisionSpeedLimitAutoPreserveSegment", {PERSISTENT, BOOL, "0", "0", 0}},
|
||||||
{"VisionSpeedLimitDetection", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"VisionSpeedLimitDetection", {PERSISTENT, BOOL, "1", "0", 0}},
|
||||||
|
{"VisionSpeedLimitLowLimitFilter", {PERSISTENT, BOOL, "0", "0", 0}},
|
||||||
|
{"VisionSpeedLimitLowLimitThreshold", {PERSISTENT, INT, "25", "25", 0}},
|
||||||
{"VisionSpeedLimitTrainingCollector", {PERSISTENT, BOOL, "1", "1", 0}},
|
{"VisionSpeedLimitTrainingCollector", {PERSISTENT, BOOL, "1", "1", 0}},
|
||||||
{"StandardFollow", {PERSISTENT, FLOAT, "1.45", "1.45", 2}},
|
{"StandardFollow", {PERSISTENT, FLOAT, "1.45", "1.45", 2}},
|
||||||
{"StandardFollowHigh", {PERSISTENT, FLOAT, "1.2", "1.2", 2}},
|
{"StandardFollowHigh", {PERSISTENT, FLOAT, "1.2", "1.2", 2}},
|
||||||
@@ -566,13 +646,14 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"StandardJerkDeceleration", {PERSISTENT, FLOAT, "100.0", "100.0", 3}},
|
{"StandardJerkDeceleration", {PERSISTENT, FLOAT, "100.0", "100.0", 3}},
|
||||||
{"StandardJerkSpeed", {PERSISTENT, FLOAT, "100.0", "100.0", 3}},
|
{"StandardJerkSpeed", {PERSISTENT, FLOAT, "100.0", "100.0", 3}},
|
||||||
{"StandardJerkSpeedDecrease", {PERSISTENT, FLOAT, "100.0", "100.0", 3}},
|
{"StandardJerkSpeedDecrease", {PERSISTENT, FLOAT, "100.0", "100.0", 3}},
|
||||||
{"StandbyMode", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"StandbyMode", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"StartAccel", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
{"StartAccel", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
{"StartAccelStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
{"StartAccelStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
{"StartupMessageBottom", {PERSISTENT, STRING, "Always keep hands on wheel and eyes on road", "Always keep hands on wheel and eyes on road", 0}},
|
{"StartupMessageBottom", {PERSISTENT, STRING, "Always keep hands on wheel and eyes on road", "Always keep hands on wheel and eyes on road", 0}},
|
||||||
{"StartupMessageTop", {PERSISTENT, STRING, "Be ready to take over at any time", "Be ready to take over at any time", 0}},
|
{"StartupMessageTop", {PERSISTENT, STRING, "Be ready to take over at any time", "Be ready to take over at any time", 0}},
|
||||||
{"StaticPedalsOnUI", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"StaticPedalsOnUI", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"SteerDelay", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
{"SteerDelay", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
|
{"SteerDelayModeMigrated", {PERSISTENT, BOOL}},
|
||||||
{"SteerDelayStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
{"SteerDelayStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
{"SteerFriction", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
{"SteerFriction", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
{"SteerFrictionStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
{"SteerFrictionStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
@@ -584,20 +665,23 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"SteerOffsetStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
{"SteerOffsetStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
{"SteerRatio", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
{"SteerRatio", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
{"SteerRatioStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
{"SteerRatioStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
{"StockConfidenceBallWidget", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"EnableTorqueBarWidget", {PERSISTENT, BOOL, "1", "0", 0}},
|
||||||
|
{"StockConfidenceBallWidget", {PERSISTENT, BOOL, "0", "0", 0, SETTINGS_SIMPLE}},
|
||||||
{"StockDongleId", {PERSISTENT, STRING, "", ""}},
|
{"StockDongleId", {PERSISTENT, STRING, "", ""}},
|
||||||
{"StopAccel", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
{"StopAccel", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
{"StopAccelStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
{"StopAccelStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
{"StoppedTimer", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"StoppedTimer", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}},
|
||||||
{"StopDistance", {PERSISTENT, FLOAT, "6.0", "6.0", 2}},
|
|
||||||
{"StoppingDecelRate", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
{"StoppingDecelRate", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
{"StoppingDecelRateStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
{"StoppingDecelRateStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
{"StarButtonControl", {PERSISTENT, INT, "0", "0", 2}},
|
{"StarButtonControl", {PERSISTENT, INT, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"SwitchbackModeCooldown", {PERSISTENT, INT, "5", "0", 2}},
|
{"SwitchbackModeCooldown", {PERSISTENT, INT, "5", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"SwitchbackModeEnabled", {CLEAR_ON_OFFROAD_TRANSITION, BOOL, "0", "0"}},
|
{"SwitchbackModeEnabled", {CLEAR_ON_OFFROAD_TRANSITION, BOOL, "0", "0"}},
|
||||||
{"SubaruSNG", {PERSISTENT, BOOL, "1", "0", 2}},
|
{"SubaruSNG", {PERSISTENT, BOOL, "1", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"SubaruSNGManualParkingBrake", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"SubaruSNGManualParkingBrake", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
|
{"SubaruStopStartOff", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
|
{"SubaruAvhOnAtStartup", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"TacoTune", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"TacoTune", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||||
|
{"TeslaCoopSteering", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"TestAlert", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
{"TestAlert", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
||||||
{"TetheringEnabled", {PERSISTENT, INT, "0", "0", 0}},
|
{"TetheringEnabled", {PERSISTENT, INT, "0", "0", 0}},
|
||||||
{"ThemeDownloadProgress", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
{"ThemeDownloadProgress", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
||||||
@@ -606,16 +690,17 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"TinygradUpdateAvailable", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"TinygradUpdateAvailable", {PERSISTENT, BOOL, "0", "0", 1}},
|
||||||
{"ToyotaDoors", {PERSISTENT, BOOL, "1", "0", 0}},
|
{"ToyotaDoors", {PERSISTENT, BOOL, "1", "0", 0}},
|
||||||
{"TrailerLoad", {PERSISTENT, INT, "0", "0", 2}},
|
{"TrailerLoad", {PERSISTENT, INT, "0", "0", 2}},
|
||||||
{"TrafficFollow", {PERSISTENT, FLOAT, "0.5", "0.5", 2}},
|
{"TrafficFollow", {PERSISTENT, FLOAT, "0.75", "0.75", 2}},
|
||||||
{"TrafficJerkAcceleration", {PERSISTENT, FLOAT, "50.0", "50.0", 3}},
|
{"TrafficJerkAcceleration", {PERSISTENT, FLOAT, "100.0", "100.0", 3}},
|
||||||
{"TrafficJerkDanger", {PERSISTENT, FLOAT, "100.0", "100.0", 3}},
|
{"TrafficJerkDanger", {PERSISTENT, FLOAT, "100.0", "100.0", 3}},
|
||||||
{"TrafficJerkDeceleration", {PERSISTENT, FLOAT, "50.0", "50.0", 3}},
|
{"TrafficJerkDeceleration", {PERSISTENT, FLOAT, "100.0", "100.0", 3}},
|
||||||
{"TrafficJerkSpeed", {PERSISTENT, FLOAT, "50.0", "50.0", 3}},
|
{"TrafficJerkSpeed", {PERSISTENT, FLOAT, "100.0", "100.0", 3}},
|
||||||
{"TrafficJerkSpeedDecrease", {PERSISTENT, FLOAT, "50.0", "50.0", 3}},
|
{"TrafficJerkSpeedDecrease", {PERSISTENT, FLOAT, "100.0", "100.0", 3}},
|
||||||
{"TruckTuning", {PERSISTENT, BOOL, "0", "0", 3}},
|
{"TruckTuning", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||||
{"TuningLevel", {PERSISTENT, INT, "0", "0", 0}},
|
{"TuningLevel", {PERSISTENT, INT, "0", "0", 0}},
|
||||||
{"TuningLevelConfirmed", {PERSISTENT, BOOL, "0", "0", 0}},
|
{"TuningLevelConfirmed", {PERSISTENT, BOOL, "0", "0", 0}},
|
||||||
{"TurnDesires", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"TurnDesires", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||||
|
{"TurnSteeringLimitMuteSpeed", {PERSISTENT, INT, "0", "0", 0}},
|
||||||
{"UnlockDoors", {PERSISTENT, BOOL, "1", "0", 0}},
|
{"UnlockDoors", {PERSISTENT, BOOL, "1", "0", 0}},
|
||||||
{"Updated", {PERSISTENT, STRING, "0", "0"}},
|
{"Updated", {PERSISTENT, STRING, "0", "0"}},
|
||||||
{"UpdateSpeedLimits", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
{"UpdateSpeedLimits", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
||||||
@@ -623,28 +708,40 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"UpdateTinygrad", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
{"UpdateTinygrad", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
||||||
{"UpdateWheelImage", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
{"UpdateWheelImage", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
||||||
{"UseActiveTheme", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
{"UseActiveTheme", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
|
||||||
{"UseKonikServer", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"UseAutoSteerDelay", {PERSISTENT, BOOL, "1", "1", 3}},
|
||||||
|
{"UseKonikServer", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"UseSI", {PERSISTENT, BOOL, "1", "1", 3}},
|
{"UseSI", {PERSISTENT, BOOL, "1", "1", 3}},
|
||||||
{"UserFavorites", {PERSISTENT, STRING, "", "", 1}},
|
{"UserFavorites", {PERSISTENT, STRING, "", "", 1}},
|
||||||
{"UseVienna", {PERSISTENT, BOOL, "0", "0", 1}},
|
{"UseVienna", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}},
|
||||||
|
{"VASMAnnotationConfig", {PERSISTENT, JSON, "{}", "{}", 2}},
|
||||||
|
{"VASMConfidenceThreshold", {PERSISTENT, FLOAT, "0.94", "0.94", 2}},
|
||||||
|
{"VASMEnabled", {PERSISTENT, BOOL, "0", "0", 1}},
|
||||||
|
{"VASMLeftActive", {CLEAR_ON_MANAGER_START, STRING, "0", "0", 2}},
|
||||||
|
{"VASMLeftConfidence", {CLEAR_ON_MANAGER_START, STRING, "0.0", "0.0", 2}},
|
||||||
|
{"VASMLastUpdateMonoTime", {CLEAR_ON_MANAGER_START, STRING, "0", "0", 2}},
|
||||||
|
{"VASMRightActive", {CLEAR_ON_MANAGER_START, STRING, "0", "0", 2}},
|
||||||
|
{"VASMRightConfidence", {CLEAR_ON_MANAGER_START, STRING, "0.0", "0.0", 2}},
|
||||||
|
{"VASMSmoothSeconds", {PERSISTENT, FLOAT, "0.2", "0.2", 2}},
|
||||||
|
{"VASMTimestampEof", {CLEAR_ON_MANAGER_START, STRING, "0", "0", 2}},
|
||||||
{"VEgoStarting", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
{"VEgoStarting", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
{"VEgoStartingStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
{"VEgoStartingStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
{"VEgoStopping", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
{"VEgoStopping", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
{"VEgoStoppingStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
{"VEgoStoppingStock", {PERSISTENT, FLOAT, "0.0", "0.0", 3}},
|
||||||
{"VeryLongCancelButtonControl", {PERSISTENT, INT, "6", "0", 2}},
|
{"VeryLongCancelButtonControl", {PERSISTENT, INT, "6", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"VeryLongDistanceButtonControl", {PERSISTENT, INT, "6", "0", 2}},
|
{"VeryLongDistanceButtonControl", {PERSISTENT, INT, "6", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"VeryLongModeButtonControl", {PERSISTENT, INT, "0", "0", 2}},
|
{"VeryLongModeButtonControl", {PERSISTENT, INT, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"VeryLongStarButtonControl", {PERSISTENT, INT, "0", "0", 2}},
|
{"VeryLongStarButtonControl", {PERSISTENT, INT, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"VoltSNG", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"VoltSNG", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"GMAutoHold", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"JeepBrakeHold", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"VoltOnePedalMode", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"GMAutoHold", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"ToyotaAutoHold", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"VoltOnePedalMode", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"WarningImmediateVolume", {PERSISTENT, INT, "101", "101", 2}},
|
{"ToyotaAutoHold", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"WarningSoftVolume", {PERSISTENT, INT, "101", "101", 2}},
|
{"WarningImmediateVolume", {PERSISTENT, INT, "101", "101", 2, SETTINGS_SIMPLE}},
|
||||||
{"WeatherPresets", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"WarningSoftVolume", {PERSISTENT, INT, "101", "101", 2, SETTINGS_SIMPLE}},
|
||||||
|
{"WeatherPresets", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"WeatherToken", {PERSISTENT | DONT_LOG, STRING, "", "", 2}},
|
{"WeatherToken", {PERSISTENT | DONT_LOG, STRING, "", "", 2}},
|
||||||
{"WheelControls", {PERSISTENT, STRING, "", "", 2}},
|
{"WheelControls", {PERSISTENT, STRING, "", "", 2}},
|
||||||
{"WheelIcon", {PERSISTENT, STRING, "stock", "stock", 0}},
|
{"WheelIcon", {PERSISTENT, STRING, "stock", "stock", 0}},
|
||||||
{"WheelSpeed", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"WheelSpeed", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"WheelToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
{"WheelToDownload", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
||||||
};
|
};
|
||||||
|
|||||||
+1104
-855
File diff suppressed because it is too large
Load Diff
@@ -32,6 +32,10 @@ cdef extern from "common/params.h":
|
|||||||
JSON
|
JSON
|
||||||
BYTES
|
BYTES
|
||||||
|
|
||||||
|
cdef enum ParamSettingsTier:
|
||||||
|
SETTINGS_SIMPLE
|
||||||
|
SETTINGS_ADVANCED
|
||||||
|
|
||||||
cdef cppclass c_Params "Params":
|
cdef cppclass c_Params "Params":
|
||||||
c_Params(string, bool) except + nogil
|
c_Params(string, bool) except + nogil
|
||||||
string get(string, bool) nogil
|
string get(string, bool) nogil
|
||||||
@@ -55,6 +59,8 @@ cdef extern from "common/params.h":
|
|||||||
|
|
||||||
int getTuningLevel(string) nogil
|
int getTuningLevel(string) nogil
|
||||||
|
|
||||||
|
ParamSettingsTier getSettingsTier(string) nogil
|
||||||
|
|
||||||
PYTHON_2_CPP = {
|
PYTHON_2_CPP = {
|
||||||
(str, STRING): lambda v: v,
|
(str, STRING): lambda v: v,
|
||||||
(builtins.bool, BOOL): lambda v: "1" if v else "0",
|
(builtins.bool, BOOL): lambda v: "1" if v else "0",
|
||||||
@@ -255,3 +261,6 @@ cdef class Params:
|
|||||||
cdef string k = self.check_key(key)
|
cdef string k = self.check_key(key)
|
||||||
cdef optional[int] level = self.p.getTuningLevel(k)
|
cdef optional[int] level = self.p.getTuningLevel(k)
|
||||||
return level.value() if level.has_value() else 0
|
return level.value() if level.has_value() else 0
|
||||||
|
|
||||||
|
def get_settings_tier(self, key):
|
||||||
|
return self.p.getSettingsTier(self.check_key(key))
|
||||||
|
|||||||
Binary file not shown.
+4
-1
@@ -50,7 +50,10 @@ class OpenpilotPrefix:
|
|||||||
symlink_path = Params().get_param_path()
|
symlink_path = Params().get_param_path()
|
||||||
if os.path.exists(symlink_path):
|
if os.path.exists(symlink_path):
|
||||||
shutil.rmtree(os.path.realpath(symlink_path), ignore_errors=True)
|
shutil.rmtree(os.path.realpath(symlink_path), ignore_errors=True)
|
||||||
os.remove(symlink_path)
|
# when the params path is a real directory rather than a symlink, rmtree above already
|
||||||
|
# removed it and there is no link left to unlink
|
||||||
|
if os.path.islink(symlink_path):
|
||||||
|
os.remove(symlink_path)
|
||||||
shutil.rmtree(self.msgq_path, ignore_errors=True)
|
shutil.rmtree(self.msgq_path, ignore_errors=True)
|
||||||
if PC:
|
if PC:
|
||||||
shutil.rmtree(Paths.log_root(), ignore_errors=True)
|
shutil.rmtree(Paths.log_root(), ignore_errors=True)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ class Priority:
|
|||||||
# - modeld = 55
|
# - modeld = 55
|
||||||
# - camerad = 54
|
# - camerad = 54
|
||||||
CTRL_LOW = 51 # plannerd & radard
|
CTRL_LOW = 51 # plannerd & radard
|
||||||
|
UI = 50
|
||||||
|
|
||||||
# CORE 3
|
# CORE 3
|
||||||
# - pandad = 55
|
# - pandad = 55
|
||||||
|
|||||||
@@ -7,19 +7,6 @@ class Spinner:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.spinner_proc = None
|
self.spinner_proc = None
|
||||||
|
|
||||||
# Prefer the legacy compiled spinner on device.
|
|
||||||
legacy_spinner = os.path.join(BASEDIR, "selfdrive", "ui", "spinner")
|
|
||||||
if os.path.isfile("/TICI") and os.path.isfile(legacy_spinner) and os.access(legacy_spinner, os.X_OK):
|
|
||||||
try:
|
|
||||||
self.spinner_proc = subprocess.Popen([legacy_spinner],
|
|
||||||
stdin=subprocess.PIPE,
|
|
||||||
cwd=os.path.join(BASEDIR, "selfdrive", "ui"),
|
|
||||||
close_fds=True)
|
|
||||||
return
|
|
||||||
except OSError:
|
|
||||||
self.spinner_proc = None
|
|
||||||
|
|
||||||
# Raylib spinner requires Python deps from the repo virtualenv.
|
|
||||||
spinner_cwd = os.path.join(BASEDIR, "system", "ui")
|
spinner_cwd = os.path.join(BASEDIR, "system", "ui")
|
||||||
venv_python = os.path.join(BASEDIR, ".venv", "bin", "python")
|
venv_python = os.path.join(BASEDIR, ".venv", "bin", "python")
|
||||||
python_exec = venv_python if os.path.isfile(venv_python) else "python3"
|
python_exec = venv_python if os.path.isfile(venv_python) else "python3"
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from openpilot.common import file_chunker
|
||||||
|
|
||||||
|
|
||||||
|
def test_chunked_stream_round_trip(tmp_path, monkeypatch):
|
||||||
|
monkeypatch.setattr(file_chunker, "CHUNK_SIZE", 7)
|
||||||
|
path = tmp_path / "artifact.pkl"
|
||||||
|
payload = b"a model artifact spanning several chunks"
|
||||||
|
path.write_bytes(payload)
|
||||||
|
|
||||||
|
targets = file_chunker.get_chunk_targets(path, len(payload))
|
||||||
|
file_chunker.chunk_file(path, targets)
|
||||||
|
|
||||||
|
assert file_chunker.file_chunked_exists(path)
|
||||||
|
assert file_chunker.read_file_chunked(path) == payload
|
||||||
|
with file_chunker.open_file_chunked(path) as stream:
|
||||||
|
assert stream.read(9) + stream.read() == payload
|
||||||
|
|
||||||
|
|
||||||
|
def test_unchunked_stream_does_not_materialize_file(tmp_path, monkeypatch):
|
||||||
|
path = tmp_path / "fat.onnx"
|
||||||
|
payload = b"large model read through bounded buffers"
|
||||||
|
path.write_bytes(payload)
|
||||||
|
original_read_bytes = Path.read_bytes
|
||||||
|
|
||||||
|
def reject_whole_file_read(candidate):
|
||||||
|
if candidate == path:
|
||||||
|
raise AssertionError("streaming must not call Path.read_bytes()")
|
||||||
|
return original_read_bytes(candidate)
|
||||||
|
|
||||||
|
monkeypatch.setattr(Path, "read_bytes", reject_whole_file_read)
|
||||||
|
with file_chunker.open_file_chunked(path) as stream:
|
||||||
|
assert stream.read() == payload
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
from types import SimpleNamespace
|
||||||
|
|
||||||
|
from opendbc.car.hyundai.values import CAR as HYUNDAI_CAR
|
||||||
|
|
||||||
|
from openpilot.starpilot.common.lateral_only_experimental import (
|
||||||
|
experimental_mode_available,
|
||||||
|
lateral_only_experimental_available,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_telluride_platform_allows_lateral_only_experimental_mode():
|
||||||
|
CP = SimpleNamespace(
|
||||||
|
carFingerprint=HYUNDAI_CAR.HYUNDAI_PALISADE_2023,
|
||||||
|
openpilotLongitudinalControl=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert lateral_only_experimental_available(CP)
|
||||||
|
assert experimental_mode_available(CP)
|
||||||
|
|
||||||
|
|
||||||
|
def test_lateral_only_mode_does_not_expand_other_stock_acc_cars():
|
||||||
|
CP = SimpleNamespace(
|
||||||
|
carFingerprint=HYUNDAI_CAR.HYUNDAI_SONATA,
|
||||||
|
openpilotLongitudinalControl=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert not lateral_only_experimental_available(CP)
|
||||||
|
assert not experimental_mode_available(CP)
|
||||||
|
|
||||||
|
old_palisade = SimpleNamespace(
|
||||||
|
carFingerprint=HYUNDAI_CAR.HYUNDAI_PALISADE,
|
||||||
|
openpilotLongitudinalControl=False,
|
||||||
|
)
|
||||||
|
assert not lateral_only_experimental_available(old_palisade)
|
||||||
|
|
||||||
|
|
||||||
|
def test_normal_experimental_mode_remains_available_with_openpilot_long():
|
||||||
|
CP = SimpleNamespace(
|
||||||
|
carFingerprint=HYUNDAI_CAR.HYUNDAI_SONATA,
|
||||||
|
openpilotLongitudinalControl=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert not lateral_only_experimental_available(CP)
|
||||||
|
assert experimental_mode_available(CP)
|
||||||
@@ -25,3 +25,13 @@ TEST_CASE("params_nonblocking_put") {
|
|||||||
REQUIRE(p.get(name) == "1");
|
REQUIRE(p.get(name) == "1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("settings_tier_is_independent_from_tuning_level") {
|
||||||
|
Params params;
|
||||||
|
|
||||||
|
REQUIRE(params.getSettingsTier("AlwaysOnLateral") == SETTINGS_SIMPLE);
|
||||||
|
REQUIRE(params.getTuningLevel("AlwaysOnLateral") == 0);
|
||||||
|
REQUIRE(params.getSettingsTier("HumanLaneChanges") == SETTINGS_SIMPLE);
|
||||||
|
REQUIRE(params.getTuningLevel("HumanLaneChanges") == 2);
|
||||||
|
REQUIRE(params.getSettingsTier("AdvancedLateralTune") == SETTINGS_ADVANCED);
|
||||||
|
}
|
||||||
|
|||||||
@@ -50,11 +50,8 @@ class TestParams:
|
|||||||
assert self.params.get("CarParams", block=True) == b"test"
|
assert self.params.get("CarParams", block=True) == b"test"
|
||||||
|
|
||||||
def test_params_unknown_key_fails(self):
|
def test_params_unknown_key_fails(self):
|
||||||
with pytest.raises(UnknownKeyName):
|
assert self.params.get("swag") is None
|
||||||
self.params.get("swag")
|
assert not self.params.get_bool("swag")
|
||||||
|
|
||||||
with pytest.raises(UnknownKeyName):
|
|
||||||
self.params.get_bool("swag")
|
|
||||||
|
|
||||||
with pytest.raises(UnknownKeyName):
|
with pytest.raises(UnknownKeyName):
|
||||||
self.params.put("swag", "abc")
|
self.params.put("swag", "abc")
|
||||||
|
|||||||
@@ -9,18 +9,6 @@ class TextWindow:
|
|||||||
def __init__(self, text):
|
def __init__(self, text):
|
||||||
self.text_proc = None
|
self.text_proc = None
|
||||||
|
|
||||||
# Prefer the legacy compiled text window on device.
|
|
||||||
legacy_text = os.path.join(BASEDIR, "selfdrive", "ui", "text")
|
|
||||||
if os.path.isfile("/TICI") and os.path.isfile(legacy_text) and os.access(legacy_text, os.X_OK):
|
|
||||||
try:
|
|
||||||
self.text_proc = subprocess.Popen([legacy_text, text],
|
|
||||||
stdin=subprocess.PIPE,
|
|
||||||
cwd=os.path.join(BASEDIR, "selfdrive", "ui"),
|
|
||||||
close_fds=True)
|
|
||||||
return
|
|
||||||
except OSError:
|
|
||||||
self.text_proc = None
|
|
||||||
|
|
||||||
text_cwd = os.path.join(BASEDIR, "system", "ui")
|
text_cwd = os.path.join(BASEDIR, "system", "ui")
|
||||||
venv_python = os.path.join(BASEDIR, ".venv", "bin", "python")
|
venv_python = os.path.join(BASEDIR, ".venv", "bin", "python")
|
||||||
python_exec = venv_python if os.path.isfile(venv_python) else "python3"
|
python_exec = venv_python if os.path.isfile(venv_python) else "python3"
|
||||||
|
|||||||
@@ -2,14 +2,18 @@ import datetime
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
MIN_DATE = datetime.datetime(year=2025, month=2, day=21)
|
MIN_DATE = datetime.datetime(year=2025, month=2, day=21)
|
||||||
|
MAX_DATE = datetime.datetime(year=2035, month=1, day=1)
|
||||||
|
|
||||||
|
def _utc_now_naive():
|
||||||
|
return datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
||||||
|
|
||||||
def min_date():
|
def min_date():
|
||||||
# on systemd systems, the default time is the systemd build time
|
# on systemd systems, the default time is the systemd build time
|
||||||
systemd_path = Path("/lib/systemd/systemd")
|
systemd_path = Path("/lib/systemd/systemd")
|
||||||
if systemd_path.exists():
|
if systemd_path.exists():
|
||||||
d = datetime.datetime.fromtimestamp(systemd_path.stat().st_mtime)
|
d = datetime.datetime.fromtimestamp(systemd_path.stat().st_mtime, datetime.UTC).replace(tzinfo=None)
|
||||||
return max(MIN_DATE, d + datetime.timedelta(days=1))
|
return max(MIN_DATE, d + datetime.timedelta(days=1))
|
||||||
return MIN_DATE
|
return MIN_DATE
|
||||||
|
|
||||||
def system_time_valid():
|
def system_time_valid():
|
||||||
return datetime.datetime.now() > min_date()
|
return min_date() < _utc_now_naive() < MAX_DATE
|
||||||
|
|||||||
Binary file not shown.
+14
-10
@@ -5,7 +5,7 @@ import contextlib
|
|||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
import functools
|
import functools
|
||||||
from subprocess import Popen, PIPE, TimeoutExpired
|
from subprocess import Popen, PIPE, STDOUT, TimeoutExpired
|
||||||
import zstandard as zstd
|
import zstandard as zstd
|
||||||
from openpilot.common.swaglog import cloudlog
|
from openpilot.common.swaglog import cloudlog
|
||||||
|
|
||||||
@@ -87,16 +87,20 @@ def run_cmd_default(cmd: list[str], default: str = "", cwd=None, env=None) -> st
|
|||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def managed_proc(cmd: list[str], env: dict[str, str]):
|
def managed_proc(cmd: list[str], env: dict[str, str]):
|
||||||
proc = Popen(cmd, env=env, stdout=PIPE, stderr=PIPE)
|
# capture output to a temp file rather than a pipe. nothing drains the pipe while the process
|
||||||
try:
|
# runs, so a long lived, chatty child would eventually fill the pipe buffer and block forever.
|
||||||
yield proc
|
with tempfile.TemporaryFile() as log_file:
|
||||||
finally:
|
proc = Popen(cmd, env=env, stdout=log_file, stderr=STDOUT)
|
||||||
if proc.poll() is None:
|
proc.log_file = log_file
|
||||||
proc.terminate()
|
|
||||||
try:
|
try:
|
||||||
proc.wait(timeout=5)
|
yield proc
|
||||||
except TimeoutExpired:
|
finally:
|
||||||
proc.kill()
|
if proc.poll() is None:
|
||||||
|
proc.terminate()
|
||||||
|
try:
|
||||||
|
proc.wait(timeout=5)
|
||||||
|
except TimeoutExpired:
|
||||||
|
proc.kill()
|
||||||
|
|
||||||
|
|
||||||
def retry(attempts=3, delay=1.0, ignore_failure=False):
|
def retry(attempts=3, delay=1.0, ignore_failure=False):
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
#define COMMA_VERSION "0.10.3"
|
#define COMMA_VERSION "0.11.2"
|
||||||
|
|||||||
+22
-2
@@ -8,6 +8,15 @@ from pathlib import Path
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
int(os.environ.get("DEBUG", "0"))
|
||||||
|
except ValueError:
|
||||||
|
os.environ["DEBUG"] = "0"
|
||||||
|
|
||||||
|
if platform.system() == "Darwin":
|
||||||
|
os.environ["SP_HEADLESS_TEST"] = "1"
|
||||||
|
|
||||||
|
|
||||||
def _prepend_host_pytest_runtime() -> None:
|
def _prepend_host_pytest_runtime() -> None:
|
||||||
if platform.system() != "Darwin" or os.getenv("SP_DISABLE_HOST_PYTEST_REDIRECT") == "1":
|
if platform.system() != "Darwin" or os.getenv("SP_DISABLE_HOST_PYTEST_REDIRECT") == "1":
|
||||||
return
|
return
|
||||||
@@ -89,8 +98,7 @@ def openpilot_function_fixture(request):
|
|||||||
# ensure the test doesn't change the prefix
|
# ensure the test doesn't change the prefix
|
||||||
assert "OPENPILOT_PREFIX" in os.environ and prefix == os.environ["OPENPILOT_PREFIX"]
|
assert "OPENPILOT_PREFIX" in os.environ and prefix == os.environ["OPENPILOT_PREFIX"]
|
||||||
|
|
||||||
# cleanup any started processes
|
manager.manager_cleanup()
|
||||||
manager.manager_cleanup()
|
|
||||||
|
|
||||||
# some processes disable gc for performance, re-enable here
|
# some processes disable gc for performance, re-enable here
|
||||||
if not gc.isenabled():
|
if not gc.isenabled():
|
||||||
@@ -118,6 +126,9 @@ def tici_setup_fixture(request, openpilot_function_fixture):
|
|||||||
@pytest.hookimpl(tryfirst=True)
|
@pytest.hookimpl(tryfirst=True)
|
||||||
def pytest_collection_modifyitems(config, items):
|
def pytest_collection_modifyitems(config, items):
|
||||||
skipper = pytest.mark.skip(reason="Skipping tici test on PC")
|
skipper = pytest.mark.skip(reason="Skipping tici test on PC")
|
||||||
|
darwin_fake_event_skipper = pytest.mark.skip(reason="Fake socket events are unavailable on macOS")
|
||||||
|
darwin_tmpfs_skipper = pytest.mark.skip(reason="tmpfs mount tests require Linux")
|
||||||
|
darwin_proxy_skipper = pytest.mark.skip(reason="Athena local proxy socket test requires Linux select semantics")
|
||||||
for item in items:
|
for item in items:
|
||||||
if "tici" in item.keywords:
|
if "tici" in item.keywords:
|
||||||
if not TICI:
|
if not TICI:
|
||||||
@@ -130,6 +141,15 @@ def pytest_collection_modifyitems(config, items):
|
|||||||
class_property_value = getattr(item.cls, class_property_name)
|
class_property_value = getattr(item.cls, class_property_name)
|
||||||
item.add_marker(pytest.mark.xdist_group(class_property_value))
|
item.add_marker(pytest.mark.xdist_group(class_property_value))
|
||||||
|
|
||||||
|
if platform.system() == "Darwin" and item.path.name in ("test_fuzzy.py", "test_processes.py") and "process_replay" in item.path.parts:
|
||||||
|
item.add_marker(darwin_fake_event_skipper)
|
||||||
|
|
||||||
|
if platform.system() == "Darwin" and item.path.name == "test_git.py" and "updated" in item.path.parts:
|
||||||
|
item.add_marker(darwin_tmpfs_skipper)
|
||||||
|
|
||||||
|
if platform.system() == "Darwin" and item.name == "test_start_local_proxy" and "athena" in item.path.parts:
|
||||||
|
item.add_marker(darwin_proxy_skipper)
|
||||||
|
|
||||||
|
|
||||||
@pytest.hookimpl(trylast=True)
|
@pytest.hookimpl(trylast=True)
|
||||||
def pytest_configure(config):
|
def pytest_configure(config):
|
||||||
|
|||||||
+296
-146
@@ -4,108 +4,183 @@
|
|||||||
|
|
||||||
A supported vehicle is one that just works when you install a comma device. All supported cars provide a better experience than any stock system. Supported vehicles reference the US market unless otherwise specified.
|
A supported vehicle is one that just works when you install a comma device. All supported cars provide a better experience than any stock system. Supported vehicles reference the US market unless otherwise specified.
|
||||||
|
|
||||||
# 326 Supported Cars
|
# 453 Supported Cars
|
||||||
|
|
||||||
|Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|<a href="##"><img width=2000></a>Hardware Needed<br> |Video|Setup Video|
|
|Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|<a href="##"><img width=2000></a>Hardware Needed<br> |Video|Setup Video|
|
||||||
|---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
|---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||||
|
|Acura|ADX 2025-26|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura ADX 2025-26">Buy Here</a></sub></details>|||
|
||||||
|Acura|ILX 2016-18|Technology Plus Package or AcuraWatch Plus|openpilot|26 mph|25 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura ILX 2016-18">Buy Here</a></sub></details>|||
|
|Acura|ILX 2016-18|Technology Plus Package or AcuraWatch Plus|openpilot|26 mph|25 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura ILX 2016-18">Buy Here</a></sub></details>|||
|
||||||
|Acura|ILX 2019|All|openpilot|26 mph|25 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura ILX 2019">Buy Here</a></sub></details>|||
|
|Acura|ILX 2019|All|openpilot|26 mph|25 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura ILX 2019">Buy Here</a></sub></details>|||
|
||||||
|Acura|MDX 2025|All except Type S|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura MDX 2025">Buy Here</a></sub></details>|||
|
|Acura|Integra 2023-26|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura Integra 2023-26">Buy Here</a></sub></details>|||
|
||||||
|
|Acura|MDX 2014-16|Advance Package|openpilot|26 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura MDX 2014-16">Buy Here</a></sub></details>|||
|
||||||
|
|Acura|MDX 2017-19|All|openpilot|26 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura MDX 2017-19">Buy Here</a></sub></details>|||
|
||||||
|
|Acura|MDX 2020|All|openpilot|26 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura MDX 2020">Buy Here</a></sub></details>|||
|
||||||
|
|Acura|MDX 2022-24|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|43 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura MDX 2022-24">Buy Here</a></sub></details>|||
|
||||||
|
|Acura|MDX 2025|All except Type S|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura MDX 2025">Buy Here</a></sub></details>|||
|
||||||
|
|Acura|MDX Hybrid 2017-19|All|openpilot|26 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura MDX Hybrid 2017-19">Buy Here</a></sub></details>|||
|
||||||
|
|Acura|MDX Hybrid 2020|All|openpilot|26 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura MDX Hybrid 2020">Buy Here</a></sub></details>|||
|
||||||
|Acura|RDX 2016-18|AcuraWatch Plus or Advance Package|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura RDX 2016-18">Buy Here</a></sub></details>|||
|
|Acura|RDX 2016-18|AcuraWatch Plus or Advance Package|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura RDX 2016-18">Buy Here</a></sub></details>|||
|
||||||
|Acura|RDX 2019-21|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura RDX 2019-21">Buy Here</a></sub></details>|||
|
|Acura|RDX 2019-21|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura RDX 2019-21">Buy Here</a></sub></details>|||
|
||||||
|Acura|TLX 2021|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura TLX 2021">Buy Here</a></sub></details>|||
|
|Acura|RDX 2022-26|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|43 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura RDX 2022-26">Buy Here</a></sub></details>|||
|
||||||
|Audi|A3 2014-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi A3 2014-19">Buy Here</a></sub></details>|||
|
|Acura|TLX 2015-17|Advance Package|openpilot|26 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura TLX 2015-17">Buy Here</a></sub></details>|||
|
||||||
|Audi|A3 Sportback e-tron 2017-18|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi A3 Sportback e-tron 2017-18">Buy Here</a></sub></details>|||
|
|Acura|TLX 2018-20|All|openpilot|26 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura TLX 2018-20">Buy Here</a></sub></details>|||
|
||||||
|Audi|Q2 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi Q2 2018">Buy Here</a></sub></details>|||
|
|Acura|TLX 2021|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura TLX 2021">Buy Here</a></sub></details>|||
|
||||||
|Audi|Q3 2019-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi Q3 2019-24">Buy Here</a></sub></details>|||
|
|Acura|TLX 2024-25|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Acura TLX 2024-25">Buy Here</a></sub></details>|||
|
||||||
|Audi|RS3 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi RS3 2018">Buy Here</a></sub></details>|||
|
|Audi|A3 2014-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi A3 2014-19">Buy Here</a></sub></details>|||
|
||||||
|Audi|S3 2015-17|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi S3 2015-17">Buy Here</a></sub></details>|||
|
|Audi|A3 Sportback e-tron 2017-18|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi A3 Sportback e-tron 2017-18">Buy Here</a></sub></details>|||
|
||||||
|Chevrolet|Bolt EUV 2022-23|Premier or Premier Redline Trim, without Super Cruise Package|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Bolt EUV 2022-23">Buy Here</a></sub></details>|<a href="https://youtu.be/xvwzGMUA210" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Audi|Q2 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi Q2 2018">Buy Here</a></sub></details>|||
|
||||||
|Chevrolet|Bolt EV 2022-23|2LT Trim with Adaptive Cruise Control Package|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Bolt EV 2022-23">Buy Here</a></sub></details>|||
|
|Audi|Q3 2019-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi Q3 2019-24">Buy Here</a></sub></details>|||
|
||||||
|
|Audi|Q4 e-tron 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi Q4 e-tron 2021-23">Buy Here</a></sub></details>|||
|
||||||
|
|Audi|Q4 e-tron 2024-25|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi Q4 e-tron 2024-25">Buy Here</a></sub></details>|||
|
||||||
|
|Audi|RS3 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi RS3 2018">Buy Here</a></sub></details>|||
|
||||||
|
|Audi|S3 2015-17|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Audi S3 2015-17">Buy Here</a></sub></details>|||
|
||||||
|
|Buick|Baby Enclave 2020-23|Driver Assist Package|Stock|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM SDGM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Buick Baby Enclave 2020-23">Buy Here</a></sub></details>|||
|
||||||
|
|Buick[<sup>3</sup>](#footnotes)|LaCrosse 2017-19|Driver Confidence Package 2|openpilot|18 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 OBD-II connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Buick LaCrosse 2017-19">Buy Here</a></sub></details>|||
|
||||||
|
|Buick|LaCrosse ASCM Harness 2017-19|Adaptive Cruise Control (ACC)|Stock|3 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Buick LaCrosse ASCM Harness 2017-19">Buy Here</a></sub></details>|||
|
||||||
|
|Buick|LaCrosse US ASCM Harness 2019|Adaptive Cruise Control (ACC)|Stock|3 mph|27 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Buick LaCrosse US ASCM Harness 2019">Buy Here</a></sub></details>|||
|
||||||
|
|Buick[<sup>3</sup>](#footnotes)|Regal Essence 2018|Adaptive Cruise Control (ACC)|openpilot|18 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 OBD-II connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Buick Regal Essence 2018">Buy Here</a></sub></details>|||
|
||||||
|
|Cadillac[<sup>3</sup>](#footnotes)|ATS Premium Performance 2018|Adaptive Cruise Control (ACC)|openpilot|18 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 OBD-II connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Cadillac ATS Premium Performance 2018">Buy Here</a></sub></details>|||
|
||||||
|
|Cadillac[<sup>3</sup>](#footnotes)|CT6 No-ACC 2016-20|Adaptive Cruise Control (ACC)|openpilot|24 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 OBD-II connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Cadillac CT6 No-ACC 2016-20">Buy Here</a></sub></details>|||
|
||||||
|
|Cadillac[<sup>3</sup>](#footnotes)|Escalade 2017|Driver Assist Package|openpilot|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 OBD-II connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Cadillac Escalade 2017">Buy Here</a></sub></details>|||
|
||||||
|
|Cadillac|Escalade ASCM Harness 2018|Driver Assist Package|Stock|3 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Cadillac Escalade ASCM Harness 2018">Buy Here</a></sub></details>|||
|
||||||
|
|Cadillac[<sup>3</sup>](#footnotes)|Escalade ESV 2016|Adaptive Cruise Control (ACC) & LKAS|openpilot|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 OBD-II connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Cadillac Escalade ESV 2016">Buy Here</a></sub></details>|||
|
||||||
|
|Cadillac[<sup>3</sup>](#footnotes)|Escalade ESV 2019|Adaptive Cruise Control (ACC) & LKAS|openpilot|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 OBD-II connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Cadillac Escalade ESV 2019">Buy Here</a></sub></details>|||
|
||||||
|
|Cadillac|Escalade ESV Platinum ASCM Harness 2019|Adaptive Cruise Control (ACC) & LKAS|Stock|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Cadillac Escalade ESV Platinum ASCM Harness 2019">Buy Here</a></sub></details>|||
|
||||||
|
|Cadillac|XT4 2023|Driver Assist Package|Stock|0 mph|30 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM SDGM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Cadillac XT4 2023">Buy Here</a></sub></details>|||
|
||||||
|
|Cadillac[<sup>3</sup>](#footnotes)|XT4 No-ACC 2023|Adaptive Cruise Control (ACC)|openpilot|24 mph|30 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 OBD-II connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Cadillac XT4 No-ACC 2023">Buy Here</a></sub></details>|||
|
||||||
|
|Cadillac|XT5 2022|Driver Assist Package|Stock|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM SDGM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Cadillac XT5 2022">Buy Here</a></sub></details>|||
|
||||||
|
|Cadillac[<sup>3</sup>](#footnotes)|XT5 No-ACC 2022|Adaptive Cruise Control (ACC)|openpilot|24 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 OBD-II connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Cadillac XT5 No-ACC 2022">Buy Here</a></sub></details>|||
|
||||||
|
|Cadillac|XT6 2020|Driver Assist Package|Stock|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM SDGM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Cadillac XT6 2020">Buy Here</a></sub></details>|||
|
||||||
|
|Chevrolet|Blazer 2019-25|Driver Assist Package|Stock|3 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM SDGM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Blazer 2019-25">Buy Here</a></sub></details>|||
|
||||||
|
|Chevrolet|Bolt EV & EUV ACC 2022-23|Premier or Premier Redline Trim without Super Cruise Package|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Bolt EV & EUV ACC 2022-23">Buy Here</a></sub></details>|<a href="https://youtu.be/xvwzGMUA210" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|
|Chevrolet|Bolt EV & EUV ACC w Pedal 2022-23|Adaptive Cruise Control (ACC)|openpilot|24 mph|6 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Bolt EV & EUV ACC w Pedal 2022-23">Buy Here</a></sub></details>|||
|
||||||
|
|Chevrolet|Bolt EV & EUV No-ACC 2022-23|Adaptive Cruise Control (ACC)|openpilot|24 mph|6 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Bolt EV & EUV No-ACC 2022-23">Buy Here</a></sub></details>|||
|
||||||
|
|Chevrolet|Bolt EV No-ACC 2017|Adaptive Cruise Control (ACC)|openpilot|24 mph|6 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Bolt EV No-ACC 2017">Buy Here</a></sub></details>|||
|
||||||
|
|Chevrolet|Bolt EV No-ACC 2018-21|Adaptive Cruise Control (ACC)|openpilot|24 mph|6 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Bolt EV No-ACC 2018-21">Buy Here</a></sub></details>|||
|
||||||
|Chevrolet|Equinox 2019-22|Adaptive Cruise Control (ACC)|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Equinox 2019-22">Buy Here</a></sub></details>|||
|
|Chevrolet|Equinox 2019-22|Adaptive Cruise Control (ACC)|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Equinox 2019-22">Buy Here</a></sub></details>|||
|
||||||
|Chevrolet|Silverado 1500 2020-21|Safety Package II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|6 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Silverado 1500 2020-21">Buy Here</a></sub></details>|||
|
|Chevrolet[<sup>3</sup>](#footnotes)|Equinox No-ACC 2019-22|Adaptive Cruise Control (ACC)|openpilot|24 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 OBD-II connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Equinox No-ACC 2019-22">Buy Here</a></sub></details>|||
|
||||||
|
|Chevrolet|Malibu 2019|SDGM Harness (Optional SASCM)|Stock|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM SDGM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Malibu 2019">Buy Here</a></sub></details>|||
|
||||||
|
|Chevrolet|Malibu ASCM Harness 2017-19|Adaptive Cruise Control (ACC)|Stock|3 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Malibu ASCM Harness 2017-19">Buy Here</a></sub></details>|||
|
||||||
|
|Chevrolet|Malibu Hybrid No-ACC 2017|Adaptive Cruise Control (ACC)|openpilot|24 mph|6 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Malibu Hybrid No-ACC 2017">Buy Here</a></sub></details>|||
|
||||||
|
|Chevrolet[<sup>3</sup>](#footnotes)|Malibu No-ACC 2023|Adaptive Cruise Control (ACC)|openpilot|24 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 OBD-II connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Malibu No-ACC 2023">Buy Here</a></sub></details>|||
|
||||||
|
|Chevrolet[<sup>3</sup>](#footnotes)|Malibu Premier 2017|Adaptive Cruise Control (ACC)|openpilot|18 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 OBD-II connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Malibu Premier 2017">Buy Here</a></sub></details>|||
|
||||||
|
|Chevrolet|Silverado 1500 2020-21|Safety Package II|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Silverado 1500 2020-21">Buy Here</a></sub></details>|||
|
||||||
|
|Chevrolet[<sup>3</sup>](#footnotes)|Silverado 1500 No-ACC 2020-21|Adaptive Cruise Control (ACC)|openpilot|18 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 OBD-II connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Silverado 1500 No-ACC 2020-21">Buy Here</a></sub></details>|||
|
||||||
|
|Chevrolet[<sup>3</sup>](#footnotes)|Suburban Premier 2016-20|Adaptive Cruise Control (ACC)|openpilot|18 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 OBD-II connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Suburban Premier 2016-20">Buy Here</a></sub></details>|||
|
||||||
|
|Chevrolet[<sup>3</sup>](#footnotes)|Suburban Premier No-ACC 2016-20|Adaptive Cruise Control (ACC)|openpilot|24 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 OBD-II connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Suburban Premier No-ACC 2016-20">Buy Here</a></sub></details>|||
|
||||||
|Chevrolet|Trailblazer 2021-22|Adaptive Cruise Control (ACC)|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Trailblazer 2021-22">Buy Here</a></sub></details>|||
|
|Chevrolet|Trailblazer 2021-22|Adaptive Cruise Control (ACC)|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Trailblazer 2021-22">Buy Here</a></sub></details>|||
|
||||||
|
|Chevrolet[<sup>3</sup>](#footnotes)|Trailblazer No-ACC 2021-22|Adaptive Cruise Control (ACC)|openpilot|24 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 OBD-II connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Trailblazer No-ACC 2021-22">Buy Here</a></sub></details>|||
|
||||||
|
|Chevrolet|Traverse 2022-23|RS, Premier, or High Country Trim|Stock|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM SDGM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Traverse 2022-23">Buy Here</a></sub></details>|||
|
||||||
|
|Chevrolet|TRAX 2024-25|Adaptive Cruise Control (ACC)|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet TRAX 2024-25">Buy Here</a></sub></details>|||
|
||||||
|
|Chevrolet[<sup>3</sup>](#footnotes)|Volt 2017-18|Adaptive Cruise Control (ACC)|openpilot|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 OBD-II connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Volt 2017-18">Buy Here</a></sub></details>|<a href="https://youtu.be/QeMCN_4TFfQ" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|
|Chevrolet|Volt 2019|Adaptive Cruise Control (ACC) & LKAS|Stock|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM SDGM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Volt 2019">Buy Here</a></sub></details>|||
|
||||||
|
|Chevrolet|Volt ASCM Harness 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Volt ASCM Harness 2017-18">Buy Here</a></sub></details>|<a href="https://youtu.be/QeMCN_4TFfQ" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|
|Chevrolet|Volt Camera Harness 2017-18|Flashed camera-forward integration with ACC|openpilot available[<sup>1</sup>](#footnotes)|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Volt Camera Harness 2017-18">Buy Here</a></sub></details>|||
|
||||||
|
|Chevrolet|Volt No-ACC 2016-18 (OBD Harness)|Redneck ACC|openpilot|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-II connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Volt No-ACC 2016-18 (OBD Harness)">Buy Here</a></sub></details>|||
|
||||||
|Chrysler|Pacifica 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chrysler Pacifica 2017-18">Buy Here</a></sub></details>|||
|
|Chrysler|Pacifica 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chrysler Pacifica 2017-18">Buy Here</a></sub></details>|||
|
||||||
|Chrysler|Pacifica 2019-20|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chrysler Pacifica 2019-20">Buy Here</a></sub></details>|||
|
|Chrysler|Pacifica 2019-20|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chrysler Pacifica 2019-20">Buy Here</a></sub></details>|||
|
||||||
|Chrysler|Pacifica 2021-23|All|Stock|0 mph|39 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chrysler Pacifica 2021-23">Buy Here</a></sub></details>|||
|
|Chrysler|Pacifica 2021-23|All|Stock|0 mph|39 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chrysler Pacifica 2021-23">Buy Here</a></sub></details>|||
|
||||||
|Chrysler|Pacifica Hybrid 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chrysler Pacifica Hybrid 2017-18">Buy Here</a></sub></details>|||
|
|Chrysler|Pacifica Hybrid 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chrysler Pacifica Hybrid 2017-18">Buy Here</a></sub></details>|||
|
||||||
|Chrysler|Pacifica Hybrid 2019-25|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chrysler Pacifica Hybrid 2019-25">Buy Here</a></sub></details>|||
|
|Chrysler|Pacifica Hybrid 2019-25|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chrysler Pacifica Hybrid 2019-25">Buy Here</a></sub></details>|||
|
||||||
|comma|body|All|openpilot|0 mph|0 mph|[](##)|[](##)|None|<a href="https://youtu.be/VT-i3yRsX2s?t=2736" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|comma|body|All|openpilot|0 mph|0 mph|[](##)|[](##)|None|<a href="https://youtu.be/VT-i3yRsX2s?t=2736" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|CUPRA|Ateca 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=CUPRA Ateca 2018-23">Buy Here</a></sub></details>|||
|
|CUPRA|Ateca 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=CUPRA Ateca 2018-23">Buy Here</a></sub></details>|||
|
||||||
|
|CUPRA|Born 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=CUPRA Born 2021-23">Buy Here</a></sub></details>|||
|
||||||
|Dodge|Durango 2020-21|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Dodge Durango 2020-21">Buy Here</a></sub></details>|||
|
|Dodge|Durango 2020-21|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Dodge Durango 2020-21">Buy Here</a></sub></details>|||
|
||||||
|Ford|Bronco Sport 2021-24|Co-Pilot360 Assist+|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Bronco Sport 2021-24">Buy Here</a></sub></details>|||
|
|Ford|Bronco Sport 2021-24|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Bronco Sport 2021-24">Buy Here</a></sub></details>|||
|
||||||
|Ford|Escape 2020-22|Co-Pilot360 Assist+|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Escape 2020-22">Buy Here</a></sub></details>|||
|
|Ford|Edge 2022|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Edge 2022">Buy Here</a></sub></details>|||
|
||||||
|
|Ford|Escape 2020-22|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Escape 2020-22">Buy Here</a></sub></details>|||
|
||||||
|Ford|Escape 2023-24|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Escape 2023-24">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
|Ford|Escape 2023-24|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Escape 2023-24">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||||
|Ford|Escape Hybrid 2020-22|Co-Pilot360 Assist+|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Escape Hybrid 2020-22">Buy Here</a></sub></details>|||
|
|Ford|Escape Hybrid 2020-22|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Escape Hybrid 2020-22">Buy Here</a></sub></details>|||
|
||||||
|Ford|Escape Hybrid 2023-24|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Escape Hybrid 2023-24">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
|Ford|Escape Hybrid 2023-24|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Escape Hybrid 2023-24">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||||
|Ford|Escape Plug-in Hybrid 2020-22|Co-Pilot360 Assist+|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Escape Plug-in Hybrid 2020-22">Buy Here</a></sub></details>|||
|
|Ford|Escape Plug-in Hybrid 2020-22|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Escape Plug-in Hybrid 2020-22">Buy Here</a></sub></details>|||
|
||||||
|Ford|Escape Plug-in Hybrid 2023-24|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Escape Plug-in Hybrid 2023-24">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
|Ford|Escape Plug-in Hybrid 2023-24|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Escape Plug-in Hybrid 2023-24">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||||
|Ford|Expedition 2022-24|Co-Pilot360 Assist 2.0|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Expedition 2022-24">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=MewJc9LYp9M" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
|Ford|Expedition 2022-24|Co-Pilot360 Assist 2.0|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Expedition 2022-24">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=MewJc9LYp9M" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||||
|Ford|Explorer 2020-24|Co-Pilot360 Assist+|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Explorer 2020-24">Buy Here</a></sub></details>|||
|
|Ford|Explorer 2020-24|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Explorer 2020-24">Buy Here</a></sub></details>|||
|
||||||
|Ford|Explorer Hybrid 2020-24|Co-Pilot360 Assist+|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Explorer Hybrid 2020-24">Buy Here</a></sub></details>|||
|
|Ford|Explorer Hybrid 2020-24|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Explorer Hybrid 2020-24">Buy Here</a></sub></details>|||
|
||||||
|Ford|F-150 2021-23|Co-Pilot360 Assist 2.0|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford F-150 2021-23">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=MewJc9LYp9M" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
|Ford|F-150 2021-23|Co-Pilot360 Assist 2.0|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford F-150 2021-23">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=MewJc9LYp9M" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||||
|Ford|F-150 Hybrid 2021-23|Co-Pilot360 Assist 2.0|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford F-150 Hybrid 2021-23">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=MewJc9LYp9M" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
|Ford|F-150 Hybrid 2021-23|Co-Pilot360 Assist 2.0|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford F-150 Hybrid 2021-23">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=MewJc9LYp9M" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||||
|Ford|Focus 2018[<sup>2</sup>](#footnotes)|Adaptive Cruise Control with Lane Centering|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Focus 2018">Buy Here</a></sub></details>|||
|
|Ford|F-150 Lightning 2022-25|Co-Pilot360 Assist 2.0|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford F-150 Lightning 2022-25">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=MewJc9LYp9M" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||||
|Ford|Focus Hybrid 2018[<sup>2</sup>](#footnotes)|Adaptive Cruise Control with Lane Centering|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Focus Hybrid 2018">Buy Here</a></sub></details>|||
|
|Ford|Focus 2018-22[<sup>2</sup>](#footnotes)|Adaptive Cruise Control with Lane Centering|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Focus 2018-22">Buy Here</a></sub></details>|||
|
||||||
|Ford|Kuga 2020-23|Adaptive Cruise Control with Lane Centering|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Kuga 2020-23">Buy Here</a></sub></details>|||
|
|Ford|Focus Hybrid 2018-22[<sup>2</sup>](#footnotes)|Adaptive Cruise Control with Lane Centering|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Focus Hybrid 2018-22">Buy Here</a></sub></details>|||
|
||||||
|Ford|Kuga Hybrid 2020-23|Adaptive Cruise Control with Lane Centering|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Kuga Hybrid 2020-23">Buy Here</a></sub></details>|||
|
|Ford|Kuga 2020-23|Adaptive Cruise Control with Lane Centering|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Kuga 2020-23">Buy Here</a></sub></details>|||
|
||||||
|
|Ford|Kuga Hybrid 2020-23|Adaptive Cruise Control with Lane Centering|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Kuga Hybrid 2020-23">Buy Here</a></sub></details>|||
|
||||||
|Ford|Kuga Hybrid 2024|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Kuga Hybrid 2024">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
|Ford|Kuga Hybrid 2024|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Kuga Hybrid 2024">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||||
|Ford|Kuga Plug-in Hybrid 2020-23|Adaptive Cruise Control with Lane Centering|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Kuga Plug-in Hybrid 2020-23">Buy Here</a></sub></details>|||
|
|Ford|Kuga Plug-in Hybrid 2020-23|Adaptive Cruise Control with Lane Centering|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Kuga Plug-in Hybrid 2020-23">Buy Here</a></sub></details>|||
|
||||||
|Ford|Kuga Plug-in Hybrid 2024|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Kuga Plug-in Hybrid 2024">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
|Ford|Kuga Plug-in Hybrid 2024|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Kuga Plug-in Hybrid 2024">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||||
|Ford|Maverick 2022|LARIAT Luxury|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Maverick 2022">Buy Here</a></sub></details>|||
|
|Ford|Maverick 2022|LARIAT Luxury|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Maverick 2022">Buy Here</a></sub></details>|||
|
||||||
|Ford|Maverick 2023-24|Co-Pilot360 Assist|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Maverick 2023-24">Buy Here</a></sub></details>|||
|
|Ford|Maverick 2023-24|Co-Pilot360 Assist|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Maverick 2023-24">Buy Here</a></sub></details>|||
|
||||||
|Ford|Maverick Hybrid 2022|LARIAT Luxury|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Maverick Hybrid 2022">Buy Here</a></sub></details>|||
|
|Ford|Maverick Hybrid 2022|LARIAT Luxury|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Maverick Hybrid 2022">Buy Here</a></sub></details>|||
|
||||||
|Ford|Maverick Hybrid 2023-24|Co-Pilot360 Assist|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Maverick Hybrid 2023-24">Buy Here</a></sub></details>|||
|
|Ford|Maverick Hybrid 2023-24|Co-Pilot360 Assist|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Maverick Hybrid 2023-24">Buy Here</a></sub></details>|||
|
||||||
|
|Ford|Mondeo 2014-22|Adaptive Cruise Control with Lane Centering|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Mondeo 2014-22">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||||
|Ford|Mustang Mach-E 2021-24|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Mustang Mach-E 2021-24">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
|Ford|Mustang Mach-E 2021-24|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Mustang Mach-E 2021-24">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||||
|Ford|Ranger 2024|Adaptive Cruise Control with Lane Centering|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Ranger 2024">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
|Ford|Ranger 2024|Adaptive Cruise Control with Lane Centering|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q4 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Ranger 2024">Buy Here</a></sub></details>||<a href="https://www.youtube.com/watch?v=uUGkH6C_EQU" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||||
|
|Ford|Transit 2025|Co-Pilot360 Assist+|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ford Transit 2025">Buy Here</a></sub></details>|||
|
||||||
|Genesis|G70 2018|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai F connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis G70 2018">Buy Here</a></sub></details>|||
|
|Genesis|G70 2018|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai F connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis G70 2018">Buy Here</a></sub></details>|||
|
||||||
|Genesis|G70 2019-21|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai F connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis G70 2019-21">Buy Here</a></sub></details>|||
|
|Genesis|G70 2019-21|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai F connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis G70 2019-21">Buy Here</a></sub></details>|||
|
||||||
|Genesis|G70 2022-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis G70 2022-23">Buy Here</a></sub></details>|||
|
|Genesis|G70 2022-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis G70 2022-23">Buy Here</a></sub></details>|||
|
||||||
|Genesis|G80 2017|All|Stock|19 mph|37 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai J connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis G80 2017">Buy Here</a></sub></details>|||
|
|Genesis|G80 2017|All|Stock|19 mph|37 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai J connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis G80 2017">Buy Here</a></sub></details>|||
|
||||||
|Genesis|G80 2018-19|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai H connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis G80 2018-19">Buy Here</a></sub></details>|||
|
|Genesis|G80 2018-19|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai H connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis G80 2018-19">Buy Here</a></sub></details>|||
|
||||||
|Genesis|G80 (2.5T Advanced Trim, with HDA II) 2024|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai P connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis G80 (2.5T Advanced Trim, with HDA II) 2024">Buy Here</a></sub></details>|||
|
|Genesis|G80 (2.5T Advanced Trim, with HDA II) 2024|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai P connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis G80 (2.5T Advanced Trim, with HDA II) 2024">Buy Here</a></sub></details>|||
|
||||||
|Genesis|G90 2017-20|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis G90 2017-20">Buy Here</a></sub></details>|||
|
|Genesis|G90 2017-20|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis G90 2017-20">Buy Here</a></sub></details>|||
|
||||||
|Genesis|GV60 (Advanced Trim) 2023|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis GV60 (Advanced Trim) 2023">Buy Here</a></sub></details>|||
|
|Genesis|GV60 (Advanced Trim) 2023|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis GV60 (Advanced Trim) 2023">Buy Here</a></sub></details>|||
|
||||||
|Genesis|GV60 (Performance Trim) 2022-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis GV60 (Performance Trim) 2022-23">Buy Here</a></sub></details>|||
|
|Genesis|GV60 (Performance Trim) 2022-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis GV60 (Performance Trim) 2022-23">Buy Here</a></sub></details>|||
|
||||||
|Genesis|GV70 (2.5T Trim, without HDA II) 2022-24|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis GV70 (2.5T Trim, without HDA II) 2022-24">Buy Here</a></sub></details>|||
|
|Genesis|GV70 (2.5T Trim, without HDA II) 2022-24|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis GV70 (2.5T Trim, without HDA II) 2022-24">Buy Here</a></sub></details>|||
|
||||||
|
|Genesis|GV70 (3.5T Sport Prestige Trim, with HDA II & LFA2) 2026|Highway Driving Assist II & Lane Follow Assist 2|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai M connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis GV70 (3.5T Sport Prestige Trim, with HDA II & LFA2) 2026">Buy Here</a></sub></details>|||
|
||||||
|Genesis|GV70 (3.5T Trim, without HDA II) 2022-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai M connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis GV70 (3.5T Trim, without HDA II) 2022-23">Buy Here</a></sub></details>|||
|
|Genesis|GV70 (3.5T Trim, without HDA II) 2022-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai M connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis GV70 (3.5T Trim, without HDA II) 2022-23">Buy Here</a></sub></details>|||
|
||||||
|
|Genesis|GV70 Electrified 2026|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai M connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis GV70 Electrified 2026">Buy Here</a></sub></details>|||
|
||||||
|Genesis|GV70 Electrified (Australia Only) 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai Q connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis GV70 Electrified (Australia Only) 2022">Buy Here</a></sub></details>|||
|
|Genesis|GV70 Electrified (Australia Only) 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai Q connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis GV70 Electrified (Australia Only) 2022">Buy Here</a></sub></details>|||
|
||||||
|Genesis|GV70 Electrified (with HDA II) 2023-24|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai Q connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis GV70 Electrified (with HDA II) 2023-24">Buy Here</a></sub></details>|||
|
|Genesis|GV70 Electrified (with HDA II) 2023-24|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai Q connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis GV70 Electrified (with HDA II) 2023-24">Buy Here</a></sub></details>|||
|
||||||
|Genesis|GV80 2023|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai M connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis GV80 2023">Buy Here</a></sub></details>|||
|
|Genesis|GV80 2023|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai M connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis GV80 2023">Buy Here</a></sub></details>|||
|
||||||
|GMC|Sierra 1500 2020-21|Driver Alert Package II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|6 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=GMC Sierra 1500 2020-21">Buy Here</a></sub></details>|<a href="https://youtu.be/5HbNoBLzRwE" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Genesis|GV80 (3.5T Prestige Trim, with HDA II & LFA2) 2025|Highway Driving Assist II & Lane Follow Assist 2|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai Q connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis GV80 (3.5T Prestige Trim, with HDA II & LFA2) 2025">Buy Here</a></sub></details>|||
|
||||||
|Honda|Accord 2018-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Accord 2018-22">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=mrUwlj3Mi58" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Genesis|GV80 Coupe (with HDA II & LFA2) 2025|Highway Driving Assist II & Lane Follow Assist 2|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai Q connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis GV80 Coupe (with HDA II & LFA2) 2025">Buy Here</a></sub></details>|||
|
||||||
|Honda|Accord 2023-25|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Accord 2023-25">Buy Here</a></sub></details>|||
|
|GMC[<sup>3</sup>](#footnotes)|Acadia 2018|Adaptive Cruise Control (ACC)|openpilot|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 OBD-II connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=GMC Acadia 2018">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=0ZN6DdsBUZo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Honda|Accord Hybrid 2018-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Accord Hybrid 2018-22">Buy Here</a></sub></details>|||
|
|GMC|Acadia ASCM Harness 2018|Adaptive Cruise Control (ACC)|Stock|3 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=GMC Acadia ASCM Harness 2018">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=0ZN6DdsBUZo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Honda|Accord Hybrid 2023-25|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Accord Hybrid 2023-25">Buy Here</a></sub></details>|||
|
|GMC|Sierra 1500 2020-21|Driver Alert Package II|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=GMC Sierra 1500 2020-21">Buy Here</a></sub></details>|<a href="https://youtu.be/5HbNoBLzRwE" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Honda|City (Brazil only) 2023|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|14 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda City (Brazil only) 2023">Buy Here</a></sub></details>|||
|
|GMC[<sup>3</sup>](#footnotes)|Sierra 1500 No-ACC 2020-21|Adaptive Cruise Control (ACC)|openpilot|18 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 OBD-II connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=GMC Sierra 1500 No-ACC 2020-21">Buy Here</a></sub></details>|||
|
||||||
|
|GMC|Yukon 2019-20|Adaptive Cruise Control (ACC) & LKAS|Stock|0 mph|6 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=GMC Yukon 2019-20">Buy Here</a></sub></details>|||
|
||||||
|
|GMC[<sup>3</sup>](#footnotes)|Yukon No-ACC 2019-20|Adaptive Cruise Control (ACC)|openpilot|24 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 OBD-II connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=GMC Yukon No-ACC 2019-20">Buy Here</a></sub></details>|||
|
||||||
|
|Holden[<sup>3</sup>](#footnotes)|Astra 2017|Adaptive Cruise Control (ACC)|openpilot|18 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 OBD-II connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Holden Astra 2017">Buy Here</a></sub></details>|||
|
||||||
|
|Honda|Accord 2016-17|Honda Sensing|openpilot|26 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Accord 2016-17">Buy Here</a></sub></details>|||
|
||||||
|
|Honda|Accord 2018-22|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Accord 2018-22">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=mrUwlj3Mi58" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|
|Honda|Accord 2023-25|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Accord 2023-25">Buy Here</a></sub></details>|||
|
||||||
|
|Honda|Accord Hybrid 2017|All|openpilot|26 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Accord Hybrid 2017">Buy Here</a></sub></details>|||
|
||||||
|
|Honda|Accord Hybrid 2018-22|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Accord Hybrid 2018-22">Buy Here</a></sub></details>|||
|
||||||
|
|Honda|Accord Hybrid 2023-25|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Accord Hybrid 2023-25">Buy Here</a></sub></details>|||
|
||||||
|
|Honda|City (Brazil only) 2023|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|14 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda City (Brazil only) 2023">Buy Here</a></sub></details>|||
|
||||||
|Honda|Civic 2016-18|Honda Sensing|openpilot|0 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic 2016-18">Buy Here</a></sub></details>|<a href="https://youtu.be/-IkImTe1NYE" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Honda|Civic 2016-18|Honda Sensing|openpilot|0 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic 2016-18">Buy Here</a></sub></details>|<a href="https://youtu.be/-IkImTe1NYE" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Honda|Civic 2019-21|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|2 mph[<sup>4</sup>](#footnotes)|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic 2019-21">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=4Iz1Mz5LGF8" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Honda|Civic 2019-21|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|2 mph[<sup>4</sup>](#footnotes)|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic 2019-21">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=4Iz1Mz5LGF8" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Honda|Civic 2022-24|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic 2022-24">Buy Here</a></sub></details>|<a href="https://youtu.be/ytiOT5lcp6Q" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Honda|Civic 2022-24|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic 2022-24">Buy Here</a></sub></details>|<a href="https://youtu.be/ytiOT5lcp6Q" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Honda|Civic Hatchback 2017-18|Honda Sensing|openpilot available[<sup>1</sup>](#footnotes)|0 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic Hatchback 2017-18">Buy Here</a></sub></details>|||
|
|Honda|Civic Hatchback 2017-18|Honda Sensing|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic Hatchback 2017-18">Buy Here</a></sub></details>|||
|
||||||
|Honda|Civic Hatchback 2019-21|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic Hatchback 2019-21">Buy Here</a></sub></details>|||
|
|Honda|Civic Hatchback 2019-21|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic Hatchback 2019-21">Buy Here</a></sub></details>|||
|
||||||
|Honda|Civic Hatchback 2022-24|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic Hatchback 2022-24">Buy Here</a></sub></details>|<a href="https://youtu.be/ytiOT5lcp6Q" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Honda|Civic Hatchback 2022-24|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic Hatchback 2022-24">Buy Here</a></sub></details>|<a href="https://youtu.be/ytiOT5lcp6Q" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Honda|Civic Hatchback Hybrid 2025-26|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic Hatchback Hybrid 2025-26">Buy Here</a></sub></details>|||
|
|Honda|Civic Hatchback Hybrid 2025-26|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic Hatchback Hybrid 2025-26">Buy Here</a></sub></details>|||
|
||||||
|Honda|Civic Hatchback Hybrid (Europe only) 2023|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic Hatchback Hybrid (Europe only) 2023">Buy Here</a></sub></details>|||
|
|Honda|Civic Hatchback Hybrid (Europe only) 2023|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic Hatchback Hybrid (Europe only) 2023">Buy Here</a></sub></details>|||
|
||||||
|Honda|Civic Hybrid 2025-26|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic Hybrid 2025-26">Buy Here</a></sub></details>|||
|
|Honda|Civic Hybrid 2025-26|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic Hybrid 2025-26">Buy Here</a></sub></details>|||
|
||||||
|
|Honda|Clarity 2018-21|All|openpilot|0 mph|3 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Clarity 2018-21">Buy Here</a></sub></details>|||
|
||||||
|Honda|CR-V 2015-16|Touring Trim|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda CR-V 2015-16">Buy Here</a></sub></details>|||
|
|Honda|CR-V 2015-16|Touring Trim|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda CR-V 2015-16">Buy Here</a></sub></details>|||
|
||||||
|Honda|CR-V 2017-22|Honda Sensing|openpilot available[<sup>1</sup>](#footnotes)|0 mph|15 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda CR-V 2017-22">Buy Here</a></sub></details>|||
|
|Honda|CR-V 2017-22|Honda Sensing|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|15 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda CR-V 2017-22">Buy Here</a></sub></details>|||
|
||||||
|Honda|CR-V 2023-26|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda CR-V 2023-26">Buy Here</a></sub></details>|||
|
|Honda|CR-V 2023-26|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda CR-V 2023-26">Buy Here</a></sub></details>|||
|
||||||
|Honda|CR-V Hybrid 2017-22|Honda Sensing|openpilot available[<sup>1</sup>](#footnotes)|0 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda CR-V Hybrid 2017-22">Buy Here</a></sub></details>|||
|
|Honda|CR-V Hybrid 2017-22|Honda Sensing|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda CR-V Hybrid 2017-22">Buy Here</a></sub></details>|||
|
||||||
|Honda|CR-V Hybrid 2023-25|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda CR-V Hybrid 2023-25">Buy Here</a></sub></details>|||
|
|Honda|CR-V Hybrid 2023-25|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda CR-V Hybrid 2023-25">Buy Here</a></sub></details>|||
|
||||||
|Honda|e 2020|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda e 2020">Buy Here</a></sub></details>|||
|
|Honda|e 2020|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda e 2020">Buy Here</a></sub></details>|||
|
||||||
|Honda|Fit 2018-20|Honda Sensing|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Fit 2018-20">Buy Here</a></sub></details>|||
|
|Honda|Fit 2018-20|Honda Sensing|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Fit 2018-20">Buy Here</a></sub></details>|||
|
||||||
|
|Honda|Fit (Taiwan) 2021|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|14 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Fit (Taiwan) 2021">Buy Here</a></sub></details>|||
|
||||||
|
|Honda|Fit (Taiwan) 2024-25|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|14 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Fit (Taiwan) 2024-25">Buy Here</a></sub></details>|||
|
||||||
|Honda|Freed 2020|Honda Sensing|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Freed 2020">Buy Here</a></sub></details>|||
|
|Honda|Freed 2020|Honda Sensing|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Freed 2020">Buy Here</a></sub></details>|||
|
||||||
|Honda|HR-V 2019-22|Honda Sensing|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda HR-V 2019-22">Buy Here</a></sub></details>|||
|
|Honda|HR-V 2019-22|Honda Sensing|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda HR-V 2019-22">Buy Here</a></sub></details>|||
|
||||||
|Honda|HR-V 2023-25|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda HR-V 2023-25">Buy Here</a></sub></details>|||
|
|Honda|HR-V 2023-25|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda HR-V 2023-25">Buy Here</a></sub></details>|||
|
||||||
|Honda|Insight 2019-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Insight 2019-22">Buy Here</a></sub></details>|||
|
|Honda|Insight 2019-22|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Insight 2019-22">Buy Here</a></sub></details>|||
|
||||||
|Honda|Inspire 2018|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Inspire 2018">Buy Here</a></sub></details>|||
|
|Honda|Inspire 2018|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Inspire 2018">Buy Here</a></sub></details>|||
|
||||||
|Honda|N-Box 2018|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|11 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda N-Box 2018">Buy Here</a></sub></details>|||
|
|Honda|N-Box 2018|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|11 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda N-Box 2018">Buy Here</a></sub></details>|||
|
||||||
|Honda|Odyssey 2018-20|Honda Sensing|openpilot|26 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Odyssey 2018-20">Buy Here</a></sub></details>|||
|
|Honda|Odyssey 2018-20|Honda Sensing|openpilot|26 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Odyssey 2018-20">Buy Here</a></sub></details>|||
|
||||||
|Honda|Odyssey 2021-26|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|43 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Odyssey 2021-26">Buy Here</a></sub></details>|||
|
|Honda|Odyssey 2021-26|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|43 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Odyssey 2021-26">Buy Here</a></sub></details>|||
|
||||||
|
|Honda|Odyssey (Singapore) 2021|Honda Sensing|openpilot|19 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Odyssey (Singapore) 2021">Buy Here</a></sub></details>|||
|
||||||
|
|Honda|Odyssey (Taiwan) 2018-19|Honda Sensing|openpilot|19 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Odyssey (Taiwan) 2018-19">Buy Here</a></sub></details>|||
|
||||||
|Honda|Passport 2019-25|All|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Passport 2019-25">Buy Here</a></sub></details>|||
|
|Honda|Passport 2019-25|All|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Passport 2019-25">Buy Here</a></sub></details>|||
|
||||||
|Honda|Passport 2026|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Passport 2026">Buy Here</a></sub></details>|||
|
|Honda|Passport 2026|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Passport 2026">Buy Here</a></sub></details>|||
|
||||||
|Honda|Pilot 2016-22|Honda Sensing|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Pilot 2016-22">Buy Here</a></sub></details>|||
|
|Honda|Pilot 2016-22|Honda Sensing|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Pilot 2016-22">Buy Here</a></sub></details>|||
|
||||||
|Honda|Pilot 2023-25|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Pilot 2023-25">Buy Here</a></sub></details>|||
|
|Honda|Pilot 2023-25|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Pilot 2023-25">Buy Here</a></sub></details>|||
|
||||||
|
|Honda|Prelude 2026|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Prelude 2026">Buy Here</a></sub></details>|||
|
||||||
|Honda|Ridgeline 2017-25|Honda Sensing|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Ridgeline 2017-25">Buy Here</a></sub></details>|||
|
|Honda|Ridgeline 2017-25|Honda Sensing|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Ridgeline 2017-25">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Azera 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Azera 2022">Buy Here</a></sub></details>|||
|
|Hyundai|Azera 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Azera 2022">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Azera Hybrid 2019|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Azera Hybrid 2019">Buy Here</a></sub></details>|||
|
|Hyundai|Azera Hybrid 2019|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Azera Hybrid 2019">Buy Here</a></sub></details>|||
|
||||||
@@ -115,14 +190,20 @@ A supported vehicle is one that just works when you install a comma device. All
|
|||||||
|Hyundai|Elantra 2017-18|Smart Cruise Control (SCC)|Stock|19 mph|32 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Elantra 2017-18">Buy Here</a></sub></details>|||
|
|Hyundai|Elantra 2017-18|Smart Cruise Control (SCC)|Stock|19 mph|32 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Elantra 2017-18">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Elantra 2019|Smart Cruise Control (SCC)|Stock|19 mph|32 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai G connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Elantra 2019">Buy Here</a></sub></details>|||
|
|Hyundai|Elantra 2019|Smart Cruise Control (SCC)|Stock|19 mph|32 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai G connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Elantra 2019">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Elantra 2021-23|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Elantra 2021-23">Buy Here</a></sub></details>|<a href="https://youtu.be/_EdYQtV52-c" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Hyundai|Elantra 2021-23|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Elantra 2021-23">Buy Here</a></sub></details>|<a href="https://youtu.be/_EdYQtV52-c" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|
|Hyundai|Elantra 2024-25|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Elantra 2024-25">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Elantra GT 2017-20|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Elantra GT 2017-20">Buy Here</a></sub></details>|||
|
|Hyundai|Elantra GT 2017-20|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Elantra GT 2017-20">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Elantra Hybrid 2021-23|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Elantra Hybrid 2021-23">Buy Here</a></sub></details>|<a href="https://youtu.be/_EdYQtV52-c" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Hyundai|Elantra Hybrid 2021-23|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Elantra Hybrid 2021-23">Buy Here</a></sub></details>|<a href="https://youtu.be/_EdYQtV52-c" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|
|Hyundai|Elantra Hybrid 2024-26|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Elantra Hybrid 2024-26">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Genesis 2015-16|Smart Cruise Control (SCC)|Stock|19 mph|37 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai J connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Genesis 2015-16">Buy Here</a></sub></details>|||
|
|Hyundai|Genesis 2015-16|Smart Cruise Control (SCC)|Stock|19 mph|37 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai J connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Genesis 2015-16">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|i30 2017-19|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai i30 2017-19">Buy Here</a></sub></details>|||
|
|Hyundai|i30 2017-19|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai i30 2017-19">Buy Here</a></sub></details>|||
|
||||||
|
|Hyundai|i30 Hybrid 2024|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai i30 Hybrid 2024">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Ioniq 5 (Southeast Asia and Europe only) 2022-24|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai Q connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq 5 (Southeast Asia and Europe only) 2022-24">Buy Here</a></sub></details>|||
|
|Hyundai|Ioniq 5 (Southeast Asia and Europe only) 2022-24|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai Q connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq 5 (Southeast Asia and Europe only) 2022-24">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Ioniq 5 (with HDA II) 2022-24|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai Q connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq 5 (with HDA II) 2022-24">Buy Here</a></sub></details>|||
|
|Hyundai|Ioniq 5 (with HDA II) 2022-24|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai Q connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq 5 (with HDA II) 2022-24">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Ioniq 5 (without HDA II) 2022-24|Highway Driving Assist|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq 5 (without HDA II) 2022-24">Buy Here</a></sub></details>|||
|
|Hyundai|Ioniq 5 (without HDA II) 2022-24|Highway Driving Assist|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq 5 (without HDA II) 2022-24">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Ioniq 6 (with HDA II) 2023-24|Highway Driving Assist II|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai P connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq 6 (with HDA II) 2023-24">Buy Here</a></sub></details>|||
|
|Hyundai|Ioniq 5 N (with HDA II) 2024|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai S connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq 5 N (with HDA II) 2024">Buy Here</a></sub></details>|||
|
||||||
|
|Hyundai|Ioniq 5 PE (with HDA II & LFA2) 2025-26|Highway Driving Assist II & Lane Follow Assist 2|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai Q connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq 5 PE (with HDA II & LFA2) 2025-26">Buy Here</a></sub></details>|||
|
||||||
|
|Hyundai|Ioniq 6 (with HDA II) 2023-24|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai P connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq 6 (with HDA II) 2023-24">Buy Here</a></sub></details>|||
|
||||||
|
|Hyundai|Ioniq 9 (with HDA II & LFA2) 2025-26|Highway Driving Assist II & Lane Follow Assist 2|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai M connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq 9 (with HDA II & LFA2) 2025-26">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Ioniq Electric 2019|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq Electric 2019">Buy Here</a></sub></details>|||
|
|Hyundai|Ioniq Electric 2019|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq Electric 2019">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Ioniq Electric 2020|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai H connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq Electric 2020">Buy Here</a></sub></details>|||
|
|Hyundai|Ioniq Electric 2020|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai H connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq Electric 2020">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Ioniq Hybrid 2017-19|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|32 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq Hybrid 2017-19">Buy Here</a></sub></details>|||
|
|Hyundai|Ioniq Hybrid 2017-19|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|32 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq Hybrid 2017-19">Buy Here</a></sub></details>|||
|
||||||
@@ -130,39 +211,62 @@ A supported vehicle is one that just works when you install a comma device. All
|
|||||||
|Hyundai|Ioniq Plug-in Hybrid 2019|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|32 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq Plug-in Hybrid 2019">Buy Here</a></sub></details>|||
|
|Hyundai|Ioniq Plug-in Hybrid 2019|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|32 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq Plug-in Hybrid 2019">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Ioniq Plug-in Hybrid 2020-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai H connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq Plug-in Hybrid 2020-22">Buy Here</a></sub></details>|||
|
|Hyundai|Ioniq Plug-in Hybrid 2020-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai H connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Ioniq Plug-in Hybrid 2020-22">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Kona 2020|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|6 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Kona 2020">Buy Here</a></sub></details>|||
|
|Hyundai|Kona 2020|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|6 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Kona 2020">Buy Here</a></sub></details>|||
|
||||||
|
|Hyundai|Kona (without HDA II) 2024-25|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Kona (without HDA II) 2024-25">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Kona Electric 2018-21|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai G connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Kona Electric 2018-21">Buy Here</a></sub></details>|||
|
|Hyundai|Kona Electric 2018-21|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai G connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Kona Electric 2018-21">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Kona Electric 2022-23|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai O connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Kona Electric 2022-23">Buy Here</a></sub></details>|||
|
|Hyundai|Kona Electric 2022-23|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai O connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Kona Electric 2022-23">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Kona Electric (with HDA II, Korea only) 2023|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai R connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Kona Electric (with HDA II, Korea only) 2023">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=U2fOCmcQ8hw" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Hyundai|Kona Electric (with HDA II, Korea only) 2023|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai R connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Kona Electric (with HDA II, Korea only) 2023">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=U2fOCmcQ8hw" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|
|Hyundai|Kona Electric (without HDA II) 2024|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Kona Electric (without HDA II) 2024">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Kona Hybrid 2020|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai I connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Kona Hybrid 2020">Buy Here</a></sub></details>|||
|
|Hyundai|Kona Hybrid 2020|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai I connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Kona Hybrid 2020">Buy Here</a></sub></details>|||
|
||||||
|
|Hyundai|Kona Hybrid (without HDA II) 2024|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Kona Hybrid (without HDA II) 2024">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Nexo 2021|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai H connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Nexo 2021">Buy Here</a></sub></details>|||
|
|Hyundai|Nexo 2021|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai H connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Nexo 2021">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Palisade 2020-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai H connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Palisade 2020-22">Buy Here</a></sub></details>|<a href="https://youtu.be/TAnDqjF4fDY?t=456" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Hyundai|Palisade 2020-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai H connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Palisade 2020-22">Buy Here</a></sub></details>|<a href="https://youtu.be/TAnDqjF4fDY?t=456" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|
|Hyundai|Palisade (with HDA II) 2023-25|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai R connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Palisade (with HDA II) 2023-25">Buy Here</a></sub></details>|||
|
||||||
|
|Hyundai|Palisade (without HDA II) 2023-25|Highway Driving Assist|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Palisade (without HDA II) 2023-25">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Santa Cruz 2022-24|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Santa Cruz 2022-24">Buy Here</a></sub></details>|||
|
|Hyundai|Santa Cruz 2022-24|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Santa Cruz 2022-24">Buy Here</a></sub></details>|||
|
||||||
|
|Hyundai|Santa Cruz (without HDA II) 2025|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Santa Cruz (without HDA II) 2025">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Santa Fe 2019-20|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai D connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Santa Fe 2019-20">Buy Here</a></sub></details>|<a href="https://youtu.be/bjDR0YjM__s" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Hyundai|Santa Fe 2019-20|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai D connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Santa Fe 2019-20">Buy Here</a></sub></details>|<a href="https://youtu.be/bjDR0YjM__s" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Hyundai|Santa Fe 2021-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Santa Fe 2021-23">Buy Here</a></sub></details>|<a href="https://youtu.be/VnHzSTygTS4" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Hyundai|Santa Fe 2021-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Santa Fe 2021-23">Buy Here</a></sub></details>|<a href="https://youtu.be/VnHzSTygTS4" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Hyundai|Santa Fe Hybrid 2022-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Santa Fe Hybrid 2022-23">Buy Here</a></sub></details>|||
|
|Hyundai|Santa Fe Hybrid 2022-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Santa Fe Hybrid 2022-23">Buy Here</a></sub></details>|||
|
||||||
|
|Hyundai|Santa Fe Hybrid (with HDA II & LFA2) 2024-25|Highway Driving Assist II & Lane Follow Assist 2|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai P connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Santa Fe Hybrid (with HDA II & LFA2) 2024-25">Buy Here</a></sub></details>|||
|
||||||
|
|Hyundai|Santa Fe Hybrid (without HDA II, LFA2) 2025-26|Lane Follow Assist 2|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Santa Fe Hybrid (without HDA II, LFA2) 2025-26">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Santa Fe Plug-in Hybrid 2022-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Santa Fe Plug-in Hybrid 2022-23">Buy Here</a></sub></details>|||
|
|Hyundai|Santa Fe Plug-in Hybrid 2022-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Santa Fe Plug-in Hybrid 2022-23">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Sonata 2018-19|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Sonata 2018-19">Buy Here</a></sub></details>|||
|
|Hyundai|Sonata 2018-19|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Sonata 2018-19">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Sonata 2020-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Sonata 2020-23">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=ix63r9kE3Fw" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Hyundai|Sonata 2020-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Sonata 2020-23">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=ix63r9kE3Fw" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|
|Hyundai|Sonata (without HDA II) 2024-25|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Sonata (without HDA II) 2024-25">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Sonata Hybrid 2020-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Sonata Hybrid 2020-23">Buy Here</a></sub></details>|||
|
|Hyundai|Sonata Hybrid 2020-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Sonata Hybrid 2020-23">Buy Here</a></sub></details>|||
|
||||||
|
|Hyundai|Sonata Hybrid (without HDA II) 2024-25|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Sonata Hybrid (without HDA II) 2024-25">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Staria 2023|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Staria 2023">Buy Here</a></sub></details>|||
|
|Hyundai|Staria 2023|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Staria 2023">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Tucson 2021|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|19 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Tucson 2021">Buy Here</a></sub></details>|||
|
|Hyundai|Tucson 2021|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|19 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Tucson 2021">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Tucson 2022|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Tucson 2022">Buy Here</a></sub></details>|||
|
|Hyundai|Tucson 2022|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Tucson 2022">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Tucson 2023-24|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Tucson 2023-24">Buy Here</a></sub></details>|||
|
|Hyundai|Tucson 2023-24|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Tucson 2023-24">Buy Here</a></sub></details>|||
|
||||||
|
|Hyundai|Tucson (without HDA II) 2025-26|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Tucson (without HDA II) 2025-26">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Tucson Diesel 2019|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Tucson Diesel 2019">Buy Here</a></sub></details>|||
|
|Hyundai|Tucson Diesel 2019|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Tucson Diesel 2019">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Tucson Hybrid 2022-24|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Tucson Hybrid 2022-24">Buy Here</a></sub></details>|||
|
|Hyundai|Tucson Hybrid 2022-24|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Tucson Hybrid 2022-24">Buy Here</a></sub></details>|||
|
||||||
|
|Hyundai|Tucson Hybrid (without HDA II) 2025-26|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Tucson Hybrid (without HDA II) 2025-26">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Tucson Plug-in Hybrid 2024|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Tucson Plug-in Hybrid 2024">Buy Here</a></sub></details>|||
|
|Hyundai|Tucson Plug-in Hybrid 2024|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Tucson Plug-in Hybrid 2024">Buy Here</a></sub></details>|||
|
||||||
|
|Hyundai|Tucson Plug-in Hybrid (without HDA II) 2025|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Tucson Plug-in Hybrid (without HDA II) 2025">Buy Here</a></sub></details>|||
|
||||||
|Hyundai|Veloster 2019-20|Smart Cruise Control (SCC)|Stock|5 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Veloster 2019-20">Buy Here</a></sub></details>|||
|
|Hyundai|Veloster 2019-20|Smart Cruise Control (SCC)|Stock|5 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Veloster 2019-20">Buy Here</a></sub></details>|||
|
||||||
|Jeep|Grand Cherokee 2016-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Jeep Grand Cherokee 2016-18">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=eLR9o2JkuRk" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Jeep|Grand Cherokee 2016-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Jeep Grand Cherokee 2016-18">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=eLR9o2JkuRk" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Jeep|Grand Cherokee 2019-21|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Jeep Grand Cherokee 2019-21">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=jBe4lWnRSu4" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Jeep|Grand Cherokee 2019-21|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Jeep Grand Cherokee 2019-21">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=jBe4lWnRSu4" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Kia|Carnival 2022-24|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Carnival 2022-24">Buy Here</a></sub></details>|||
|
|Kia|Carnival 2022-24|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Carnival 2022-24">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|Carnival 2025|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Carnival 2025">Buy Here</a></sub></details>|||
|
||||||
|Kia|Carnival (China only) 2023|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Carnival (China only) 2023">Buy Here</a></sub></details>|||
|
|Kia|Carnival (China only) 2023|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Carnival (China only) 2023">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|Carnival (with HDA II) 2025|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai Q connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Carnival (with HDA II) 2025">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|Carnival Hybrid 2025|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Carnival Hybrid 2025">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|Carnival Hybrid 2026|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Carnival Hybrid 2026">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|Carnival Hybrid (with HDA II) 2025-26|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai Q connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Carnival Hybrid (with HDA II) 2025-26">Buy Here</a></sub></details>|||
|
||||||
|Kia|Ceed 2019-21|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Ceed 2019-21">Buy Here</a></sub></details>|||
|
|Kia|Ceed 2019-21|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Ceed 2019-21">Buy Here</a></sub></details>|||
|
||||||
|Kia|EV6 (Southeast Asia only) 2022-24|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai P connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia EV6 (Southeast Asia only) 2022-24">Buy Here</a></sub></details>|||
|
|Kia|EV6 (Southeast Asia only) 2022-24|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai P connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia EV6 (Southeast Asia only) 2022-24">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|EV6 (with HDA I) 2025|Highway Driving Assist I|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai P connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia EV6 (with HDA I) 2025">Buy Here</a></sub></details>|||
|
||||||
|Kia|EV6 (with HDA II) 2022-24|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai P connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia EV6 (with HDA II) 2022-24">Buy Here</a></sub></details>|||
|
|Kia|EV6 (with HDA II) 2022-24|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai P connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia EV6 (with HDA II) 2022-24">Buy Here</a></sub></details>|||
|
||||||
|Kia|EV6 (without HDA II) 2022-24|Highway Driving Assist|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia EV6 (without HDA II) 2022-24">Buy Here</a></sub></details>|||
|
|Kia|EV6 (without HDA II) 2022-24|Highway Driving Assist|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia EV6 (without HDA II) 2022-24">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|EV9 2025-26|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai R connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia EV9 2025-26">Buy Here</a></sub></details>|||
|
||||||
|Kia|Forte 2019-21|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|6 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai G connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Forte 2019-21">Buy Here</a></sub></details>|||
|
|Kia|Forte 2019-21|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|6 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai G connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Forte 2019-21">Buy Here</a></sub></details>|||
|
||||||
|Kia|Forte 2022-23|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Forte 2022-23">Buy Here</a></sub></details>|||
|
|Kia|Forte 2022-23|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Forte 2022-23">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|K4 (with HDA II) 2025|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai R connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia K4 (with HDA II) 2025">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|K4 (without HDA II) 2025|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia K4 (without HDA II) 2025">Buy Here</a></sub></details>|||
|
||||||
|Kia|K5 2021-24|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia K5 2021-24">Buy Here</a></sub></details>|||
|
|Kia|K5 2021-24|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia K5 2021-24">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|K5 (without HDA II) 2025|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai M connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia K5 (without HDA II) 2025">Buy Here</a></sub></details>|||
|
||||||
|Kia|K5 Hybrid 2020-22|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia K5 Hybrid 2020-22">Buy Here</a></sub></details>|||
|
|Kia|K5 Hybrid 2020-22|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia K5 Hybrid 2020-22">Buy Here</a></sub></details>|||
|
||||||
|Kia|K8 Hybrid (with HDA II) 2023|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai Q connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia K8 Hybrid (with HDA II) 2023">Buy Here</a></sub></details>|||
|
|Kia|K8 Hybrid (with HDA II) 2023|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai Q connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia K8 Hybrid (with HDA II) 2023">Buy Here</a></sub></details>|||
|
||||||
|Kia|Niro EV 2019|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai H connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Niro EV 2019">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=lT7zcG6ZpGo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Kia|Niro EV 2019|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai H connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Niro EV 2019">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=lT7zcG6ZpGo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
@@ -186,13 +290,20 @@ A supported vehicle is one that just works when you install a comma device. All
|
|||||||
|Kia|Sorento 2018|Advanced Smart Cruise Control & LKAS|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Sorento 2018">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=Fkh3s6WHJz8" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Kia|Sorento 2018|Advanced Smart Cruise Control & LKAS|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Sorento 2018">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=Fkh3s6WHJz8" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Kia|Sorento 2019|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Sorento 2019">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=Fkh3s6WHJz8" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Kia|Sorento 2019|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Sorento 2019">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=Fkh3s6WHJz8" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Kia|Sorento 2021-23|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Sorento 2021-23">Buy Here</a></sub></details>|||
|
|Kia|Sorento 2021-23|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Sorento 2021-23">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|Sorento (without HDA II) 2024-25|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Sorento (without HDA II) 2024-25">Buy Here</a></sub></details>|||
|
||||||
|Kia|Sorento Hybrid 2021-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Sorento Hybrid 2021-23">Buy Here</a></sub></details>|||
|
|Kia|Sorento Hybrid 2021-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Sorento Hybrid 2021-23">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|Sorento Hybrid 2026|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai Q connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Sorento Hybrid 2026">Buy Here</a></sub></details>|||
|
||||||
|Kia|Sorento Plug-in Hybrid 2022-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Sorento Plug-in Hybrid 2022-23">Buy Here</a></sub></details>|||
|
|Kia|Sorento Plug-in Hybrid 2022-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Sorento Plug-in Hybrid 2022-23">Buy Here</a></sub></details>|||
|
||||||
|Kia|Sportage 2023-24|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Sportage 2023-24">Buy Here</a></sub></details>|||
|
|Kia|Sportage 2023-24|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Sportage 2023-24">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|Sportage (without HDA II) 2026|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Sportage (without HDA II) 2026">Buy Here</a></sub></details>|||
|
||||||
|Kia|Sportage Hybrid 2023|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Sportage Hybrid 2023">Buy Here</a></sub></details>|||
|
|Kia|Sportage Hybrid 2023|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Sportage Hybrid 2023">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|Sportage Hybrid 2026|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Sportage Hybrid 2026">Buy Here</a></sub></details>|||
|
||||||
|Kia|Stinger 2018-20|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Stinger 2018-20">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=MJ94qoofYw0" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Kia|Stinger 2018-20|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Stinger 2018-20">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=MJ94qoofYw0" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Kia|Stinger 2022-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Stinger 2022-23">Buy Here</a></sub></details>|||
|
|Kia|Stinger 2022-23|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Stinger 2022-23">Buy Here</a></sub></details>|||
|
||||||
|Kia|Telluride 2020-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai H connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Telluride 2020-22">Buy Here</a></sub></details>|||
|
|Kia|Telluride 2020-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai H connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Telluride 2020-22">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|Telluride (with HDA II) 2023-24|Highway Driving Assist II|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai P connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Telluride (with HDA II) 2023-24">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|Telluride (without HDA II) 2023-25|Highway Driving Assist|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Telluride (without HDA II) 2023-25">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|XCeed Plug-in Hybrid 2021|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia XCeed Plug-in Hybrid 2021">Buy Here</a></sub></details>|||
|
||||||
|Lexus|CT Hybrid 2017-18|Lexus Safety System+|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lexus CT Hybrid 2017-18">Buy Here</a></sub></details>|||
|
|Lexus|CT Hybrid 2017-18|Lexus Safety System+|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lexus CT Hybrid 2017-18">Buy Here</a></sub></details>|||
|
||||||
|Lexus|ES 2017-18|All|Stock|19 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lexus ES 2017-18">Buy Here</a></sub></details>|||
|
|Lexus|ES 2017-18|All|Stock|19 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lexus ES 2017-18">Buy Here</a></sub></details>|||
|
||||||
|Lexus|ES 2019-25|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lexus ES 2019-25">Buy Here</a></sub></details>|||
|
|Lexus|ES 2019-25|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lexus ES 2019-25">Buy Here</a></sub></details>|||
|
||||||
@@ -215,44 +326,54 @@ A supported vehicle is one that just works when you install a comma device. All
|
|||||||
|Lexus|RX Hybrid 2017-19|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lexus RX Hybrid 2017-19">Buy Here</a></sub></details>|||
|
|Lexus|RX Hybrid 2017-19|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lexus RX Hybrid 2017-19">Buy Here</a></sub></details>|||
|
||||||
|Lexus|RX Hybrid 2020-22|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lexus RX Hybrid 2020-22">Buy Here</a></sub></details>|||
|
|Lexus|RX Hybrid 2020-22|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lexus RX Hybrid 2020-22">Buy Here</a></sub></details>|||
|
||||||
|Lexus|UX Hybrid 2019-24|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lexus UX Hybrid 2019-24">Buy Here</a></sub></details>|||
|
|Lexus|UX Hybrid 2019-24|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lexus UX Hybrid 2019-24">Buy Here</a></sub></details>|||
|
||||||
|Lincoln|Aviator 2020-24|Co-Pilot360 Plus|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lincoln Aviator 2020-24">Buy Here</a></sub></details>|||
|
|Lincoln|Aviator 2020-24|Co-Pilot360 Plus|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lincoln Aviator 2020-24">Buy Here</a></sub></details>|||
|
||||||
|Lincoln|Aviator Plug-in Hybrid 2020-24|Co-Pilot360 Plus|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lincoln Aviator Plug-in Hybrid 2020-24">Buy Here</a></sub></details>|||
|
|Lincoln|Aviator Plug-in Hybrid 2020-24|Co-Pilot360 Plus|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Lincoln Aviator Plug-in Hybrid 2020-24">Buy Here</a></sub></details>|||
|
||||||
|MAN|eTGE 2020-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=MAN eTGE 2020-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|MAN|eTGE 2020-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=MAN eTGE 2020-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|MAN|TGE 2017-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=MAN TGE 2017-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|MAN|TGE 2017-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=MAN TGE 2017-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Mazda|CX-5 2022-25|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Mazda connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Mazda CX-5 2022-25">Buy Here</a></sub></details>|||
|
|Mazda|CX-5 2022-25|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Mazda connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Mazda CX-5 2022-25">Buy Here</a></sub></details>|||
|
||||||
|Mazda|CX-9 2021-23|All|Stock|0 mph|28 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Mazda connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Mazda CX-9 2021-23">Buy Here</a></sub></details>|<a href="https://youtu.be/dA3duO4a0O4" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Mazda|CX-9 2021-23|All|Stock|0 mph|28 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Mazda connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Mazda CX-9 2021-23">Buy Here</a></sub></details>|<a href="https://youtu.be/dA3duO4a0O4" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Nissan[<sup>5</sup>](#footnotes)|Altima 2019-20, 2024|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Nissan B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan Altima 2019-20, 2024">Buy Here</a></sub></details>|||
|
|Nissan[<sup>6</sup>](#footnotes)|Altima 2019-20, 2024|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Nissan B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan Altima 2019-20, 2024">Buy Here</a></sub></details>|||
|
||||||
|Nissan[<sup>5</sup>](#footnotes)|Leaf 2018-23|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Nissan A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan Leaf 2018-23">Buy Here</a></sub></details>|<a href="https://youtu.be/vaMbtAh_0cY" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Nissan[<sup>6</sup>](#footnotes)|Leaf 2018-25|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Nissan A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan Leaf 2018-25">Buy Here</a></sub></details>|<a href="https://youtu.be/vaMbtAh_0cY" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Nissan[<sup>5</sup>](#footnotes)|Rogue 2018-20|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Nissan A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan Rogue 2018-20">Buy Here</a></sub></details>|||
|
|Nissan[<sup>6</sup>](#footnotes)|Leaf Instrument Cluster 2018-25|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Nissan A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan Leaf Instrument Cluster 2018-25">Buy Here</a></sub></details>|<a href="https://youtu.be/vaMbtAh_0cY" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Nissan[<sup>5</sup>](#footnotes)|X-Trail 2017|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Nissan A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan X-Trail 2017">Buy Here</a></sub></details>|||
|
|Nissan[<sup>6</sup>](#footnotes)|Rogue 2018-20|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Nissan A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan Rogue 2018-20">Buy Here</a></sub></details>|||
|
||||||
|Ram|1500 2019-24|Adaptive Cruise Control (ACC)|Stock|0 mph|32 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Ram connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ram 1500 2019-24">Buy Here</a></sub></details>|||
|
|Nissan[<sup>6</sup>](#footnotes)|X-Trail 2017|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Nissan A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan X-Trail 2017">Buy Here</a></sub></details>|||
|
||||||
|Rivian|R1S 2022-24|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Rivian A connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Rivian R1S 2022-24">Buy Here</a></sub></details>||<a href="https://youtu.be/uaISd1j7Z4U" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
|Ram|1500 2019-24|Adaptive Cruise Control (ACC)|Stock|32 mph|1 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Ram connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ram 1500 2019-24">Buy Here</a></sub></details>|||
|
||||||
|Rivian|R1T 2022-24|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Rivian A connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Rivian R1T 2022-24">Buy Here</a></sub></details>||<a href="https://youtu.be/uaISd1j7Z4U" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
|Rivian|R1S 2022-24|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Rivian A connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Rivian R1S 2022-24">Buy Here</a></sub></details>||<a href="https://youtu.be/uaISd1j7Z4U" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||||
|SEAT|Ateca 2016-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=SEAT Ateca 2016-23">Buy Here</a></sub></details>|||
|
|Rivian|R1S 2025|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Rivian B connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Rivian R1S 2025">Buy Here</a></sub></details>|||
|
||||||
|SEAT|Leon 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=SEAT Leon 2014-20">Buy Here</a></sub></details>|||
|
|Rivian|R1T 2022-24|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Rivian A connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Rivian R1T 2022-24">Buy Here</a></sub></details>||<a href="https://youtu.be/uaISd1j7Z4U" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||||
|Subaru|Ascent 2019-21|All[<sup>6</sup>](#footnotes)|openpilot available[<sup>1,7</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Ascent 2019-21">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|
|Rivian|R1T 2025|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Rivian B connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Rivian R1T 2025">Buy Here</a></sub></details>|||
|
||||||
|Subaru|Crosstrek 2018-19|EyeSight Driver Assistance[<sup>6</sup>](#footnotes)|openpilot available[<sup>1,7</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Crosstrek 2018-19">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|<a href="https://youtu.be/Agww7oE1k-s?t=26" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|SEAT|Ateca 2016-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=SEAT Ateca 2016-23">Buy Here</a></sub></details>|||
|
||||||
|Subaru|Crosstrek 2020-23|EyeSight Driver Assistance[<sup>6</sup>](#footnotes)|openpilot available[<sup>1,7</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Crosstrek 2020-23">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|
|SEAT|Leon 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=SEAT Leon 2014-20">Buy Here</a></sub></details>|||
|
||||||
|Subaru|Forester 2019-21|All[<sup>6</sup>](#footnotes)|openpilot available[<sup>1,7</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Forester 2019-21">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|
|Subaru|Ascent 2019-21|All[<sup>7</sup>](#footnotes)|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Ascent 2019-21">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|
||||||
|Subaru|Impreza 2017-19|EyeSight Driver Assistance[<sup>6</sup>](#footnotes)|openpilot available[<sup>1,7</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Impreza 2017-19">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|
|Subaru|Ascent 2023-25|All[<sup>7</sup>](#footnotes)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru D connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Ascent 2023-25">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|
||||||
|Subaru|Impreza 2020-22|EyeSight Driver Assistance[<sup>6</sup>](#footnotes)|openpilot available[<sup>1,7</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Impreza 2020-22">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|
|Subaru|Crosstrek 2018-19|EyeSight Driver Assistance[<sup>7</sup>](#footnotes)|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Crosstrek 2018-19">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|<a href="https://youtu.be/Agww7oE1k-s?t=26" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Subaru|Legacy 2020-22|All[<sup>6</sup>](#footnotes)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru B connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Legacy 2020-22">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|
|Subaru|Crosstrek 2020-23|EyeSight Driver Assistance[<sup>7</sup>](#footnotes)|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Crosstrek 2020-23">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|
||||||
|Subaru|Outback 2020-22|All[<sup>6</sup>](#footnotes)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru B connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Outback 2020-22">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|
|Subaru|Crosstrek 2025|All[<sup>7</sup>](#footnotes)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru D connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Crosstrek 2025">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|
||||||
|Subaru|XV 2018-19|EyeSight Driver Assistance[<sup>6</sup>](#footnotes)|openpilot available[<sup>1,7</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru XV 2018-19">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|<a href="https://youtu.be/Agww7oE1k-s?t=26" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Subaru|Forester 2019-21|All[<sup>7</sup>](#footnotes)|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Forester 2019-21">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|
||||||
|Subaru|XV 2020-21|EyeSight Driver Assistance[<sup>6</sup>](#footnotes)|openpilot available[<sup>1,7</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru XV 2020-21">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|
|Subaru|Forester 2022-24|All[<sup>7</sup>](#footnotes)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru C connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Forester 2022-24">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|
||||||
|Škoda|Fabia 2022-23[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Fabia 2022-23">Buy Here</a></sub></details>[<sup>15</sup>](#footnotes)|||
|
|Subaru|Impreza 2017-19|EyeSight Driver Assistance[<sup>7</sup>](#footnotes)|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Impreza 2017-19">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|
||||||
|Škoda|Kamiq 2021-23[<sup>11,13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Kamiq 2021-23">Buy Here</a></sub></details>[<sup>15</sup>](#footnotes)|||
|
|Subaru|Impreza 2020-22|EyeSight Driver Assistance[<sup>7</sup>](#footnotes)|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Impreza 2020-22">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|
||||||
|Škoda|Karoq 2019-23[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Karoq 2019-23">Buy Here</a></sub></details>|||
|
|Subaru|Legacy 2020-22|All[<sup>7</sup>](#footnotes)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru B connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Legacy 2020-22">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|
||||||
|Škoda|Kodiaq 2017-23[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Kodiaq 2017-23">Buy Here</a></sub></details>|||
|
|Subaru|Legacy 2025|All[<sup>7</sup>](#footnotes)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru D connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Legacy 2025">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|
||||||
|Škoda|Octavia 2015-19[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Octavia 2015-19">Buy Here</a></sub></details>|||
|
|Subaru|Outback 2020-22|All[<sup>7</sup>](#footnotes)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru B connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Outback 2020-22">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|
||||||
|Škoda|Octavia RS 2016[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Octavia RS 2016">Buy Here</a></sub></details>|||
|
|Subaru|Outback 2023-24|All[<sup>7</sup>](#footnotes)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru D connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru Outback 2023-24">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|
||||||
|Škoda|Octavia Scout 2017-19[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Octavia Scout 2017-19">Buy Here</a></sub></details>|||
|
|Subaru|XV 2018-19|EyeSight Driver Assistance[<sup>7</sup>](#footnotes)|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru XV 2018-19">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|<a href="https://youtu.be/Agww7oE1k-s?t=26" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Škoda|Scala 2020-23[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Scala 2020-23">Buy Here</a></sub></details>[<sup>15</sup>](#footnotes)|||
|
|Subaru|XV 2020-21|EyeSight Driver Assistance[<sup>7</sup>](#footnotes)|openpilot available[<sup>1,8</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Subaru A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Subaru XV 2020-21">Buy Here</a></sub></details><details><summary>Tools</summary><sub>- 1 Pry Tool<br>- 1 Socket Wrench 8mm or 5/16" (deep)</sub></details>|||
|
||||||
|Škoda|Superb 2015-22[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Superb 2015-22">Buy Here</a></sub></details>|||
|
|Škoda|Enyaq 2021-23[<sup>14</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Enyaq 2021-23">Buy Here</a></sub></details>|||
|
||||||
|Tesla[<sup>9</sup>](#footnotes)|Model 3 (with HW3) 2019-23[<sup>8</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Tesla A connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Tesla Model 3 (with HW3) 2019-23">Buy Here</a></sub></details>|||
|
|Škoda|Enyaq 2024-25[<sup>14</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Enyaq 2024-25">Buy Here</a></sub></details>|||
|
||||||
|Tesla[<sup>9</sup>](#footnotes)|Model 3 (with HW4) 2024-25[<sup>8</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Tesla B connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Tesla Model 3 (with HW4) 2024-25">Buy Here</a></sub></details>|||
|
|Škoda|Fabia 2022-23[<sup>14</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Fabia 2022-23">Buy Here</a></sub></details>[<sup>16</sup>](#footnotes)|||
|
||||||
|Tesla[<sup>9</sup>](#footnotes)|Model Y (with HW3) 2020-23[<sup>8</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Tesla A connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Tesla Model Y (with HW3) 2020-23">Buy Here</a></sub></details>|||
|
|Škoda|Kamiq 2021-23[<sup>12,14</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Kamiq 2021-23">Buy Here</a></sub></details>[<sup>16</sup>](#footnotes)|||
|
||||||
|Tesla[<sup>9</sup>](#footnotes)|Model Y (with HW4) 2024-25[<sup>8</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Tesla B connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Tesla Model Y (with HW4) 2024-25">Buy Here</a></sub></details>|||
|
|Škoda|Karoq 2019-23[<sup>14</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Karoq 2019-23">Buy Here</a></sub></details>|||
|
||||||
|
|Škoda|Kodiaq 2017-23[<sup>14</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Kodiaq 2017-23">Buy Here</a></sub></details>|||
|
||||||
|
|Škoda|Octavia 2015-19[<sup>14</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Octavia 2015-19">Buy Here</a></sub></details>|||
|
||||||
|
|Škoda|Octavia RS 2016[<sup>14</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Octavia RS 2016">Buy Here</a></sub></details>|||
|
||||||
|
|Škoda|Octavia Scout 2017-19[<sup>14</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Octavia Scout 2017-19">Buy Here</a></sub></details>|||
|
||||||
|
|Škoda|Scala 2020-23[<sup>14</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Scala 2020-23">Buy Here</a></sub></details>[<sup>16</sup>](#footnotes)|||
|
||||||
|
|Škoda|Superb 2015-22[<sup>14</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Škoda Superb 2015-22">Buy Here</a></sub></details>|||
|
||||||
|
|Tesla[<sup>10</sup>](#footnotes)|Model 3 (with HW3) 2019-23[<sup>9</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Tesla A connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Tesla Model 3 (with HW3) 2019-23">Buy Here</a></sub></details>|||
|
||||||
|
|Tesla[<sup>10</sup>](#footnotes)|Model 3 (with HW4) 2024-26[<sup>9</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Tesla B connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Tesla Model 3 (with HW4) 2024-26">Buy Here</a></sub></details>|||
|
||||||
|
|Tesla[<sup>10</sup>](#footnotes)|Model Y (with HW3) 2020-23[<sup>9</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Tesla A connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Tesla Model Y (with HW3) 2020-23">Buy Here</a></sub></details>|||
|
||||||
|
|Tesla[<sup>10</sup>](#footnotes)|Model Y (with HW4) 2024-25[<sup>9</sup>](#footnotes)|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Tesla B connector<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Tesla Model Y (with HW4) 2024-25">Buy Here</a></sub></details>|||
|
||||||
|Toyota|Alphard 2019-20|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Alphard 2019-20">Buy Here</a></sub></details>|||
|
|Toyota|Alphard 2019-20|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Alphard 2019-20">Buy Here</a></sub></details>|||
|
||||||
|Toyota|Alphard Hybrid 2021|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Alphard Hybrid 2021">Buy Here</a></sub></details>|||
|
|Toyota|Alphard Hybrid 2021|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Alphard Hybrid 2021">Buy Here</a></sub></details>|||
|
||||||
|Toyota|Avalon 2016|Toyota Safety Sense P|Stock|19 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Avalon 2016">Buy Here</a></sub></details>|||
|
|Toyota|Avalon 2016|Toyota Safety Sense P|Stock|19 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Avalon 2016">Buy Here</a></sub></details>|||
|
||||||
@@ -265,8 +386,8 @@ A supported vehicle is one that just works when you install a comma device. All
|
|||||||
|Toyota|C-HR 2021|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota C-HR 2021">Buy Here</a></sub></details>|||
|
|Toyota|C-HR 2021|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota C-HR 2021">Buy Here</a></sub></details>|||
|
||||||
|Toyota|C-HR Hybrid 2017-20|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota C-HR Hybrid 2017-20">Buy Here</a></sub></details>|||
|
|Toyota|C-HR Hybrid 2017-20|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota C-HR Hybrid 2017-20">Buy Here</a></sub></details>|||
|
||||||
|Toyota|C-HR Hybrid 2021-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota C-HR Hybrid 2021-22">Buy Here</a></sub></details>|||
|
|Toyota|C-HR Hybrid 2021-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota C-HR Hybrid 2021-22">Buy Here</a></sub></details>|||
|
||||||
|Toyota|Camry 2018-20|All|Stock|0 mph[<sup>10</sup>](#footnotes)|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Camry 2018-20">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=fkcjviZY9CM" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Toyota|Camry 2018-20|All|Stock|0 mph[<sup>11</sup>](#footnotes)|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Camry 2018-20">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=fkcjviZY9CM" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Toyota|Camry 2021-24|All|openpilot|0 mph[<sup>10</sup>](#footnotes)|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Camry 2021-24">Buy Here</a></sub></details>|||
|
|Toyota|Camry 2021-24|All|openpilot|0 mph[<sup>11</sup>](#footnotes)|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Camry 2021-24">Buy Here</a></sub></details>|||
|
||||||
|Toyota|Camry Hybrid 2018-20|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Camry Hybrid 2018-20">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=Q2DYY0AWKgk" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Toyota|Camry Hybrid 2018-20|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Camry Hybrid 2018-20">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=Q2DYY0AWKgk" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Toyota|Camry Hybrid 2021-24|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Camry Hybrid 2021-24">Buy Here</a></sub></details>|||
|
|Toyota|Camry Hybrid 2021-24|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Camry Hybrid 2021-24">Buy Here</a></sub></details>|||
|
||||||
|Toyota|Corolla 2017-19|All|Stock|19 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Corolla 2017-19">Buy Here</a></sub></details>|||
|
|Toyota|Corolla 2017-19|All|Stock|19 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Corolla 2017-19">Buy Here</a></sub></details>|||
|
||||||
@@ -298,62 +419,91 @@ A supported vehicle is one that just works when you install a comma device. All
|
|||||||
|Toyota|RAV4 Hybrid 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota RAV4 Hybrid 2022">Buy Here</a></sub></details>|<a href="https://youtu.be/U0nH9cnrFB0" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Toyota|RAV4 Hybrid 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota RAV4 Hybrid 2022">Buy Here</a></sub></details>|<a href="https://youtu.be/U0nH9cnrFB0" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Toyota|RAV4 Hybrid 2023-25|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota RAV4 Hybrid 2023-25">Buy Here</a></sub></details>|<a href="https://youtu.be/4eIsEq4L4Ng" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Toyota|RAV4 Hybrid 2023-25|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota RAV4 Hybrid 2023-25">Buy Here</a></sub></details>|<a href="https://youtu.be/4eIsEq4L4Ng" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Toyota|Sienna 2018-20|All|Stock|19 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Sienna 2018-20">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=q1UPOo4Sh68" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Toyota|Sienna 2018-20|All|Stock|19 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Sienna 2018-20">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=q1UPOo4Sh68" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Volkswagen|Arteon 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Arteon 2018-23">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Volkswagen|Arteon 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Arteon 2018-23">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Volkswagen|Arteon eHybrid 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Arteon eHybrid 2020-23">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Volkswagen|Arteon eHybrid 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Arteon eHybrid 2020-23">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Volkswagen|Arteon R 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Arteon R 2020-23">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Volkswagen|Arteon R 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Arteon R 2020-23">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Volkswagen|Arteon Shooting Brake 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Arteon Shooting Brake 2020-23">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Volkswagen|Arteon Shooting Brake 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Arteon Shooting Brake 2020-23">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Volkswagen|Atlas 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Atlas 2018-23">Buy Here</a></sub></details>|||
|
|Volkswagen|Atlas 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Atlas 2018-23">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|Atlas Cross Sport 2020-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Atlas Cross Sport 2020-22">Buy Here</a></sub></details>|||
|
|Volkswagen|Atlas Cross Sport 2020-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Atlas Cross Sport 2020-22">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|California 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen California 2021-23">Buy Here</a></sub></details>|||
|
|Volkswagen|California 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen California 2021-23">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|Caravelle 2020|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Caravelle 2020">Buy Here</a></sub></details>|||
|
|Volkswagen|Caravelle 2020|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Caravelle 2020">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|CC 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen CC 2018-22">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Volkswagen|CC 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen CC 2018-22">Buy Here</a></sub></details>|<a href="https://youtu.be/FAomFKPFlDA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Volkswagen|Crafter 2017-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Crafter 2017-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Volkswagen|Crafter 2017-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Crafter 2017-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Volkswagen|e-Crafter 2018-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen e-Crafter 2018-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Volkswagen|e-Crafter 2018-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen e-Crafter 2018-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Volkswagen|e-Golf 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen e-Golf 2014-20">Buy Here</a></sub></details>|||
|
|Volkswagen|e-Golf 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen e-Golf 2014-20">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|Golf 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf 2015-20">Buy Here</a></sub></details>|||
|
|Volkswagen|Golf 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf 2015-20">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|Golf Alltrack 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf Alltrack 2015-19">Buy Here</a></sub></details>|||
|
|Volkswagen|Golf Alltrack 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf Alltrack 2015-19">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|Golf GTD 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf GTD 2015-20">Buy Here</a></sub></details>|||
|
|Volkswagen|Golf GTD 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf GTD 2015-20">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|Golf GTE 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf GTE 2015-20">Buy Here</a></sub></details>|||
|
|Volkswagen|Golf GTE 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf GTE 2015-20">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|Golf GTI 2015-21|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf GTI 2015-21">Buy Here</a></sub></details>|||
|
|Volkswagen|Golf GTI 2015-21|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf GTI 2015-21">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|Golf R 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf R 2015-19">Buy Here</a></sub></details>|||
|
|Volkswagen|Golf R 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf R 2015-19">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|Golf SportsVan 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf SportsVan 2015-20">Buy Here</a></sub></details>|||
|
|Volkswagen|Golf SportsVan 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Golf SportsVan 2015-20">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|Grand California 2019-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Grand California 2019-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Volkswagen|Grand California 2019-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Grand California 2019-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Volkswagen|Jetta 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Jetta 2018-23">Buy Here</a></sub></details>|||
|
|Volkswagen|ID.3 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen ID.3 2020-23">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|Jetta GLI 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Jetta GLI 2021-23">Buy Here</a></sub></details>|||
|
|Volkswagen|ID.3 2024-25|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen ID.3 2024-25">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|Passat 2015-22[<sup>12</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Passat 2015-22">Buy Here</a></sub></details>|||
|
|Volkswagen|ID.4 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen ID.4 2021-23">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|Passat Alltrack 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Passat Alltrack 2015-22">Buy Here</a></sub></details>|||
|
|Volkswagen|ID.4 2024-25|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen ID.4 2024-25">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|Passat GTE 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Passat GTE 2015-22">Buy Here</a></sub></details>|||
|
|Volkswagen|ID.5 2022-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen ID.5 2022-23">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|Polo 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Polo 2018-23">Buy Here</a></sub></details>[<sup>15</sup>](#footnotes)|||
|
|Volkswagen|Jetta 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Jetta 2018-23">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|Polo GTI 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Polo GTI 2018-23">Buy Here</a></sub></details>[<sup>15</sup>](#footnotes)|||
|
|Volkswagen|Jetta GLI 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Jetta GLI 2021-23">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|T-Cross 2021|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen T-Cross 2021">Buy Here</a></sub></details>[<sup>15</sup>](#footnotes)|||
|
|Volkswagen|Passat 2015-22[<sup>13</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Passat 2015-22">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|T-Roc 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen T-Roc 2018-23">Buy Here</a></sub></details>|||
|
|Volkswagen|Passat Alltrack 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Passat Alltrack 2015-22">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|Taos 2022-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Taos 2022-24">Buy Here</a></sub></details>|||
|
|Volkswagen|Passat GTE 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Passat GTE 2015-22">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|Teramont 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Teramont 2018-22">Buy Here</a></sub></details>|||
|
|Volkswagen|Polo 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Polo 2018-23">Buy Here</a></sub></details>[<sup>16</sup>](#footnotes)|||
|
||||||
|Volkswagen|Teramont Cross Sport 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Teramont Cross Sport 2021-22">Buy Here</a></sub></details>|||
|
|Volkswagen|Polo GTI 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Polo GTI 2018-23">Buy Here</a></sub></details>[<sup>16</sup>](#footnotes)|||
|
||||||
|Volkswagen|Teramont X 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Teramont X 2021-22">Buy Here</a></sub></details>|||
|
|Volkswagen|T-Cross 2021|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen T-Cross 2021">Buy Here</a></sub></details>[<sup>16</sup>](#footnotes)|||
|
||||||
|Volkswagen|Tiguan 2018-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Tiguan 2018-24">Buy Here</a></sub></details>|||
|
|Volkswagen|T-Roc 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen T-Roc 2018-23">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|Tiguan eHybrid 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Tiguan eHybrid 2021-23">Buy Here</a></sub></details>|||
|
|Volkswagen|Taos 2022-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Taos 2022-24">Buy Here</a></sub></details>|||
|
||||||
|Volkswagen|Touran 2016-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,14</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Touran 2016-23">Buy Here</a></sub></details>|||
|
|Volkswagen|Teramont 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Teramont 2018-22">Buy Here</a></sub></details>|||
|
||||||
|
|Volkswagen|Teramont Cross Sport 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Teramont Cross Sport 2021-22">Buy Here</a></sub></details>|||
|
||||||
|
|Volkswagen|Teramont X 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Teramont X 2021-22">Buy Here</a></sub></details>|||
|
||||||
|
|Volkswagen|Tiguan 2018-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Tiguan 2018-24">Buy Here</a></sub></details>|||
|
||||||
|
|Volkswagen|Tiguan eHybrid 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Tiguan eHybrid 2021-23">Buy Here</a></sub></details>|||
|
||||||
|
|Volkswagen|Touran 2016-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,15</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Volkswagen Touran 2016-23">Buy Here</a></sub></details>|||
|
||||||
|
|
||||||
|
## StarPilot Community Cars
|
||||||
|
|
||||||
|
These additional vehicle ports are maintained by StarPilot rather than upstream openpilot.
|
||||||
|
|
||||||
|
# 17 Community Cars
|
||||||
|
|
||||||
|
|Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|<a href="##"><img width=2000></a>Hardware Needed<br> |Video|Setup Video|
|
||||||
|
|---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||||
|
|Genesis|G70 Non-SCC 2021|No Smart Cruise Control (Non-SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai F connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Genesis G70 Non-SCC 2021">Buy Here</a></sub></details>|||
|
||||||
|
|Hyundai|Bayon Non-SCC 2021|No Smart Cruise Control (Non-SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai N connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Bayon Non-SCC 2021">Buy Here</a></sub></details>|||
|
||||||
|
|Hyundai|Elantra Hybrid Non-SCC 2022|No Smart Cruise Control (Non-SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Elantra Hybrid Non-SCC 2022">Buy Here</a></sub></details>|||
|
||||||
|
|Hyundai|Elantra Non-SCC 2022|No Smart Cruise Control (Non-SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Elantra Non-SCC 2022">Buy Here</a></sub></details>|||
|
||||||
|
|Hyundai|Kona Electric Non-SCC 2019|No Smart Cruise Control (Non-SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai G connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Kona Electric Non-SCC 2019">Buy Here</a></sub></details>|||
|
||||||
|
|Hyundai|Kona Non-SCC 2019|No Smart Cruise Control (Non-SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Hyundai Kona Non-SCC 2019">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|Ceed Plug-in Hybrid Non-SCC 2022|No Smart Cruise Control (Non-SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai I connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Ceed Plug-in Hybrid Non-SCC 2022">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|Forte Non-SCC 2019|No Smart Cruise Control (Non-SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai G connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Forte Non-SCC 2019">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|Forte Non-SCC 2021|No Smart Cruise Control (Non-SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai G connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Forte Non-SCC 2021">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|Ray EV 2025|No Smart Cruise Control (Non-SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai H connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Ray EV 2025">Buy Here</a></sub></details>|||
|
||||||
|
|Kia|Seltos Non-SCC 2023-24|No Smart Cruise Control (Non-SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai L connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Seltos Non-SCC 2023-24">Buy Here</a></sub></details>|||
|
||||||
|
|Tesla|Model S (Pre-AP) 2012-14|All|Stock|0 mph|0 mph|[](##)|[](##)|None|||
|
||||||
|
|Toyota|Matrix Retrofit 2005|Custom retrofit|Stock|19 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Matrix Retrofit 2005">Buy Here</a></sub></details>|||
|
||||||
|
|Toyota|Prius 2016-20 with TSS2 EPS retrofit|Custom retrofit|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Prius 2016-20 with TSS2 EPS retrofit">Buy Here</a></sub></details>|||
|
||||||
|
|Toyota|RAV4 Prime 2021-23|All|openpilot|19 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota RAV4 Prime 2021-23">Buy Here</a></sub></details>|||
|
||||||
|
|Toyota|Sienna 2021-25|All|openpilot|19 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Sienna 2021-25">Buy Here</a></sub></details>|||
|
||||||
|
|Toyota|Yaris (Non-US only) 2020, 2023|All|openpilot available[<sup>1</sup>](#footnotes)|19 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Toyota A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Toyota Yaris (Non-US only) 2020, 2023">Buy Here</a></sub></details>|||
|
||||||
|
|
||||||
### Footnotes
|
### Footnotes
|
||||||
<sup>1</sup>openpilot Longitudinal Control (Alpha) is available behind a toggle; the toggle is only available in non-release branches such as `devel` or `nightly-dev`. <br />
|
<sup>1</sup>openpilot Longitudinal Control (Alpha) is available behind a toggle; the toggle is only available in non-release branches such as `devel` or `nightly-dev`. <br />
|
||||||
<sup>2</sup>Refers only to the Focus Mk4 (C519) available in Europe/China/Taiwan/Australasia, not the Focus Mk3 (C346) in North and South America/Southeast Asia. <br />
|
<sup>2</sup>Refers only to the Focus Mk4 (C519) available in Europe/China/Taiwan/Australasia, not the Focus Mk3 (C346) in North and South America/Southeast Asia. <br />
|
||||||
<sup>3</sup>See more setup details for <a href="https://github.com/commaai/openpilot/wiki/gm" target="_blank">GM</a>. <br />
|
<sup>3</sup>See more setup details for <a href="https://github.com/commaai/openpilot/wiki/gm" target="_blank">GM</a>. <br />
|
||||||
<sup>4</sup>2019 Honda Civic 1.6L Diesel Sedan does not have ALC below 12mph. <br />
|
<sup>4</sup>2019 Honda Civic 1.6L Diesel Sedan does not have ALC below 12mph. <br />
|
||||||
<sup>5</sup>See more setup details for <a href="https://github.com/commaai/openpilot/wiki/nissan" target="_blank">Nissan</a>. <br />
|
<sup>5</sup>Enabling longitudinal control (alpha) will disable all CMBS functionality, including AEB and FCW. <br />
|
||||||
<sup>6</sup>In the non-US market, openpilot requires the car to come equipped with EyeSight with Lane Keep Assistance. <br />
|
<sup>6</sup>See more setup details for <a href="https://github.com/commaai/openpilot/wiki/nissan" target="_blank">Nissan</a>. <br />
|
||||||
<sup>7</sup>Enabling longitudinal control (alpha) will disable all EyeSight functionality, including AEB, LDW, and RAB. <br />
|
<sup>7</sup>In the non-US market, openpilot requires the car to come equipped with EyeSight with Lane Keep Assistance. <br />
|
||||||
<sup>8</sup>Some 2023 model years have HW4. To check which hardware type your vehicle has, look for <b>Autopilot computer</b> under <b>Software -> Additional Vehicle Information</b> on your vehicle's touchscreen. See <a href="https://www.notateslaapp.com/news/2173/how-to-check-if-your-tesla-has-hardware-4-ai4-or-hardware-3">this page</a> for more information. <br />
|
<sup>8</sup>Enabling longitudinal control (alpha) will disable all EyeSight functionality, including AEB, LDW, and RAB. <br />
|
||||||
<sup>9</sup>See more setup details for <a href="https://github.com/commaai/openpilot/wiki/tesla" target="_blank">Tesla</a>. <br />
|
<sup>9</sup>Some 2023 model years have HW4. To check which hardware type your vehicle has, look for <b>Autopilot computer</b> under <b>Software -> Additional Vehicle Information</b> on your vehicle's touchscreen. See <a href="https://www.notateslaapp.com/news/2173/how-to-check-if-your-tesla-has-hardware-4-ai4-or-hardware-3">this page</a> for more information. <br />
|
||||||
<sup>10</sup>openpilot operates above 28mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control. <br />
|
<sup>10</sup>See more setup details for <a href="https://github.com/commaai/openpilot/wiki/tesla" target="_blank">Tesla</a>. <br />
|
||||||
<sup>11</sup>Not including the China market Kamiq, which is based on the (currently) unsupported PQ34 platform. <br />
|
<sup>11</sup>openpilot operates above 28mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control. <br />
|
||||||
<sup>12</sup>Refers only to the MQB-based European B8 Passat, not the NMS Passat in the USA/China/Mideast markets. <br />
|
<sup>12</sup>Not including the China market Kamiq, which is based on the (currently) unsupported PQ34 platform. <br />
|
||||||
<sup>13</sup>Some Škoda vehicles are equipped with heated windshields, which are known to block GPS signal needed for some comma four functionality. <br />
|
<sup>13</sup>Refers only to the MQB-based European B8 Passat, not the NMS Passat in the USA/China/Mideast markets. <br />
|
||||||
<sup>14</sup>Only available for vehicles using a gateway (J533) harness. At this time, vehicles using a camera harness are limited to using stock ACC. <br />
|
<sup>14</sup>Some Škoda vehicles are equipped with heated windshields, which are known to block GPS signal needed for some comma four functionality. <br />
|
||||||
<sup>15</sup>Model-years 2022 and beyond may have a combined CAN gateway and BCM, which is supported by openpilot in software, but doesn't yet have a harness available from the comma store. <br />
|
<sup>15</sup>Only available for vehicles using a gateway (J533) harness. At this time, vehicles using a camera harness are limited to using stock ACC. <br />
|
||||||
|
<sup>16</sup>Model-years 2022 and beyond may have a combined CAN gateway and BCM, which is supported by openpilot in software, but doesn't yet have a harness available from the comma store. <br />
|
||||||
## Community Maintained Cars
|
|
||||||
Although they're not upstream, the community has openpilot running on other makes and models. See the 'Community Supported Models' section of each make [on our wiki](https://wiki.comma.ai/).
|
|
||||||
|
|
||||||
# Don't see your car here?
|
# Don't see your car here?
|
||||||
|
|
||||||
|
|||||||
+81
-11
@@ -4,9 +4,9 @@ This workflow rebuilds StarPilot driving and driver-monitoring artifacts for the
|
|||||||
|
|
||||||
## Safety
|
## Safety
|
||||||
|
|
||||||
- The supported build device is `comma@192.168.3.110`.
|
- The supported build device is `comma@192.168.3.109`.
|
||||||
- Never run these commands against `192.168.3.109`.
|
- Never run these commands against `192.168.3.110`.
|
||||||
- Do not compile normal and big-GPU artifacts together. This workflow builds normal QCOM artifacts only.
|
- Normal artifacts target QCOM. External-GPU artifacts must be compiled explicitly and tagged in the manifest.
|
||||||
- Keep source ONNX files and compiled PKLs on the T5 workspace, not the comma.
|
- Keep source ONNX files and compiled PKLs on the T5 workspace, not the comma.
|
||||||
|
|
||||||
## Workspace
|
## Workspace
|
||||||
@@ -26,7 +26,8 @@ Important directories:
|
|||||||
- Oversized models are represented by repository-safe `.p00`, `.p01`, and `.sha256` files in `ready-for-resources/`.
|
- Oversized models are represented by repository-safe `.p00`, `.p01`, and `.sha256` files in `ready-for-resources/`.
|
||||||
- `logs/`: one remote compilation log per model.
|
- `logs/`: one remote compilation log per model.
|
||||||
- `results/`: source and artifact checksum records.
|
- `results/`: source and artifact checksum records.
|
||||||
- `manifests/`: generated `model_names_v22.json`.
|
- `manifests/`: source `model_names_v22.json` and namespaced release `model_names_v23.json`.
|
||||||
|
- The v23 manifest and compiled artifacts are published together in the resource repository's `Models` branch.
|
||||||
|
|
||||||
## Initialize And Extract
|
## Initialize And Extract
|
||||||
|
|
||||||
@@ -46,7 +47,10 @@ python3 scripts/model_rebuild_pipeline.py extract \
|
|||||||
--base-manifest /path/to/model_names_v21.json
|
--base-manifest /path/to/model_names_v21.json
|
||||||
```
|
```
|
||||||
|
|
||||||
Source commits are defined in `scripts/model_source_map_v22.json`.
|
The original catalog sources are defined in `scripts/model_source_map_v22.json`.
|
||||||
|
Recovered late-model and supercombo sources, including RDF2, are defined in
|
||||||
|
`scripts/model_source_map_v23.json`. The v23 map is intentionally separate so
|
||||||
|
adding a recovered iteration cannot alter the older model source history.
|
||||||
|
|
||||||
## Compile
|
## Compile
|
||||||
|
|
||||||
@@ -65,7 +69,7 @@ python3 scripts/model_rebuild_pipeline.py compile \
|
|||||||
--base-manifest /path/to/model_names_v21.json
|
--base-manifest /path/to/model_names_v21.json
|
||||||
```
|
```
|
||||||
|
|
||||||
Existing artifacts are skipped unless `--force` is passed. Each model is staged in its own remote input directory, compiled on `.110`, copied back to the T5, hashed, and copied into `ready-for-resources/`. Failures are written to `results/<id>_failure.json`; rerunning the same command resumes incomplete models.
|
Existing artifacts are skipped unless `--force` is passed. Each model is staged in its own remote input directory, compiled on `.109`, copied back to the T5, hashed, and copied into `ready-for-resources/`. Failures are written to `results/<id>_failure.json`; rerunning the same command resumes incomplete models.
|
||||||
|
|
||||||
Validate one or all completed artifacts with synthetic camera inputs on QCOM:
|
Validate one or all completed artifacts with synthetic camera inputs on QCOM:
|
||||||
|
|
||||||
@@ -82,6 +86,34 @@ The lower-level device compiler also supports direct use:
|
|||||||
./models --model deeprl3v2 --input-format supercombo --version v15
|
./models --model deeprl3v2 --input-format supercombo --version v15
|
||||||
```
|
```
|
||||||
|
|
||||||
|
For a model that cannot run on the device GPU, compile with the USB AMD GPU attached:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./models --lebowski --gpu
|
||||||
|
```
|
||||||
|
|
||||||
|
The ASM2464PD bridge must run the current tinygrad custom firmware from
|
||||||
|
https://github.com/tinygrad/asm2464pd-firmware. Its USB product string starts
|
||||||
|
with `custom`; the legacy `USB 3.2 PCIe TinyEnclosure` patch is not compatible
|
||||||
|
with comma's current external-GPU runtime. Firmware flashing is a separate,
|
||||||
|
explicit hardware setup step and StarPilot never performs it automatically.
|
||||||
|
|
||||||
|
The dynamic flag (`--lebowski` above) sets the output and manifest model ID;
|
||||||
|
when only one source model is staged, its ONNX filename does not need to match
|
||||||
|
that ID. Input format and behavior version are inferred. `--external-gpu`
|
||||||
|
remains available as a compatibility alias for `--gpu`.
|
||||||
|
|
||||||
|
This emits a streaming out-of-band pickle and keeps QCOM available for camera warps. Its manifest entry must include:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "lebowski",
|
||||||
|
"uses_external_gpu": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Only tagged models activate the external GPU. If the GPU or artifact is unavailable, runtime falls back to the built-in model; all untagged models retain the existing QCOM path.
|
||||||
|
|
||||||
`--version` records behavioral semantics only. It does not change artifact layout.
|
`--version` records behavioral semantics only. It does not change artifact layout.
|
||||||
|
|
||||||
If the compiled PKL exceeds 100 MiB, `./models` automatically keeps the full
|
If the compiled PKL exceeds 100 MiB, `./models` automatically keeps the full
|
||||||
@@ -127,18 +159,56 @@ All four files must be updated together.
|
|||||||
|
|
||||||
## Manifest
|
## Manifest
|
||||||
|
|
||||||
Generate v22 after compilation:
|
The current test branch uses manifest v25 and requests v25 only. Seed the new
|
||||||
|
manifest from the previous catalog, then replace entries as artifacts are
|
||||||
|
rebuilt with the pinned runtime:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp /path/to/model_names_v24.json /path/to/model_names_v25.json
|
||||||
|
```
|
||||||
|
|
||||||
|
The current tinygrad pin is `f6fc4e3f2c3db5fae1e19cbfbc3ad9fc579a12ae`, from
|
||||||
|
`openpilot` `origin/master` (`bump tg + TC_MIN_GLOBALS`). StarPilot's
|
||||||
|
multi-model `modeld` remains in place; do not replace it with upstream's
|
||||||
|
single-model `modeld`.
|
||||||
|
|
||||||
|
For the older namespace migration workflow, generate the base manifest after
|
||||||
|
compilation and namespace the release artifacts as v23:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 scripts/model_rebuild_pipeline.py manifest \
|
python3 scripts/model_rebuild_pipeline.py manifest \
|
||||||
--base-manifest /path/to/model_names_v21.json
|
--base-manifest /path/to/model_names_v21.json
|
||||||
```
|
```
|
||||||
|
|
||||||
The generator preserves existing IDs and behavioral metadata and adds
|
```bash
|
||||||
`deeprl3v2`. Manifest v22 implies the unified single-PKL runtime layout.
|
python3 scripts/namespace_model_artifacts.py \
|
||||||
|
--workspace /Volumes/T5/StarPilot-Model-Rebuild-2026-06-22 \
|
||||||
|
--base-manifest /Volumes/T5/StarPilot-Model-Rebuild-2026-06-22/manifests/model_names_v22.json \
|
||||||
|
--manifest-version v23 --suffix 3
|
||||||
|
```
|
||||||
|
|
||||||
|
The namespace command changes IDs such as `tr1422` to `tr14223`, renames the
|
||||||
|
compiled and upload-ready files, and writes an ID map. It preserves display
|
||||||
|
names and behavioral versions. The current model manager requests v25 only; the
|
||||||
|
manifest is fetched from `Models/model_names_v25.json`. Devices still running
|
||||||
|
the prior branch continue to request their existing manifest version.
|
||||||
|
|
||||||
|
After importing newly compiled sources, normalize the release namespace before
|
||||||
|
copying files into either resource repository:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 scripts/reconcile_v23_artifacts.py \
|
||||||
|
--workspace /Volumes/T5/StarPilot-Model-Rebuild-2026-06-22
|
||||||
|
```
|
||||||
|
|
||||||
|
This maps recovered source IDs to their v23 release IDs, removes duplicate
|
||||||
|
macOS metadata files, and adds `rdf23` for Regret Driven Framework V2. It does
|
||||||
|
not overwrite a conflicting artifact.
|
||||||
Repository-hosted multipart files are discovered by naming convention, so no
|
Repository-hosted multipart files are discovered by naming convention, so no
|
||||||
size, hash, format, or part-count metadata is required.
|
size, hash, format, or part-count metadata is required.
|
||||||
|
|
||||||
|
`uses_external_gpu` is optional and defaults to `false`.
|
||||||
|
|
||||||
## Runtime Verification
|
## Runtime Verification
|
||||||
|
|
||||||
Compilation validates JIT capture/replay, pickle round-trip, finite outputs, metadata slices, and both camera warps. Before release:
|
Compilation validates JIT capture/replay, pickle round-trip, finite outputs, metadata slices, and both camera warps. Before release:
|
||||||
@@ -147,6 +217,6 @@ Compilation validates JIT capture/replay, pickle round-trip, finite outputs, met
|
|||||||
2. Confirm `modeld` stays running.
|
2. Confirm `modeld` stays running.
|
||||||
3. Confirm finite `modelV2` path, lane-line, lead, pose, and action data.
|
3. Confirm finite `modelV2` path, lane-line, lead, pose, and action data.
|
||||||
4. Confirm `driverStateV2` on both supported camera resolutions.
|
4. Confirm `driverStateV2` on both supported camera resolutions.
|
||||||
5. Test download, selection, deletion, randomization, migration, and fallback in QT, raylib/mici, and Galaxy.
|
5. Test download, selection, deletion, randomization, migration, and fallback in both device UIs and Galaxy.
|
||||||
|
|
||||||
The built-in South Carolina artifact is `selfdrive/modeld/models/driving_tinygrad.pkl`. If migration cannot download the selected v22 artifact, StarPilot switches to that built-in model.
|
The built-in RDF artifact is `selfdrive/modeld/models/driving_tinygrad.pkl`. If migration cannot download the selected v25 artifact, StarPilot switches to that built-in model.
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 88 KiB |
Binary file not shown.
@@ -0,0 +1,102 @@
|
|||||||
|
# Contribute to StarPilot
|
||||||
|
|
||||||
|
Contributions are welcome. StarPilot is driver-assistance software, so changes should be focused, testable, and safe for vehicles outside the change's intended scope.
|
||||||
|
|
||||||
|
## Pull requests
|
||||||
|
|
||||||
|
Open all pull requests against the **`Dom` branch**. `Dom` is StarPilot's testing and integration branch; do not target the release branch directly.
|
||||||
|
|
||||||
|
A pull request should:
|
||||||
|
|
||||||
|
* have one clear purpose and contain only changes needed for that purpose;
|
||||||
|
* explain what changed, why it changed, and how it was tested;
|
||||||
|
* link the relevant issue or feedback item when one exists;
|
||||||
|
* avoid unrelated cleanup, refactors, dependency changes, and formatting churn; and
|
||||||
|
* pass the existing tests and checks.
|
||||||
|
|
||||||
|
Keep commits reviewable and update documentation when behavior or configuration changes. If a change needs a large refactor, separate that work from the behavior change when practical.
|
||||||
|
|
||||||
|
### Vehicle-specific changes
|
||||||
|
|
||||||
|
Do your best to ensure a vehicle-specific change affects only the intended vehicle, platform, or brand. Prefer the narrowest appropriate condition instead of changing shared behavior for every vehicle.
|
||||||
|
|
||||||
|
Tests should prove both sides of that boundary:
|
||||||
|
|
||||||
|
* the affected vehicle receives the new or corrected behavior; and
|
||||||
|
* an unaffected vehicle, platform, brand, or configuration retains the existing behavior.
|
||||||
|
|
||||||
|
Include the vehicle and hardware used for on-road or bench testing in the pull request. Hardware testing is valuable, but it does not replace an automated regression test when the behavior can be tested in code.
|
||||||
|
|
||||||
|
## Development environment
|
||||||
|
|
||||||
|
StarPilot keeps host-native development tools separate from device-target builds. Run the setup and development commands from the repository root.
|
||||||
|
|
||||||
|
Install the Python dependencies before starting:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tools/install_python_dependencies.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
On Ubuntu, `tools/ubuntu_setup.sh` installs both the system and Python dependencies. The development tools also require `uv`.
|
||||||
|
|
||||||
|
Use `./dev` for host-native tools. It creates and reuses an isolated environment under `.host_runtime/`, keeping host build artifacts out of the working tree:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./dev replay
|
||||||
|
./dev cabana
|
||||||
|
./dev plotjuggler
|
||||||
|
./dev shell
|
||||||
|
```
|
||||||
|
|
||||||
|
For desktop UI work, use `./c3` or `./c4`. These commands use the same isolated host environment.
|
||||||
|
|
||||||
|
Use `./build` when you need comma-compatible device artifacts. This is the expected validation for changes that affect compiled device code or runtime behavior:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./build
|
||||||
|
```
|
||||||
|
|
||||||
|
Device builds require Docker Desktop or Podman with Linux/aarch64 support and a configured comma sysroot. See the [laptop device-build guide](../how-to/laptop-device-build.md) for setup instructions and the [complete StarPilot development workflow](https://github.com/firestar5683/StarPilot/blob/Dom/tools/STARPILOT_DEVELOPMENT.md) for all host commands and troubleshooting.
|
||||||
|
|
||||||
|
## Code formatting
|
||||||
|
|
||||||
|
Match the style of the code around your change and do not reformat unrelated files. Python formatting and lint rules are defined in `pyproject.toml`; the project uses two-space indentation and Ruff.
|
||||||
|
|
||||||
|
Run Ruff on changed Python files while developing:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ruff check path/to/changed_file.py
|
||||||
|
ruff format --check path/to/changed_file.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Before submitting, run the repository lint checks from the project root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/lint/lint.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing standards
|
||||||
|
|
||||||
|
Every behavior change or bug fix should include focused automated tests when practical. Recent StarPilot tests favor small regression cases that construct the relevant state, exercise one behavior, and assert the exact result.
|
||||||
|
|
||||||
|
At minimum:
|
||||||
|
|
||||||
|
1. Add or update a test that would fail without the change.
|
||||||
|
2. Cover important boundaries, modes, and disabled states related to the change.
|
||||||
|
3. For vehicle-specific behavior, add a negative case showing the change does not bleed into an unaffected vehicle or configuration.
|
||||||
|
4. Run the directly affected test module and the existing tests for the affected subsystem.
|
||||||
|
5. Ensure the pull request passes all existing CI checks before it is ready to merge.
|
||||||
|
|
||||||
|
Run a focused test module with pytest:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pytest path/to/test_file.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Run the full test suite when your development environment supports it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pytest
|
||||||
|
```
|
||||||
|
|
||||||
|
If a test requires special hardware or cannot run in your environment, say so in the pull request and document the closest validation you completed.
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
This flow builds **device-target (`larch64`) binaries on your laptop** using a Linux/aarch64 container and a synced comma sysroot.
|
This flow builds **device-target (`larch64`) binaries on your laptop** using a Linux/aarch64 container and a synced comma sysroot.
|
||||||
|
|
||||||
For the full StarPilot branch workflow, including host-native shorthand tools such as `./dev`, `./c3`, `./c4`, and `./raybig`, see [tools/STARPILOT_DEVELOPMENT.md](../../tools/STARPILOT_DEVELOPMENT.md).
|
For the full StarPilot branch workflow, including host-native shorthand tools such as `./dev`, `./c3`, and `./c4`, see the [StarPilot development guide](https://github.com/firestar5683/StarPilot/blob/Dom/tools/STARPILOT_DEVELOPMENT.md).
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
@@ -71,10 +71,10 @@ This runs:
|
|||||||
- `SP_TICI_SYSROOT=/opt/tici-sysroot`
|
- `SP_TICI_SYSROOT=/opt/tici-sysroot`
|
||||||
- `touch prebuilt`
|
- `touch prebuilt`
|
||||||
|
|
||||||
To run `scons` targets explicitly in the same device-compatible environment:
|
To run SCons targets explicitly in the same device-compatible environment:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
scripts/laptop_device_build.sh scons selfdrive/ui/ui
|
scripts/laptop_device_build.sh scons common/params_pyx.so
|
||||||
```
|
```
|
||||||
|
|
||||||
On macOS, once `.comma_sysroot` is present, plain `scons ...` auto-routes to this containerized device build.
|
On macOS, once `.comma_sysroot` is present, plain `scons ...` auto-routes to this containerized device build.
|
||||||
@@ -112,7 +112,6 @@ Preferred host-side shorthand commands on this branch:
|
|||||||
```bash
|
```bash
|
||||||
./c3
|
./c3
|
||||||
./c4
|
./c4
|
||||||
./raybig
|
|
||||||
./dev replay
|
./dev replay
|
||||||
./dev cabana
|
./dev cabana
|
||||||
./dev plotjuggler
|
./dev plotjuggler
|
||||||
@@ -120,10 +119,9 @@ Preferred host-side shorthand commands on this branch:
|
|||||||
|
|
||||||
These commands use the isolated `.host_runtime` cache so host-native artifacts do not churn the main tree.
|
These commands use the isolated `.host_runtime` cache so host-native artifacts do not churn the main tree.
|
||||||
|
|
||||||
Legacy direct script entrypoints still exist if needed:
|
Direct script entrypoints are also available:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
scripts/launch_ui_desktop.sh
|
scripts/launch_ui_c3_desktop.sh
|
||||||
scripts/launch_ui_c4_desktop.sh
|
scripts/launch_ui_c4_desktop.sh
|
||||||
scripts/launch_ui_raybig_desktop.sh
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -302,3 +302,112 @@ For temporal behavior on a saved frame directory or route extract, replay the ru
|
|||||||
```bash
|
```bash
|
||||||
.venv/bin/python scripts/replay_speed_limit_vision.py .tmp/vision_iter/seg10_5fps --frames-fps 5
|
.venv/bin/python scripts/replay_speed_limit_vision.py .tmp/vision_iter/seg10_5fps --frames-fps 5
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The detector/classifier runtime is model-only by default. Use `--crop-ocr` with
|
||||||
|
`evaluate_runtime_manifest.py` or `replay_route_runtime.py` only for an explicit
|
||||||
|
legacy comparison. A model-only release must match reviewed-manifest accuracy
|
||||||
|
and pass representative route replays at measured on-device cadence. Evaluate
|
||||||
|
candidate recognition and temporal publish behavior separately: a correct
|
||||||
|
single-frame candidate can still be suppressed by the history and speed-change
|
||||||
|
confirmation policy.
|
||||||
|
|
||||||
|
Ignored review rows label the proposed crop, not the entire camera frame.
|
||||||
|
Consequently, negative-window candidate and publish counts from
|
||||||
|
`evaluate_reviewed_route_events.py` are an upper bound until the full frame is
|
||||||
|
audited; another valid sign can be present outside the rejected crop. Use the
|
||||||
|
per-row output and frame image to audit any regression delta before treating it
|
||||||
|
as a runtime false positive.
|
||||||
|
|
||||||
|
## Promotion Gate
|
||||||
|
|
||||||
|
Do not promote a checkpoint from classifier validation accuracy alone. Export it
|
||||||
|
to an isolated model directory and run the complete runtime pipeline against the
|
||||||
|
reviewed positive, hard-negative, and failed-drive manifests. A candidate must
|
||||||
|
preserve exact-value recall, avoid new wrong-value reads, and remain within the
|
||||||
|
accepted false-positive budget before route replay.
|
||||||
|
|
||||||
|
Mine detector proposals that fool an integrated-reject classifier into a new
|
||||||
|
reject class before retraining:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
.venv/bin/python scripts/speed_limit_vision/mine_classifier_reject_crops.py \
|
||||||
|
--models-dir /path/to/candidate/models \
|
||||||
|
--dataset /path/to/versioned/classifier \
|
||||||
|
--manifest /path/to/reviewed-negative-manifest.csv
|
||||||
|
```
|
||||||
|
|
||||||
|
Keep the resulting dataset version separate from the current training set. If a
|
||||||
|
hard-negative retrain lowers reviewed recall, reject the checkpoint even when it
|
||||||
|
improves aggregate validation accuracy or removes a known false positive.
|
||||||
|
|
||||||
|
## Active-Learning Review Pass
|
||||||
|
|
||||||
|
Keep parallel miners in separate directories and merge them only when their
|
||||||
|
model and mining fingerprints match:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
.venv/bin/python scripts/speed_limit_vision/merge_manual_review_queues.py \
|
||||||
|
/path/to/shard0 /path/to/shard1 /path/to/shard2 /path/to/shard3 \
|
||||||
|
--output-dir /path/to/merged
|
||||||
|
```
|
||||||
|
|
||||||
|
When rescanning with a new model, compare the fingerprinted queues before
|
||||||
|
selecting another batch. The optional review output retains the full queue
|
||||||
|
schema so it can be passed directly to the selector and review server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
.venv/bin/python scripts/speed_limit_vision/compare_manual_review_queues.py \
|
||||||
|
--before /path/to/baseline/manual_review_queue.csv \
|
||||||
|
--after /path/to/candidate/manual_review_queue.csv \
|
||||||
|
--output-csv /path/to/comparison.csv \
|
||||||
|
--review-output /path/to/disagreements/manual_review_queue.csv
|
||||||
|
|
||||||
|
.venv/bin/python scripts/speed_limit_vision/select_manual_review_queue.py \
|
||||||
|
--input /path/to/disagreements/manual_review_queue.csv \
|
||||||
|
--output /path/to/review/manual_review_queue.csv \
|
||||||
|
--max-rows 1200 \
|
||||||
|
--min-seconds-per-route-speed 3
|
||||||
|
```
|
||||||
|
|
||||||
|
The selector prioritizes value changes and gained/lost reads, balances routes
|
||||||
|
and speed classes, and removes adjacent same-speed frames from one scene. Start
|
||||||
|
the reviewer and import its labels without moving route media off the training
|
||||||
|
volume:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
.venv/bin/python scripts/speed_limit_vision/serve_manual_review_queue.py \
|
||||||
|
--manifest /path/to/review/manual_review_queue.csv \
|
||||||
|
--port 8765
|
||||||
|
|
||||||
|
.venv/bin/python scripts/speed_limit_vision/import_manual_review_queue.py \
|
||||||
|
--queue /path/to/review/manual_review_queue.csv
|
||||||
|
```
|
||||||
|
|
||||||
|
## Re-mine the Route Backlog
|
||||||
|
|
||||||
|
Re-run the backlog after a candidate passes the reviewed-manifest and route
|
||||||
|
replay gates. Use a model fingerprinted run so new pseudo-labels are staged next
|
||||||
|
to, rather than merged into, the original route-mining data:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
.venv/bin/python scripts/speed_limit_vision/mine_route_training_samples.py \
|
||||||
|
--workspace /Volumes/T5/starpilot_speed_limit/workspace/speed_limit_training_clean \
|
||||||
|
--models-dir /path/to/promoted/models \
|
||||||
|
--model-only \
|
||||||
|
--run-id auto \
|
||||||
|
--sample-every 2.0 \
|
||||||
|
--transition-step 0.5 \
|
||||||
|
--max-frames-per-route 720 \
|
||||||
|
--max-positives-per-route 120 \
|
||||||
|
--max-negatives-per-route 200
|
||||||
|
```
|
||||||
|
|
||||||
|
The output is written under
|
||||||
|
`staging/route_mining/model_<model-fingerprint>_run_<mining-fingerprint>/` with
|
||||||
|
its own detector images, classifier labels, review manifest, and per-route
|
||||||
|
completion state. The mining fingerprint includes the model-only mode,
|
||||||
|
thresholds, sampling configuration, and relevant source code. Review and
|
||||||
|
deduplicate that staged run before merging it into a training dataset. Never
|
||||||
|
overwrite the canonical route samples or automatically train on every mined
|
||||||
|
positive; map agreement and human review remain required because a stronger
|
||||||
|
model can still reproduce its own mistakes at larger scale.
|
||||||
|
|||||||
@@ -0,0 +1,278 @@
|
|||||||
|
# I Taught My Comma to Read Speed Limit Signs
|
||||||
|
|
||||||
|
<video controls playsinline preload="metadata" poster="assets/speed-limit-vision-demo-poster.jpg" style="width: 100%; max-width: 1280px;">
|
||||||
|
<source src="assets/speed-limit-vision-demo.mp4" type="video/mp4">
|
||||||
|
</video>
|
||||||
|
|
||||||
|
[Watch the speed-limit vision demo](assets/speed-limit-vision-demo.mp4)
|
||||||
|
|
||||||
|
This whole project started because I was lazy.
|
||||||
|
|
||||||
|
If you’ve driven an HKG or Toyota vehicle in recent years, you’ve probably seen the dashboard automatically pick up speed limits using the camera. Coming from a car that didn't have this functionality, I was very jealous. Those cars can feed those speed limits directly into openpilot forks speed limit controllers. Mine couldn't.
|
||||||
|
|
||||||
|
The “solution” has been to manually add speed limits to Mapbox or OpenStreetMaps. It worked, but it was tedious. I live in rural Kansas, where my commute is almost entirely devoid of nerds contributing open source map data. I began mapping my commute when I first joined the project and within an hour said, “I ain't doin this”
|
||||||
|
|
||||||
|
We have an AI model that's good enough to drive our cars running on a smartphone chipset from years ago. How hard could it be to build one that just reads speed limit signs? I wanted StarPilot to look out the windshield, see a speed limit sign, and just know what it said.
|
||||||
|
|
||||||
|
That sounded simple enough.
|
||||||
|
|
||||||
|
It wasn’t.
|
||||||
|
|
||||||
|
The first prototype was basically held together with duct tape: I used all the public speed limit datasets I could find (glare and Lisa), some OpenCV, a little OCR, and a lot of wishful thinking. It could occasionally read a sign, but it missed 90% of them and produced enough false positives that you definitely wouldn’t want to trust it.
|
||||||
|
|
||||||
|
The important part wasn’t that it sucked - it was that it worked just well enough to start collecting better training data.
|
||||||
|
|
||||||
|
I run a fork of openpilot called StarPilot. We're heavily focused on tuning and testing wild ideas, which made my users the perfect candidates for this project.
|
||||||
|
|
||||||
|
Instead of relying on public datasets that barely resembled comma camera footage, StarPilot started collecting its own. Community members submitted routes from all over the country using bookmarks that were generated automatically when the model said "I think this might've been a sign," and every promising detection went through manual review. Eventually that grew into hundreds of gigabytes of real driving footage and thousands of carefully labeled speed limit signs.
|
||||||
|
|
||||||
|
From there it became an endless cycle:
|
||||||
|
|
||||||
|
- Train a better model.
|
||||||
|
- Mine more routes.
|
||||||
|
- Find more missed signs.
|
||||||
|
- Label them.
|
||||||
|
- Repeat.
|
||||||
|
|
||||||
|
The funny part is that training the neural network wasn’t actually the hardest problem.
|
||||||
|
|
||||||
|
The hard part was everything around it.
|
||||||
|
|
||||||
|
One of the biggest challenges wasn’t accuracy, it was speed. Every millisecond spent processing was another frame the model didn't have time to see. The faster it could process frames, the more chances it had to catch a sharp, readable speed limit sign before it disappeared. This was particularly imperative at night, when naturally camera frame rates drop alongside your chances of picking up a clear sign.
|
||||||
|
|
||||||
|
It’s slowly evolved from a proof of concept into a model that’s trained primarily on real comma footage instead of generic traffic sign datasets. It now runs entirely on-device, publishes vision-based speed limits directly into StarPilot, and no longer depends on OCR or manually maintaining map data.
|
||||||
|
|
||||||
|
And best of all…
|
||||||
|
|
||||||
|
While I'm too lazy to hand write hundreds of speed limit signs into OpenStreetMaps, this tool can now be used to automate the entire process, giving back to the open source mapping community that helps those in larger areas so well.
|
||||||
|
|
||||||
|
Give my vision speed limits a try, or help continue to build a better one than mine! All info and training stack is available on the StarPilot repo.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*For a full LLM style, more technical breakdown for those interested in the process, please read below:*
|
||||||
|
|
||||||
|
|
||||||
|
## Teaching StarPilot to Read Speed Limit Signs
|
||||||
|
|
||||||
|
In March 2026, this project started with a practical question: could StarPilot use the road camera to recognize speed-limit signs, attach them to GPS data, and help fill gaps in OpenStreetMap?
|
||||||
|
|
||||||
|
The first answer was "probably." A clean 40 mph sign in recorded comma footage was large enough to detect and read. StarPilot already had access to the live road-camera stream through VisionIPC, ONNX models could run through OpenCV DNN, and the existing Speed Limit Controller already knew how to combine several sources. The pieces existed.
|
||||||
|
|
||||||
|
What did not exist was a model trained for this camera, a trustworthy dataset, an honest replay benchmark, or a runtime that could analyze enough frames without interfering with openpilot. Building those became the real project.
|
||||||
|
|
||||||
|
This is the story of how we went from a weak imported model that was barely useful for automatic bookmarks to a custom detector and classifier trained primarily from real comma footage, how community routes changed the quality of the data, and why model accuracy on a laptop turned out to be only half of the problem.
|
||||||
|
|
||||||
|
### The first prototype
|
||||||
|
|
||||||
|
The first live implementation used an imported Ultralytics-style checkpoint called `ayoubsa_best`. Its provenance was thin: the ONNX metadata identified it as a Kaggle-trained detector, but there was no training notebook or source dataset in the repository. More importantly, its classes were a poor fit for American roads. It knew speed limits in 10 mph increments, such as 20, 30, and 40, but not the common 25, 35, 45, 55, or 65 mph signs.
|
||||||
|
|
||||||
|
That led to a hybrid design. The model proposed a sign region, then lightweight OpenCV and OCR-like digit logic tried to read the crop. It was enough to prove the complete path:
|
||||||
|
|
||||||
|
1. Read the live road-camera stream.
|
||||||
|
2. Search the right side of the frame for likely signs.
|
||||||
|
3. Produce a candidate speed and confidence.
|
||||||
|
4. Confirm it over time.
|
||||||
|
5. Publish it as a selectable `Vision` source for the Speed Limit Controller.
|
||||||
|
6. Save debug frames and bookmarks for later training.
|
||||||
|
|
||||||
|
It was not yet a good speed-limit reader. It missed most signs, produced false positives, and struggled badly with 5 mph increments. But it could occasionally find real signs, which meant it could help us collect the data needed to replace itself.
|
||||||
|
|
||||||
|
That bootstrap capability mattered more than its initial accuracy.
|
||||||
|
|
||||||
|
### Public data gave us a starting point
|
||||||
|
|
||||||
|
We chose a two-stage architecture early: one model would answer "where is the speed-limit sign and what kind is it?" while another would answer "what number is printed on it?" Detection and reading are related, but they are not the same task. Keeping them separate let the detector learn the general shape and location of a sign without needing a separate object class for every posted speed.
|
||||||
|
|
||||||
|
Three public U.S. traffic-sign datasets formed the initial training base:
|
||||||
|
|
||||||
|
- [LISA](https://cvrr.ucsd.edu/lisa-traffic-signs-dataset) provided U.S. road scenes, 47 sign types, and 7,855 annotations across 6,610 frames. Its annotations also included useful information such as occlusion and whether a sign belonged to a side road.
|
||||||
|
- [GLARE](https://arxiv.org/abs/2209.08716) provided 2,157 U.S. traffic-sign images taken from 33 dashcam videos under strong sun glare. The paper itself demonstrated why mixed normal and glare training was important.
|
||||||
|
- [ARTS](https://swshah.w3.uvm.edu/vail/datasets.php), the Automotive Repository of Traffic Signs, provided additional U.S. signs in easy, challenging, and video-log configurations.
|
||||||
|
|
||||||
|
The clean first pass imported 3,078 ARTS images with 3,139 relevant boxes. When a working LISA archive was found, it added 1,577 images and 1,680 boxes, including 15, 25, 35, 45, 55, and 65 mph classes. GLARE was downloaded selectively to avoid pulling a large collection of unrelated checkpoints.
|
||||||
|
|
||||||
|
|
||||||
|
### More data made the first retrain worse
|
||||||
|
|
||||||
|
The first clean public-data retrain looked reasonable in conventional validation metrics and failed badly on real comma routes.
|
||||||
|
|
||||||
|
The stronger older model found a candidate in 9 of 39 bookmarked route windows. The clean public-data model found only 1 of 39. It also regressed the saved-frame suite. We restored the older model instead of promoting a checkpoint merely because it was newer or had better training curves.
|
||||||
|
|
||||||
|
The domain gap was larger than image dimensions suggested. LISA, GLARE, ARTS, and comma footage were all forward-looking road imagery, but they differed in lens distortion, mounting position, exposure, dynamic range, compression, motion blur, sign position, and the number of pixels available when a sign first appeared. Public data often contained a cleaner or more centered sign than the live comma pipeline would see.
|
||||||
|
|
||||||
|
This established a rule that guided every later pass: public data was useful for bootstrapping and preservation, but real comma footage had to dominate final training and evaluation.
|
||||||
|
|
||||||
|
### Turning StarPilot into a data engine
|
||||||
|
|
||||||
|
The next large improvement did not come from a new backbone. It came from collecting better data.
|
||||||
|
|
||||||
|
StarPilot gained an automatic training collector, automatic bookmarks, manual bookmarks, debug snapshots, route metadata, and tools to preserve full-resolution video segments. A route-bundling script verified that a contributed route was public, contained the required qlogs, rlogs, and `fcamera.hevc` files, and had the vision collector enabled before packaging it.
|
||||||
|
|
||||||
|
That allowed StarPilot users to contribute real driving data from different cars, cameras, roads, states, lighting conditions, and sign styles. Eventually, nearly 200 GB of zipped comma routes landed on disk. This was enormously more useful than another generic sign dataset because it matched the exact production domain:
|
||||||
|
|
||||||
|
- the same road camera and encoding path;
|
||||||
|
- the same wide-angle geometry;
|
||||||
|
- the same night exposure and motion blur;
|
||||||
|
- the same right-shoulder sign placement;
|
||||||
|
- the same live crop errors;
|
||||||
|
- and the same hard negatives seen by the runtime detector.
|
||||||
|
|
||||||
|
The model could then scan old routes, find likely signs and mistakes, and generate another review queue. A better model could rescan the same backlog and find candidates the weaker model had never seen. Each iteration improved not only the deployed model, but also the quality of the next dataset.
|
||||||
|
|
||||||
|
### Human review was the quality control
|
||||||
|
|
||||||
|
Automatic labels were never trusted blindly. A map transition did not prove that a sign was visible, a bookmark did not prove that the best frame had been selected, and a confident model prediction did not prove that the crop contained the correct sign.
|
||||||
|
|
||||||
|
The manual review UI evolved around throughput. Typing a number labeled a regulatory sign. Single-key shortcuts marked advisory (`a`), school-zone (`s`), regulatory (`r`), uncertain (`u`), or ignored/not-a-sign (`i` or `x`) samples. Enter or Space accepted a prediction. Reviewers could also redraw a bad bounding box.
|
||||||
|
|
||||||
|
Those details affected model quality directly:
|
||||||
|
|
||||||
|
- A readable but slightly imperfect crop was useful.
|
||||||
|
- A crop that showed only the minimum-speed portion of a 65/40 sign was not a valid 40 mph regulatory label.
|
||||||
|
- Stop signs and empty crops became hard negatives.
|
||||||
|
- Advisory signs were labeled explicitly, even though overall sign recall remained the product priority.
|
||||||
|
- Uncertain night crops were retained separately instead of being treated as equally strong labels.
|
||||||
|
- Repeated frames from the same sign track were deduplicated so one scene could not dominate the dataset.
|
||||||
|
- Incorrectly large or shifted boxes were redrawn once the review tool exposed that capability.
|
||||||
|
|
||||||
|
One labeling ambiguity forced a larger re-review: earlier sessions had not made regulatory versus advisory state clear enough. Rather than preserve potentially poisoned labels, affected advisory candidates were put back into the queue under the corrected UI contract.
|
||||||
|
|
||||||
|
This was active learning in a practical form: spend human time on disagreements, weak reads, false publishes, missed signs, bad boxes, and rare conditions, not on thousands of easy duplicate frames.
|
||||||
|
|
||||||
|
By one later OCR-free promotion audit, the backlog covered 80 routes and 366,946 sampled frames. The model under audit produced 34,260 candidates for rescoring, while the canonical review database contained 5,383 unique human-reviewed crops: 593 positive reads and 4,146 usable crop-level rejects, with the remainder reserved for uncertain or otherwise excluded decisions. The raw route collection was large, but those reviewed examples were the part that made it trustworthy.
|
||||||
|
|
||||||
|
### The architecture that survived
|
||||||
|
|
||||||
|
The current production path is model-only. OCR remains in the source tree for legacy compatibility and offline experiments, but both full-frame OCR and crop OCR are disabled for the active detector/classifier pipeline.
|
||||||
|
|
||||||
|
The deployed stack contains:
|
||||||
|
|
||||||
|
- A YOLO11n-derived detector exported as a fixed `256x256` ONNX model. It proposes regulatory, advisory, and school-zone speed-limit signs.
|
||||||
|
- A YOLO11n-classifier-derived `128x128` ONNX model. It predicts 15 through 75 mph in 5 mph increments and includes a learned reject class for crops that are not valid speed-limit reads.
|
||||||
|
- Runtime logic that evaluates several crop expansions, combines their support, applies geometry and sign-type checks, and confirms lower-confidence changes over multiple frames.
|
||||||
|
- A right-side region of interest, which reduces wasted work while retaining the part of U.S. road scenes where most applicable signs appear.
|
||||||
|
|
||||||
|
The detector is about 9.9 MB and the classifier about 5.9 MB. They remain separate ONNX files intentionally. Joining the graphs into one file would make packaging look tidier, but it would not eliminate the detector or classifier computation. Separate models also let us change detector resolution, classifier training, reject behavior, and crop strategy independently.
|
||||||
|
|
||||||
|
A third standalone reject model was tested and discarded. It added another inference pass without measurably improving the reviewed positives or surviving false positive. Folding rejection into the value classifier produced a better cost/accuracy tradeoff.
|
||||||
|
|
||||||
|
OCR was removed only after the model-only path could pass the preservation suites on its own. In the decisive audit, model consensus improved the targeted 20 mph events from 1/14 to 11/14 and the broader targeted set from 21/36 to 27/36 without regressing the established legacy suites. At that point, OCR's occasional rescue was no longer worth the latency, extra failure modes, and frames lost while the device waited for it to finish.
|
||||||
|
|
||||||
|
Direct-value detectors, smaller input sizes, MobileNet-style classifiers, optical-flow tracking, and multiple crop strategies were also tested. Some looked attractive on desktop metrics and failed where it mattered. In particular, a 224-pixel detector was faster but dropped the hometown 20 mph suite from 14/14 to 9/14. The 256-pixel detector remained the better production choice.
|
||||||
|
|
||||||
|
### Frame rate is part of accuracy
|
||||||
|
|
||||||
|
The most important evaluation lesson came from a route with seven manually bookmarked signs.
|
||||||
|
|
||||||
|
An early offline replay sampled the video at 5 fps and found several signs. The actual comma found almost none. The model files matched and the vision process was running, so the discrepancy initially looked mysterious.
|
||||||
|
|
||||||
|
The replay had been landing on lucky frames.
|
||||||
|
|
||||||
|
The camera produced 25 frames per second, but the live process only attempted inference every 0.4 seconds. When we replayed all 25 source frames while enforcing that real inference gate, the local result fell to 0 of 7, matching the drive. Halving the interval to 0.2 seconds moved the same honest replay to 5 of 7 candidate windows and 3 of 7 actual publishes.
|
||||||
|
|
||||||
|
From then on, a model was not evaluated only as a collection of independent images. Route replay had to include:
|
||||||
|
|
||||||
|
- source-frame timing;
|
||||||
|
- the measured detector and classifier cost;
|
||||||
|
- steady and follow-up inference intervals;
|
||||||
|
- temporal confirmation rules;
|
||||||
|
- CPU backoff;
|
||||||
|
- and the distinction between a candidate and a value actually published to the UI or controller.
|
||||||
|
|
||||||
|
This distinction explained many arguments over numbers. A candidate means the detector and reader noticed something in a sign window. A publish means the temporal and confidence gates accepted it as the live speed limit. A model can read a sign correctly once and still fail to publish if a weak read requires a second frame that the device never processes.
|
||||||
|
|
||||||
|
Later-frame mining showed why this mattered. One pass revisited 405 known sign events and extracted 939 clearer frames from later in their tracks. Combined with track-aware classifier training and a reduction from four classifier crops to three, the measured runtime suite improved from 247 to 265 correct publications, including a gain from 211 to 229 in the priority 30-65 mph range. Better frame selection and less per-frame work helped at the same time.
|
||||||
|
|
||||||
|
### Making it fit beside openpilot
|
||||||
|
|
||||||
|
The comma is already running camera processing, the main driving models, localization, controls, the UI, and vehicle communication. A speed-limit sidecar cannot assume an idle CPU.
|
||||||
|
|
||||||
|
The early hybrid pipeline could take roughly 1.5 seconds per frame when the detector, crop reader, and OCR paths all fired. At that cadence, signs could pass through their brief readable window without ever being analyzed. It also added enough CPU pressure to coincide with camera/model frame-sync errors and temporary `locationd` alerts on some night drives.
|
||||||
|
|
||||||
|
Changing process priority was not the solution. The daemon was already running at a very low scheduling priority. The useful changes were to remove OCR from production, restrict detection to the right-side ROI, shrink the models carefully, avoid the extra reject-model pass, add device-load backoff, and use a faster follow-up cadence after a candidate appeared.
|
||||||
|
|
||||||
|
The current runtime requests a 0.15-second steady interval and a 0.10-second follow-up interval, but inference cost is the real limiter. On two measured routes, the complete process sustained about 1.77 to 1.81 inferences per second. The detector alone took roughly 0.43 to 0.44 seconds, and each classifier crop could add about 0.066 seconds. A sign may receive only 4 to 13 analyzed frames in a seven-second approach window.
|
||||||
|
|
||||||
|
This is why "run it at 10 Hz" is not a configuration change. The process can ask for 10 Hz, but it cannot start the next inference until the current one finishes.
|
||||||
|
|
||||||
|
### Debugging the system, not just the model
|
||||||
|
|
||||||
|
Several apparent model regressions were actually system problems.
|
||||||
|
|
||||||
|
|
||||||
|
These failures led to better observability: model hashes, inference counts, interval reasons, detector and classifier timing, CPU backoff state, candidates, publications, and debug captures all became part of route analysis. We stopped asking only "is the model accurate?" and started asking "which exact model and runtime processed which exact frames, and what did it publish?"
|
||||||
|
|
||||||
|
### How we decide whether a model is better
|
||||||
|
|
||||||
|
The promotion process now uses several independent gates:
|
||||||
|
|
||||||
|
- Reviewed crop accuracy checks whether the classifier can read localized signs.
|
||||||
|
- Hard-negative sets contain parking signs, traffic signals, truck restrictions, taillights, and other shapes that previously caused false reads.
|
||||||
|
- A 100-event main route suite tests full candidate and publication behavior at measured comma cadence.
|
||||||
|
- A separate 34-event held-out suite guards against tuning directly to the main set.
|
||||||
|
- A hometown 20 mph suite protects a class that earlier models repeatedly missed.
|
||||||
|
- Legacy suites ensure that old wins do not disappear.
|
||||||
|
- Targeted night and glare replays test the conditions most likely to break normal validation assumptions.
|
||||||
|
- On-device timing and live routes remain the final authority.
|
||||||
|
|
||||||
|
Many experiments were rejected despite improving one number. A glare-focused model lost broader recall. A traffic-signal hard-negative detector fixed one false positive and lost legitimate 35 mph signs. A more aggressive reject-classifier update reduced errors and then changed enough timing to expose different false publishes. Conservative weight interpolation often produced the safest result because it taught a narrow correction without erasing the representation that already worked.
|
||||||
|
|
||||||
|
The drive currently contains 87 detector experiment directories and 72 classifier experiment directories. Those are not 159 successive improvements. They are the record of resolution bake-offs, failed hard-negative passes, direct-value experiments, night/glare runs, integrated-reject models, temporal-crop training, and interpolations that mapped the boundaries of the system.
|
||||||
|
|
||||||
|
### Where accuracy is now
|
||||||
|
|
||||||
|
The current classifier, internally called `distilled-moonstone v3`, improved the deployed route suite without changing model size or runtime cost:
|
||||||
|
|
||||||
|
| Runtime suite | Previous tree | Current model |
|
||||||
|
| --- | ---: | ---: |
|
||||||
|
| Main route publishes | 78/100 | **92/100** |
|
||||||
|
| Main wrong publishes | 0 | **0** |
|
||||||
|
| Held-out publishes | 24/34 | **26/34** |
|
||||||
|
| Hometown 20 mph signs | 14/14 | **14/14** |
|
||||||
|
| Hard sun-glare check | 70 mph published | **70 mph published** |
|
||||||
|
|
||||||
|
These denominators are manually confirmed sign events, not arbitrary video frames. `92/100` means the full runtime pipeline published the correct value in 92 of 100 known sign windows while running with measured comma timing. It does not mean the model is 92 percent accurate on every road or every possible sign.
|
||||||
|
|
||||||
|
In ordinary daylight scenes, current performance is very good. The model is now reliable when signs are reasonably exposed and readable, while extreme image quality and limited frame opportunities remain the dominant failures.
|
||||||
|
|
||||||
|
The current result is also substantially better than the first public-data prototype, which missed nearly every sign on several routes and sometimes produced only a single useful event in an entire drive.
|
||||||
|
|
||||||
|
### The next hard barriers
|
||||||
|
|
||||||
|
The remaining misses are unusually informative. Of the 18 main-suite events the current model does not publish:
|
||||||
|
|
||||||
|
- 6 never produce a correct candidate at measured cadence.
|
||||||
|
- 4 produce exactly one weak correct read, but cannot satisfy the two-read confirmation rule.
|
||||||
|
- At an idealized 6.7 Hz cadence, the same model recovers 7 of those 10 publishes, reaching a theoretical 97/100, but also introduces one wrong publish.
|
||||||
|
- The three stubborn cases are all 45 mph scenes: two remain unreadable even at ideal cadence, and one first reads 40 before seeing 45 too late.
|
||||||
|
|
||||||
|
That theoretical 97/100 is not a production accuracy claim. It is a diagnostic result showing that most remaining failures already contain a readable frame that the device does not process.
|
||||||
|
|
||||||
|
The next large improvement is therefore likely to come from throughput and temporal reuse, not from simply lowering confidence thresholds:
|
||||||
|
|
||||||
|
1. Make the detector materially faster without giving up the small-sign and 20 mph recall lost by the 224- and 192-pixel experiments.
|
||||||
|
2. After a detector finds a sign, track or cheaply reclassify that crop across nearby frames instead of paying for another full detector pass every time.
|
||||||
|
3. Investigate a more efficient inference backend or model architecture on comma hardware. Direct model microbenchmarks are useful, but the complete process and onroad CPU contention must remain the acceptance metric.
|
||||||
|
4. Add targeted, human-reviewed sequences for the remaining 45 mph failures, night ghosting, distant signs, and direct-sun approaches.
|
||||||
|
5. Improve sign applicability for minimum-speed, truck-only, school-zone, advisory, side-road, and exit-ramp signs without sacrificing the product's primary goal: finding normal regulatory speed limits.
|
||||||
|
6. Keep model-fingerprinted backlog mining so every promoted model can rescan old routes into an isolated review set without silently replacing canonical labels.
|
||||||
|
|
||||||
|
Night remains difficult because the camera often produces fewer sharp frames, motion blur can create double digits, and reflective signs may be detected while they are still too distant to read. Glare is difficult for the opposite reason: contrast collapses and sign edges disappear into the sky. Both problems require sequence-level examples, not just one selected crop.
|
||||||
|
|
||||||
|
### What we learned
|
||||||
|
|
||||||
|
This was never one long training run. It was the construction of a data and evaluation system.
|
||||||
|
|
||||||
|
Public datasets made the first detector possible. A weak model made automatic collection possible. StarPilot users supplied the camera-native diversity that public data could not. Human review turned model proposals into trustworthy labels. Full-cadence replay exposed timing mistakes that image metrics hid. Live device telemetry kept CPU and process failures from being mistaken for neural-network failures. Conservative promotion gates preserved hard-won behavior while narrow experiments improved specific weaknesses.
|
||||||
|
|
||||||
|
The result is already useful and, in ordinary scenes, often impressively accurate. The path to the next jump is also clearer than it was at the beginning. We do not mainly need another giant pile of generic sign images. We need to process more of the good frames the comma already sees, teach the remaining hard sequences carefully, and continue judging the complete on-device system rather than the model in isolation.
|
||||||
|
|
||||||
|
That is the difference between training a traffic-sign classifier and building a speed-limit reader that works in a car.
|
||||||
|
|
||||||
|
### Technical references
|
||||||
|
|
||||||
|
- Runtime implementation: [`starpilot/system/speed_limit_vision.py`](../starpilot/system/speed_limit_vision.py)
|
||||||
|
- Training runbook: [`docs/how-to/train-speed-limit-vision.md`](how-to/train-speed-limit-vision.md)
|
||||||
|
- Training, mining, review, and evaluation tools: [`scripts/speed_limit_vision`](../scripts/speed_limit_vision)
|
||||||
|
- Deployed model assets: [`starpilot/assets/vision_models`](../starpilot/assets/vision_models)
|
||||||
+46
-58
@@ -4,7 +4,25 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
|||||||
|
|
||||||
source "$DIR/launch_env.sh"
|
source "$DIR/launch_env.sh"
|
||||||
|
|
||||||
|
export SP_BOOT_TIMING_LOG="${SP_BOOT_TIMING_LOG:-/tmp/starpilot_boot_timing.log}"
|
||||||
|
: > "$SP_BOOT_TIMING_LOG" 2>/dev/null || true
|
||||||
|
SP_LAUNCH_LAST_SECONDS=$SECONDS
|
||||||
|
|
||||||
|
function sp_boot_timing_line {
|
||||||
|
echo "$1"
|
||||||
|
printf '%s\n' "$1" >> "$SP_BOOT_TIMING_LOG" 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
function sp_launch_timing {
|
||||||
|
local now=$SECONDS
|
||||||
|
local delta=$((now - SP_LAUNCH_LAST_SECONDS))
|
||||||
|
sp_boot_timing_line "SP_BOOT_TIMING launch $1 +${delta}s total=${now}s"
|
||||||
|
SP_LAUNCH_LAST_SECONDS=$now
|
||||||
|
}
|
||||||
|
|
||||||
function agnos_init {
|
function agnos_init {
|
||||||
|
sp_launch_timing "agnos_init_start"
|
||||||
|
|
||||||
# TODO: move this to agnos
|
# TODO: move this to agnos
|
||||||
sudo rm -f /data/etc/NetworkManager/system-connections/*.nmmeta
|
sudo rm -f /data/etc/NetworkManager/system-connections/*.nmmeta
|
||||||
|
|
||||||
@@ -33,10 +51,17 @@ function agnos_init {
|
|||||||
# StarPilot variables
|
# StarPilot variables
|
||||||
sudo chmod 0777 /cache
|
sudo chmod 0777 /cache
|
||||||
|
|
||||||
sudo rm -f /data/misc/display/color_cal/color_cal /data/misc/display/color_cal/source.sha256
|
|
||||||
|
|
||||||
# Check if AGNOS update is required
|
# Check if AGNOS update is required
|
||||||
if [ $(< /VERSION) != "$AGNOS_VERSION" ]; then
|
AGNOS_CURRENT_VERSION="$(< /VERSION)"
|
||||||
|
AGNOS_UPDATE_REQUIRED=1
|
||||||
|
for accepted_version in $AGNOS_ACCEPTED_VERSIONS; do
|
||||||
|
if [ "$AGNOS_CURRENT_VERSION" = "$accepted_version" ]; then
|
||||||
|
AGNOS_UPDATE_REQUIRED=0
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$AGNOS_UPDATE_REQUIRED" = "1" ]; then
|
||||||
AGNOS_PY="$DIR/system/hardware/tici/agnos.py"
|
AGNOS_PY="$DIR/system/hardware/tici/agnos.py"
|
||||||
MANIFEST="$DIR/system/hardware/tici/agnos.json"
|
MANIFEST="$DIR/system/hardware/tici/agnos.json"
|
||||||
if $AGNOS_PY --verify $MANIFEST; then
|
if $AGNOS_PY --verify $MANIFEST; then
|
||||||
@@ -44,9 +69,13 @@ function agnos_init {
|
|||||||
fi
|
fi
|
||||||
$DIR/system/hardware/tici/updater $AGNOS_PY $MANIFEST
|
$DIR/system/hardware/tici/updater $AGNOS_PY $MANIFEST
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
sp_launch_timing "agnos_init_done"
|
||||||
}
|
}
|
||||||
|
|
||||||
function launch {
|
function launch {
|
||||||
|
sp_launch_timing "launch_start"
|
||||||
|
|
||||||
# Remove orphaned git lock if it exists on boot
|
# Remove orphaned git lock if it exists on boot
|
||||||
[ -f "$DIR/.git/index.lock" ] && rm -f $DIR/.git/index.lock
|
[ -f "$DIR/.git/index.lock" ] && rm -f $DIR/.git/index.lock
|
||||||
|
|
||||||
@@ -83,91 +112,50 @@ function launch {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
sp_launch_timing "overlay_check_done"
|
||||||
|
|
||||||
# handle pythonpath
|
# handle pythonpath
|
||||||
ln -sfn $(pwd) /data/pythonpath
|
ln -sfn $(pwd) /data/pythonpath
|
||||||
export BASEDIR="$DIR"
|
export BASEDIR="$DIR"
|
||||||
export PYTHONPATH="$DIR/starpilot/third_party:$PWD"
|
export PYTHONPATH="$DIR/starpilot/third_party:$PWD"
|
||||||
|
sp_launch_timing "pythonpath_done"
|
||||||
|
|
||||||
# hardware specific init
|
# hardware specific init
|
||||||
if [ -f /AGNOS ]; then
|
if [ -f /AGNOS ]; then
|
||||||
agnos_init
|
agnos_init
|
||||||
fi
|
fi
|
||||||
|
sp_launch_timing "hardware_init_done"
|
||||||
|
|
||||||
# write tmux scrollback to a file
|
# write tmux scrollback to a file
|
||||||
tmux capture-pane -pq -S-1000 > /tmp/launch_log
|
tmux capture-pane -pq -S-1000 > /tmp/launch_log
|
||||||
|
sp_launch_timing "capture_launch_log_done"
|
||||||
|
|
||||||
# start manager
|
# start manager
|
||||||
cd system/manager
|
cd system/manager
|
||||||
|
|
||||||
|
sp_launch_timing "launch_param_migrations_start"
|
||||||
if ! python3 ./launch_param_migrations.py; then
|
if ! python3 ./launch_param_migrations.py; then
|
||||||
echo "Launch param migrations failed; continuing boot."
|
echo "Launch param migrations failed; continuing boot."
|
||||||
fi
|
fi
|
||||||
|
sp_launch_timing "launch_param_migrations_done"
|
||||||
|
|
||||||
# Bootstrap runtime (e.g. /usr/comma after reset/uninstall) must go straight
|
# Bootstrap runtime (e.g. /usr/comma after reset/uninstall) must go straight
|
||||||
# to manager/setup flow. Do not run StarPilot prebuilt checks/builds here.
|
# to manager/setup flow. Do not run StarPilot prebuilt checks/builds here.
|
||||||
if [ "$DIR" = "/usr/comma" ] || [ ! -d "$DIR/.git" ]; then
|
if [ "$DIR" = "/usr/comma" ] || [ ! -d "$DIR/.git" ]; then
|
||||||
|
sp_launch_timing "bootstrap_manager_start"
|
||||||
./manager.py
|
./manager.py
|
||||||
while true; do sleep 1; done
|
while true; do sleep 1; done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
function prebuilt_runtime_compatible {
|
sp_launch_timing "prebuilt_decision_done"
|
||||||
python3 - <<'PY'
|
# Published trees carry this marker and must never compile on-device.
|
||||||
import importlib
|
# Developers can remove it explicitly when working from a source tree.
|
||||||
from pathlib import Path
|
if [ ! -f "$DIR/prebuilt" ]; then
|
||||||
import sys
|
sp_launch_timing "build_start"
|
||||||
|
|
||||||
mods = [
|
|
||||||
"openpilot.common.params_pyx",
|
|
||||||
"msgq.ipc_pyx",
|
|
||||||
"msgq.visionipc.visionipc_pyx",
|
|
||||||
"openpilot.common.transformations.transformations",
|
|
||||||
"openpilot.selfdrive.pandad.pandad_api_impl",
|
|
||||||
"openpilot.selfdrive.controls.lib.lateral_mpc_lib.c_generated_code.acados_ocp_solver_pyx",
|
|
||||||
"openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.c_generated_code.acados_ocp_solver_pyx",
|
|
||||||
]
|
|
||||||
|
|
||||||
for mod in mods:
|
|
||||||
try:
|
|
||||||
importlib.import_module(mod)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Prebuilt compatibility failure in {mod}: {e}", file=sys.stderr)
|
|
||||||
raise
|
|
||||||
|
|
||||||
repo_root = Path.cwd().parents[1]
|
|
||||||
required_files = [
|
|
||||||
repo_root / "selfdrive/modeld/models/driving_tinygrad.pkl",
|
|
||||||
repo_root / "selfdrive/modeld/models/dmonitoring_model_metadata.pkl",
|
|
||||||
repo_root / "selfdrive/modeld/models/dmonitoring_model_tinygrad.pkl",
|
|
||||||
repo_root / "selfdrive/modeld/models/dm_warp_1928x1208_tinygrad.pkl",
|
|
||||||
repo_root / "selfdrive/modeld/models/dm_warp_1344x760_tinygrad.pkl",
|
|
||||||
repo_root / "selfdrive/pandad/pandad_api_impl.so",
|
|
||||||
repo_root / "selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so",
|
|
||||||
repo_root / "selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/libacados_ocp_solver_lat.so",
|
|
||||||
repo_root / "selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so",
|
|
||||||
repo_root / "selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/libacados_ocp_solver_long.so",
|
|
||||||
repo_root / "opendbc_repo/opendbc/dbc/gm_global_a_powertrain_generated.dbc",
|
|
||||||
]
|
|
||||||
|
|
||||||
for path in required_files:
|
|
||||||
if not path.is_file():
|
|
||||||
raise FileNotFoundError(f"Missing prebuilt runtime artifact: {path}")
|
|
||||||
PY
|
|
||||||
}
|
|
||||||
|
|
||||||
USE_PREBUILT=1
|
|
||||||
if [ -f /data/params/d/UsePrebuilt ]; then
|
|
||||||
USE_PREBUILT=$(tr -d '\n' < /data/params/d/UsePrebuilt)
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$USE_PREBUILT" = "1" ] && [ -f $DIR/prebuilt ] && ! prebuilt_runtime_compatible; then
|
|
||||||
echo "Prebuilt runtime artifacts are incompatible on this device; rebuilding locally."
|
|
||||||
USE_PREBUILT=0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$USE_PREBUILT" != "1" ] || [ ! -f $DIR/prebuilt ]; then
|
|
||||||
./build.py
|
./build.py
|
||||||
|
sp_launch_timing "build_done"
|
||||||
fi
|
fi
|
||||||
|
sp_launch_timing "manager_start"
|
||||||
./manager.py
|
./manager.py
|
||||||
|
|
||||||
# if broken, keep on screen error
|
# if broken, keep on screen error
|
||||||
|
|||||||
+5
-1
@@ -21,7 +21,11 @@ fi
|
|||||||
export QCOM_PRIORITY=12
|
export QCOM_PRIORITY=12
|
||||||
|
|
||||||
if [ -z "$AGNOS_VERSION" ]; then
|
if [ -z "$AGNOS_VERSION" ]; then
|
||||||
export AGNOS_VERSION="12.8.17"
|
export AGNOS_VERSION="19.6.16"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$AGNOS_ACCEPTED_VERSIONS" ]; then
|
||||||
|
export AGNOS_ACCEPTED_VERSIONS="$AGNOS_VERSION"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export STAGING_ROOT="/data/safe_staging"
|
export STAGING_ROOT="/data/safe_staging"
|
||||||
|
|||||||
+2
-2
@@ -32,10 +32,10 @@ nav:
|
|||||||
- What is a car port?: car-porting/what-is-a-car-port.md
|
- What is a car port?: car-porting/what-is-a-car-port.md
|
||||||
- Porting a car brand: car-porting/brand-port.md
|
- Porting a car brand: car-porting/brand-port.md
|
||||||
- Porting a car model: car-porting/model-port.md
|
- Porting a car model: car-porting/model-port.md
|
||||||
- Contributing:
|
- Contribute:
|
||||||
|
- Contributing Guide: contributing/contribute.md
|
||||||
- Roadmap: contributing/roadmap.md
|
- Roadmap: contributing/roadmap.md
|
||||||
#- Architecture: contributing/architecture.md
|
#- Architecture: contributing/architecture.md
|
||||||
- Contributing Guide →: https://github.com/commaai/openpilot/blob/master/docs/CONTRIBUTING.md
|
|
||||||
- Links:
|
- Links:
|
||||||
- Blog →: https://blog.comma.ai
|
- Blog →: https://blog.comma.ai
|
||||||
- Bounties →: https://comma.ai/bounties
|
- Bounties →: https://comma.ai/bounties
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
exec python3 "$DIR/scripts/model_release.py" "$@"
|
||||||
@@ -21,6 +21,9 @@ static size_t fnv1a_hash(const std::string &str) {
|
|||||||
|
|
||||||
static std::string namespaced_endpoint(std::string endpoint) {
|
static std::string namespaced_endpoint(std::string endpoint) {
|
||||||
const char *namespace_env = std::getenv("OPENPILOT_ZMQ_NAMESPACE");
|
const char *namespace_env = std::getenv("OPENPILOT_ZMQ_NAMESPACE");
|
||||||
|
if (namespace_env == nullptr || namespace_env[0] == '\0') {
|
||||||
|
namespace_env = std::getenv("OPENPILOT_PREFIX");
|
||||||
|
}
|
||||||
if (namespace_env != nullptr && namespace_env[0] != '\0') {
|
if (namespace_env != nullptr && namespace_env[0] != '\0') {
|
||||||
endpoint = std::string(namespace_env) + ":" + endpoint;
|
endpoint = std::string(namespace_env) + ":" + endpoint;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,6 @@ const bool MUST_USE_ZMQ = false;
|
|||||||
|
|
||||||
bool messaging_use_zmq(){
|
bool messaging_use_zmq(){
|
||||||
if (std::getenv("ZMQ") || MUST_USE_ZMQ) {
|
if (std::getenv("ZMQ") || MUST_USE_ZMQ) {
|
||||||
if (std::getenv("OPENPILOT_PREFIX")) {
|
|
||||||
std::cerr << "OPENPILOT_PREFIX not supported with ZMQ backend\n";
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Binary file not shown.
@@ -61,6 +61,7 @@ class TestVisionIpc:
|
|||||||
recv_buf = self.client.recv()
|
recv_buf = self.client.recv()
|
||||||
assert recv_buf is not None
|
assert recv_buf is not None
|
||||||
assert recv_buf.data.view('<i4')[0] == 1234
|
assert recv_buf.data.view('<i4')[0] == 1234
|
||||||
|
assert recv_buf.frame_id == 1337
|
||||||
assert self.client.frame_id == 1337
|
assert self.client.frame_id == 1337
|
||||||
del self.client
|
del self.client
|
||||||
del self.server
|
del self.server
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ cdef extern from "msgq/visionipc/visionbuf.h":
|
|||||||
size_t idx
|
size_t idx
|
||||||
cl_mem buf_cl
|
cl_mem buf_cl
|
||||||
void set_frame_id(uint64_t id)
|
void set_frame_id(uint64_t id)
|
||||||
|
uint64_t get_frame_id()
|
||||||
|
|
||||||
cdef extern from "msgq/visionipc/visionipc.h":
|
cdef extern from "msgq/visionipc/visionipc.h":
|
||||||
struct VisionIpcBufExtra:
|
struct VisionIpcBufExtra:
|
||||||
|
|||||||
@@ -67,6 +67,10 @@ cdef class VisionBuf:
|
|||||||
def fd(self):
|
def fd(self):
|
||||||
return self.buf.fd
|
return self.buf.fd
|
||||||
|
|
||||||
|
@property
|
||||||
|
def frame_id(self):
|
||||||
|
return self.buf.get_frame_id()
|
||||||
|
|
||||||
|
|
||||||
cdef class VisionIpcServer:
|
cdef class VisionIpcServer:
|
||||||
cdef cppVisionIpcServer * server
|
cdef cppVisionIpcServer * server
|
||||||
|
|||||||
Binary file not shown.
+148
-14
@@ -1,24 +1,36 @@
|
|||||||
<!--- AUTOGENERATED FROM selfdrive/car/CARS_template.md, DO NOT EDIT. --->
|
<!--- AUTOGENERATED FROM selfdrive/car/CARS_template.md, DO NOT EDIT. --->
|
||||||
|
|
||||||
# Support Information for 384 Known Cars
|
# Support Information for 518 Known Cars
|
||||||
|
|
||||||
|Make|Model|Package|Support Level|
|
|Make|Model|Package|Support Level|
|
||||||
|---|---|---|:---:|
|
|---|---|---|:---:|
|
||||||
|
|Acura|ADX 2025-26|All|[Upstream](#upstream)|
|
||||||
|Acura|ILX 2016-18|Technology Plus Package or AcuraWatch Plus|[Upstream](#upstream)|
|
|Acura|ILX 2016-18|Technology Plus Package or AcuraWatch Plus|[Upstream](#upstream)|
|
||||||
|Acura|ILX 2019|All|[Upstream](#upstream)|
|
|Acura|ILX 2019|All|[Upstream](#upstream)|
|
||||||
|Acura|Integra 2023-25|All|[Community](#community)|
|
|Acura|Integra 2023-25|All|[Community](#community)|
|
||||||
|
|Acura|Integra 2023-26|All|[Upstream](#upstream)|
|
||||||
|
|Acura|MDX 2014-16|Advance Package|[Upstream](#upstream)|
|
||||||
|Acura|MDX 2015-16|Advance Package|[Community](#community)|
|
|Acura|MDX 2015-16|Advance Package|[Community](#community)|
|
||||||
|
|Acura|MDX 2017-19|All|[Upstream](#upstream)|
|
||||||
|Acura|MDX 2017-20|All|[Community](#community)|
|
|Acura|MDX 2017-20|All|[Community](#community)|
|
||||||
|
|Acura|MDX 2020|All|[Upstream](#upstream)|
|
||||||
|
|Acura|MDX 2022-24|All|[Upstream](#upstream)|
|
||||||
|Acura|MDX 2022-24|All|[Community](#community)|
|
|Acura|MDX 2022-24|All|[Community](#community)|
|
||||||
|Acura|MDX 2025|All except Type S|[Upstream](#upstream)|
|
|Acura|MDX 2025|All except Type S|[Upstream](#upstream)|
|
||||||
|
|Acura|MDX Hybrid 2017-19|All|[Upstream](#upstream)|
|
||||||
|
|Acura|MDX Hybrid 2020|All|[Upstream](#upstream)|
|
||||||
|Acura|RDX 2016-18|AcuraWatch Plus or Advance Package|[Upstream](#upstream)|
|
|Acura|RDX 2016-18|AcuraWatch Plus or Advance Package|[Upstream](#upstream)|
|
||||||
|Acura|RDX 2019-21|All|[Upstream](#upstream)|
|
|Acura|RDX 2019-21|All|[Upstream](#upstream)|
|
||||||
|Acura|RDX 2022-25|All|[Community](#community)|
|
|Acura|RDX 2022-25|All|[Community](#community)|
|
||||||
|
|Acura|RDX 2022-26|All|[Upstream](#upstream)|
|
||||||
|Acura|RLX 2017|Advance Package or Technology Package|[Community](#community)|
|
|Acura|RLX 2017|Advance Package or Technology Package|[Community](#community)|
|
||||||
|
|Acura|TLX 2015-17|Advance Package|[Upstream](#upstream)|
|
||||||
|Acura|TLX 2015-17|Advance Package|[Community](#community)|
|
|Acura|TLX 2015-17|Advance Package|[Community](#community)|
|
||||||
|
|Acura|TLX 2018-20|All|[Upstream](#upstream)|
|
||||||
|Acura|TLX 2018-20|All|[Community](#community)|
|
|Acura|TLX 2018-20|All|[Community](#community)|
|
||||||
|Acura|TLX 2021|All|[Upstream](#upstream)|
|
|Acura|TLX 2021|All|[Upstream](#upstream)|
|
||||||
|Acura|TLX 2022-23|All|[Community](#community)|
|
|Acura|TLX 2022-23|All|[Community](#community)|
|
||||||
|
|Acura|TLX 2024-25|All|[Upstream](#upstream)|
|
||||||
|Acura|ZDX 2024|All|[Not compatible](#can-bus-security)|
|
|Acura|ZDX 2024|All|[Not compatible](#can-bus-security)|
|
||||||
|Audi|A3 2014-19|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
|Audi|A3 2014-19|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|Audi|A3 Sportback e-tron 2017-18|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
|Audi|A3 Sportback e-tron 2017-18|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
@@ -26,14 +38,54 @@
|
|||||||
|Audi|A5 2016-24|All|[Not compatible](#flexray)|
|
|Audi|A5 2016-24|All|[Not compatible](#flexray)|
|
||||||
|Audi|Q2 2018|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
|Audi|Q2 2018|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|Audi|Q3 2019-24|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
|Audi|Q3 2019-24|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|
|Audi|Q4 e-tron 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|
|Audi|Q4 e-tron 2024-25|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|Audi|Q5 2017-24|All|[Not compatible](#flexray)|
|
|Audi|Q5 2017-24|All|[Not compatible](#flexray)|
|
||||||
|Audi|RS3 2018|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
|Audi|RS3 2018|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|Audi|S3 2015-17|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
|Audi|S3 2015-17|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|Chevrolet|Bolt EUV 2022-23|Premier or Premier Redline Trim, without Super Cruise Package|[Upstream](#upstream)|
|
|Buick|Baby Enclave 2020-23|Driver Assist Package|[Upstream](#upstream)|
|
||||||
|Chevrolet|Bolt EV 2022-23|2LT Trim with Adaptive Cruise Control Package|[Upstream](#upstream)|
|
|Buick|LaCrosse 2017-19|Driver Confidence Package 2|[Upstream](#upstream)|
|
||||||
|
|Buick|LaCrosse ASCM Harness 2017-19|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Buick|LaCrosse US ASCM Harness 2019|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Buick|Regal Essence 2018|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Cadillac|ATS Premium Performance 2018|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Cadillac|CT6 No-ACC 2016-20|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Cadillac|Escalade 2017|Driver Assist Package|[Upstream](#upstream)|
|
||||||
|
|Cadillac|Escalade ASCM Harness 2018|Driver Assist Package|[Upstream](#upstream)|
|
||||||
|
|Cadillac|Escalade ESV 2016|Adaptive Cruise Control (ACC) & LKAS|[Upstream](#upstream)|
|
||||||
|
|Cadillac|Escalade ESV 2019|Adaptive Cruise Control (ACC) & LKAS|[Upstream](#upstream)|
|
||||||
|
|Cadillac|Escalade ESV Platinum ASCM Harness 2019|Adaptive Cruise Control (ACC) & LKAS|[Upstream](#upstream)|
|
||||||
|
|Cadillac|XT4 2023|Driver Assist Package|[Upstream](#upstream)|
|
||||||
|
|Cadillac|XT4 No-ACC 2023|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Cadillac|XT5 2022|Driver Assist Package|[Upstream](#upstream)|
|
||||||
|
|Cadillac|XT5 No-ACC 2022|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Cadillac|XT6 2020|Driver Assist Package|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Blazer 2019-25|Driver Assist Package|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Bolt EV & EUV ACC 2022-23|Premier or Premier Redline Trim without Super Cruise Package|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Bolt EV & EUV ACC w Pedal 2022-23|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Bolt EV & EUV No-ACC 2022-23|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Bolt EV No-ACC 2017|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Bolt EV No-ACC 2018-21|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|Chevrolet|Equinox 2019-22|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
|Chevrolet|Equinox 2019-22|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Equinox No-ACC 2019-22|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Malibu 2019|SDGM Harness (Optional SASCM)|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Malibu ASCM Harness 2017-19|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Malibu Hybrid No-ACC 2017|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Malibu No-ACC 2023|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Malibu Premier 2017|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|Chevrolet|Silverado 1500 2020-21|Safety Package II|[Upstream](#upstream)|
|
|Chevrolet|Silverado 1500 2020-21|Safety Package II|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Silverado 1500 No-ACC 2020-21|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Suburban Premier 2016-20|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Suburban Premier No-ACC 2016-20|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|Chevrolet|Trailblazer 2021-22|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
|Chevrolet|Trailblazer 2021-22|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Trailblazer No-ACC 2021-22|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Traverse 2022-23|RS, Premier, or High Country Trim|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|TRAX 2024-25|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Volt 2017-18|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Volt 2019|Adaptive Cruise Control (ACC) & LKAS|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Volt ASCM Harness 2017-18|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Volt Camera Harness 2017-18|Flashed camera-forward integration with ACC|[Upstream](#upstream)|
|
||||||
|
|Chevrolet|Volt No-ACC 2016-18 (OBD Harness)|Redneck ACC|[Upstream](#upstream)|
|
||||||
|Chrysler|Pacifica 2017-18|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
|Chrysler|Pacifica 2017-18|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|Chrysler|Pacifica 2019-20|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
|Chrysler|Pacifica 2019-20|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|Chrysler|Pacifica 2021-23|All|[Upstream](#upstream)|
|
|Chrysler|Pacifica 2021-23|All|[Upstream](#upstream)|
|
||||||
@@ -41,8 +93,10 @@
|
|||||||
|Chrysler|Pacifica Hybrid 2019-25|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
|Chrysler|Pacifica Hybrid 2019-25|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|comma|body|All|[Upstream](#upstream)|
|
|comma|body|All|[Upstream](#upstream)|
|
||||||
|CUPRA|Ateca 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
|CUPRA|Ateca 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|
|CUPRA|Born 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|Dodge|Durango 2020-21|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
|Dodge|Durango 2020-21|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|Ford|Bronco Sport 2021-24|Co-Pilot360 Assist+|[Upstream](#upstream)|
|
|Ford|Bronco Sport 2021-24|Co-Pilot360 Assist+|[Upstream](#upstream)|
|
||||||
|
|Ford|Edge 2022|Co-Pilot360 Assist+|[Upstream](#upstream)|
|
||||||
|Ford|Escape 2020-22|Co-Pilot360 Assist+|[Upstream](#upstream)|
|
|Ford|Escape 2020-22|Co-Pilot360 Assist+|[Upstream](#upstream)|
|
||||||
|Ford|Escape 2023-24|Co-Pilot360 Assist+|[Upstream](#upstream)|
|
|Ford|Escape 2023-24|Co-Pilot360 Assist+|[Upstream](#upstream)|
|
||||||
|Ford|Escape Hybrid 2020-22|Co-Pilot360 Assist+|[Upstream](#upstream)|
|
|Ford|Escape Hybrid 2020-22|Co-Pilot360 Assist+|[Upstream](#upstream)|
|
||||||
@@ -54,8 +108,9 @@
|
|||||||
|Ford|Explorer Hybrid 2020-24|Co-Pilot360 Assist+|[Upstream](#upstream)|
|
|Ford|Explorer Hybrid 2020-24|Co-Pilot360 Assist+|[Upstream](#upstream)|
|
||||||
|Ford|F-150 2021-23|Co-Pilot360 Assist 2.0|[Upstream](#upstream)|
|
|Ford|F-150 2021-23|Co-Pilot360 Assist 2.0|[Upstream](#upstream)|
|
||||||
|Ford|F-150 Hybrid 2021-23|Co-Pilot360 Assist 2.0|[Upstream](#upstream)|
|
|Ford|F-150 Hybrid 2021-23|Co-Pilot360 Assist 2.0|[Upstream](#upstream)|
|
||||||
|Ford|Focus 2018|Adaptive Cruise Control with Lane Centering|[Upstream](#upstream)|
|
|Ford|F-150 Lightning 2022-25|Co-Pilot360 Assist 2.0|[Upstream](#upstream)|
|
||||||
|Ford|Focus Hybrid 2018|Adaptive Cruise Control with Lane Centering|[Upstream](#upstream)|
|
|Ford|Focus 2018-22|Adaptive Cruise Control with Lane Centering|[Upstream](#upstream)|
|
||||||
|
|Ford|Focus Hybrid 2018-22|Adaptive Cruise Control with Lane Centering|[Upstream](#upstream)|
|
||||||
|Ford|Kuga 2020-23|Adaptive Cruise Control with Lane Centering|[Upstream](#upstream)|
|
|Ford|Kuga 2020-23|Adaptive Cruise Control with Lane Centering|[Upstream](#upstream)|
|
||||||
|Ford|Kuga Hybrid 2020-23|Adaptive Cruise Control with Lane Centering|[Upstream](#upstream)|
|
|Ford|Kuga Hybrid 2020-23|Adaptive Cruise Control with Lane Centering|[Upstream](#upstream)|
|
||||||
|Ford|Kuga Hybrid 2024|All|[Upstream](#upstream)|
|
|Ford|Kuga Hybrid 2024|All|[Upstream](#upstream)|
|
||||||
@@ -65,11 +120,14 @@
|
|||||||
|Ford|Maverick 2023-24|Co-Pilot360 Assist|[Upstream](#upstream)|
|
|Ford|Maverick 2023-24|Co-Pilot360 Assist|[Upstream](#upstream)|
|
||||||
|Ford|Maverick Hybrid 2022|LARIAT Luxury|[Upstream](#upstream)|
|
|Ford|Maverick Hybrid 2022|LARIAT Luxury|[Upstream](#upstream)|
|
||||||
|Ford|Maverick Hybrid 2023-24|Co-Pilot360 Assist|[Upstream](#upstream)|
|
|Ford|Maverick Hybrid 2023-24|Co-Pilot360 Assist|[Upstream](#upstream)|
|
||||||
|
|Ford|Mondeo 2014-22|Adaptive Cruise Control with Lane Centering|[Upstream](#upstream)|
|
||||||
|Ford|Mustang Mach-E 2021-24|All|[Upstream](#upstream)|
|
|Ford|Mustang Mach-E 2021-24|All|[Upstream](#upstream)|
|
||||||
|Ford|Ranger 2024|Adaptive Cruise Control with Lane Centering|[Upstream](#upstream)|
|
|Ford|Ranger 2024|Adaptive Cruise Control with Lane Centering|[Upstream](#upstream)|
|
||||||
|
|Ford|Transit 2025|Co-Pilot360 Assist+|[Upstream](#upstream)|
|
||||||
|Genesis|G70 2018|All|[Upstream](#upstream)|
|
|Genesis|G70 2018|All|[Upstream](#upstream)|
|
||||||
|Genesis|G70 2019-21|All|[Upstream](#upstream)|
|
|Genesis|G70 2019-21|All|[Upstream](#upstream)|
|
||||||
|Genesis|G70 2022-23|All|[Upstream](#upstream)|
|
|Genesis|G70 2022-23|All|[Upstream](#upstream)|
|
||||||
|
|Genesis|G70 Non-SCC 2021|No Smart Cruise Control (Non-SCC)|[Community](community)|
|
||||||
|Genesis|G80 2017|All|[Upstream](#upstream)|
|
|Genesis|G80 2017|All|[Upstream](#upstream)|
|
||||||
|Genesis|G80 2018-19|All|[Upstream](#upstream)|
|
|Genesis|G80 2018-19|All|[Upstream](#upstream)|
|
||||||
|Genesis|G80 (2.5T Advanced Trim, with HDA II) 2024|Highway Driving Assist II|[Upstream](#upstream)|
|
|Genesis|G80 (2.5T Advanced Trim, with HDA II) 2024|Highway Driving Assist II|[Upstream](#upstream)|
|
||||||
@@ -78,14 +136,24 @@
|
|||||||
|Genesis|GV60 (Performance Trim) 2022-23|All|[Upstream](#upstream)|
|
|Genesis|GV60 (Performance Trim) 2022-23|All|[Upstream](#upstream)|
|
||||||
|Genesis|GV70 (2.5T Trim, without HDA II) 2022-24|All|[Upstream](#upstream)|
|
|Genesis|GV70 (2.5T Trim, without HDA II) 2022-24|All|[Upstream](#upstream)|
|
||||||
|Genesis|GV70 (3.5T Trim, without HDA II) 2022-23|All|[Upstream](#upstream)|
|
|Genesis|GV70 (3.5T Trim, without HDA II) 2022-23|All|[Upstream](#upstream)|
|
||||||
|
|Genesis|GV70 Electrified 2026|All|[Upstream](#upstream)|
|
||||||
|Genesis|GV70 Electrified (Australia Only) 2022|All|[Upstream](#upstream)|
|
|Genesis|GV70 Electrified (Australia Only) 2022|All|[Upstream](#upstream)|
|
||||||
|Genesis|GV70 Electrified (with HDA II) 2023-24|Highway Driving Assist II|[Upstream](#upstream)|
|
|Genesis|GV70 Electrified (with HDA II) 2023-24|Highway Driving Assist II|[Upstream](#upstream)|
|
||||||
|Genesis|GV80 2023|All|[Upstream](#upstream)|
|
|Genesis|GV80 2023|All|[Upstream](#upstream)|
|
||||||
|
|Genesis|GV80 (3.5T Prestige Trim, with HDA II & LFA2) 2025|Highway Driving Assist II & Lane Follow Assist 2|[Upstream](#upstream)|
|
||||||
|
|Genesis|GV80 Coupe (with HDA II & LFA2) 2025|Highway Driving Assist II & Lane Follow Assist 2|[Upstream](#upstream)|
|
||||||
|
|GMC|Acadia 2018|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|GMC|Acadia ASCM Harness 2018|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|GMC|Sierra 1500 2020-21|Driver Alert Package II|[Upstream](#upstream)|
|
|GMC|Sierra 1500 2020-21|Driver Alert Package II|[Upstream](#upstream)|
|
||||||
|GMC|Yukon 2019-20|Adaptive Cruise Control (ACC) & LKAS|[Dashcam mode](#dashcam)|
|
|GMC|Sierra 1500 No-ACC 2020-21|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|GMC|Yukon 2019-20|Adaptive Cruise Control (ACC) & LKAS|[Upstream](#upstream)|
|
||||||
|
|GMC|Yukon No-ACC 2019-20|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Holden|Astra 2017|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|
|Honda|Accord 2016-17|Honda Sensing|[Upstream](#upstream)|
|
||||||
|Honda|Accord 2016-17|Honda Sensing|[Community](#community)|
|
|Honda|Accord 2016-17|Honda Sensing|[Community](#community)|
|
||||||
|Honda|Accord 2018-22|All|[Upstream](#upstream)|
|
|Honda|Accord 2018-22|All|[Upstream](#upstream)|
|
||||||
|Honda|Accord 2023-25|All|[Upstream](#upstream)|
|
|Honda|Accord 2023-25|All|[Upstream](#upstream)|
|
||||||
|
|Honda|Accord Hybrid 2017|All|[Upstream](#upstream)|
|
||||||
|Honda|Accord Hybrid 2018-22|All|[Upstream](#upstream)|
|
|Honda|Accord Hybrid 2018-22|All|[Upstream](#upstream)|
|
||||||
|Honda|Accord Hybrid 2023-25|All|[Upstream](#upstream)|
|
|Honda|Accord Hybrid 2023-25|All|[Upstream](#upstream)|
|
||||||
|Honda|City (Brazil only) 2023|All|[Upstream](#upstream)|
|
|Honda|City (Brazil only) 2023|All|[Upstream](#upstream)|
|
||||||
@@ -98,6 +166,7 @@
|
|||||||
|Honda|Civic Hatchback Hybrid 2025-26|All|[Upstream](#upstream)|
|
|Honda|Civic Hatchback Hybrid 2025-26|All|[Upstream](#upstream)|
|
||||||
|Honda|Civic Hatchback Hybrid (Europe only) 2023|All|[Upstream](#upstream)|
|
|Honda|Civic Hatchback Hybrid (Europe only) 2023|All|[Upstream](#upstream)|
|
||||||
|Honda|Civic Hybrid 2025-26|All|[Upstream](#upstream)|
|
|Honda|Civic Hybrid 2025-26|All|[Upstream](#upstream)|
|
||||||
|
|Honda|Clarity 2018-21|All|[Upstream](#upstream)|
|
||||||
|Honda|Clarity 2018-21|All|[Community](#community)|
|
|Honda|Clarity 2018-21|All|[Community](#community)|
|
||||||
|Honda|CR-V 2015-16|Touring Trim|[Upstream](#upstream)|
|
|Honda|CR-V 2015-16|Touring Trim|[Upstream](#upstream)|
|
||||||
|Honda|CR-V 2017-22|Honda Sensing|[Upstream](#upstream)|
|
|Honda|CR-V 2017-22|Honda Sensing|[Upstream](#upstream)|
|
||||||
@@ -106,6 +175,8 @@
|
|||||||
|Honda|CR-V Hybrid 2023-25|All|[Upstream](#upstream)|
|
|Honda|CR-V Hybrid 2023-25|All|[Upstream](#upstream)|
|
||||||
|Honda|e 2020|All|[Upstream](#upstream)|
|
|Honda|e 2020|All|[Upstream](#upstream)|
|
||||||
|Honda|Fit 2018-20|Honda Sensing|[Upstream](#upstream)|
|
|Honda|Fit 2018-20|Honda Sensing|[Upstream](#upstream)|
|
||||||
|
|Honda|Fit (Taiwan) 2021|All|[Upstream](#upstream)|
|
||||||
|
|Honda|Fit (Taiwan) 2024-25|All|[Upstream](#upstream)|
|
||||||
|Honda|Freed 2020|Honda Sensing|[Upstream](#upstream)|
|
|Honda|Freed 2020|Honda Sensing|[Upstream](#upstream)|
|
||||||
|Honda|HR-V 2019-22|Honda Sensing|[Upstream](#upstream)|
|
|Honda|HR-V 2019-22|Honda Sensing|[Upstream](#upstream)|
|
||||||
|Honda|HR-V 2023-25|All|[Upstream](#upstream)|
|
|Honda|HR-V 2023-25|All|[Upstream](#upstream)|
|
||||||
@@ -114,27 +185,40 @@
|
|||||||
|Honda|N-Box 2018|All|[Upstream](#upstream)|
|
|Honda|N-Box 2018|All|[Upstream](#upstream)|
|
||||||
|Honda|Odyssey 2018-20|Honda Sensing|[Upstream](#upstream)|
|
|Honda|Odyssey 2018-20|Honda Sensing|[Upstream](#upstream)|
|
||||||
|Honda|Odyssey 2021-26|All|[Upstream](#upstream)|
|
|Honda|Odyssey 2021-26|All|[Upstream](#upstream)|
|
||||||
|
|Honda|Odyssey (Singapore) 2021|Honda Sensing|[Upstream](#upstream)|
|
||||||
|
|Honda|Odyssey (Taiwan) 2018-19|Honda Sensing|[Upstream](#upstream)|
|
||||||
|Honda|Passport 2019-25|All|[Upstream](#upstream)|
|
|Honda|Passport 2019-25|All|[Upstream](#upstream)|
|
||||||
|Honda|Passport 2026|All|[Upstream](#upstream)|
|
|Honda|Passport 2026|All|[Upstream](#upstream)|
|
||||||
|Honda|Pilot 2016-22|Honda Sensing|[Upstream](#upstream)|
|
|Honda|Pilot 2016-22|Honda Sensing|[Upstream](#upstream)|
|
||||||
|Honda|Pilot 2023-25|All|[Upstream](#upstream)|
|
|Honda|Pilot 2023-25|All|[Upstream](#upstream)|
|
||||||
|
|Honda|Prelude 2026|All|[Upstream](#upstream)|
|
||||||
|Honda|Prologue 2024-25|All|[Not compatible](#can-bus-security)|
|
|Honda|Prologue 2024-25|All|[Not compatible](#can-bus-security)|
|
||||||
|Honda|Ridgeline 2017-25|Honda Sensing|[Upstream](#upstream)|
|
|Honda|Ridgeline 2017-25|Honda Sensing|[Upstream](#upstream)|
|
||||||
|Hyundai|Azera 2022|All|[Upstream](#upstream)|
|
|Hyundai|Azera 2022|All|[Upstream](#upstream)|
|
||||||
|Hyundai|Azera Hybrid 2019|All|[Upstream](#upstream)|
|
|Hyundai|Azera Hybrid 2019|All|[Upstream](#upstream)|
|
||||||
|Hyundai|Azera Hybrid 2020|All|[Upstream](#upstream)|
|
|Hyundai|Azera Hybrid 2020|All|[Upstream](#upstream)|
|
||||||
|
|Hyundai|Azera Hybrid (with HDA II & LFA2) 2025|Highway Driving Assist II & Lane Follow Assist 2|[Upstream](#upstream)|
|
||||||
|
|Hyundai|Bayon Non-SCC 2021|No Smart Cruise Control (Non-SCC)|[Community](community)|
|
||||||
|Hyundai|Custin 2023|All|[Upstream](#upstream)|
|
|Hyundai|Custin 2023|All|[Upstream](#upstream)|
|
||||||
|Hyundai|Elantra 2017-18|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Hyundai|Elantra 2017-18|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Hyundai|Elantra 2019|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Hyundai|Elantra 2019|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Hyundai|Elantra 2021-23|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Hyundai|Elantra 2021-23|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Hyundai|Elantra 2024-25|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Hyundai|Elantra GT 2017-20|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Hyundai|Elantra GT 2017-20|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Hyundai|Elantra Hybrid 2021-23|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Hyundai|Elantra Hybrid 2021-23|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Hyundai|Elantra Hybrid 2024-26|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Hyundai|Elantra Hybrid Non-SCC 2022|No Smart Cruise Control (Non-SCC)|[Community](community)|
|
||||||
|
|Hyundai|Elantra Non-SCC 2022|No Smart Cruise Control (Non-SCC)|[Community](community)|
|
||||||
|Hyundai|Genesis 2015-16|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Hyundai|Genesis 2015-16|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Hyundai|i30 2017-19|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Hyundai|i30 2017-19|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Hyundai|i30 Hybrid 2024|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Hyundai|Ioniq 5 (Southeast Asia and Europe only) 2022-24|All|[Upstream](#upstream)|
|
|Hyundai|Ioniq 5 (Southeast Asia and Europe only) 2022-24|All|[Upstream](#upstream)|
|
||||||
|Hyundai|Ioniq 5 (with HDA II) 2022-24|Highway Driving Assist II|[Upstream](#upstream)|
|
|Hyundai|Ioniq 5 (with HDA II) 2022-24|Highway Driving Assist II|[Upstream](#upstream)|
|
||||||
|Hyundai|Ioniq 5 (without HDA II) 2022-24|Highway Driving Assist|[Upstream](#upstream)|
|
|Hyundai|Ioniq 5 (without HDA II) 2022-24|Highway Driving Assist|[Upstream](#upstream)|
|
||||||
|
|Hyundai|Ioniq 5 N (with HDA II) 2024|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Hyundai|Ioniq 5 PE (with HDA II & LFA2) 2025-26|Highway Driving Assist II & Lane Follow Assist 2|[Upstream](#upstream)|
|
||||||
|Hyundai|Ioniq 6 (with HDA II) 2023-24|Highway Driving Assist II|[Upstream](#upstream)|
|
|Hyundai|Ioniq 6 (with HDA II) 2023-24|Highway Driving Assist II|[Upstream](#upstream)|
|
||||||
|
|Hyundai|Ioniq 9 (with HDA II & LFA2) 2025-26|Highway Driving Assist II & Lane Follow Assist 2|[Upstream](#upstream)|
|
||||||
|Hyundai|Ioniq Electric 2019|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Hyundai|Ioniq Electric 2019|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Hyundai|Ioniq Electric 2020|All|[Upstream](#upstream)|
|
|Hyundai|Ioniq Electric 2020|All|[Upstream](#upstream)|
|
||||||
|Hyundai|Ioniq Hybrid 2017-19|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Hyundai|Ioniq Hybrid 2017-19|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
@@ -143,40 +227,68 @@
|
|||||||
|Hyundai|Ioniq Plug-in Hybrid 2020-22|All|[Upstream](#upstream)|
|
|Hyundai|Ioniq Plug-in Hybrid 2020-22|All|[Upstream](#upstream)|
|
||||||
|Hyundai|Kona 2020|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Hyundai|Kona 2020|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Hyundai|Kona 2022-23|Smart Cruise Control (SCC)|[Dashcam mode](#dashcam)|
|
|Hyundai|Kona 2022-23|Smart Cruise Control (SCC)|[Dashcam mode](#dashcam)|
|
||||||
|
|Hyundai|Kona (without HDA II) 2024-25|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Hyundai|Kona Electric 2018-21|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Hyundai|Kona Electric 2018-21|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Hyundai|Kona Electric 2022-23|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Hyundai|Kona Electric 2022-23|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Hyundai|Kona Electric (with HDA II, Korea only) 2023|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Hyundai|Kona Electric (with HDA II, Korea only) 2023|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Hyundai|Kona Electric (without HDA II) 2024|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Hyundai|Kona Electric Non-SCC 2019|No Smart Cruise Control (Non-SCC)|[Community](community)|
|
||||||
|Hyundai|Kona Hybrid 2020|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Hyundai|Kona Hybrid 2020|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Hyundai|Kona Hybrid (without HDA II) 2024|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Hyundai|Kona Non-SCC 2019|No Smart Cruise Control (Non-SCC)|[Community](community)|
|
||||||
|Hyundai|Nexo 2021|All|[Upstream](#upstream)|
|
|Hyundai|Nexo 2021|All|[Upstream](#upstream)|
|
||||||
|Hyundai|Palisade 2020-22|All|[Upstream](#upstream)|
|
|Hyundai|Palisade 2020-22|All|[Upstream](#upstream)|
|
||||||
|Hyundai|Palisade 2023-24|HDA2|[Community](#community)|
|
|Hyundai|Palisade 2023-25|HDA2|[Community](#community)|
|
||||||
|
|Hyundai|Palisade (with HDA II) 2023-25|Highway Driving Assist II|[Upstream](#upstream)|
|
||||||
|
|Hyundai|Palisade (without HDA II) 2023-25|Highway Driving Assist|[Upstream](#upstream)|
|
||||||
|Hyundai|Santa Cruz 2022-24|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Hyundai|Santa Cruz 2022-24|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Hyundai|Santa Cruz (without HDA II) 2025|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Hyundai|Santa Fe 2019-20|All|[Upstream](#upstream)|
|
|Hyundai|Santa Fe 2019-20|All|[Upstream](#upstream)|
|
||||||
|Hyundai|Santa Fe 2021-23|All|[Upstream](#upstream)|
|
|Hyundai|Santa Fe 2021-23|All|[Upstream](#upstream)|
|
||||||
|Hyundai|Santa Fe Hybrid 2022-23|All|[Upstream](#upstream)|
|
|Hyundai|Santa Fe Hybrid 2022-23|All|[Upstream](#upstream)|
|
||||||
|
|Hyundai|Santa Fe Hybrid (with HDA II & LFA2) 2024-25|Highway Driving Assist II & Lane Follow Assist 2|[Upstream](#upstream)|
|
||||||
|
|Hyundai|Santa Fe Hybrid (without HDA II, LFA2) 2025-26|Lane Follow Assist 2|[Upstream](#upstream)|
|
||||||
|Hyundai|Santa Fe Plug-in Hybrid 2022-23|All|[Upstream](#upstream)|
|
|Hyundai|Santa Fe Plug-in Hybrid 2022-23|All|[Upstream](#upstream)|
|
||||||
|Hyundai|Sonata 2018-19|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Hyundai|Sonata 2018-19|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Hyundai|Sonata 2020-23|All|[Upstream](#upstream)|
|
|Hyundai|Sonata 2020-23|All|[Upstream](#upstream)|
|
||||||
|
|Hyundai|Sonata (without HDA II) 2024-25|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Hyundai|Sonata Hybrid 2020-23|All|[Upstream](#upstream)|
|
|Hyundai|Sonata Hybrid 2020-23|All|[Upstream](#upstream)|
|
||||||
|
|Hyundai|Sonata Hybrid (without HDA II) 2024-25|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Hyundai|Staria 2023|All|[Upstream](#upstream)|
|
|Hyundai|Staria 2023|All|[Upstream](#upstream)|
|
||||||
|Hyundai|Tucson 2021|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Hyundai|Tucson 2021|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Hyundai|Tucson 2022|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Hyundai|Tucson 2022|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Hyundai|Tucson 2023-24|All|[Upstream](#upstream)|
|
|Hyundai|Tucson 2023-24|All|[Upstream](#upstream)|
|
||||||
|
|Hyundai|Tucson (without HDA II) 2025-26|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Hyundai|Tucson Diesel 2019|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Hyundai|Tucson Diesel 2019|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Hyundai|Tucson Hybrid 2022-24|All|[Upstream](#upstream)|
|
|Hyundai|Tucson Hybrid 2022-24|All|[Upstream](#upstream)|
|
||||||
|
|Hyundai|Tucson Hybrid (without HDA II) 2025-26|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Hyundai|Tucson Plug-in Hybrid 2024|All|[Upstream](#upstream)|
|
|Hyundai|Tucson Plug-in Hybrid 2024|All|[Upstream](#upstream)|
|
||||||
|
|Hyundai|Tucson Plug-in Hybrid (without HDA II) 2025|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Hyundai|Veloster 2019-20|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Hyundai|Veloster 2019-20|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Jeep|Grand Cherokee 2016-18|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
|Jeep|Grand Cherokee 2016-18|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|Jeep|Grand Cherokee 2019-21|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
|Jeep|Grand Cherokee 2019-21|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|Kia|Carnival 2022-24|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Kia|Carnival 2022-24|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Kia|Carnival 2025|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Kia|Carnival (China only) 2023|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Kia|Carnival (China only) 2023|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Kia|Carnival (with HDA II) 2025|Highway Driving Assist II|[Upstream](#upstream)|
|
||||||
|
|Kia|Carnival Hybrid 2025|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Kia|Carnival Hybrid 2026|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Kia|Carnival Hybrid (with HDA II) 2025-26|Highway Driving Assist II|[Upstream](#upstream)|
|
||||||
|Kia|Ceed 2019-21|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Kia|Ceed 2019-21|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Kia|Ceed Plug-in Hybrid Non-SCC 2022|No Smart Cruise Control (Non-SCC)|[Community](community)|
|
||||||
|Kia|EV6 (Southeast Asia only) 2022-24|All|[Upstream](#upstream)|
|
|Kia|EV6 (Southeast Asia only) 2022-24|All|[Upstream](#upstream)|
|
||||||
|
|Kia|EV6 (with HDA I) 2025|Highway Driving Assist I|[Upstream](#upstream)|
|
||||||
|Kia|EV6 (with HDA II) 2022-24|Highway Driving Assist II|[Upstream](#upstream)|
|
|Kia|EV6 (with HDA II) 2022-24|Highway Driving Assist II|[Upstream](#upstream)|
|
||||||
|Kia|EV6 (without HDA II) 2022-24|Highway Driving Assist|[Upstream](#upstream)|
|
|Kia|EV6 (without HDA II) 2022-24|Highway Driving Assist|[Upstream](#upstream)|
|
||||||
|
|Kia|EV9 2025-26|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Kia|Forte 2019-21|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Kia|Forte 2019-21|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Kia|Forte 2022-23|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Kia|Forte 2022-23|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Kia|Forte Non-SCC 2019|No Smart Cruise Control (Non-SCC)|[Community](community)|
|
||||||
|
|Kia|Forte Non-SCC 2021|No Smart Cruise Control (Non-SCC)|[Community](community)|
|
||||||
|
|Kia|K4 (with HDA II) 2025|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Kia|K4 (without HDA II) 2025|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Kia|K5 2021-24|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Kia|K5 2021-24|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Kia|K5 (without HDA II) 2025|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Kia|K5 Hybrid 2020-22|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Kia|K5 Hybrid 2020-22|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Kia|K8 Hybrid (with HDA II) 2023|Highway Driving Assist II|[Upstream](#upstream)|
|
|Kia|K8 Hybrid (with HDA II) 2023|Highway Driving Assist II|[Upstream](#upstream)|
|
||||||
|Kia|Niro EV 2019|All|[Upstream](#upstream)|
|
|Kia|Niro EV 2019|All|[Upstream](#upstream)|
|
||||||
@@ -198,17 +310,25 @@
|
|||||||
|Kia|Optima Hybrid 2017|Advanced Smart Cruise Control|[Dashcam mode](#dashcam)|
|
|Kia|Optima Hybrid 2017|Advanced Smart Cruise Control|[Dashcam mode](#dashcam)|
|
||||||
|Kia|Optima Hybrid 2019|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Kia|Optima Hybrid 2019|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Kia|Seltos 2021|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Kia|Seltos 2021|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Kia|Seltos Non-SCC 2023-24|No Smart Cruise Control (Non-SCC)|[Community](community)|
|
||||||
|Kia|Sorento 2018|Advanced Smart Cruise Control & LKAS|[Upstream](#upstream)|
|
|Kia|Sorento 2018|Advanced Smart Cruise Control & LKAS|[Upstream](#upstream)|
|
||||||
|Kia|Sorento 2019|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Kia|Sorento 2019|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Kia|Sorento 2021-23|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Kia|Sorento 2021-23|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Kia|Sorento (without HDA II) 2024-25|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Kia|Sorento Hybrid 2021-23|All|[Upstream](#upstream)|
|
|Kia|Sorento Hybrid 2021-23|All|[Upstream](#upstream)|
|
||||||
|
|Kia|Sorento Hybrid 2026|All|[Upstream](#upstream)|
|
||||||
|Kia|Sorento Plug-in Hybrid 2022-23|All|[Upstream](#upstream)|
|
|Kia|Sorento Plug-in Hybrid 2022-23|All|[Upstream](#upstream)|
|
||||||
|Kia|Sportage 2023-24|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Kia|Sportage 2023-24|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Kia|Sportage (without HDA II) 2026|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Kia|Sportage Hybrid 2023|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Kia|Sportage Hybrid 2023|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|
|Kia|Sportage Hybrid 2026|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Kia|Stinger 2018-20|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
|Kia|Stinger 2018-20|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Kia|Stinger 2022-23|All|[Upstream](#upstream)|
|
|Kia|Stinger 2022-23|All|[Upstream](#upstream)|
|
||||||
|Kia|Telluride 2020-22|All|[Upstream](#upstream)|
|
|Kia|Telluride 2020-22|All|[Upstream](#upstream)|
|
||||||
|Kia|Telluride 2023-24|HDA2|[Community](#community)|
|
|Kia|Telluride 2023-24|HDA2|[Community](#community)|
|
||||||
|
|Kia|Telluride (with HDA II) 2023-24|Highway Driving Assist II|[Upstream](#upstream)|
|
||||||
|
|Kia|Telluride (without HDA II) 2023-25|Highway Driving Assist|[Upstream](#upstream)|
|
||||||
|
|Kia|XCeed Plug-in Hybrid 2021|Smart Cruise Control (SCC)|[Upstream](#upstream)|
|
||||||
|Lexus|CT Hybrid 2017-18|Lexus Safety System+|[Upstream](#upstream)|
|
|Lexus|CT Hybrid 2017-18|Lexus Safety System+|[Upstream](#upstream)|
|
||||||
|Lexus|ES 2017-18|All|[Upstream](#upstream)|
|
|Lexus|ES 2017-18|All|[Upstream](#upstream)|
|
||||||
|Lexus|ES 2019-25|All|[Upstream](#upstream)|
|
|Lexus|ES 2019-25|All|[Upstream](#upstream)|
|
||||||
@@ -243,7 +363,8 @@
|
|||||||
|Mazda|CX-9 2016-20|All|[Dashcam mode](#dashcam)|
|
|Mazda|CX-9 2016-20|All|[Dashcam mode](#dashcam)|
|
||||||
|Mazda|CX-9 2021-23|All|[Upstream](#upstream)|
|
|Mazda|CX-9 2021-23|All|[Upstream](#upstream)|
|
||||||
|Nissan|Altima 2019-20, 2024|ProPILOT Assist|[Upstream](#upstream)|
|
|Nissan|Altima 2019-20, 2024|ProPILOT Assist|[Upstream](#upstream)|
|
||||||
|Nissan|Leaf 2018-23|ProPILOT Assist|[Upstream](#upstream)|
|
|Nissan|Leaf 2018-25|ProPILOT Assist|[Upstream](#upstream)|
|
||||||
|
|Nissan|Leaf Instrument Cluster 2018-25|ProPILOT Assist|[Upstream](#upstream)|
|
||||||
|Nissan|Rogue 2018-20|ProPILOT Assist|[Upstream](#upstream)|
|
|Nissan|Rogue 2018-20|ProPILOT Assist|[Upstream](#upstream)|
|
||||||
|Nissan|X-Trail 2017|ProPILOT Assist|[Upstream](#upstream)|
|
|Nissan|X-Trail 2017|ProPILOT Assist|[Upstream](#upstream)|
|
||||||
|Peugeot|208 2019-25|Adaptive Cruise Control (ACC) & Lane Assist|[Dashcam mode](#dashcam)|
|
|Peugeot|208 2019-25|Adaptive Cruise Control (ACC) & Lane Assist|[Dashcam mode](#dashcam)|
|
||||||
@@ -252,30 +373,36 @@
|
|||||||
|Ram|2500 2020-24|Adaptive Cruise Control (ACC)|[Dashcam mode](#dashcam)|
|
|Ram|2500 2020-24|Adaptive Cruise Control (ACC)|[Dashcam mode](#dashcam)|
|
||||||
|Ram|3500 2019-22|Adaptive Cruise Control (ACC)|[Dashcam mode](#dashcam)|
|
|Ram|3500 2019-22|Adaptive Cruise Control (ACC)|[Dashcam mode](#dashcam)|
|
||||||
|Rivian|R1S 2022-24|All|[Upstream](#upstream)|
|
|Rivian|R1S 2022-24|All|[Upstream](#upstream)|
|
||||||
|
|Rivian|R1S 2025|All|[Upstream](#upstream)|
|
||||||
|Rivian|R1T 2022-24|All|[Upstream](#upstream)|
|
|Rivian|R1T 2022-24|All|[Upstream](#upstream)|
|
||||||
|
|Rivian|R1T 2025|All|[Upstream](#upstream)|
|
||||||
|SEAT|Alhambra 2018-20|Adaptive Cruise Control (ACC) & Lane Assist|[Dashcam mode](#dashcam)|
|
|SEAT|Alhambra 2018-20|Adaptive Cruise Control (ACC) & Lane Assist|[Dashcam mode](#dashcam)|
|
||||||
|SEAT|Ateca 2016-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
|SEAT|Ateca 2016-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|SEAT|Leon 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
|SEAT|Leon 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|Subaru|Ascent 2019-21|All|[Upstream](#upstream)|
|
|Subaru|Ascent 2019-21|All|[Upstream](#upstream)|
|
||||||
|Subaru|Ascent 2023|All|[Dashcam mode](#dashcam)|
|
|Subaru|Ascent 2023-25|All|[Upstream](#upstream)|
|
||||||
|Subaru|Crosstrek 2018-19|EyeSight Driver Assistance|[Upstream](#upstream)|
|
|Subaru|Crosstrek 2018-19|EyeSight Driver Assistance|[Upstream](#upstream)|
|
||||||
|Subaru|Crosstrek 2020-23|EyeSight Driver Assistance|[Upstream](#upstream)|
|
|Subaru|Crosstrek 2020-23|EyeSight Driver Assistance|[Upstream](#upstream)|
|
||||||
|
|Subaru|Crosstrek 2025|All|[Upstream](#upstream)|
|
||||||
|Subaru|Crosstrek Hybrid 2020|EyeSight Driver Assistance|[Dashcam mode](#dashcam)|
|
|Subaru|Crosstrek Hybrid 2020|EyeSight Driver Assistance|[Dashcam mode](#dashcam)|
|
||||||
|Subaru|Forester 2017-18|EyeSight Driver Assistance|[Dashcam mode](#dashcam)|
|
|Subaru|Forester 2017-18|EyeSight Driver Assistance|[Dashcam mode](#dashcam)|
|
||||||
|Subaru|Forester 2019-21|All|[Upstream](#upstream)|
|
|Subaru|Forester 2019-21|All|[Upstream](#upstream)|
|
||||||
|Subaru|Forester 2022-24|All|[Dashcam mode](#dashcam)|
|
|Subaru|Forester 2022-24|All|[Upstream](#upstream)|
|
||||||
|Subaru|Forester Hybrid 2020|EyeSight Driver Assistance|[Dashcam mode](#dashcam)|
|
|Subaru|Forester Hybrid 2020|EyeSight Driver Assistance|[Dashcam mode](#dashcam)|
|
||||||
|Subaru|Impreza 2017-19|EyeSight Driver Assistance|[Upstream](#upstream)|
|
|Subaru|Impreza 2017-19|EyeSight Driver Assistance|[Upstream](#upstream)|
|
||||||
|Subaru|Impreza 2020-22|EyeSight Driver Assistance|[Upstream](#upstream)|
|
|Subaru|Impreza 2020-22|EyeSight Driver Assistance|[Upstream](#upstream)|
|
||||||
|Subaru|Legacy 2015-18|EyeSight Driver Assistance|[Dashcam mode](#dashcam)|
|
|Subaru|Legacy 2015-18|EyeSight Driver Assistance|[Dashcam mode](#dashcam)|
|
||||||
|Subaru|Legacy 2020-22|All|[Upstream](#upstream)|
|
|Subaru|Legacy 2020-22|All|[Upstream](#upstream)|
|
||||||
|
|Subaru|Legacy 2025|All|[Upstream](#upstream)|
|
||||||
|Subaru|Outback 2015-17|EyeSight Driver Assistance|[Dashcam mode](#dashcam)|
|
|Subaru|Outback 2015-17|EyeSight Driver Assistance|[Dashcam mode](#dashcam)|
|
||||||
|Subaru|Outback 2018-19|EyeSight Driver Assistance|[Dashcam mode](#dashcam)|
|
|Subaru|Outback 2018-19|EyeSight Driver Assistance|[Dashcam mode](#dashcam)|
|
||||||
|Subaru|Outback 2020-22|All|[Upstream](#upstream)|
|
|Subaru|Outback 2020-22|All|[Upstream](#upstream)|
|
||||||
|Subaru|Outback 2023|All|[Dashcam mode](#dashcam)|
|
|Subaru|Outback 2023-24|All|[Upstream](#upstream)|
|
||||||
|Subaru|Solterra 2023-25|Any|[Not compatible](#can-bus-security)|
|
|Subaru|Solterra 2023-25|Any|[Not compatible](#can-bus-security)|
|
||||||
|Subaru|XV 2018-19|EyeSight Driver Assistance|[Upstream](#upstream)|
|
|Subaru|XV 2018-19|EyeSight Driver Assistance|[Upstream](#upstream)|
|
||||||
|Subaru|XV 2020-21|EyeSight Driver Assistance|[Upstream](#upstream)|
|
|Subaru|XV 2020-21|EyeSight Driver Assistance|[Upstream](#upstream)|
|
||||||
|
|Škoda|Enyaq 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|
|Škoda|Enyaq 2024-25|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|Škoda|Fabia 2022-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
|Škoda|Fabia 2022-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|Škoda|Kamiq 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
|Škoda|Kamiq 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|Škoda|Karoq 2019-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
|Škoda|Karoq 2019-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
@@ -286,7 +413,8 @@
|
|||||||
|Škoda|Scala 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
|Škoda|Scala 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|Škoda|Superb 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
|Škoda|Superb 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|Tesla|Model 3 (with HW3) 2019-23|All|[Upstream](#upstream)|
|
|Tesla|Model 3 (with HW3) 2019-23|All|[Upstream](#upstream)|
|
||||||
|Tesla|Model 3 (with HW4) 2024-25|All|[Upstream](#upstream)|
|
|Tesla|Model 3 (with HW4) 2024-26|All|[Upstream](#upstream)|
|
||||||
|
|Tesla|Model S (Pre-AP) 2012-14|All|[Community](#community)|
|
||||||
|Tesla|Model X (with HW4) 2024|All|[Dashcam mode](#dashcam)|
|
|Tesla|Model X (with HW4) 2024|All|[Dashcam mode](#dashcam)|
|
||||||
|Tesla|Model Y (with HW3) 2020-23|All|[Upstream](#upstream)|
|
|Tesla|Model Y (with HW3) 2020-23|All|[Upstream](#upstream)|
|
||||||
|Tesla|Model Y (with HW4) 2024-25|All|[Upstream](#upstream)|
|
|Tesla|Model Y (with HW4) 2024-25|All|[Upstream](#upstream)|
|
||||||
@@ -321,6 +449,7 @@
|
|||||||
|Toyota|Highlander 2025|Any|[Not compatible](#can-bus-security)|
|
|Toyota|Highlander 2025|Any|[Not compatible](#can-bus-security)|
|
||||||
|Toyota|Highlander Hybrid 2017-19|All|[Upstream](#upstream)|
|
|Toyota|Highlander Hybrid 2017-19|All|[Upstream](#upstream)|
|
||||||
|Toyota|Highlander Hybrid 2020-23|All|[Upstream](#upstream)|
|
|Toyota|Highlander Hybrid 2020-23|All|[Upstream](#upstream)|
|
||||||
|
|Toyota|Matrix Retrofit 2005|Custom retrofit|[Community](#community)|
|
||||||
|Toyota|Mirai 2021|All|[Upstream](#upstream)|
|
|Toyota|Mirai 2021|All|[Upstream](#upstream)|
|
||||||
|Toyota|Prius 2016|Toyota Safety Sense P|[Upstream](#upstream)|
|
|Toyota|Prius 2016|Toyota Safety Sense P|[Upstream](#upstream)|
|
||||||
|Toyota|Prius 2017-20|All|[Upstream](#upstream)|
|
|Toyota|Prius 2017-20|All|[Upstream](#upstream)|
|
||||||
@@ -342,7 +471,7 @@
|
|||||||
|Toyota|RAV4 Prime 2024-25|Any|[Not compatible](#can-bus-security)|
|
|Toyota|RAV4 Prime 2024-25|Any|[Not compatible](#can-bus-security)|
|
||||||
|Toyota|Sequoia 2023-25|Any|[Not compatible](#can-bus-security)|
|
|Toyota|Sequoia 2023-25|Any|[Not compatible](#can-bus-security)|
|
||||||
|Toyota|Sienna 2018-20|All|[Upstream](#upstream)|
|
|Toyota|Sienna 2018-20|All|[Upstream](#upstream)|
|
||||||
|Toyota|Sienna 2021-23|All|[Community](#community)|
|
|Toyota|Sienna 2021-25|All|[Community](#community)|
|
||||||
|Toyota|Sienna 2024-25|Any|[Not compatible](#can-bus-security)|
|
|Toyota|Sienna 2024-25|Any|[Not compatible](#can-bus-security)|
|
||||||
|Toyota|Tundra 2022-25|Any|[Not compatible](#can-bus-security)|
|
|Toyota|Tundra 2022-25|Any|[Not compatible](#can-bus-security)|
|
||||||
|Toyota|Venza 2021-25|Any|[Not compatible](#can-bus-security)|
|
|Toyota|Venza 2021-25|Any|[Not compatible](#can-bus-security)|
|
||||||
@@ -369,6 +498,11 @@
|
|||||||
|Volkswagen|Golf R 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
|Volkswagen|Golf R 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|Volkswagen|Golf SportsVan 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
|Volkswagen|Golf SportsVan 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|Volkswagen|Grand California 2019-24|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
|Volkswagen|Grand California 2019-24|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|
|Volkswagen|ID.3 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|
|Volkswagen|ID.3 2024-25|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|
|Volkswagen|ID.4 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|
|Volkswagen|ID.4 2024-25|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|
|Volkswagen|ID.5 2022-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|Volkswagen|Jetta 2015-18|Adaptive Cruise Control (ACC) & Lane Assist|[Dashcam mode](#dashcam)|
|
|Volkswagen|Jetta 2015-18|Adaptive Cruise Control (ACC) & Lane Assist|[Dashcam mode](#dashcam)|
|
||||||
|Volkswagen|Jetta 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
|Volkswagen|Jetta 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
|Volkswagen|Jetta GLI 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
|Volkswagen|Jetta GLI 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|[Upstream](#upstream)|
|
||||||
@@ -444,4 +578,4 @@ Toyota, and the GM Global B platform.
|
|||||||
All the cars that openpilot supports use a [CAN bus](https://en.wikipedia.org/wiki/CAN_bus) for communication between all the car's computers, however a
|
All the cars that openpilot supports use a [CAN bus](https://en.wikipedia.org/wiki/CAN_bus) for communication between all the car's computers, however a
|
||||||
CAN bus isn't the only way that the computers in your car can communicate. Most, if not all, vehicles from the following
|
CAN bus isn't the only way that the computers in your car can communicate. Most, if not all, vehicles from the following
|
||||||
manufacturers use [FlexRay](https://en.wikipedia.org/wiki/FlexRay) instead of a CAN bus: **BMW, Mercedes, Audi, Land Rover, and some Volvo**. These cars
|
manufacturers use [FlexRay](https://en.wikipedia.org/wiki/FlexRay) instead of a CAN bus: **BMW, Mercedes, Audi, Land Rover, and some Volvo**. These cars
|
||||||
may one day be supported, but we have no immediate plans to support FlexRay.
|
may one day be supported, but we have no immediate plans to support FlexRay.
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ test:
|
|||||||
run: codespell {files} -L tge,stdio -S *.dbc
|
run: codespell {files} -L tge,stdio -S *.dbc
|
||||||
files: git ls-tree -r HEAD --name-only
|
files: git ls-tree -r HEAD --name-only
|
||||||
cpplint:
|
cpplint:
|
||||||
run: cpplint --exclude=opendbc/safety/tests/misra/cppcheck/ --exclude=opendbc/can/*_pyx.cpp --recursive --quiet --counting=detailed --linelength=240 --filter=-build,-legal,-readability,-runtime,-whitespace,+build/include_subdir,+build/forward_decl,+build/include_what_you_use,+build/deprecated,+whitespace/comma,+whitespace/line_length,+whitespace/empty_if_body,+whitespace/empty_loop_body,+whitespace/empty_conditional_body,+whitespace/forcolon,+whitespace/parens,+whitespace/semicolon,+whitespace/tab,+readability/braces opendbc/
|
run: cpplint --exclude=opendbc/safety/tests/misra/cppcheck/ --exclude=opendbc/safety/tests/.venv/ --exclude=opendbc/can/*_pyx.cpp --recursive --quiet --counting=detailed --linelength=240 --filter=-build,-legal,-readability,-runtime,-whitespace,+build/include_subdir,+build/forward_decl,+build/include_what_you_use,+build/deprecated,+whitespace/comma,+whitespace/line_length,+whitespace/empty_if_body,+whitespace/empty_loop_body,+whitespace/empty_conditional_body,+whitespace/forcolon,+whitespace/parens,+whitespace/semicolon,+whitespace/tab,+readability/braces opendbc/
|
||||||
misra:
|
misra:
|
||||||
run: opendbc/safety/tests/misra/test_misra.sh
|
run: opendbc/safety/tests/misra/test_misra.sh
|
||||||
|
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ class CANParser:
|
|||||||
self.dbc: DBC = DBC(dbc_name)
|
self.dbc: DBC = DBC(dbc_name)
|
||||||
|
|
||||||
self.vl: dict[int | str, dict[str, float]] = VLDict(self)
|
self.vl: dict[int | str, dict[str, float]] = VLDict(self)
|
||||||
|
self.vl_raw: dict[int | str, bytes] = {}
|
||||||
self.vl_all: dict[int | str, dict[str, list[float]]] = {}
|
self.vl_all: dict[int | str, dict[str, list[float]]] = {}
|
||||||
self.ts_nanos: dict[int | str, dict[str, int]] = {}
|
self.ts_nanos: dict[int | str, dict[str, int]] = {}
|
||||||
self.addresses: set[int] = set()
|
self.addresses: set[int] = set()
|
||||||
@@ -166,6 +167,8 @@ class CANParser:
|
|||||||
signals_dict = {s: 0.0 for s in signal_names}
|
signals_dict = {s: 0.0 for s in signal_names}
|
||||||
dict.__setitem__(self.vl, msg.address, signals_dict)
|
dict.__setitem__(self.vl, msg.address, signals_dict)
|
||||||
dict.__setitem__(self.vl, msg.name, signals_dict)
|
dict.__setitem__(self.vl, msg.name, signals_dict)
|
||||||
|
self.vl_raw[msg.address] = bytes(msg.size)
|
||||||
|
self.vl_raw[msg.name] = bytes(msg.size)
|
||||||
self.vl_all[msg.address] = defaultdict(list)
|
self.vl_all[msg.address] = defaultdict(list)
|
||||||
self.vl_all[msg.name] = self.vl_all[msg.address]
|
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.address] = {s: 0 for s in signal_names}
|
||||||
@@ -247,6 +250,8 @@ class CANParser:
|
|||||||
vl_addr[sig.name] = state.vals[i]
|
vl_addr[sig.name] = state.vals[i]
|
||||||
vl_all_addr[sig.name] = state.all_vals[i]
|
vl_all_addr[sig.name] = state.all_vals[i]
|
||||||
ts_addr[sig.name] = state.timestamps[-1]
|
ts_addr[sig.name] = state.timestamps[-1]
|
||||||
|
self.vl_raw[address] = bytes(dat)
|
||||||
|
self.vl_raw[state.name] = bytes(dat)
|
||||||
|
|
||||||
if not bus_empty:
|
if not bus_empty:
|
||||||
self.last_nonempty_nanos = t
|
self.last_nonempty_nanos = t
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import copy
|
import copy
|
||||||
from opendbc.can import CANPacker, CANParser
|
from opendbc.can import CANPacker, CANParser
|
||||||
|
from opendbc.car.honda.hondacan import honda_checksum
|
||||||
|
|
||||||
|
|
||||||
class TestCanChecksums:
|
class TestCanChecksums:
|
||||||
@@ -90,6 +91,13 @@ class TestCanChecksums:
|
|||||||
assert parser.vl['LKAS_HUD']['CHECKSUM'] == std
|
assert parser.vl['LKAS_HUD']['CHECKSUM'] == std
|
||||||
assert parser.vl['LKAS_HUD_A']['CHECKSUM'] == ext
|
assert parser.vl['LKAS_HUD_A']['CHECKSUM'] == ext
|
||||||
|
|
||||||
|
def test_honda_canfd_checksum_offset_is_scoped_to_mvl_messages(self):
|
||||||
|
# Existing high-ID Honda messages retain the legacy extended-ID offset;
|
||||||
|
# only the Accord MVL replacement-radar IDs use the CAN-FD offset.
|
||||||
|
payload = bytearray(8)
|
||||||
|
assert honda_checksum(0xF31AA54, None, payload) == 11 # existing radarless LKAS_HUD_2
|
||||||
|
assert honda_checksum(0xF31AA52, None, payload) == 4 # Accord MVL RADAR_LEAD2
|
||||||
|
|
||||||
def verify_volkswagen_mqb_crc(self, subtests, msg_name: str, msg_addr: int, test_messages: list[bytes], counter_field: str = 'COUNTER'):
|
def verify_volkswagen_mqb_crc(self, subtests, msg_name: str, msg_addr: int, test_messages: list[bytes], counter_field: str = 'COUNTER'):
|
||||||
"""Test AUTOSAR E2E Profile 2 CRCs"""
|
"""Test AUTOSAR E2E Profile 2 CRCs"""
|
||||||
assert len(test_messages) == 16 # All counter values must be tested
|
assert len(test_messages) == 16 # All counter values must be tested
|
||||||
|
|||||||
@@ -374,6 +374,7 @@ struct CarControl {
|
|||||||
brake @1: Float32; # [0.0, 1.0]
|
brake @1: Float32; # [0.0, 1.0]
|
||||||
torqueOutputCan @8: Float32; # value sent over can to the car
|
torqueOutputCan @8: Float32; # value sent over can to the car
|
||||||
speed @6: Float32; # m/s
|
speed @6: Float32; # m/s
|
||||||
|
lateralControlMode @9: LateralControlMode;
|
||||||
|
|
||||||
enum LongControlState @0xe40f3a917d908282{
|
enum LongControlState @0xe40f3a917d908282{
|
||||||
off @0;
|
off @0;
|
||||||
@@ -381,6 +382,13 @@ struct CarControl {
|
|||||||
stopping @2;
|
stopping @2;
|
||||||
starting @3;
|
starting @3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum LateralControlMode {
|
||||||
|
inactive @0;
|
||||||
|
torque @1;
|
||||||
|
angle @2;
|
||||||
|
torqueRecovering @3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CruiseControl {
|
struct CruiseControl {
|
||||||
@@ -510,6 +518,7 @@ struct CarParams {
|
|||||||
startingState @70 :Bool; # Does this car make use of special starting state
|
startingState @70 :Bool; # Does this car make use of special starting state
|
||||||
|
|
||||||
steerActuatorDelay @36 :Float32; # Steering wheel actuator delay in seconds
|
steerActuatorDelay @36 :Float32; # Steering wheel actuator delay in seconds
|
||||||
|
lateralSmoothSeconds @78 :Float32; # Speed-scheduled curvature smoothing used by select angle-control platforms
|
||||||
longitudinalActuatorDelay @58 :Float32; # Gas/Brake actuator delay in seconds
|
longitudinalActuatorDelay @58 :Float32; # Gas/Brake actuator delay in seconds
|
||||||
openpilotLongitudinalControl @37 :Bool; # is openpilot doing the longitudinal control?
|
openpilotLongitudinalControl @37 :Bool; # is openpilot doing the longitudinal control?
|
||||||
carVin @38 :Text; # VIN number queried during fingerprinting
|
carVin @38 :Text; # VIN number queried during fingerprinting
|
||||||
@@ -635,6 +644,8 @@ struct CarParams {
|
|||||||
fcaGiorgio @32;
|
fcaGiorgio @32;
|
||||||
rivian @33;
|
rivian @33;
|
||||||
volkswagenMeb @34;
|
volkswagenMeb @34;
|
||||||
|
teslaPreAP @35;
|
||||||
|
volvo @36;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SteerControlType {
|
enum SteerControlType {
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ def _normalize_forced_candidate(candidate: str | None) -> str | None:
|
|||||||
return LEGACY_FORCED_CANDIDATE_MAP.get(candidate, candidate)
|
return LEGACY_FORCED_CANDIDATE_MAP.get(candidate, candidate)
|
||||||
|
|
||||||
|
|
||||||
def _normalize_gm_bolt_candidate(candidate: str | None, fingerprints: dict[int, dict]) -> str | None:
|
def _normalize_gm_bolt_candidate(candidate: str | None, fingerprints: dict[int, dict], vin: str | None = None) -> str | None:
|
||||||
"""
|
"""
|
||||||
Normalize ambiguous/mismatched Bolt candidates using robust PT message signatures.
|
Normalize ambiguous/mismatched Bolt candidates using robust PT message signatures.
|
||||||
This guards against occasional wrong variant selection causing persistent canError.
|
This guards against occasional wrong variant selection causing persistent canError.
|
||||||
@@ -79,7 +79,22 @@ def _normalize_gm_bolt_candidate(candidate: str | None, fingerprints: dict[int,
|
|||||||
msg_304_len = pt.get(304) # 8 on 2017 Gen1, 1 on 2018-2021 Gen1
|
msg_304_len = pt.get(304) # 8 on 2017 Gen1, 1 on 2018-2021 Gen1
|
||||||
has_pedal = 513 in pt
|
has_pedal = 513 in pt
|
||||||
|
|
||||||
|
# The 2022-23 Bolt ACC, pedal, and CC variants share the same FPv1
|
||||||
|
# fingerprint. Recover an ambiguous match when the observed traffic
|
||||||
|
# matches the Bolt family and the VIN confirms model year 2022/2023.
|
||||||
|
bolt_2022_2023_signature = (
|
||||||
|
pt.get(190) == 7 and
|
||||||
|
msg_211_len == 3 and
|
||||||
|
pt.get(566) == 8 and
|
||||||
|
pt.get(458) == 5
|
||||||
|
)
|
||||||
|
vin_year = vin[9] if isinstance(vin, str) and len(vin) > 9 else None
|
||||||
|
|
||||||
|
# VIN model-year codes: N=2022, P=2023.
|
||||||
|
if candidate is None and bolt_2022_2023_signature and vin_year in ("N", "P"):
|
||||||
|
return "CHEVROLET_BOLT_ACC_2022_2023_PEDAL" if has_pedal else "CHEVROLET_BOLT_ACC_2022_2023"
|
||||||
# If detection failed entirely but the signature is clearly Bolt, recover to a sane default.
|
# If detection failed entirely but the signature is clearly Bolt, recover to a sane default.
|
||||||
|
|
||||||
if candidate is None and 170 in pt and 188 in pt and msg_211_len in (2, 3):
|
if candidate is None and 170 in pt and 188 in pt and msg_211_len in (2, 3):
|
||||||
if msg_211_len == 3:
|
if msg_211_len == 3:
|
||||||
return "CHEVROLET_BOLT_ACC_2022_2023_PEDAL" if has_pedal else "CHEVROLET_BOLT_ACC_2022_2023"
|
return "CHEVROLET_BOLT_ACC_2022_2023_PEDAL" if has_pedal else "CHEVROLET_BOLT_ACC_2022_2023"
|
||||||
@@ -279,7 +294,7 @@ def fingerprint(can_recv: CanRecvCallable, can_send: CanSendCallable, set_obd_mu
|
|||||||
def get_car(can_recv: CanRecvCallable, can_send: CanSendCallable, set_obd_multiplexing: ObdCallback, alpha_long_allowed: bool,
|
def get_car(can_recv: CanRecvCallable, can_send: CanSendCallable, set_obd_multiplexing: ObdCallback, alpha_long_allowed: bool,
|
||||||
is_release: bool, params: Params, num_pandas: int = 1, cached_params: CarParamsT | None = None, starpilot_toggles: SimpleNamespace = None):
|
is_release: bool, params: Params, num_pandas: int = 1, cached_params: CarParamsT | None = None, starpilot_toggles: SimpleNamespace = None):
|
||||||
candidate, fingerprints, vin, car_fw, source, exact_match = fingerprint(can_recv, can_send, set_obd_multiplexing, num_pandas, cached_params)
|
candidate, fingerprints, vin, car_fw, source, exact_match = fingerprint(can_recv, can_send, set_obd_multiplexing, num_pandas, cached_params)
|
||||||
candidate = _normalize_gm_bolt_candidate(candidate, fingerprints)
|
candidate = _normalize_gm_bolt_candidate(candidate, fingerprints, vin)
|
||||||
candidate = _normalize_gm_volt_candidate(candidate, fingerprints)
|
candidate = _normalize_gm_volt_candidate(candidate, fingerprints)
|
||||||
candidate = _normalize_forced_candidate(candidate)
|
candidate = _normalize_forced_candidate(candidate)
|
||||||
fingerprinted_candidate = candidate
|
fingerprinted_candidate = candidate
|
||||||
|
|||||||
@@ -2,9 +2,28 @@ from opendbc.can import CANPacker
|
|||||||
from opendbc.car import Bus, DT_CTRL
|
from opendbc.car import Bus, DT_CTRL
|
||||||
from opendbc.car.lateral import apply_meas_steer_torque_limits
|
from opendbc.car.lateral import apply_meas_steer_torque_limits
|
||||||
from opendbc.car.chrysler import chryslercan
|
from opendbc.car.chrysler import chryslercan
|
||||||
from opendbc.car.chrysler.values import RAM_CARS, RAM_DT, CarControllerParams, ChryslerFlags, ChryslerStarPilotFlags
|
from opendbc.car.chrysler.values import JEEPS, RAM_CARS, RAM_DT, CarControllerParams, ChryslerFlags, ChryslerSafetyFlags, ChryslerStarPilotFlags
|
||||||
from opendbc.car.interfaces import CarControllerBase
|
from opendbc.car.interfaces import CarControllerBase
|
||||||
|
|
||||||
|
JEEP_BRAKE_HOLD_DEFAULT_DECEL = -2.0
|
||||||
|
JEEP_BRAKE_HOLD_MIN_DECEL = -0.5
|
||||||
|
JEEP_BRAKE_HOLD_MAX_DECEL = -3.0
|
||||||
|
|
||||||
|
|
||||||
|
def clip_jeep_brake_hold_decel(decel: float) -> float:
|
||||||
|
return max(JEEP_BRAKE_HOLD_MAX_DECEL, min(JEEP_BRAKE_HOLD_MIN_DECEL, float(decel)))
|
||||||
|
|
||||||
|
|
||||||
|
def supports_jeep_brake_hold(CP, brake_hold_enabled: bool) -> bool:
|
||||||
|
safety_cfg = getattr(CP, "safetyConfigs", ())
|
||||||
|
safety_param = safety_cfg[0].safetyParam if safety_cfg else 0
|
||||||
|
return (
|
||||||
|
brake_hold_enabled and
|
||||||
|
getattr(CP, "pcmCruise", False) and
|
||||||
|
CP.carFingerprint in JEEPS and
|
||||||
|
bool(safety_param & ChryslerSafetyFlags.JEEP_BRAKE_HOLD.value)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CarController(CarControllerBase):
|
class CarController(CarControllerBase):
|
||||||
def __init__(self, dbc_names, CP):
|
def __init__(self, dbc_names, CP):
|
||||||
@@ -18,6 +37,8 @@ class CarController(CarControllerBase):
|
|||||||
|
|
||||||
self.packer = CANPacker(dbc_names[Bus.pt])
|
self.packer = CANPacker(dbc_names[Bus.pt])
|
||||||
self.params = CarControllerParams(CP)
|
self.params = CarControllerParams(CP)
|
||||||
|
self.jeep_brake_hold_decel = JEEP_BRAKE_HOLD_DEFAULT_DECEL
|
||||||
|
self.last_das_3_counter = -1
|
||||||
|
|
||||||
def update(self, CC, CS, now_nanos, starpilot_toggles):
|
def update(self, CC, CS, now_nanos, starpilot_toggles):
|
||||||
can_sends = []
|
can_sends = []
|
||||||
@@ -82,6 +103,11 @@ class CarController(CarControllerBase):
|
|||||||
|
|
||||||
can_sends.append(chryslercan.create_lkas_command(self.packer, self.CP, int(apply_torque), lkas_control_bit))
|
can_sends.append(chryslercan.create_lkas_command(self.packer, self.CP, int(apply_torque), lkas_control_bit))
|
||||||
|
|
||||||
|
if supports_jeep_brake_hold(self.CP, getattr(starpilot_toggles, "jeep_brake_hold", False)):
|
||||||
|
self.update_jeep_brake_hold(CC, CS, can_sends)
|
||||||
|
elif getattr(CS, "brake_hold", False):
|
||||||
|
CS.brake_hold = False
|
||||||
|
|
||||||
self.frame += 1
|
self.frame += 1
|
||||||
|
|
||||||
new_actuators = CC.actuators.as_builder()
|
new_actuators = CC.actuators.as_builder()
|
||||||
@@ -89,3 +115,43 @@ class CarController(CarControllerBase):
|
|||||||
new_actuators.torqueOutputCan = self.apply_torque_last
|
new_actuators.torqueOutputCan = self.apply_torque_last
|
||||||
|
|
||||||
return new_actuators, can_sends
|
return new_actuators, can_sends
|
||||||
|
|
||||||
|
def update_jeep_brake_hold(self, CC, CS, can_sends):
|
||||||
|
if not getattr(CS, "das_3", None):
|
||||||
|
CS.brake_hold = False
|
||||||
|
return
|
||||||
|
|
||||||
|
counter_changed = CS.das_3.get("COUNTER") != self.last_das_3_counter
|
||||||
|
self.last_das_3_counter = CS.das_3.get("COUNTER")
|
||||||
|
|
||||||
|
if not CS.brake_hold and CS.cruise_active_actual and CS.acc_decelerating and CS.out.standstill:
|
||||||
|
CS.brake_hold = True
|
||||||
|
self.jeep_brake_hold_decel = JEEP_BRAKE_HOLD_DEFAULT_DECEL
|
||||||
|
|
||||||
|
driver_intervened = (
|
||||||
|
CC.cruiseControl.cancel or
|
||||||
|
CS.out.gasPressed or
|
||||||
|
CS.out.brakePressed or
|
||||||
|
not CS.forward_gear or
|
||||||
|
not CS.out.standstill
|
||||||
|
)
|
||||||
|
if CS.brake_hold and driver_intervened:
|
||||||
|
CS.brake_hold = False
|
||||||
|
return
|
||||||
|
|
||||||
|
if not CS.brake_hold:
|
||||||
|
return
|
||||||
|
|
||||||
|
if CS.cruise_active_actual:
|
||||||
|
self.jeep_brake_hold_decel = clip_jeep_brake_hold_decel(
|
||||||
|
min(self.jeep_brake_hold_decel, CS.das_3.get("ACC_DECEL", JEEP_BRAKE_HOLD_DEFAULT_DECEL))
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
counter_offset = 2 if counter_changed else 3
|
||||||
|
can_sends.append(chryslercan.create_das_3_command(self.packer, counter_offset, self.jeep_brake_hold_decel, CS.das_3))
|
||||||
|
|
||||||
|
if self.frame % 10 == 0:
|
||||||
|
can_sends.append(chryslercan.create_cruise_buttons(
|
||||||
|
self.packer, CS.button_counter + 1, 0, CS.button_message, resume=True
|
||||||
|
))
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from cereal import custom
|
from cereal import custom
|
||||||
from opendbc.can import CANDefine, CANParser
|
from opendbc.can import CANDefine, CANParser
|
||||||
from opendbc.car import Bus, create_button_events, structs
|
from opendbc.car import Bus, create_button_events, structs
|
||||||
from opendbc.car.chrysler.values import DBC, STEER_THRESHOLD, RAM_CARS, ChryslerStarPilotFlags
|
from opendbc.car.chrysler.values import DBC, JEEPS, STEER_THRESHOLD, RAM_CARS, ChryslerStarPilotFlags
|
||||||
from opendbc.car.common.conversions import Conversions as CV
|
from opendbc.car.common.conversions import Conversions as CV
|
||||||
from opendbc.car.interfaces import CarStateBase
|
from opendbc.car.interfaces import CarStateBase
|
||||||
|
|
||||||
@@ -29,6 +29,11 @@ class CarState(CarStateBase):
|
|||||||
self.button_message = "CRUISE_BUTTONS_ALT" if FPCP.flags & ChryslerStarPilotFlags.RAM_HD_ALT_BUTTONS else "CRUISE_BUTTONS"
|
self.button_message = "CRUISE_BUTTONS_ALT" if FPCP.flags & ChryslerStarPilotFlags.RAM_HD_ALT_BUTTONS else "CRUISE_BUTTONS"
|
||||||
|
|
||||||
self.lkas_button = 0
|
self.lkas_button = 0
|
||||||
|
self.brake_hold = False
|
||||||
|
self.cruise_active_actual = False
|
||||||
|
self.forward_gear = False
|
||||||
|
self.acc_decelerating = False
|
||||||
|
self.das_3 = {}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_lkas_button(pt_signals, is_ram: bool) -> bool:
|
def get_lkas_button(pt_signals, is_ram: bool) -> bool:
|
||||||
@@ -93,6 +98,13 @@ class CarState(CarStateBase):
|
|||||||
ret.cruiseState.standstill = cp_cruise.vl["DAS_3"]["ACC_STANDSTILL"] == 1
|
ret.cruiseState.standstill = cp_cruise.vl["DAS_3"]["ACC_STANDSTILL"] == 1
|
||||||
ret.accFaulted = cp_cruise.vl["DAS_3"]["ACC_FAULTED"] != 0
|
ret.accFaulted = cp_cruise.vl["DAS_3"]["ACC_FAULTED"] != 0
|
||||||
|
|
||||||
|
if self.CP.carFingerprint in JEEPS:
|
||||||
|
self.forward_gear = ret.gearShifter == structs.CarState.GearShifter.drive
|
||||||
|
self.cruise_active_actual = ret.cruiseState.enabled
|
||||||
|
self.acc_decelerating = cp_cruise.vl["DAS_3"]["ACC_DECEL"] < -0.5
|
||||||
|
self.das_3 = dict(cp_cruise.vl["DAS_3"])
|
||||||
|
ret.brakeHoldActive = self.brake_hold
|
||||||
|
|
||||||
if self.CP.carFingerprint in RAM_CARS:
|
if self.CP.carFingerprint in RAM_CARS:
|
||||||
# Auto High Beam isn't Located in this message on chrysler or jeep currently located in 729 message
|
# Auto High Beam isn't Located in this message on chrysler or jeep currently located in 729 message
|
||||||
self.auto_high_beam = cp_cam.vl["DAS_6"]['AUTO_HIGH_BEAM_ON']
|
self.auto_high_beam = cp_cam.vl["DAS_6"]['AUTO_HIGH_BEAM_ON']
|
||||||
|
|||||||
@@ -73,6 +73,21 @@ def create_cruise_buttons(packer, frame, bus, button_message, cancel=False, resu
|
|||||||
return packer.make_can_msg(button_message, bus, values)
|
return packer.make_can_msg(button_message, bus, values)
|
||||||
|
|
||||||
|
|
||||||
|
def create_das_3_command(packer, counter_offset, brake_decel, das_3):
|
||||||
|
values = das_3.copy()
|
||||||
|
values["ACC_AVAILABLE"] = 1
|
||||||
|
values["ACC_ACTIVE"] = 1
|
||||||
|
values["ACC_GO"] = 0
|
||||||
|
values["ACC_STANDSTILL"] = 0
|
||||||
|
values["ACC_DECEL_REQ"] = 1
|
||||||
|
values["ACC_DECEL"] = brake_decel
|
||||||
|
values["ACC_BRK_PREP"] = 0
|
||||||
|
values["ENGINE_TORQUE_REQUEST_MAX"] = 0
|
||||||
|
values["GR_MAX_REQ"] = 2
|
||||||
|
values["COUNTER"] = (das_3["COUNTER"] + counter_offset) % 0x10
|
||||||
|
return packer.make_can_msg("DAS_3", 0, values)
|
||||||
|
|
||||||
|
|
||||||
def chrysler_checksum(address: int, sig, d: bytearray) -> int:
|
def chrysler_checksum(address: int, sig, d: bytearray) -> int:
|
||||||
checksum = 0xFF
|
checksum = 0xFF
|
||||||
for j in range(len(d) - 1):
|
for j in range(len(d) - 1):
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from opendbc.car import get_safety_config, structs
|
|||||||
from opendbc.car.chrysler.carcontroller import CarController
|
from opendbc.car.chrysler.carcontroller import CarController
|
||||||
from opendbc.car.chrysler.carstate import CarState
|
from opendbc.car.chrysler.carstate import CarState
|
||||||
from opendbc.car.chrysler.radar_interface import RadarInterface
|
from opendbc.car.chrysler.radar_interface import RadarInterface
|
||||||
from opendbc.car.chrysler.values import CAR, RAM_HD, RAM_DT, RAM_CARS, ChryslerFlags, ChryslerSafetyFlags
|
from opendbc.car.chrysler.values import CAR, JEEPS, RAM_HD, RAM_DT, RAM_CARS, ChryslerFlags, ChryslerSafetyFlags
|
||||||
from opendbc.car.interfaces import CarInterfaceBase
|
from opendbc.car.interfaces import CarInterfaceBase
|
||||||
|
|
||||||
|
|
||||||
@@ -28,6 +28,8 @@ class CarInterface(CarInterfaceBase):
|
|||||||
ret.safetyConfigs[0].safetyParam |= ChryslerSafetyFlags.RAM_HD.value
|
ret.safetyConfigs[0].safetyParam |= ChryslerSafetyFlags.RAM_HD.value
|
||||||
elif candidate in RAM_DT:
|
elif candidate in RAM_DT:
|
||||||
ret.safetyConfigs[0].safetyParam |= ChryslerSafetyFlags.RAM_DT.value
|
ret.safetyConfigs[0].safetyParam |= ChryslerSafetyFlags.RAM_DT.value
|
||||||
|
elif candidate in JEEPS:
|
||||||
|
ret.safetyConfigs[0].safetyParam |= ChryslerSafetyFlags.JEEP_BRAKE_HOLD.value
|
||||||
|
|
||||||
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
|
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
|
||||||
if candidate not in RAM_CARS:
|
if candidate not in RAM_CARS:
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ Ecu = CarParams.Ecu
|
|||||||
class ChryslerSafetyFlags(IntFlag):
|
class ChryslerSafetyFlags(IntFlag):
|
||||||
RAM_DT = 1
|
RAM_DT = 1
|
||||||
RAM_HD = 2
|
RAM_HD = 2
|
||||||
|
JEEP_BRAKE_HOLD = 4
|
||||||
|
|
||||||
|
|
||||||
class ChryslerFlags(IntFlag):
|
class ChryslerFlags(IntFlag):
|
||||||
@@ -140,6 +141,7 @@ STEER_THRESHOLD = 120
|
|||||||
RAM_DT = {CAR.RAM_1500_5TH_GEN, }
|
RAM_DT = {CAR.RAM_1500_5TH_GEN, }
|
||||||
RAM_HD = {CAR.RAM_HD_5TH_GEN, }
|
RAM_HD = {CAR.RAM_HD_5TH_GEN, }
|
||||||
RAM_CARS = RAM_DT | RAM_HD
|
RAM_CARS = RAM_DT | RAM_HD
|
||||||
|
JEEPS = {CAR.JEEP_GRAND_CHEROKEE, CAR.JEEP_GRAND_CHEROKEE_2019}
|
||||||
|
|
||||||
|
|
||||||
CHRYSLER_VERSION_REQUEST = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER]) + \
|
CHRYSLER_VERSION_REQUEST = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER]) + \
|
||||||
|
|||||||
@@ -23,9 +23,11 @@ def ecu_log(msg):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def disable_ecu(can_recv, can_send, bus=0, addr=0x7d0, sub_addr=None, com_cont_req=b'\x28\x83\x01', timeout=0.1, retry=10, reset=False):
|
def disable_ecu(can_recv, can_send, bus=0, addr=0x7d0, sub_addr=None, com_cont_req=b'\x28\x83\x01', timeout=0.1, retry=10, reset=False,
|
||||||
|
require_response=False, diag_request=EXT_DIAG_REQUEST, diag_response=EXT_DIAG_RESPONSE, response_offset=0x8):
|
||||||
"""Silence an ECU by disabling sending and receiving messages using UDS 0x28.
|
"""Silence an ECU by disabling sending and receiving messages using UDS 0x28.
|
||||||
The ECU will stay silent as long as openpilot keeps sending Tester Present.
|
The ECU will stay silent as long as openpilot keeps sending Tester Present.
|
||||||
|
Set require_response for takeovers that must fail closed unless the ECU confirms communication control.
|
||||||
|
|
||||||
This is used to disable the radar in some cars. Openpilot will emulate the radar.
|
This is used to disable the radar in some cars. Openpilot will emulate the radar.
|
||||||
WARNING: THIS DISABLES AEB!"""
|
WARNING: THIS DISABLES AEB!"""
|
||||||
@@ -34,7 +36,8 @@ def disable_ecu(can_recv, can_send, bus=0, addr=0x7d0, sub_addr=None, com_cont_r
|
|||||||
if reset:
|
if reset:
|
||||||
try:
|
try:
|
||||||
ecu_log("sending ECU reset before communication control...")
|
ecu_log("sending ECU reset before communication control...")
|
||||||
reset_query = IsoTpParallelQuery(can_send, can_recv, bus, [(addr, sub_addr)], [RESET_REQUEST], [RESET_RESPONSE])
|
reset_query = IsoTpParallelQuery(can_send, can_recv, bus, [(addr, sub_addr)], [RESET_REQUEST], [RESET_RESPONSE],
|
||||||
|
response_offset=response_offset)
|
||||||
reset_query.get_data(timeout=timeout)
|
reset_query.get_data(timeout=timeout)
|
||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -45,7 +48,8 @@ def disable_ecu(can_recv, can_send, bus=0, addr=0x7d0, sub_addr=None, com_cont_r
|
|||||||
try:
|
try:
|
||||||
# Enter extended diagnostic session
|
# Enter extended diagnostic session
|
||||||
ecu_log(f"attempt {i+1}/{retry}: diag session...")
|
ecu_log(f"attempt {i+1}/{retry}: diag session...")
|
||||||
query = IsoTpParallelQuery(can_send, can_recv, bus, [(addr, sub_addr)], [EXT_DIAG_REQUEST], [EXT_DIAG_RESPONSE])
|
query = IsoTpParallelQuery(can_send, can_recv, bus, [(addr, sub_addr)], [diag_request], [diag_response],
|
||||||
|
response_offset=response_offset)
|
||||||
|
|
||||||
for _, _ in query.get_data(timeout).items():
|
for _, _ in query.get_data(timeout).items():
|
||||||
ecu_log("diag session OK")
|
ecu_log("diag session OK")
|
||||||
@@ -55,14 +59,15 @@ def disable_ecu(can_recv, can_send, bus=0, addr=0x7d0, sub_addr=None, com_cont_r
|
|||||||
|
|
||||||
# Send CC command and log the response
|
# Send CC command and log the response
|
||||||
ecu_log("sending CC...")
|
ecu_log("sending CC...")
|
||||||
cc_query = IsoTpParallelQuery(can_send, can_recv, bus, [(addr, sub_addr)], [com_cont_req], [b''])
|
cc_query = IsoTpParallelQuery(can_send, can_recv, bus, [(addr, sub_addr)], [com_cont_req], [b''],
|
||||||
|
response_offset=response_offset)
|
||||||
cc_response = cc_query.get_data(timeout)
|
cc_response = cc_query.get_data(timeout)
|
||||||
|
|
||||||
# Log what we got back
|
# Log what we got back
|
||||||
cc_success = False
|
cc_success = False
|
||||||
cc_rejected = False
|
cc_rejected = False
|
||||||
cc_nrc = None
|
cc_nrc = None
|
||||||
for (rx_addr, _), data in cc_response.items():
|
for (_rx_addr, _), data in cc_response.items():
|
||||||
ecu_log(f"CC response: {data.hex() if data else 'empty'}")
|
ecu_log(f"CC response: {data.hex() if data else 'empty'}")
|
||||||
# Check for positive response (0x68 = 0x28 + 0x40)
|
# Check for positive response (0x68 = 0x28 + 0x40)
|
||||||
if len(data) >= 1 and data[0] == 0x68:
|
if len(data) >= 1 and data[0] == 0x68:
|
||||||
@@ -93,6 +98,9 @@ def disable_ecu(can_recv, can_send, bus=0, addr=0x7d0, sub_addr=None, com_cont_r
|
|||||||
# ECU explicitly rejected - don't retry, it won't work
|
# ECU explicitly rejected - don't retry, it won't work
|
||||||
ecu_log("=== ECU DISABLE REJECTED ===")
|
ecu_log("=== ECU DISABLE REJECTED ===")
|
||||||
return False
|
return False
|
||||||
|
elif require_response:
|
||||||
|
ecu_log("CC response required but none received; retrying...")
|
||||||
|
continue
|
||||||
else:
|
else:
|
||||||
# No response - consider it sent (ECU might have stopped responding)
|
# No response - consider it sent (ECU might have stopped responding)
|
||||||
ecu_log("=== ECU DISABLE SENT (no response) ===")
|
ecu_log("=== ECU DISABLE SENT (no response) ===")
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ class CarHarness(EnumBase):
|
|||||||
ford_q3 = BaseCarHarness("Ford Q3 connector")
|
ford_q3 = BaseCarHarness("Ford Q3 connector")
|
||||||
ford_q4 = BaseCarHarness("Ford Q4 connector", parts=[Accessory.harness_box, Accessory.comma_power, Cable.long_obdc_cable, Cable.usbc_coupler])
|
ford_q4 = BaseCarHarness("Ford Q4 connector", parts=[Accessory.harness_box, Accessory.comma_power, Cable.long_obdc_cable, Cable.usbc_coupler])
|
||||||
rivian = BaseCarHarness("Rivian A connector", parts=[Accessory.harness_box, Accessory.comma_power, Cable.long_obdc_cable, Cable.usbc_coupler])
|
rivian = BaseCarHarness("Rivian A connector", parts=[Accessory.harness_box, Accessory.comma_power, Cable.long_obdc_cable, Cable.usbc_coupler])
|
||||||
|
rivian_b = BaseCarHarness("Rivian B connector", parts=[Accessory.harness_box, Accessory.comma_power, Cable.long_obdc_cable, Cable.usbc_coupler])
|
||||||
tesla_a = BaseCarHarness("Tesla A connector", parts=[Accessory.harness_box, Cable.long_obdc_cable, Cable.usbc_coupler])
|
tesla_a = BaseCarHarness("Tesla A connector", parts=[Accessory.harness_box, Cable.long_obdc_cable, Cable.usbc_coupler])
|
||||||
tesla_b = BaseCarHarness("Tesla B connector", parts=[Accessory.harness_box, Cable.long_obdc_cable, Cable.usbc_coupler])
|
tesla_b = BaseCarHarness("Tesla B connector", parts=[Accessory.harness_box, Cable.long_obdc_cable, Cable.usbc_coupler])
|
||||||
psa_a = BaseCarHarness("PSA A connector", parts=[Accessory.harness_box, Cable.long_obdc_cable, Cable.usbc_coupler])
|
psa_a = BaseCarHarness("PSA A connector", parts=[Accessory.harness_box, Cable.long_obdc_cable, Cable.usbc_coupler])
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class CAR(Platforms):
|
|||||||
|
|
||||||
EXTRA_HYUNDAI = ExtraPlatformConfig(
|
EXTRA_HYUNDAI = ExtraPlatformConfig(
|
||||||
[
|
[
|
||||||
CommunityCarDocs("Hyundai Palisade 2023-24", package="HDA2"),
|
CommunityCarDocs("Hyundai Palisade 2023-25", package="HDA2"),
|
||||||
CommunityCarDocs("Kia Telluride 2023-24", package="HDA2"),
|
CommunityCarDocs("Kia Telluride 2023-24", package="HDA2"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -245,7 +245,6 @@ MIGRATION = {
|
|||||||
"KIA SELTOS 2021": HYUNDAI.KIA_SELTOS,
|
"KIA SELTOS 2021": HYUNDAI.KIA_SELTOS,
|
||||||
"KIA SPORTAGE 5TH GEN": HYUNDAI.KIA_SPORTAGE_5TH_GEN,
|
"KIA SPORTAGE 5TH GEN": HYUNDAI.KIA_SPORTAGE_5TH_GEN,
|
||||||
"KIA SPORTAGE 2026": HYUNDAI.KIA_SPORTAGE_2026,
|
"KIA SPORTAGE 2026": HYUNDAI.KIA_SPORTAGE_2026,
|
||||||
"KIA SPORTAGE HYBRID 2026": HYUNDAI.KIA_SPORTAGE_HEV_2026,
|
|
||||||
"KIA SORENTO GT LINE 2018": HYUNDAI.KIA_SORENTO,
|
"KIA SORENTO GT LINE 2018": HYUNDAI.KIA_SORENTO,
|
||||||
"KIA SORENTO 4TH GEN": HYUNDAI.KIA_SORENTO_4TH_GEN,
|
"KIA SORENTO 4TH GEN": HYUNDAI.KIA_SORENTO_4TH_GEN,
|
||||||
"KIA SORENTO 2024": HYUNDAI.KIA_SORENTO_2024,
|
"KIA SORENTO 2024": HYUNDAI.KIA_SORENTO_2024,
|
||||||
@@ -258,11 +257,14 @@ MIGRATION = {
|
|||||||
"KIA EV6 2025": HYUNDAI.KIA_EV6_2025,
|
"KIA EV6 2025": HYUNDAI.KIA_EV6_2025,
|
||||||
"KIA EV9 2025": HYUNDAI.KIA_EV9,
|
"KIA EV9 2025": HYUNDAI.KIA_EV9,
|
||||||
"KIA CARNIVAL 4TH GEN": HYUNDAI.KIA_CARNIVAL_4TH_GEN,
|
"KIA CARNIVAL 4TH GEN": HYUNDAI.KIA_CARNIVAL_4TH_GEN,
|
||||||
|
"KIA CARNIVAL 2025": HYUNDAI.KIA_CARNIVAL_2025,
|
||||||
|
"KIA CARNIVAL HYBRID 4TH GEN": HYUNDAI.KIA_CARNIVAL_HEV_4TH_GEN,
|
||||||
"GENESIS GV60 ELECTRIC 1ST GEN": HYUNDAI.GENESIS_GV60_EV_1ST_GEN,
|
"GENESIS GV60 ELECTRIC 1ST GEN": HYUNDAI.GENESIS_GV60_EV_1ST_GEN,
|
||||||
"GENESIS G70 2018": HYUNDAI.GENESIS_G70,
|
"GENESIS G70 2018": HYUNDAI.GENESIS_G70,
|
||||||
"GENESIS G70 2020": HYUNDAI.GENESIS_G70_2020,
|
"GENESIS G70 2020": HYUNDAI.GENESIS_G70_2020,
|
||||||
"GENESIS GV70 1ST GEN": HYUNDAI.GENESIS_GV70_1ST_GEN,
|
"GENESIS GV70 1ST GEN": HYUNDAI.GENESIS_GV70_1ST_GEN,
|
||||||
"GENESIS GV70 ELECTRIFIED 2026": HYUNDAI.GENESIS_GV70_ELECTRIFIED_2ND_GEN,
|
"GENESIS GV70 ELECTRIFIED 2026": HYUNDAI.GENESIS_GV70_ELECTRIFIED_2ND_GEN,
|
||||||
|
"GENESIS GV70 2026": HYUNDAI.GENESIS_GV70_2026,
|
||||||
"GENESIS G80 2017": HYUNDAI.GENESIS_G80,
|
"GENESIS G80 2017": HYUNDAI.GENESIS_G80,
|
||||||
"GENESIS G90 2017": HYUNDAI.GENESIS_G90,
|
"GENESIS G90 2017": HYUNDAI.GENESIS_G90,
|
||||||
"GENESIS GV80 2023": HYUNDAI.GENESIS_GV80,
|
"GENESIS GV80 2023": HYUNDAI.GENESIS_GV80,
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ from opendbc.car.lateral import ISO_LATERAL_ACCEL, apply_std_steer_angle_limits
|
|||||||
from opendbc.car.ford import fordcan
|
from opendbc.car.ford import fordcan
|
||||||
from opendbc.car.ford.values import CarControllerParams, FordFlags, CAR
|
from opendbc.car.ford.values import CarControllerParams, FordFlags, CAR
|
||||||
from opendbc.car.interfaces import CarControllerBase, V_CRUISE_MAX
|
from opendbc.car.interfaces import CarControllerBase, V_CRUISE_MAX
|
||||||
|
from openpilot.starpilot.car.ford import fordcan as starpilot_fordcan
|
||||||
|
from openpilot.starpilot.car.ford.lateral import FordLateralController, FordLateralMode, FordLateralResult
|
||||||
|
|
||||||
LongCtrlState = structs.CarControl.Actuators.LongControlState
|
LongCtrlState = structs.CarControl.Actuators.LongControlState
|
||||||
VisualAlert = structs.CarControl.HUDControl.VisualAlert
|
VisualAlert = structs.CarControl.HUDControl.VisualAlert
|
||||||
@@ -16,6 +18,11 @@ AVERAGE_ROAD_ROLL = 0.06 # ~3.4 degrees, 6% superelevation. higher actual roll
|
|||||||
MAX_LATERAL_ACCEL = ISO_LATERAL_ACCEL - (ACCELERATION_DUE_TO_GRAVITY * AVERAGE_ROAD_ROLL) # ~2.4 m/s^2
|
MAX_LATERAL_ACCEL = ISO_LATERAL_ACCEL - (ACCELERATION_DUE_TO_GRAVITY * AVERAGE_ROAD_ROLL) # ~2.4 m/s^2
|
||||||
|
|
||||||
|
|
||||||
|
def apply_ford_angle(desired_angle_deg: float, current_angle_deg: float) -> float:
|
||||||
|
relative_angle = desired_angle_deg - current_angle_deg
|
||||||
|
return float(np.clip(relative_angle, -5.8, 5.8))
|
||||||
|
|
||||||
|
|
||||||
def anti_overshoot(apply_curvature, apply_curvature_last, v_ego):
|
def anti_overshoot(apply_curvature, apply_curvature_last, v_ego):
|
||||||
diff = 0.1
|
diff = 0.1
|
||||||
tau = 5 # 5s smooths over the overshoot
|
tau = 5 # 5s smooths over the overshoot
|
||||||
@@ -65,6 +72,7 @@ class CarController(CarControllerBase):
|
|||||||
self.CAN = fordcan.CanBus(CP)
|
self.CAN = fordcan.CanBus(CP)
|
||||||
|
|
||||||
self.apply_curvature_last = 0
|
self.apply_curvature_last = 0
|
||||||
|
self.apply_angle_last = 0
|
||||||
self.anti_overshoot_curvature_last = 0
|
self.anti_overshoot_curvature_last = 0
|
||||||
self.accel = 0.0
|
self.accel = 0.0
|
||||||
self.gas = 0.0
|
self.gas = 0.0
|
||||||
@@ -74,6 +82,9 @@ class CarController(CarControllerBase):
|
|||||||
self.steer_alert_last = False
|
self.steer_alert_last = False
|
||||||
self.lead_distance_bars_last = None
|
self.lead_distance_bars_last = None
|
||||||
self.distance_bar_frame = 0
|
self.distance_bar_frame = 0
|
||||||
|
self.ford_lateral = None if CP.flags & FordFlags.LKA_STEERING else FordLateralController(CP)
|
||||||
|
self.ford_shadow_curvature = 0.0
|
||||||
|
self.ford_lateral_announced_mode = FordLateralMode.native
|
||||||
|
|
||||||
def update(self, CC, CS, now_nanos, starpilot_toggles):
|
def update(self, CC, CS, now_nanos, starpilot_toggles):
|
||||||
can_sends = []
|
can_sends = []
|
||||||
@@ -85,6 +96,9 @@ class CarController(CarControllerBase):
|
|||||||
steer_alert = hud_control.visualAlert in (VisualAlert.steerRequired, VisualAlert.ldw)
|
steer_alert = hud_control.visualAlert in (VisualAlert.steerRequired, VisualAlert.ldw)
|
||||||
fcw_alert = hud_control.visualAlert == VisualAlert.fcw
|
fcw_alert = hud_control.visualAlert == VisualAlert.fcw
|
||||||
|
|
||||||
|
if self.ford_lateral is not None:
|
||||||
|
self.ford_lateral.update_inputs()
|
||||||
|
|
||||||
### acc buttons ###
|
### acc buttons ###
|
||||||
if CC.cruiseControl.cancel:
|
if CC.cruiseControl.cancel:
|
||||||
can_sends.append(fordcan.create_button_msg(self.packer, self.CAN.camera, CS.buttons_stock_values, cancel=True))
|
can_sends.append(fordcan.create_button_msg(self.packer, self.CAN.camera, CS.buttons_stock_values, cancel=True))
|
||||||
@@ -98,38 +112,94 @@ class CarController(CarControllerBase):
|
|||||||
can_sends.append(fordcan.create_button_msg(self.packer, self.CAN.camera, CS.buttons_stock_values, tja_toggle=True))
|
can_sends.append(fordcan.create_button_msg(self.packer, self.CAN.camera, CS.buttons_stock_values, tja_toggle=True))
|
||||||
|
|
||||||
### lateral control ###
|
### lateral control ###
|
||||||
# send steer msg at 20Hz
|
if self.CP.flags & FordFlags.LKA_STEERING:
|
||||||
if (self.frame % CarControllerParams.STEER_STEP) == 0:
|
lka_active = CC.latActive and CS.lkas_available
|
||||||
# Bronco and some other cars consistently overshoot curv requests
|
if lka_active:
|
||||||
# Apply some deadzone + smoothing convergence to avoid oscillations
|
self.apply_angle_last = apply_ford_angle(actuators.steeringAngleDeg, CS.out.steeringAngleDeg)
|
||||||
if self.CP.carFingerprint in (CAR.FORD_BRONCO_SPORT_MK1, CAR.FORD_F_150_MK14):
|
current_curvature = -CS.out.yawRate / max(CS.out.vEgoRaw, 0.1)
|
||||||
self.anti_overshoot_curvature_last = anti_overshoot(actuators.curvature, self.anti_overshoot_curvature_last, CS.out.vEgoRaw)
|
self.apply_curvature_last = apply_ford_curvature_limits(actuators.curvature, self.apply_curvature_last, current_curvature,
|
||||||
apply_curvature = self.anti_overshoot_curvature_last
|
CS.out.vEgoRaw, 0., True, self.CP)
|
||||||
else:
|
else:
|
||||||
apply_curvature = actuators.curvature
|
self.apply_angle_last = 0.
|
||||||
|
self.apply_curvature_last = 0.
|
||||||
|
|
||||||
# apply rate limits, curvature error limit, and clip to signal range
|
# Keep the stock LMC heartbeat present while steering through Lane_Assist_Data1.
|
||||||
current_curvature = -CS.out.yawRate / max(CS.out.vEgoRaw, 0.1)
|
if (self.frame % CarControllerParams.STEER_STEP) == 0:
|
||||||
|
can_sends.append(fordcan.create_lat_ctl_msg(self.packer, self.CAN, False, 0., 0., 0., 0.,
|
||||||
|
stock_lmc=CS.lateral_motion_control))
|
||||||
|
|
||||||
self.apply_curvature_last = apply_ford_curvature_limits(apply_curvature, self.apply_curvature_last, current_curvature,
|
if (self.frame % CarControllerParams.LKA_STEP) == 0:
|
||||||
CS.out.vEgoRaw, 0., CC.latActive, self.CP)
|
direction = 0
|
||||||
|
if lka_active:
|
||||||
|
direction = 2 if CS.out.steeringAngleDeg > 0 else 4
|
||||||
|
ramp_type = 1 if abs(self.apply_angle_last) >= 5 else 0
|
||||||
|
can_sends.append(fordcan.create_lka_msg(self.packer, self.CAN, active=lka_active, apply_angle=self.apply_angle_last,
|
||||||
|
direction=direction, ramp_type=ramp_type, curvature=-self.apply_curvature_last))
|
||||||
|
else:
|
||||||
|
lateral_mode = self.ford_lateral.mode
|
||||||
|
lateral_mode_ready = lateral_mode == self.ford_lateral_announced_mode
|
||||||
|
|
||||||
if self.CP.flags & FordFlags.CANFD:
|
# Keep the original Ford path available without changing its command behavior.
|
||||||
# TODO: extended mode
|
if lateral_mode == FordLateralMode.native:
|
||||||
# Ford uses four individual signals to dictate how to drive to the car. Curvature alone (limited to 0.02m/s^2)
|
if (self.frame % CarControllerParams.STEER_STEP) == 0:
|
||||||
# can actuate the steering for a large portion of any lateral movements. However, in order to get further control on
|
if not lateral_mode_ready:
|
||||||
# steer actuation, the other three signals are necessary. Ford controls vehicles differently than most other makes.
|
self.apply_curvature_last = 0.0
|
||||||
# A detailed explanation on ford control can be found here:
|
apply_curvature = 0.0
|
||||||
# https://www.f150gen14.com/forum/threads/introducing-bluepilot-a-ford-specific-fork-for-comma3x-openpilot.24241/#post-457706
|
elif self.CP.carFingerprint in (CAR.FORD_BRONCO_SPORT_MK1, CAR.FORD_F_150_MK14):
|
||||||
mode = 1 if CC.latActive else 0
|
self.anti_overshoot_curvature_last = anti_overshoot(
|
||||||
counter = (self.frame // CarControllerParams.STEER_STEP) % 0x10
|
actuators.curvature, self.anti_overshoot_curvature_last, CS.out.vEgoRaw)
|
||||||
can_sends.append(fordcan.create_lat_ctl2_msg(self.packer, self.CAN, mode, 0., 0., -self.apply_curvature_last, 0., counter))
|
apply_curvature = self.anti_overshoot_curvature_last
|
||||||
else:
|
else:
|
||||||
can_sends.append(fordcan.create_lat_ctl_msg(self.packer, self.CAN, CC.latActive, 0., 0., -self.apply_curvature_last, 0.))
|
apply_curvature = actuators.curvature
|
||||||
|
|
||||||
# send lka msg at 33Hz
|
current_curvature = -CS.out.yawRate / max(CS.out.vEgoRaw, 0.1)
|
||||||
if (self.frame % CarControllerParams.LKA_STEP) == 0:
|
self.apply_curvature_last = apply_ford_curvature_limits(
|
||||||
can_sends.append(fordcan.create_lka_msg(self.packer, self.CAN))
|
apply_curvature, self.apply_curvature_last, current_curvature,
|
||||||
|
CS.out.vEgoRaw, 0., CC.latActive and lateral_mode_ready, self.CP)
|
||||||
|
|
||||||
|
if self.CP.flags & FordFlags.CANFD:
|
||||||
|
mode = 1 if CC.latActive and lateral_mode_ready else 0
|
||||||
|
counter = (self.frame // CarControllerParams.STEER_STEP) % 0x10
|
||||||
|
can_sends.append(fordcan.create_lat_ctl2_msg(
|
||||||
|
self.packer, self.CAN, mode, 0., 0., -self.apply_curvature_last, 0., counter))
|
||||||
|
else:
|
||||||
|
can_sends.append(fordcan.create_lat_ctl_msg(
|
||||||
|
self.packer, self.CAN, CC.latActive and lateral_mode_ready, 0., 0., -self.apply_curvature_last, 0.))
|
||||||
|
elif (self.frame % CarControllerParams.STEER_STEP) == 0:
|
||||||
|
if not lateral_mode_ready:
|
||||||
|
lateral = FordLateralResult(shadow_curvature=self.ford_lateral._current_curvature(CS))
|
||||||
|
elif lateral_mode == FordLateralMode.angle:
|
||||||
|
lateral = self.ford_lateral.update_angle(CC, CS, actuators)
|
||||||
|
else:
|
||||||
|
lateral = self.ford_lateral.update_curvature(CC, CS, actuators)
|
||||||
|
|
||||||
|
self.apply_curvature_last = lateral.curvature
|
||||||
|
self.ford_shadow_curvature = lateral.shadow_curvature
|
||||||
|
if self.CP.flags & FordFlags.CANFD:
|
||||||
|
counter = (self.frame // CarControllerParams.STEER_STEP) % 0x10
|
||||||
|
can_sends.append(starpilot_fordcan.create_lat_ctl2_msg(
|
||||||
|
self.packer, self.CAN, 1 if lateral.active else 0,
|
||||||
|
lateral.ramp_type, lateral.precision_type,
|
||||||
|
-lateral.path_offset, -lateral.path_angle,
|
||||||
|
-lateral.curvature, -lateral.curvature_rate, counter))
|
||||||
|
else:
|
||||||
|
can_sends.append(starpilot_fordcan.create_lat_ctl_msg(
|
||||||
|
self.packer, self.CAN, lateral.active,
|
||||||
|
lateral.ramp_type, lateral.precision_type,
|
||||||
|
-lateral.path_offset, -lateral.path_angle,
|
||||||
|
-lateral.curvature, -lateral.curvature_rate))
|
||||||
|
|
||||||
|
if (self.frame % CarControllerParams.LKA_STEP) == 0:
|
||||||
|
if lateral_mode == FordLateralMode.native:
|
||||||
|
can_sends.append(fordcan.create_lka_msg(self.packer, self.CAN))
|
||||||
|
else:
|
||||||
|
angle_mode = lateral_mode == FordLateralMode.angle
|
||||||
|
shadow_curvature = -self.ford_lateral._current_curvature(CS)
|
||||||
|
if angle_mode:
|
||||||
|
shadow_curvature = -self.ford_shadow_curvature
|
||||||
|
can_sends.append(starpilot_fordcan.create_lka_msg(
|
||||||
|
self.packer, self.CAN, angle_mode=angle_mode, shadow_curvature=shadow_curvature))
|
||||||
|
self.ford_lateral_announced_mode = lateral_mode
|
||||||
|
|
||||||
### longitudinal control ###
|
### longitudinal control ###
|
||||||
# send acc msg at 50Hz
|
# send acc msg at 50Hz
|
||||||
@@ -185,9 +255,15 @@ class CarController(CarControllerBase):
|
|||||||
|
|
||||||
if (self.frame % CarControllerParams.ACC_UI_STEP) == 0 or send_ui:
|
if (self.frame % CarControllerParams.ACC_UI_STEP) == 0 or send_ui:
|
||||||
show_distance_bars = self.frame - self.distance_bar_frame < 400
|
show_distance_bars = self.frame - self.distance_bar_frame < 400
|
||||||
|
hands_free_cluster = bool(
|
||||||
|
self.ford_lateral is not None
|
||||||
|
and self.ford_lateral.mode != FordLateralMode.native
|
||||||
|
and self.ford_lateral.mode == self.ford_lateral_announced_mode
|
||||||
|
and self.ford_lateral.hands_free_cluster_enabled)
|
||||||
can_sends.append(fordcan.create_acc_ui_msg(self.packer, self.CAN, self.CP, main_on, CC.latActive,
|
can_sends.append(fordcan.create_acc_ui_msg(self.packer, self.CAN, self.CP, main_on, CC.latActive,
|
||||||
fcw_alert, CS.out.cruiseState.standstill, show_distance_bars,
|
fcw_alert, CS.out.cruiseState.standstill, show_distance_bars,
|
||||||
hud_control, CS.acc_tja_status_stock_values))
|
hud_control, CS.acc_tja_status_stock_values,
|
||||||
|
hands_free_cluster))
|
||||||
|
|
||||||
self.main_on_last = main_on
|
self.main_on_last = main_on
|
||||||
self.lkas_enabled_last = CC.latActive
|
self.lkas_enabled_last = CC.latActive
|
||||||
@@ -195,6 +271,8 @@ class CarController(CarControllerBase):
|
|||||||
self.lead_distance_bars_last = hud_control.leadDistanceBars
|
self.lead_distance_bars_last = hud_control.leadDistanceBars
|
||||||
|
|
||||||
new_actuators = actuators.as_builder()
|
new_actuators = actuators.as_builder()
|
||||||
|
if self.CP.flags & FordFlags.LKA_STEERING:
|
||||||
|
new_actuators.steeringAngleDeg = self.apply_angle_last + CS.out.steeringAngleDeg
|
||||||
new_actuators.curvature = self.apply_curvature_last
|
new_actuators.curvature = self.apply_curvature_last
|
||||||
new_actuators.accel = self.accel
|
new_actuators.accel = self.accel
|
||||||
new_actuators.gas = self.gas
|
new_actuators.gas = self.gas
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from opendbc.car import Bus, create_button_events, structs
|
|||||||
from opendbc.car.common.conversions import Conversions as CV
|
from opendbc.car.common.conversions import Conversions as CV
|
||||||
from opendbc.car.ford.fordcan import CanBus
|
from opendbc.car.ford.fordcan import CanBus
|
||||||
from opendbc.car.ford.values import DBC, CarControllerParams, FordFlags
|
from opendbc.car.ford.values import DBC, CarControllerParams, FordFlags
|
||||||
|
from opendbc.car.gps import get_car_gps_config
|
||||||
from opendbc.car.interfaces import CarStateBase
|
from opendbc.car.interfaces import CarStateBase
|
||||||
|
|
||||||
ButtonType = structs.CarState.ButtonEvent.Type
|
ButtonType = structs.CarState.ButtonEvent.Type
|
||||||
@@ -16,24 +17,71 @@ class CarState(CarStateBase):
|
|||||||
super().__init__(CP, FPCP)
|
super().__init__(CP, FPCP)
|
||||||
can_define = CANDefine(DBC[CP.carFingerprint][Bus.pt])
|
can_define = CANDefine(DBC[CP.carFingerprint][Bus.pt])
|
||||||
if CP.transmissionType == TransmissionType.automatic:
|
if CP.transmissionType == TransmissionType.automatic:
|
||||||
self.shifter_values = can_define.dv["PowertrainData_10"]["TrnRng_D_Rq"]
|
if CP.flags & FordFlags.CANFD:
|
||||||
|
self.shifter_values = can_define.dv["Gear_Shift_by_Wire_FD1"]["TrnRng_D_RqGsm"]
|
||||||
|
elif CP.flags & FordFlags.ALT_STEER_ANGLE:
|
||||||
|
self.shifter_values = can_define.dv["TransGearData"]["GearLvrPos_D_Actl"]
|
||||||
|
else:
|
||||||
|
self.shifter_values = can_define.dv["PowertrainData_10"]["TrnRng_D_Rq"]
|
||||||
|
|
||||||
self.distance_button = 0
|
self.distance_button = 0
|
||||||
self.lc_button = 0
|
self.lc_button = 0
|
||||||
|
self.lkas_available = False
|
||||||
|
self.lateral_motion_control = None
|
||||||
|
self.lateral_control_status = None
|
||||||
|
self.steering_angle_offset_deg = 0.0
|
||||||
|
self.car_gps_config = get_car_gps_config(CP)
|
||||||
|
self.car_gps_supported = self.car_gps_config is not None
|
||||||
|
self.car_gps = None
|
||||||
|
self._car_gps_timestamp_nanos = 0
|
||||||
|
|
||||||
|
def _update_car_gps(self, cp) -> None:
|
||||||
|
if self.car_gps_config is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
timestamps = [max(cp.ts_nanos[name].values(), default=0) for name in self.car_gps_config.messages]
|
||||||
|
if not all(timestamps) or max(timestamps) - min(timestamps) > 2_000_000_000:
|
||||||
|
return
|
||||||
|
|
||||||
|
timestamp_nanos = max(timestamps)
|
||||||
|
if timestamp_nanos <= self._car_gps_timestamp_nanos:
|
||||||
|
return
|
||||||
|
|
||||||
|
gps = self.car_gps_config.decoder(*(cp.vl[name] for name in self.car_gps_config.messages))
|
||||||
|
if gps is not None:
|
||||||
|
gps["timestamp_nanos"] = timestamp_nanos
|
||||||
|
self.car_gps = gps
|
||||||
|
self._car_gps_timestamp_nanos = timestamp_nanos
|
||||||
|
|
||||||
|
def get_car_gps(self):
|
||||||
|
return self.car_gps
|
||||||
|
|
||||||
def update(self, can_parsers, starpilot_toggles) -> structs.CarState:
|
def update(self, can_parsers, starpilot_toggles) -> structs.CarState:
|
||||||
cp = can_parsers[Bus.pt]
|
cp = can_parsers[Bus.pt]
|
||||||
cp_cam = can_parsers[Bus.cam]
|
cp_cam = can_parsers[Bus.cam]
|
||||||
|
|
||||||
|
self._update_car_gps(cp)
|
||||||
|
|
||||||
ret = structs.CarState()
|
ret = structs.CarState()
|
||||||
|
|
||||||
# Occasionally on startup, the ABS module recalibrates the steering pinion offset, so we need to block engagement
|
if self.CP.flags & FordFlags.ALT_STEER_ANGLE:
|
||||||
# The vehicle usually recovers out of this state within a minute of normal driving
|
sensors_valid = (
|
||||||
ret.vehicleSensorsInvalid = cp.vl["SteeringPinion_Data"]["StePinCompAnEst_D_Qf"] != 3
|
int((cp.vl["ParkAid_Data"]["ExtSteeringAngleReq2"] + 1000) * 10) not in (32766, 32767)
|
||||||
|
and cp.vl["ParkAid_Data"]["EPASExtAngleStatReq"] == 0
|
||||||
|
and cp.vl["ParkAid_Data"]["ApaSys_D_Stat"] in (0, 1)
|
||||||
|
)
|
||||||
|
ret.vehicleSensorsInvalid = not sensors_valid
|
||||||
|
else:
|
||||||
|
# The ABS can recalibrate the steering pinion offset briefly after startup.
|
||||||
|
ret.vehicleSensorsInvalid = cp.vl["SteeringPinion_Data"]["StePinCompAnEst_D_Qf"] != 3
|
||||||
|
|
||||||
# car speed
|
# car speed
|
||||||
ret.vEgoRaw = cp.vl["BrakeSysFeatures"]["Veh_V_ActlBrk"] * CV.KPH_TO_MS
|
ret.vEgoRaw = cp.vl["BrakeSysFeatures"]["Veh_V_ActlBrk"] * CV.KPH_TO_MS
|
||||||
ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw)
|
ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw)
|
||||||
|
if self.CP.flags & FordFlags.CANFD:
|
||||||
|
ret.vEgoCluster = ((cp.vl["Cluster_Info_3_FD1"]["DISPLAY_SPEED_SCALING"] / 100) *
|
||||||
|
cp.vl["EngVehicleSpThrottle2"]["Veh_V_ActlEng"] +
|
||||||
|
cp.vl["Cluster_Info_3_FD1"]["DISPLAY_SPEED_OFFSET"]) * CV.KPH_TO_MS
|
||||||
ret.yawRate = cp.vl["Yaw_Data_FD1"]["VehYaw_W_Actl"]
|
ret.yawRate = cp.vl["Yaw_Data_FD1"]["VehYaw_W_Actl"]
|
||||||
ret.standstill = cp.vl["DesiredTorqBrk"]["VehStop_D_Stat"] == 1
|
ret.standstill = cp.vl["DesiredTorqBrk"]["VehStop_D_Stat"] == 1
|
||||||
|
|
||||||
@@ -46,7 +94,14 @@ class CarState(CarStateBase):
|
|||||||
ret.parkingBrake = cp.vl["DesiredTorqBrk"]["PrkBrkStatus"] in (1, 2)
|
ret.parkingBrake = cp.vl["DesiredTorqBrk"]["PrkBrkStatus"] in (1, 2)
|
||||||
|
|
||||||
# steering wheel
|
# steering wheel
|
||||||
ret.steeringAngleDeg = cp.vl["SteeringPinion_Data"]["StePinComp_An_Est"]
|
if self.CP.flags & FordFlags.ALT_STEER_ANGLE:
|
||||||
|
steering_angle_init = cp.vl["SteeringPinion_Data_Alt"]["StePinRelInit_An_Sns"]
|
||||||
|
if not ret.vehicleSensorsInvalid:
|
||||||
|
steering_angle_est = cp.vl["ParkAid_Data"]["ExtSteeringAngleReq2"]
|
||||||
|
self.steering_angle_offset_deg = steering_angle_est - steering_angle_init
|
||||||
|
ret.steeringAngleDeg = steering_angle_init + self.steering_angle_offset_deg
|
||||||
|
else:
|
||||||
|
ret.steeringAngleDeg = cp.vl["SteeringPinion_Data"]["StePinComp_An_Est"]
|
||||||
ret.steeringTorque = cp.vl["EPAS_INFO"]["SteeringColumnTorque"]
|
ret.steeringTorque = cp.vl["EPAS_INFO"]["SteeringColumnTorque"]
|
||||||
ret.steeringPressed = self.update_steering_pressed(abs(ret.steeringTorque) > CarControllerParams.STEER_DRIVER_ALLOWANCE, 5)
|
ret.steeringPressed = self.update_steering_pressed(abs(ret.steeringTorque) > CarControllerParams.STEER_DRIVER_ALLOWANCE, 5)
|
||||||
ret.steerFaultTemporary = cp.vl["EPAS_INFO"]["EPAS_Failure"] == 1
|
ret.steerFaultTemporary = cp.vl["EPAS_INFO"]["EPAS_Failure"] == 1
|
||||||
@@ -55,10 +110,12 @@ class CarState(CarStateBase):
|
|||||||
|
|
||||||
if self.CP.flags & FordFlags.CANFD:
|
if self.CP.flags & FordFlags.CANFD:
|
||||||
# this signal is always 0 on non-CAN FD cars
|
# this signal is always 0 on non-CAN FD cars
|
||||||
ret.steerFaultTemporary |= cp.vl["Lane_Assist_Data3_FD1"]["LatCtlSte_D_Stat"] not in (1, 2, 3)
|
self.lateral_control_status = int(cp.vl["Lane_Assist_Data3_FD1"]["LatCtlSte_D_Stat"])
|
||||||
|
ret.steerFaultTemporary |= self.lateral_control_status not in (1, 2, 3)
|
||||||
|
|
||||||
# cruise state
|
# cruise state
|
||||||
is_metric = cp.vl["INSTRUMENT_PANEL"]["METRIC_UNITS"] == 1 if not self.CP.flags & FordFlags.CANFD else False
|
is_metric = cp.vl["INSTRUMENT_PANEL"]["METRIC_UNITS"] == 1 if not self.CP.flags & FordFlags.CANFD else \
|
||||||
|
cp_cam.vl["IPMA_Data2"]["IsaVLimUnit_D_Rq"] == 1
|
||||||
ret.cruiseState.speed = cp.vl["EngBrakeData"]["Veh_V_DsplyCcSet"] * (CV.KPH_TO_MS if is_metric else CV.MPH_TO_MS)
|
ret.cruiseState.speed = cp.vl["EngBrakeData"]["Veh_V_DsplyCcSet"] * (CV.KPH_TO_MS if is_metric else CV.MPH_TO_MS)
|
||||||
ret.cruiseState.enabled = cp.vl["EngBrakeData"]["CcStat_D_Actl"] in (4, 5)
|
ret.cruiseState.enabled = cp.vl["EngBrakeData"]["CcStat_D_Actl"] in (4, 5)
|
||||||
ret.cruiseState.available = cp.vl["EngBrakeData"]["CcStat_D_Actl"] in (3, 4, 5)
|
ret.cruiseState.available = cp.vl["EngBrakeData"]["CcStat_D_Actl"] in (3, 4, 5)
|
||||||
@@ -70,7 +127,12 @@ class CarState(CarStateBase):
|
|||||||
|
|
||||||
# gear
|
# gear
|
||||||
if self.CP.transmissionType == TransmissionType.automatic:
|
if self.CP.transmissionType == TransmissionType.automatic:
|
||||||
gear = self.shifter_values.get(cp.vl["PowertrainData_10"]["TrnRng_D_Rq"])
|
if self.CP.flags & FordFlags.CANFD:
|
||||||
|
gear = self.shifter_values.get(cp.vl["Gear_Shift_by_Wire_FD1"]["TrnRng_D_RqGsm"])
|
||||||
|
elif self.CP.flags & FordFlags.ALT_STEER_ANGLE:
|
||||||
|
gear = self.shifter_values.get(cp.vl["TransGearData"]["GearLvrPos_D_Actl"])
|
||||||
|
else:
|
||||||
|
gear = self.shifter_values.get(cp.vl["PowertrainData_10"]["TrnRng_D_Rq"])
|
||||||
ret.gearShifter = self.parse_gear_shifter(gear)
|
ret.gearShifter = self.parse_gear_shifter(gear)
|
||||||
elif self.CP.transmissionType == TransmissionType.manual:
|
elif self.CP.transmissionType == TransmissionType.manual:
|
||||||
if bool(cp.vl["BCM_Lamp_Stat_FD1"]["RvrseLghtOn_B_Stat"]):
|
if bool(cp.vl["BCM_Lamp_Stat_FD1"]["RvrseLghtOn_B_Stat"]):
|
||||||
@@ -108,6 +170,15 @@ class CarState(CarStateBase):
|
|||||||
# Stock values from IPMA so that we can retain some stock functionality
|
# Stock values from IPMA so that we can retain some stock functionality
|
||||||
self.acc_tja_status_stock_values = cp_cam.vl["ACCDATA_3"]
|
self.acc_tja_status_stock_values = cp_cam.vl["ACCDATA_3"]
|
||||||
self.lkas_status_stock_values = cp_cam.vl["IPMA_Data"]
|
self.lkas_status_stock_values = cp_cam.vl["IPMA_Data"]
|
||||||
|
if self.CP.flags & FordFlags.LKA_STEERING:
|
||||||
|
try:
|
||||||
|
self.lkas_available = cp.vl["Lane_Assist_Data3_FD1"]["LaActAvail_D_Actl"] == 3
|
||||||
|
except KeyError:
|
||||||
|
self.lkas_available = False
|
||||||
|
try:
|
||||||
|
self.lateral_motion_control = cp_cam.vl["LateralMotionControl"]
|
||||||
|
except KeyError:
|
||||||
|
self.lateral_motion_control = None
|
||||||
|
|
||||||
ret.buttonEvents = [
|
ret.buttonEvents = [
|
||||||
*create_button_events(self.distance_button, prev_distance_button, {1: ButtonType.gapAdjustCruise}),
|
*create_button_events(self.distance_button, prev_distance_button, {1: ButtonType.gapAdjustCruise}),
|
||||||
@@ -115,12 +186,102 @@ class CarState(CarStateBase):
|
|||||||
]
|
]
|
||||||
|
|
||||||
fp_ret = custom.StarPilotCarState.new_message()
|
fp_ret = custom.StarPilotCarState.new_message()
|
||||||
|
fp_ret.brakeLights = ret.brakePressed
|
||||||
|
try:
|
||||||
|
fp_ret.brakeLights = bool(cp.vl["BCM_Lamp_Stat_FD1"]["StopLghtOn_B_Stat"])
|
||||||
|
except (KeyError, AttributeError):
|
||||||
|
try:
|
||||||
|
fp_ret.brakeLights = cp.vl["BrakeSysFeatures_2"]["BrkLamp_B_Rq"] == 1
|
||||||
|
except (KeyError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
speed_limit = cp_cam.vl["Traffic_RecognitnData"]["TsrVLim1MsgTxt_D_Rq"]
|
||||||
|
speed_limit_unit = cp_cam.vl["Traffic_RecognitnData"]["TsrVlUnitMsgTxt_D_Rq"]
|
||||||
|
speed_factor = CV.MPH_TO_MS if speed_limit_unit == 2 else CV.KPH_TO_MS if speed_limit_unit == 1 else 0.0
|
||||||
|
fp_ret.dashboardSpeedLimit = speed_limit * speed_factor if speed_limit not in (0, 255) else 0.0
|
||||||
|
except (KeyError, AttributeError):
|
||||||
|
fp_ret.dashboardSpeedLimit = 0.0
|
||||||
|
|
||||||
return ret, fp_ret
|
return ret, fp_ret
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_can_parsers(CP):
|
def get_can_parsers(CP):
|
||||||
|
gps_config = get_car_gps_config(CP)
|
||||||
|
gps_messages = [(name, 0) for name in gps_config.messages] if gps_config is not None else []
|
||||||
|
|
||||||
|
pt_messages = [
|
||||||
|
("BrakeSysFeatures", 50),
|
||||||
|
("Yaw_Data_FD1", 100),
|
||||||
|
("DesiredTorqBrk", 50),
|
||||||
|
("EngVehicleSpThrottle", 100),
|
||||||
|
("EngVehicleSpThrottle2", 50),
|
||||||
|
("BrakeSnData_4", 50),
|
||||||
|
("EngBrakeData", 10),
|
||||||
|
("EPAS_INFO", 50),
|
||||||
|
("Cluster_Info1_FD1", 10),
|
||||||
|
("Steering_Data_FD1", 10),
|
||||||
|
("BodyInfo_3_FD1", 2),
|
||||||
|
("RCMStatusMessage2_FD1", 10),
|
||||||
|
("BCM_Lamp_Stat_FD1", 0),
|
||||||
|
*gps_messages,
|
||||||
|
]
|
||||||
|
|
||||||
|
if CP.flags & FordFlags.ALT_STEER_ANGLE:
|
||||||
|
pt_messages += [
|
||||||
|
("SteeringPinion_Data_Alt", 100),
|
||||||
|
("ParkAid_Data", 50),
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
pt_messages += [("SteeringPinion_Data", 100)]
|
||||||
|
|
||||||
|
if CP.flags & FordFlags.CANFD:
|
||||||
|
pt_messages += [
|
||||||
|
("Lane_Assist_Data3_FD1", 33),
|
||||||
|
("Cluster_Info_3_FD1", 10),
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
pt_messages += [("INSTRUMENT_PANEL", 1)]
|
||||||
|
|
||||||
|
if CP.transmissionType == TransmissionType.automatic:
|
||||||
|
if CP.flags & FordFlags.CANFD:
|
||||||
|
pt_messages += [("Gear_Shift_by_Wire_FD1", 10)]
|
||||||
|
elif CP.flags & FordFlags.ALT_STEER_ANGLE:
|
||||||
|
pt_messages += [("TransGearData", 10)]
|
||||||
|
else:
|
||||||
|
pt_messages += [("PowertrainData_10", 10)]
|
||||||
|
|
||||||
|
if CP.enableBsm and not (CP.flags & FordFlags.CANFD):
|
||||||
|
pt_messages += [
|
||||||
|
("Side_Detect_L_Stat", 5),
|
||||||
|
("Side_Detect_R_Stat", 5),
|
||||||
|
]
|
||||||
|
|
||||||
|
cam_messages = [
|
||||||
|
("ACCDATA", 50),
|
||||||
|
("ACCDATA_2", 50),
|
||||||
|
("ACCDATA_3", 5),
|
||||||
|
("IPMA_Data", 1),
|
||||||
|
]
|
||||||
|
|
||||||
|
if CP.flags & FordFlags.CANFD:
|
||||||
|
cam_messages += [
|
||||||
|
("Traffic_RecognitnData", 1),
|
||||||
|
("IPMA_Data2", 1),
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
cam_messages += [("Traffic_RecognitnData", 0)]
|
||||||
|
|
||||||
|
if CP.enableBsm and CP.flags & FordFlags.CANFD:
|
||||||
|
cam_messages += [
|
||||||
|
("Side_Detect_L_Stat", 5),
|
||||||
|
("Side_Detect_R_Stat", 5),
|
||||||
|
]
|
||||||
|
|
||||||
|
if CP.flags & FordFlags.LKA_STEERING:
|
||||||
|
cam_messages += [("LateralMotionControl", 20)]
|
||||||
|
|
||||||
return {
|
return {
|
||||||
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], [], CanBus(CP).main),
|
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], pt_messages, CanBus(CP).main),
|
||||||
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], [], CanBus(CP).camera),
|
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], cam_messages, CanBus(CP).camera),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ FW_VERSIONS = {
|
|||||||
b'LX6C-14D003-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'LX6C-14D003-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
(Ecu.abs, 0x760, None): [
|
(Ecu.abs, 0x760, None): [
|
||||||
|
b'LX6C-2D053-KF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'LX6C-2D053-KG\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'LX6C-2D053-RD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'LX6C-2D053-RD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'LX6C-2D053-RE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'LX6C-2D053-RE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'LX6C-2D053-RF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'LX6C-2D053-RF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
@@ -24,6 +26,21 @@ FW_VERSIONS = {
|
|||||||
b'M1PT-14F397-AD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'M1PT-14F397-AD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
CAR.FORD_EDGE_MK2: {
|
||||||
|
(Ecu.eps, 0x730, None): [
|
||||||
|
b'M2GC-14D003-AA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
],
|
||||||
|
(Ecu.abs, 0x760, None): [
|
||||||
|
b'M2GC-2D053-CB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'M2GC-2D053-EA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
],
|
||||||
|
(Ecu.fwdRadar, 0x764, None): [
|
||||||
|
b'JX7T-14D049-AD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
],
|
||||||
|
(Ecu.fwdCamera, 0x706, None): [
|
||||||
|
b'KT4T-14F397-AF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
],
|
||||||
|
},
|
||||||
CAR.FORD_ESCAPE_MK4: {
|
CAR.FORD_ESCAPE_MK4: {
|
||||||
(Ecu.eps, 0x730, None): [
|
(Ecu.eps, 0x730, None): [
|
||||||
b'LX6C-14D003-AF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'LX6C-14D003-AF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
@@ -49,7 +66,9 @@ FW_VERSIONS = {
|
|||||||
},
|
},
|
||||||
CAR.FORD_ESCAPE_MK4_5: {
|
CAR.FORD_ESCAPE_MK4_5: {
|
||||||
(Ecu.eps, 0x730, None): [
|
(Ecu.eps, 0x730, None): [
|
||||||
|
b'PZ11-14D003-AB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'PZ11-14D003-EA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'PZ11-14D003-EA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'PZ11-14D003-FA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
(Ecu.abs, 0x760, None): [
|
(Ecu.abs, 0x760, None): [
|
||||||
b'PZ1C-2D053-EJ\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'PZ1C-2D053-EJ\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
@@ -58,11 +77,20 @@ FW_VERSIONS = {
|
|||||||
b'ML3T-14D049-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'ML3T-14D049-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
(Ecu.fwdCamera, 0x706, None): [
|
(Ecu.fwdCamera, 0x706, None): [
|
||||||
|
b'PJ6T-14H102-ABE\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'PJ6T-14H102-ABL\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'PJ6T-14H102-ABL\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'PJ6T-14H102-MDC\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'PJ6T-14H102-MDF\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'PJ6T-14H102-SCD\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'PJ6T-14H102-SCG\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
CAR.FORD_EXPLORER_MK6: {
|
CAR.FORD_EXPLORER_MK6: {
|
||||||
(Ecu.eps, 0x730, None): [
|
(Ecu.eps, 0x730, None): [
|
||||||
|
b'R1MC-14D003-AE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'R1MC-14D003-AF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'R1MC-14D003-AG\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'R1MC-14D003-AH\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'L1MC-14D003-AJ\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'L1MC-14D003-AJ\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'L1MC-14D003-AK\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'L1MC-14D003-AK\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'L1MC-14D003-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'L1MC-14D003-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
@@ -96,6 +124,7 @@ FW_VERSIONS = {
|
|||||||
],
|
],
|
||||||
(Ecu.abs, 0x760, None): [
|
(Ecu.abs, 0x760, None): [
|
||||||
b'RL14-2D053-AA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'RL14-2D053-AA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'PL14-2D053-AB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
(Ecu.fwdRadar, 0x764, None): [
|
(Ecu.fwdRadar, 0x764, None): [
|
||||||
b'ML3T-14D049-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'ML3T-14D049-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
@@ -106,10 +135,13 @@ FW_VERSIONS = {
|
|||||||
},
|
},
|
||||||
CAR.FORD_F_150_MK14: {
|
CAR.FORD_F_150_MK14: {
|
||||||
(Ecu.eps, 0x730, None): [
|
(Ecu.eps, 0x730, None): [
|
||||||
|
b'MB3C-14D003-AA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'ML3V-14D003-BA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'ML3V-14D003-BC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'ML3V-14D003-BC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'ML3V-14D003-BD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'ML3V-14D003-BD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
(Ecu.abs, 0x760, None): [
|
(Ecu.abs, 0x760, None): [
|
||||||
|
b'ML34-2D053-AJ\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'NL34-2D053-CA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'NL34-2D053-CA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'PL34-2D053-CA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'PL34-2D053-CA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'PL34-2D053-CC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'PL34-2D053-CC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
@@ -117,6 +149,7 @@ FW_VERSIONS = {
|
|||||||
b'PL3V-2D053-BB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'PL3V-2D053-BB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
(Ecu.fwdRadar, 0x764, None): [
|
(Ecu.fwdRadar, 0x764, None): [
|
||||||
|
b'ML3T-14D049-AH\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'ML3T-14D049-AK\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'ML3T-14D049-AK\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'ML3T-14D049-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'ML3T-14D049-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
@@ -124,6 +157,7 @@ FW_VERSIONS = {
|
|||||||
b'ML3T-14H102-ABR\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'ML3T-14H102-ABR\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'ML3T-14H102-ABS\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'ML3T-14H102-ABS\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'ML3T-14H102-ABT\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'ML3T-14H102-ABT\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'ML3T-14H102-ACA\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'PJ6T-14H102-ABJ\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'PJ6T-14H102-ABJ\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'PJ6T-14H102-ABS\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'PJ6T-14H102-ABS\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'RJ6T-14H102-ACJ\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'RJ6T-14H102-ACJ\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
@@ -132,8 +166,11 @@ FW_VERSIONS = {
|
|||||||
},
|
},
|
||||||
CAR.FORD_F_150_LIGHTNING_MK1: {
|
CAR.FORD_F_150_LIGHTNING_MK1: {
|
||||||
(Ecu.abs, 0x760, None): [
|
(Ecu.abs, 0x760, None): [
|
||||||
|
b'NL38-2D053-AF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'PL38-2D053-AA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'PL38-2D053-AA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'RL38-2D053-BC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'RL38-2D053-BD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'RL38-2D053-BD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'TL38-2D053-AD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
(Ecu.fwdCamera, 0x706, None): [
|
(Ecu.fwdCamera, 0x706, None): [
|
||||||
b'ML3T-14H102-ABT\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'ML3T-14H102-ABT\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
@@ -141,9 +178,13 @@ FW_VERSIONS = {
|
|||||||
b'RJ6T-14H102-BBC\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'RJ6T-14H102-BBC\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
(Ecu.fwdRadar, 0x764, None): [
|
(Ecu.fwdRadar, 0x764, None): [
|
||||||
|
b'ML3T-14D049-AH\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'ML3T-14D049-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'ML3T-14D049-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'RB5T-14D049-AB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
(Ecu.eps, 0x730, None): [
|
(Ecu.eps, 0x730, None): [
|
||||||
|
b'NL38-14D003-AA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'NL38-14D003-AC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'RL38-14D003-AA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'RL38-14D003-AA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -160,6 +201,8 @@ FW_VERSIONS = {
|
|||||||
b'LK9C-2D053-CN\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'LK9C-2D053-CN\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
(Ecu.fwdRadar, 0x764, None): [
|
(Ecu.fwdRadar, 0x764, None): [
|
||||||
|
b'ML3T-14D049-AH\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'ML3T-14D049-AK\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'ML3T-14D049-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'ML3T-14D049-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
(Ecu.fwdCamera, 0x706, None): [
|
(Ecu.fwdCamera, 0x706, None): [
|
||||||
@@ -170,15 +213,42 @@ FW_VERSIONS = {
|
|||||||
CAR.FORD_FOCUS_MK4: {
|
CAR.FORD_FOCUS_MK4: {
|
||||||
(Ecu.eps, 0x730, None): [
|
(Ecu.eps, 0x730, None): [
|
||||||
b'JX6C-14D003-AH\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'JX6C-14D003-AH\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'JX6C-14D003-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'JX6C-14D003-BB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'NX6C-14D003-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
(Ecu.abs, 0x760, None): [
|
(Ecu.abs, 0x760, None): [
|
||||||
b'JX61-2D053-CJ\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'JX61-2D053-CJ\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'LX61-2D053-AD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'NX61-2D053-MD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
(Ecu.fwdRadar, 0x764, None): [
|
(Ecu.fwdRadar, 0x764, None): [
|
||||||
b'JX7T-14D049-AC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'JX7T-14D049-AC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'JX7T-14D049-AD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
(Ecu.fwdCamera, 0x706, None): [
|
(Ecu.fwdCamera, 0x706, None): [
|
||||||
b'JX7T-14F397-AH\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'JX7T-14F397-AH\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'N1BT-14F397-AA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
CAR.FORD_MONDEO_MK5: {
|
||||||
|
(Ecu.fwdCamera, 0x706, None): [
|
||||||
|
b'KT4T-14F397-AE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
],
|
||||||
|
(Ecu.abs, 0x760, None): [
|
||||||
|
b'KG9C-2D053-DF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
],
|
||||||
|
(Ecu.eps, 0x730, None): [
|
||||||
|
b'K2GC-14D003-AJ\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
],
|
||||||
|
(Ecu.fwdRadar, 0x764, None): [
|
||||||
|
b'JX7T-14D049-AD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
],
|
||||||
|
(Ecu.engine, 0x7e0, None): [
|
||||||
|
b'HS7A-14C204-CJD\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
],
|
||||||
|
(Ecu.debug, 0x7d0, None): [
|
||||||
|
b'1U5T-14G374-DA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
CAR.FORD_MAVERICK_MK1: {
|
CAR.FORD_MAVERICK_MK1: {
|
||||||
@@ -203,16 +273,25 @@ FW_VERSIONS = {
|
|||||||
},
|
},
|
||||||
CAR.FORD_RANGER_MK2: {
|
CAR.FORD_RANGER_MK2: {
|
||||||
(Ecu.eps, 0x730, None): [
|
(Ecu.eps, 0x730, None): [
|
||||||
|
b'JR3C-14D003-AA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'NB3C-14D003-AB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'NB3C-14D003-AB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'NL14-14D003-AC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'NL14-14D003-AE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'NL14-14D003-AE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'RB3C-14D003-AA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'RB3C-14D003-AA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
(Ecu.abs, 0x760, None): [
|
(Ecu.abs, 0x760, None): [
|
||||||
|
b'MB3C-2D053-AE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'MB3C-2D053-ZJ\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'PB3C-2D053-ZB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'PB3C-2D053-ZC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'PB3C-2D053-ZD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'PB3C-2D053-ZD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'PB3C-2D053-ZG\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'PB3C-2D053-ZG\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'PB3C-2D053-ZJ\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'PB3C-2D053-ZJ\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'PB9C-2D053-ZG\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
b'RB3C-2D053-AK\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
(Ecu.fwdRadar, 0x764, None): [
|
(Ecu.fwdRadar, 0x764, None): [
|
||||||
|
b'JX7T-14D049-AD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
b'ML3T-14D049-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'ML3T-14D049-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
(Ecu.fwdCamera, 0x706, None): [
|
(Ecu.fwdCamera, 0x706, None): [
|
||||||
@@ -220,4 +299,18 @@ FW_VERSIONS = {
|
|||||||
b'RJ6T-14H102-BBB\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
b'RJ6T-14H102-BBB\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
CAR.FORD_TRANSIT_MK5: {
|
||||||
|
(Ecu.eps, 0x730, None): [
|
||||||
|
b'KK21-14D003-AM\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
],
|
||||||
|
(Ecu.abs, 0x760, None): [
|
||||||
|
b'NK41-2D053-DF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
],
|
||||||
|
(Ecu.fwdRadar, 0x764, None): [
|
||||||
|
b'PC4T-14D049-AA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
],
|
||||||
|
(Ecu.fwdCamera, 0x706, None): [
|
||||||
|
b'NK3T-14F397-AB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||||
|
],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import math
|
||||||
|
|
||||||
from opendbc.car import CanBusBase, structs
|
from opendbc.car import CanBusBase, structs
|
||||||
|
|
||||||
HUDControl = structs.CarControl.HUDControl
|
HUDControl = structs.CarControl.HUDControl
|
||||||
@@ -33,20 +35,40 @@ def calculate_lat_ctl2_checksum(mode: int, counter: int, dat: bytearray) -> int:
|
|||||||
return 0xFF - (checksum & 0xFF)
|
return 0xFF - (checksum & 0xFF)
|
||||||
|
|
||||||
|
|
||||||
def create_lka_msg(packer, CAN: CanBus):
|
def create_lka_msg(packer, CAN: CanBus, active: bool = False, apply_angle: float = 0.0,
|
||||||
|
direction: int = 0, ramp_type: int = 0, curvature: float = 0.0):
|
||||||
"""
|
"""
|
||||||
Creates an empty CAN message for the Ford LKA Command.
|
Creates a CAN message for the Ford LKA Command.
|
||||||
|
|
||||||
This command can apply "Lane Keeping Aid" maneuvers, which are subject to the PSCM lockout.
|
On LKA-steering platforms, this command applies Lane Keeping Aid maneuvers through the PSCM.
|
||||||
|
|
||||||
Frequency is 33Hz.
|
Frequency is 33Hz.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return packer.make_can_msg("Lane_Assist_Data1", CAN.main, {})
|
if active:
|
||||||
|
mrad = math.radians(max(-5.8, min(5.8, apply_angle))) * 1000.0
|
||||||
|
mrad = max(-102.4, min(102.3, mrad))
|
||||||
|
curvature = max(-0.01023, min(0.01023, curvature))
|
||||||
|
else:
|
||||||
|
mrad = 0.0
|
||||||
|
direction = 0
|
||||||
|
ramp_type = 0
|
||||||
|
curvature = 0.0
|
||||||
|
|
||||||
|
values = {
|
||||||
|
"LkaDrvOvrrd_D_Rq": 0,
|
||||||
|
"LkaActvStats_D2_Req": direction if active else 0,
|
||||||
|
"LaRefAng_No_Req": mrad,
|
||||||
|
"LaRampType_B_Req": ramp_type,
|
||||||
|
"LaCurvature_No_Calc": curvature,
|
||||||
|
"LdwActvStats_D_Req": 0,
|
||||||
|
"LdwActvIntns_D_Req": 3,
|
||||||
|
}
|
||||||
|
return packer.make_can_msg("Lane_Assist_Data1", CAN.main, values)
|
||||||
|
|
||||||
|
|
||||||
def create_lat_ctl_msg(packer, CAN: CanBus, lat_active: bool, path_offset: float, path_angle: float, curvature: float,
|
def create_lat_ctl_msg(packer, CAN: CanBus, lat_active: bool, path_offset: float, path_angle: float, curvature: float,
|
||||||
curvature_rate: float):
|
curvature_rate: float, stock_lmc=None):
|
||||||
"""
|
"""
|
||||||
Creates a CAN message for the Ford TJA/LCA Command.
|
Creates a CAN message for the Ford TJA/LCA Command.
|
||||||
|
|
||||||
@@ -68,20 +90,33 @@ def create_lat_ctl_msg(packer, CAN: CanBus, lat_active: bool, path_offset: float
|
|||||||
Frequency is 20Hz.
|
Frequency is 20Hz.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
values = {
|
if stock_lmc is not None:
|
||||||
"LatCtlRng_L_Max": 0, # Unknown [0|126] meter
|
values = {
|
||||||
"HandsOffCnfm_B_Rq": 0, # Unknown: 0=Inactive, 1=Active [0|1]
|
"LatCtlRng_L_Max": stock_lmc["LatCtlRng_L_Max"],
|
||||||
"LatCtl_D_Rq": 1 if lat_active else 0, # Mode: 0=None, 1=ContinuousPathFollowing, 2=InterventionLeft,
|
"HandsOffCnfm_B_Rq": stock_lmc["HandsOffCnfm_B_Rq"],
|
||||||
# 3=InterventionRight, 4-7=NotUsed [0|7]
|
"LatCtl_D_Rq": 0,
|
||||||
"LatCtlRampType_D_Rq": 0, # Ramp speed: 0=Slow, 1=Medium, 2=Fast, 3=Immediate [0|3]
|
"LatCtlRampType_D_Rq": stock_lmc["LatCtlRampType_D_Rq"],
|
||||||
# Makes no difference with curvature control
|
"LatCtlPrecision_D_Rq": stock_lmc["LatCtlPrecision_D_Rq"],
|
||||||
"LatCtlPrecision_D_Rq": 1, # Precision: 0=Comfortable, 1=Precise, 2/3=NotUsed [0|3]
|
"LatCtlPathOffst_L_Actl": stock_lmc["LatCtlPathOffst_L_Actl"],
|
||||||
# The stock system always uses comfortable
|
"LatCtlPath_An_Actl": stock_lmc["LatCtlPath_An_Actl"],
|
||||||
"LatCtlPathOffst_L_Actl": path_offset, # Path offset [-5.12|5.11] meter
|
"LatCtlCurv_NoRate_Actl": stock_lmc["LatCtlCurv_NoRate_Actl"],
|
||||||
"LatCtlPath_An_Actl": path_angle, # Path angle [-0.5|0.5235] radians
|
"LatCtlCurv_No_Actl": stock_lmc["LatCtlCurv_No_Actl"],
|
||||||
"LatCtlCurv_NoRate_Actl": curvature_rate, # Curvature rate [-0.001024|0.00102375] 1/meter^2
|
}
|
||||||
"LatCtlCurv_No_Actl": curvature, # Curvature [-0.02|0.02094] 1/meter
|
else:
|
||||||
}
|
values = {
|
||||||
|
"LatCtlRng_L_Max": 0, # Unknown [0|126] meter
|
||||||
|
"HandsOffCnfm_B_Rq": 0, # Unknown: 0=Inactive, 1=Active [0|1]
|
||||||
|
"LatCtl_D_Rq": 1 if lat_active else 0, # Mode: 0=None, 1=ContinuousPathFollowing, 2=InterventionLeft,
|
||||||
|
# 3=InterventionRight, 4-7=NotUsed [0|7]
|
||||||
|
"LatCtlRampType_D_Rq": 0, # Ramp speed: 0=Slow, 1=Medium, 2=Fast, 3=Immediate [0|3]
|
||||||
|
# Makes no difference with curvature control
|
||||||
|
"LatCtlPrecision_D_Rq": 1, # Precision: 0=Comfortable, 1=Precise, 2/3=NotUsed [0|3]
|
||||||
|
# The stock system always uses comfortable
|
||||||
|
"LatCtlPathOffst_L_Actl": path_offset, # Path offset [-5.12|5.11] meter
|
||||||
|
"LatCtlPath_An_Actl": path_angle, # Path angle [-0.5|0.5235] radians
|
||||||
|
"LatCtlCurv_NoRate_Actl": curvature_rate, # Curvature rate [-0.001024|0.00102375] 1/meter^2
|
||||||
|
"LatCtlCurv_No_Actl": curvature, # Curvature [-0.02|0.02094] 1/meter
|
||||||
|
}
|
||||||
return packer.make_can_msg("LateralMotionControl", CAN.main, values)
|
return packer.make_can_msg("LateralMotionControl", CAN.main, values)
|
||||||
|
|
||||||
|
|
||||||
@@ -146,7 +181,7 @@ def create_acc_msg(packer, CAN: CanBus, long_active: bool, gas: float, accel: fl
|
|||||||
|
|
||||||
|
|
||||||
def create_acc_ui_msg(packer, CAN: CanBus, CP, main_on: bool, enabled: bool, fcw_alert: bool, standstill: bool,
|
def create_acc_ui_msg(packer, CAN: CanBus, CP, main_on: bool, enabled: bool, fcw_alert: bool, standstill: bool,
|
||||||
show_distance_bars: bool, hud_control, stock_values: dict):
|
show_distance_bars: bool, hud_control, stock_values: dict, hands_free_cluster: bool = False):
|
||||||
"""
|
"""
|
||||||
Creates a CAN message for the Ford IPC adaptive cruise, forward collision warning and traffic jam
|
Creates a CAN message for the Ford IPC adaptive cruise, forward collision warning and traffic jam
|
||||||
assist status.
|
assist status.
|
||||||
@@ -162,6 +197,8 @@ def create_acc_ui_msg(packer, CAN: CanBus, CP, main_on: bool, enabled: bool, fcw
|
|||||||
status = 3 # ActiveInterventionLeft
|
status = 3 # ActiveInterventionLeft
|
||||||
elif hud_control.rightLaneDepart:
|
elif hud_control.rightLaneDepart:
|
||||||
status = 4 # ActiveInterventionRight
|
status = 4 # ActiveInterventionRight
|
||||||
|
elif hands_free_cluster:
|
||||||
|
status = 7 # Hands-free assistance display
|
||||||
else:
|
else:
|
||||||
status = 2 # Active
|
status = 2 # Active
|
||||||
elif main_on:
|
elif main_on:
|
||||||
|
|||||||
@@ -31,12 +31,13 @@ class CarInterface(CarInterfaceBase):
|
|||||||
|
|
||||||
ret.radarUnavailable = Bus.radar not in DBC[candidate]
|
ret.radarUnavailable = Bus.radar not in DBC[candidate]
|
||||||
ret.steerControlType = structs.CarParams.SteerControlType.angle
|
ret.steerControlType = structs.CarParams.SteerControlType.angle
|
||||||
ret.steerActuatorDelay = 0.2
|
ret.steerActuatorDelay = 0.05 if ret.flags & FordFlags.LKA_STEERING else 0.22
|
||||||
ret.steerLimitTimer = 1.0
|
ret.steerLimitTimer = 1.0
|
||||||
ret.steerAtStandstill = True
|
ret.steerAtStandstill = True
|
||||||
|
|
||||||
ret.longitudinalTuning.kiBP = [0.]
|
ret.longitudinalTuning.kiBP = [0.]
|
||||||
ret.longitudinalTuning.kiV = [0.5]
|
ret.longitudinalTuning.kiV = [0.5]
|
||||||
|
ret.longitudinalTuning.kpV = [0.]
|
||||||
|
|
||||||
if not ret.radarUnavailable and DBC[candidate][Bus.radar] == RADAR.DELPHI_MRR:
|
if not ret.radarUnavailable and DBC[candidate][Bus.radar] == RADAR.DELPHI_MRR:
|
||||||
# average of 33.3 Hz radar timestep / 4 scan modes = 60 ms
|
# average of 33.3 Hz radar timestep / 4 scan modes = 60 ms
|
||||||
@@ -44,15 +45,19 @@ class CarInterface(CarInterfaceBase):
|
|||||||
ret.radarDelay = 0.06
|
ret.radarDelay = 0.06
|
||||||
|
|
||||||
CAN = CanBus(fingerprint=fingerprint)
|
CAN = CanBus(fingerprint=fingerprint)
|
||||||
|
if 0x365 in fingerprint[CAN.main]:
|
||||||
|
ret.flags |= int(FordFlags.HEV_CLUSTER_DATA)
|
||||||
|
if all(address in fingerprint[CAN.main] for address in (0x07A, 0x24B, 0x24C)):
|
||||||
|
ret.flags |= int(FordFlags.HEV_BATTERY_DATA)
|
||||||
cfgs = [get_safety_config(structs.CarParams.SafetyModel.ford)]
|
cfgs = [get_safety_config(structs.CarParams.SafetyModel.ford)]
|
||||||
if CAN.main >= 4:
|
if CAN.main >= 4:
|
||||||
cfgs.insert(0, get_safety_config(structs.CarParams.SafetyModel.noOutput))
|
cfgs.insert(0, get_safety_config(structs.CarParams.SafetyModel.noOutput))
|
||||||
ret.safetyConfigs = cfgs
|
ret.safetyConfigs = cfgs
|
||||||
|
|
||||||
ret.alphaLongitudinalAvailable = ret.radarUnavailable
|
ret.alphaLongitudinalAvailable = True
|
||||||
if alpha_long or not ret.radarUnavailable:
|
ret.openpilotLongitudinalControl = bool(alpha_long)
|
||||||
|
if ret.openpilotLongitudinalControl:
|
||||||
ret.safetyConfigs[-1].safetyParam |= FordSafetyFlags.LONG_CONTROL.value
|
ret.safetyConfigs[-1].safetyParam |= FordSafetyFlags.LONG_CONTROL.value
|
||||||
ret.openpilotLongitudinalControl = True
|
|
||||||
|
|
||||||
if ret.flags & FordFlags.CANFD:
|
if ret.flags & FordFlags.CANFD:
|
||||||
ret.safetyConfigs[-1].safetyParam |= FordSafetyFlags.CANFD.value
|
ret.safetyConfigs[-1].safetyParam |= FordSafetyFlags.CANFD.value
|
||||||
@@ -63,6 +68,8 @@ class CarInterface(CarInterfaceBase):
|
|||||||
if fingerprint[CAN.camera].get(0x3d6) != 8 or fingerprint[CAN.camera].get(0x186) != 8:
|
if fingerprint[CAN.camera].get(0x3d6) != 8 or fingerprint[CAN.camera].get(0x186) != 8:
|
||||||
carlog.error('dashcamOnly: SecOC is unsupported')
|
carlog.error('dashcamOnly: SecOC is unsupported')
|
||||||
ret.dashcamOnly = True
|
ret.dashcamOnly = True
|
||||||
|
elif ret.flags & FordFlags.LKA_STEERING:
|
||||||
|
ret.safetyConfigs[-1].safetyParam |= FordSafetyFlags.LKA_STEERING.value
|
||||||
else:
|
else:
|
||||||
# Lock out if the car does not have needed lateral and longitudinal control APIs.
|
# Lock out if the car does not have needed lateral and longitudinal control APIs.
|
||||||
# Note that we also check CAN for adaptive cruise, but no known signal for LCA exists
|
# Note that we also check CAN for adaptive cruise, but no known signal for LCA exists
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
|
from collections import deque
|
||||||
from typing import cast
|
from typing import cast
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from math import cos, sin
|
from math import cos, sin
|
||||||
@@ -19,6 +20,7 @@ DELPHI_MRR_RADAR_MSG_COUNT = 64
|
|||||||
DELPHI_MRR_RADAR_RANGE_COVERAGE = {0: 42, 1: 164, 2: 45, 3: 175} # scan index to detection range (m)
|
DELPHI_MRR_RADAR_RANGE_COVERAGE = {0: 42, 1: 164, 2: 45, 3: 175} # scan index to detection range (m)
|
||||||
DELPHI_MRR_MIN_LONG_RANGE_DIST = 30 # meters
|
DELPHI_MRR_MIN_LONG_RANGE_DIST = 30 # meters
|
||||||
DELPHI_MRR_CLUSTER_THRESHOLD = 5 # meters, lateral distance and relative velocity are weighted
|
DELPHI_MRR_CLUSTER_THRESHOLD = 5 # meters, lateral distance and relative velocity are weighted
|
||||||
|
STEER_ASSIST_DATA_ADDR = 0x3D7
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -89,12 +91,17 @@ def _create_delphi_mrr_radar_can_parser(CP) -> CANParser:
|
|||||||
return CANParser(RADAR.DELPHI_MRR, messages, CanBus(CP).radar)
|
return CANParser(RADAR.DELPHI_MRR, messages, CanBus(CP).radar)
|
||||||
|
|
||||||
|
|
||||||
|
def _create_steer_assist_radar_can_parser(CP) -> CANParser:
|
||||||
|
return CANParser(RADAR.STEER_ASSIST_DATA, [("Steer_Assist_Data", 20)], CanBus(CP).camera)
|
||||||
|
|
||||||
|
|
||||||
class RadarInterface(RadarInterfaceBase):
|
class RadarInterface(RadarInterfaceBase):
|
||||||
def __init__(self, CP):
|
def __init__(self, CP):
|
||||||
super().__init__(CP)
|
super().__init__(CP)
|
||||||
|
|
||||||
self.points: list[list[float]] = []
|
self.points: list[list[float]] = []
|
||||||
self.clusters: list[Cluster] = []
|
self.clusters: list[Cluster] = []
|
||||||
|
self.v_rel_history = deque(maxlen=20)
|
||||||
|
|
||||||
self.updated_messages = set()
|
self.updated_messages = set()
|
||||||
self.track_id = 0
|
self.track_id = 0
|
||||||
@@ -111,6 +118,9 @@ class RadarInterface(RadarInterfaceBase):
|
|||||||
elif self.radar == RADAR.DELPHI_MRR:
|
elif self.radar == RADAR.DELPHI_MRR:
|
||||||
self.rcp = _create_delphi_mrr_radar_can_parser(CP)
|
self.rcp = _create_delphi_mrr_radar_can_parser(CP)
|
||||||
self.trigger_msg = DELPHI_MRR_RADAR_HEADER_ADDR
|
self.trigger_msg = DELPHI_MRR_RADAR_HEADER_ADDR
|
||||||
|
elif self.radar == RADAR.STEER_ASSIST_DATA:
|
||||||
|
self.rcp = _create_steer_assist_radar_can_parser(CP)
|
||||||
|
self.trigger_msg = STEER_ASSIST_DATA_ADDR
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Unsupported radar: {self.radar}")
|
raise ValueError(f"Unsupported radar: {self.radar}")
|
||||||
|
|
||||||
@@ -135,10 +145,45 @@ class RadarInterface(RadarInterfaceBase):
|
|||||||
_update = self._update_delphi_mrr(ret)
|
_update = self._update_delphi_mrr(ret)
|
||||||
if not _update:
|
if not _update:
|
||||||
return None
|
return None
|
||||||
|
elif self.radar == RADAR.STEER_ASSIST_DATA:
|
||||||
|
self._update_steer_assist()
|
||||||
|
|
||||||
ret.points = list(self.pts.values())
|
ret.points = list(self.pts.values())
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def _update_steer_assist(self):
|
||||||
|
msg = self.rcp.vl["Steer_Assist_Data"]
|
||||||
|
confidence = msg["CmbbObjConfdnc_D_Stat"]
|
||||||
|
if confidence <= 0:
|
||||||
|
self.pts.pop(0, None)
|
||||||
|
self.v_rel_history.clear()
|
||||||
|
return
|
||||||
|
|
||||||
|
d_rel = msg["CmbbObjDistLong_L_Actl"]
|
||||||
|
v_rel = msg["CmbbObjRelLong_V_Actl"]
|
||||||
|
new_track = 0 not in self.pts
|
||||||
|
if new_track:
|
||||||
|
self.pts[0] = structs.RadarData.RadarPoint()
|
||||||
|
self.pts[0].trackId = self.track_id
|
||||||
|
self.track_id += 1
|
||||||
|
elif abs(v_rel) < 1e-2:
|
||||||
|
self.v_rel_history.append(d_rel - self.pts[0].dRel)
|
||||||
|
v_rel = sum(self.v_rel_history)
|
||||||
|
else:
|
||||||
|
self.v_rel_history.clear()
|
||||||
|
|
||||||
|
if not new_track and (abs(self.pts[0].vRel - v_rel) > 2.0 or abs(self.pts[0].dRel - d_rel) > 5.0):
|
||||||
|
self.pts[0].trackId = self.track_id
|
||||||
|
self.track_id += 1
|
||||||
|
self.v_rel_history.clear()
|
||||||
|
|
||||||
|
self.pts[0].dRel = d_rel
|
||||||
|
self.pts[0].yRel = msg["CmbbObjDistLat_L_Actl"]
|
||||||
|
self.pts[0].vRel = v_rel
|
||||||
|
self.pts[0].aRel = float('nan')
|
||||||
|
self.pts[0].yvRel = msg["CmbbObjRelLat_V_Actl"]
|
||||||
|
self.pts[0].measured = True
|
||||||
|
|
||||||
def _update_delphi_esr(self):
|
def _update_delphi_esr(self):
|
||||||
for ii in sorted(self.updated_messages):
|
for ii in sorted(self.updated_messages):
|
||||||
cpt = self.rcp.vl[ii]
|
cpt = self.rcp.vl[ii]
|
||||||
|
|||||||
@@ -1,12 +1,19 @@
|
|||||||
import random
|
import random
|
||||||
from collections.abc import Iterable
|
from collections.abc import Iterable
|
||||||
|
from types import SimpleNamespace
|
||||||
|
|
||||||
from hypothesis import settings, given, strategies as st
|
from hypothesis import settings, given, strategies as st
|
||||||
from parameterized import parameterized
|
from parameterized import parameterized
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from opendbc.car import Bus, gen_empty_fingerprint
|
||||||
|
from opendbc.can import CANPacker
|
||||||
|
from opendbc.car.ford import fordcan
|
||||||
|
from opendbc.car.gps import FORD_MACH_E_GPS_MESSAGES, get_car_gps_config, parse_ford_can_gps
|
||||||
from opendbc.car.structs import CarParams
|
from opendbc.car.structs import CarParams
|
||||||
from opendbc.car.fw_versions import build_fw_dict
|
from opendbc.car.fw_versions import build_fw_dict
|
||||||
from opendbc.car.ford.values import CAR, FW_QUERY_CONFIG, FW_PATTERN, get_platform_codes
|
from opendbc.car.ford.interface import CarInterface
|
||||||
|
from opendbc.car.ford.values import CAR, FW_QUERY_CONFIG, FW_PATTERN, FordSafetyFlags, get_platform_codes, match_vin_to_car
|
||||||
from opendbc.car.ford.fingerprints import FW_VERSIONS
|
from opendbc.car.ford.fingerprints import FW_VERSIONS
|
||||||
|
|
||||||
Ecu = CarParams.Ecu
|
Ecu = CarParams.Ecu
|
||||||
@@ -20,6 +27,7 @@ ECU_ADDRESSES = {
|
|||||||
Ecu.engine: 0x7E0, # Powertrain Control Module (PCM)
|
Ecu.engine: 0x7E0, # Powertrain Control Module (PCM)
|
||||||
Ecu.shiftByWire: 0x732, # Gear Shift Module (GSM)
|
Ecu.shiftByWire: 0x732, # Gear Shift Module (GSM)
|
||||||
Ecu.debug: 0x7D0, # Accessory Protocol Interface Module (APIM)
|
Ecu.debug: 0x7D0, # Accessory Protocol Interface Module (APIM)
|
||||||
|
Ecu.hud: 0x720, # Instrument Cluster Module (ICM)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -41,6 +49,16 @@ ECU_PART_NUMBER = {
|
|||||||
|
|
||||||
|
|
||||||
class TestFordFW:
|
class TestFordFW:
|
||||||
|
def test_vin_fallback(self):
|
||||||
|
def vin(wmi, vds, powertrain, year):
|
||||||
|
return f"{wmi}{vds}{powertrain}0{year}1234567"
|
||||||
|
|
||||||
|
assert match_vin_to_car(vin("2FM", "PK4A", "A", "N")) == {str(CAR.FORD_EDGE_MK2)}
|
||||||
|
assert match_vin_to_car(vin("3FM", "K1RA", "A", "M")) == {str(CAR.FORD_MUSTANG_MACH_E_MK1)}
|
||||||
|
assert match_vin_to_car(vin("1FT", "F1CA", "A", "M")) == {str(CAR.FORD_F_150_MK14)}
|
||||||
|
assert match_vin_to_car(vin("1FT", "F1CA", "L", "N")) == {str(CAR.FORD_F_150_LIGHTNING_MK1)}
|
||||||
|
assert match_vin_to_car("0" * 17) == set()
|
||||||
|
|
||||||
def test_fw_query_config(self):
|
def test_fw_query_config(self):
|
||||||
for (ecu, addr, subaddr) in FW_QUERY_CONFIG.extra_ecus:
|
for (ecu, addr, subaddr) in FW_QUERY_CONFIG.extra_ecus:
|
||||||
assert ecu in ECU_ADDRESSES, "Unknown ECU"
|
assert ecu in ECU_ADDRESSES, "Unknown ECU"
|
||||||
@@ -50,10 +68,13 @@ class TestFordFW:
|
|||||||
@parameterized.expand(FW_VERSIONS.items())
|
@parameterized.expand(FW_VERSIONS.items())
|
||||||
def test_fw_versions(self, car_model: str, fw_versions: dict[tuple[int, int, int | None], Iterable[bytes]]):
|
def test_fw_versions(self, car_model: str, fw_versions: dict[tuple[int, int, int | None], Iterable[bytes]]):
|
||||||
for (ecu, addr, subaddr), fws in fw_versions.items():
|
for (ecu, addr, subaddr), fws in fw_versions.items():
|
||||||
assert ecu in ECU_PART_NUMBER, "Unexpected ECU"
|
assert ecu in ECU_ADDRESSES, "Unknown ECU"
|
||||||
assert addr == ECU_ADDRESSES[ecu], "ECU address mismatch"
|
assert addr == ECU_ADDRESSES[ecu], "ECU address mismatch"
|
||||||
assert subaddr is None, "Unexpected ECU subaddress"
|
assert subaddr is None, "Unexpected ECU subaddress"
|
||||||
|
|
||||||
|
if ecu not in ECU_PART_NUMBER:
|
||||||
|
continue
|
||||||
|
|
||||||
for fw in fws:
|
for fw in fws:
|
||||||
assert len(fw) == 24, "Expected ECU response to be 24 bytes"
|
assert len(fw) == 24, "Expected ECU response to be 24 bytes"
|
||||||
|
|
||||||
@@ -140,3 +161,158 @@ class TestFordFW:
|
|||||||
live_fw[(0x760, None)] = {b"M1MC-2D053-XX\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"}
|
live_fw[(0x760, None)] = {b"M1MC-2D053-XX\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"}
|
||||||
candidates = FW_QUERY_CONFIG.match_fw_to_car_fuzzy(live_fw, '', {expected_fingerprint: offline_fw})
|
candidates = FW_QUERY_CONFIG.match_fw_to_car_fuzzy(live_fw, '', {expected_fingerprint: offline_fw})
|
||||||
assert len(candidates) == 0, "Should not match new model year hint"
|
assert len(candidates) == 0, "Should not match new model year hint"
|
||||||
|
|
||||||
|
|
||||||
|
def test_mach_e_longitudinal_toggle_controls_stock_acc_selection():
|
||||||
|
stock = CarInterface.get_params(
|
||||||
|
CAR.FORD_MUSTANG_MACH_E_MK1, gen_empty_fingerprint(), [], False, False, False, None)
|
||||||
|
enhanced = CarInterface.get_params(
|
||||||
|
CAR.FORD_MUSTANG_MACH_E_MK1, gen_empty_fingerprint(), [], True, False, False, None)
|
||||||
|
|
||||||
|
assert stock.alphaLongitudinalAvailable
|
||||||
|
assert not stock.openpilotLongitudinalControl
|
||||||
|
assert stock.pcmCruise
|
||||||
|
assert not (stock.safetyConfigs[-1].safetyParam & FordSafetyFlags.LONG_CONTROL)
|
||||||
|
|
||||||
|
assert enhanced.alphaLongitudinalAvailable
|
||||||
|
assert enhanced.openpilotLongitudinalControl
|
||||||
|
assert enhanced.safetyConfigs[-1].safetyParam & FordSafetyFlags.LONG_CONTROL
|
||||||
|
|
||||||
|
|
||||||
|
def test_mach_e_can_gps_decode():
|
||||||
|
nav1 = {
|
||||||
|
"GpsHsphLattSth_D_Actl": 2,
|
||||||
|
"GpsHsphLongEast_D_Actl": 2,
|
||||||
|
"GPS_Latitude_Degrees": 37,
|
||||||
|
"GPS_Latitude_Minutes": 57,
|
||||||
|
"GPS_Latitude_Min_dec": 0.8864,
|
||||||
|
"GPS_Longitude_Degrees": -121,
|
||||||
|
"GPS_Longitude_Minutes": 44,
|
||||||
|
"GPS_Longitude_Min_dec": 0.22,
|
||||||
|
}
|
||||||
|
nav2 = {
|
||||||
|
"GpsUtcYr_No_Actl": 2026,
|
||||||
|
"GpsUtcMnth_No_Actl": 8,
|
||||||
|
"GpsUtcDay_No_Actl": 26,
|
||||||
|
"GPS_UTC_hours": 0,
|
||||||
|
"GPS_UTC_minutes": 24,
|
||||||
|
"GPS_UTC_seconds": 38,
|
||||||
|
"Gps_B_Falt": 0,
|
||||||
|
}
|
||||||
|
nav3 = {
|
||||||
|
"GPS_dimension": 2,
|
||||||
|
"GPS_Hdop": 0.6,
|
||||||
|
"GPS_Vdop": 0.8,
|
||||||
|
"GPS_Sat_num_in_view": 31,
|
||||||
|
"GPS_MSL_altitude": 90,
|
||||||
|
"GPS_Speed": 10,
|
||||||
|
"GPS_Heading": 180,
|
||||||
|
}
|
||||||
|
|
||||||
|
gps = parse_ford_can_gps(nav1, nav2, nav3)
|
||||||
|
|
||||||
|
assert gps is not None
|
||||||
|
assert gps["latitude"] == 37.96477333333333
|
||||||
|
assert gps["longitude"] == -121.737
|
||||||
|
assert abs(gps["altitude"] - 27.432) < 1e-9
|
||||||
|
assert abs(gps["speed"] - 10 * 0.44704) < 1e-9
|
||||||
|
assert gps["hasFix"]
|
||||||
|
assert gps["satelliteCount"] == 0 # 31 is Ford's invalid sentinel.
|
||||||
|
|
||||||
|
|
||||||
|
def test_mach_e_can_gps_fault_invalidates_fix():
|
||||||
|
nav1 = {
|
||||||
|
"GpsHsphLattSth_D_Actl": 2,
|
||||||
|
"GpsHsphLongEast_D_Actl": 2,
|
||||||
|
"GPS_Latitude_Degrees": 37,
|
||||||
|
"GPS_Latitude_Minutes": 57,
|
||||||
|
"GPS_Latitude_Min_dec": 0.8864,
|
||||||
|
"GPS_Longitude_Degrees": -121,
|
||||||
|
"GPS_Longitude_Minutes": 44,
|
||||||
|
"GPS_Longitude_Min_dec": 0.22,
|
||||||
|
}
|
||||||
|
nav2 = {
|
||||||
|
"GpsUtcYr_No_Actl": 2026,
|
||||||
|
"GpsUtcMnth_No_Actl": 8,
|
||||||
|
"GpsUtcDay_No_Actl": 26,
|
||||||
|
"GPS_UTC_hours": 0,
|
||||||
|
"GPS_UTC_minutes": 24,
|
||||||
|
"GPS_UTC_seconds": 38,
|
||||||
|
"Gps_B_Falt": 1,
|
||||||
|
}
|
||||||
|
nav3 = {
|
||||||
|
"GPS_dimension": 2,
|
||||||
|
"GPS_Hdop": 0.6,
|
||||||
|
"GPS_Vdop": 0.8,
|
||||||
|
"GPS_Sat_num_in_view": 31,
|
||||||
|
"GPS_MSL_altitude": 90,
|
||||||
|
"GPS_Speed": 0,
|
||||||
|
"GPS_Heading": 180,
|
||||||
|
}
|
||||||
|
|
||||||
|
gps = parse_ford_can_gps(nav1, nav2, nav3)
|
||||||
|
|
||||||
|
assert gps is not None
|
||||||
|
assert not gps["hasFix"]
|
||||||
|
assert gps["latitude"] == 37.96477333333333
|
||||||
|
assert gps["altitude"] == 0.0
|
||||||
|
|
||||||
|
|
||||||
|
def test_mach_e_can_gps_messages_are_optional_main_bus_inputs():
|
||||||
|
cp = CarInterface.get_params(CAR.FORD_MUSTANG_MACH_E_MK1, gen_empty_fingerprint(), [], False, False, False, None)
|
||||||
|
parser = CarInterface.CarState.get_can_parsers(cp)[Bus.pt]
|
||||||
|
gps_config = get_car_gps_config(cp)
|
||||||
|
|
||||||
|
assert gps_config is not None
|
||||||
|
assert gps_config.messages == FORD_MACH_E_GPS_MESSAGES
|
||||||
|
assert gps_config.decoder is parse_ford_can_gps
|
||||||
|
assert set(parser.addresses) >= {0x462, 0x463, 0x464}
|
||||||
|
assert set(FORD_MACH_E_GPS_MESSAGES) == set(gps_config.messages) == {
|
||||||
|
parser.dbc.addr_to_msg[0x462].name,
|
||||||
|
parser.dbc.addr_to_msg[0x463].name,
|
||||||
|
parser.dbc.addr_to_msg[0x464].name,
|
||||||
|
}
|
||||||
|
assert all(parser.message_states[address].ignore_alive for address in (0x462, 0x463, 0x464))
|
||||||
|
|
||||||
|
|
||||||
|
def test_lightning_low_rate_camera_messages_use_declared_frequencies():
|
||||||
|
cp = CarInterface.get_params(CAR.FORD_F_150_LIGHTNING_MK1, gen_empty_fingerprint(), [], True, False, False, None)
|
||||||
|
cp.enableBsm = True
|
||||||
|
parser = CarInterface.CarState.get_can_parsers(cp)[Bus.cam]
|
||||||
|
|
||||||
|
expected_frequencies = {
|
||||||
|
"IPMA_Data": 1,
|
||||||
|
"Traffic_RecognitnData": 1,
|
||||||
|
"Side_Detect_L_Stat": 5,
|
||||||
|
"Side_Detect_R_Stat": 5,
|
||||||
|
}
|
||||||
|
for message, frequency in expected_frequencies.items():
|
||||||
|
state = parser.message_states[parser.dbc.name_to_msg[message].address]
|
||||||
|
assert state.frequency == frequency
|
||||||
|
assert state.timeout_threshold == pytest.approx(10e9 / frequency)
|
||||||
|
|
||||||
|
|
||||||
|
def test_hands_free_cluster_status_is_opt_in():
|
||||||
|
packer = CANPacker("ford_lincoln_base_pt")
|
||||||
|
CAN = SimpleNamespace(main=0)
|
||||||
|
CP = SimpleNamespace(openpilotLongitudinalControl=False)
|
||||||
|
hud = SimpleNamespace(leftLaneDepart=False, rightLaneDepart=False)
|
||||||
|
stock_values = dict.fromkeys([
|
||||||
|
"HaDsply_No_Cs", "HaDsply_No_Cnt", "AccStopStat_D_Dsply", "AccTrgDist2_D_Dsply",
|
||||||
|
"AccStopRes_B_Dsply", "TjaWarn_D_Rq", "TjaMsgTxt_D_Dsply", "IaccLamp_D_Rq",
|
||||||
|
"AccMsgTxt_D2_Rq", "FcwDeny_B_Dsply", "FcwMemStat_B_Actl", "AccTGap_B_Dsply",
|
||||||
|
"CadsAlignIncplt_B_Actl", "AccFllwMde_B_Dsply", "CadsRadrBlck_B_Actl",
|
||||||
|
"CmbbPostEvnt_B_Dsply", "AccStopMde_B_Dsply", "FcwMemSens_D_Actl",
|
||||||
|
"FcwMsgTxt_D_Rq", "AccWarn_D_Dsply", "FcwVisblWarn_B_Rq", "FcwAudioWarn_B_Rq",
|
||||||
|
"AccTGap_D_Dsply", "AccMemEnbl_B_RqDrv", "FdaMem_B_Stat",
|
||||||
|
], 0)
|
||||||
|
|
||||||
|
regular = fordcan.create_acc_ui_msg(
|
||||||
|
packer, CAN, CP, True, True, False, False, False, hud, stock_values)
|
||||||
|
hands_free = fordcan.create_acc_ui_msg(
|
||||||
|
packer, CAN, CP, True, True, False, False, False, hud, stock_values, True)
|
||||||
|
expected_regular = packer.make_can_msg("ACCDATA_3", 0, {"Tja_D_Stat": 2})
|
||||||
|
expected_hands_free = packer.make_can_msg("ACCDATA_3", 0, {"Tja_D_Stat": 7})
|
||||||
|
|
||||||
|
assert regular == expected_regular
|
||||||
|
assert hands_free == expected_hands_free
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from opendbc.car.lateral import AngleSteeringLimits
|
|||||||
from opendbc.car.structs import CarParams
|
from opendbc.car.structs import CarParams
|
||||||
from opendbc.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column
|
from opendbc.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column
|
||||||
from opendbc.car.fw_query_definitions import FwQueryConfig, LiveFwVersions, OfflineFwVersions, Request, StdQueries, p16
|
from opendbc.car.fw_query_definitions import FwQueryConfig, LiveFwVersions, OfflineFwVersions, Request, StdQueries, p16
|
||||||
|
from opendbc.car.vin import Vin, is_valid_vin
|
||||||
|
|
||||||
Ecu = CarParams.Ecu
|
Ecu = CarParams.Ecu
|
||||||
|
|
||||||
@@ -46,16 +47,22 @@ class CarControllerParams:
|
|||||||
class FordSafetyFlags(IntFlag):
|
class FordSafetyFlags(IntFlag):
|
||||||
LONG_CONTROL = 1
|
LONG_CONTROL = 1
|
||||||
CANFD = 2
|
CANFD = 2
|
||||||
|
LKA_STEERING = 4
|
||||||
|
|
||||||
|
|
||||||
class FordFlags(IntFlag):
|
class FordFlags(IntFlag):
|
||||||
# Static flags
|
# Static flags
|
||||||
CANFD = 1
|
CANFD = 1
|
||||||
|
LKA_STEERING = 2
|
||||||
|
ALT_STEER_ANGLE = 4
|
||||||
|
HEV_CLUSTER_DATA = 8
|
||||||
|
HEV_BATTERY_DATA = 16
|
||||||
|
|
||||||
|
|
||||||
class RADAR:
|
class RADAR:
|
||||||
DELPHI_ESR = 'ford_fusion_2018_adas'
|
DELPHI_ESR = 'ford_fusion_2018_adas'
|
||||||
DELPHI_MRR = 'FORD_CADS'
|
DELPHI_MRR = 'FORD_CADS'
|
||||||
|
STEER_ASSIST_DATA = 'ford_lincoln_base_pt'
|
||||||
|
|
||||||
|
|
||||||
class Footnote(Enum):
|
class Footnote(Enum):
|
||||||
@@ -85,6 +92,10 @@ class FordCarDocs(CarDocs):
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class FordPlatformConfig(PlatformConfig):
|
class FordPlatformConfig(PlatformConfig):
|
||||||
|
wmis: set[str] = field(default_factory=set)
|
||||||
|
vds_codes: set[str] = field(default_factory=set)
|
||||||
|
years: set[str] = field(default_factory=set)
|
||||||
|
|
||||||
dbc_dict: DbcDict = field(default_factory=lambda: {
|
dbc_dict: DbcDict = field(default_factory=lambda: {
|
||||||
Bus.pt: 'ford_lincoln_base_pt',
|
Bus.pt: 'ford_lincoln_base_pt',
|
||||||
Bus.radar: RADAR.DELPHI_MRR,
|
Bus.radar: RADAR.DELPHI_MRR,
|
||||||
@@ -104,6 +115,7 @@ class FordPlatformConfig(PlatformConfig):
|
|||||||
class FordCANFDPlatformConfig(FordPlatformConfig):
|
class FordCANFDPlatformConfig(FordPlatformConfig):
|
||||||
dbc_dict: DbcDict = field(default_factory=lambda: {
|
dbc_dict: DbcDict = field(default_factory=lambda: {
|
||||||
Bus.pt: 'ford_lincoln_base_pt',
|
Bus.pt: 'ford_lincoln_base_pt',
|
||||||
|
Bus.radar: RADAR.STEER_ASSIST_DATA,
|
||||||
})
|
})
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
@@ -112,18 +124,34 @@ class FordCANFDPlatformConfig(FordPlatformConfig):
|
|||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class FordF150LightningPlatform(FordCANFDPlatformConfig):
|
class FordLKASteeringPlatformConfig(FordPlatformConfig):
|
||||||
def init(self):
|
def init(self):
|
||||||
super().init()
|
super().init()
|
||||||
|
self.flags |= FordFlags.LKA_STEERING
|
||||||
|
|
||||||
# Don't show in docs until this issue is resolved. See https://github.com/commaai/openpilot/issues/30302
|
|
||||||
self.car_docs = []
|
@dataclass
|
||||||
|
class FordF150LightningPlatform(FordCANFDPlatformConfig):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
MY_2020, MY_2021, MY_2022, MY_2023, MY_2024, MY_2025 = 'L', 'M', 'N', 'P', 'R', 'S'
|
||||||
|
F150_VDS_CODES = {'F1C', 'F1E', 'W1C', 'W1E', 'X1C', 'X1E', 'W1R', 'W1P', 'W1S', 'W1T'}
|
||||||
|
F150_ELECTRIC_CODES = {'L', 'V'}
|
||||||
|
MACH_E_VDS_CODES = {'K1R', 'K1S', 'K2S', 'K3R', 'K3S', 'K4S'}
|
||||||
|
|
||||||
|
|
||||||
class CAR(Platforms):
|
class CAR(Platforms):
|
||||||
FORD_BRONCO_SPORT_MK1 = FordPlatformConfig(
|
FORD_BRONCO_SPORT_MK1 = FordPlatformConfig(
|
||||||
[FordCarDocs("Ford Bronco Sport 2021-24")],
|
[FordCarDocs("Ford Bronco Sport 2021-24")],
|
||||||
CarSpecs(mass=1625, wheelbase=2.67, steerRatio=17.7),
|
CarSpecs(mass=1625, wheelbase=2.67, steerRatio=17.7),
|
||||||
|
wmis={'3FM'}, vds_codes={'CR9'}, years={MY_2021, MY_2022, MY_2023, MY_2024},
|
||||||
|
)
|
||||||
|
FORD_EDGE_MK2 = FordPlatformConfig(
|
||||||
|
[FordCarDocs("Ford Edge 2022")],
|
||||||
|
CarSpecs(mass=1933, wheelbase=2.824, steerRatio=15.3),
|
||||||
|
flags=FordFlags.ALT_STEER_ANGLE,
|
||||||
|
wmis={'2FM'}, vds_codes={'PK4'}, years={MY_2022},
|
||||||
)
|
)
|
||||||
FORD_ESCAPE_MK4 = FordPlatformConfig(
|
FORD_ESCAPE_MK4 = FordPlatformConfig(
|
||||||
[
|
[
|
||||||
@@ -131,6 +159,7 @@ class CAR(Platforms):
|
|||||||
FordCarDocs("Ford Kuga 2020-23", "Adaptive Cruise Control with Lane Centering", hybrid=True, plug_in_hybrid=True),
|
FordCarDocs("Ford Kuga 2020-23", "Adaptive Cruise Control with Lane Centering", hybrid=True, plug_in_hybrid=True),
|
||||||
],
|
],
|
||||||
CarSpecs(mass=1750, wheelbase=2.71, steerRatio=16.7),
|
CarSpecs(mass=1750, wheelbase=2.71, steerRatio=16.7),
|
||||||
|
wmis={'1FM'}, vds_codes={'CU0', 'CU9'}, years={MY_2020, MY_2021, MY_2022},
|
||||||
)
|
)
|
||||||
FORD_ESCAPE_MK4_5 = FordCANFDPlatformConfig(
|
FORD_ESCAPE_MK4_5 = FordCANFDPlatformConfig(
|
||||||
[
|
[
|
||||||
@@ -139,6 +168,7 @@ class CAR(Platforms):
|
|||||||
FordCarDocs("Ford Kuga Plug-in Hybrid 2024", "All"),
|
FordCarDocs("Ford Kuga Plug-in Hybrid 2024", "All"),
|
||||||
],
|
],
|
||||||
CarSpecs(mass=1750, wheelbase=2.71, steerRatio=16.7),
|
CarSpecs(mass=1750, wheelbase=2.71, steerRatio=16.7),
|
||||||
|
wmis={'1FM'}, vds_codes={'CU0', 'CU9'}, years={MY_2023, MY_2024},
|
||||||
)
|
)
|
||||||
FORD_EXPLORER_MK6 = FordPlatformConfig(
|
FORD_EXPLORER_MK6 = FordPlatformConfig(
|
||||||
[
|
[
|
||||||
@@ -146,37 +176,53 @@ class CAR(Platforms):
|
|||||||
FordCarDocs("Lincoln Aviator 2020-24", "Co-Pilot360 Plus", plug_in_hybrid=True), # Hybrid: Grand Touring only
|
FordCarDocs("Lincoln Aviator 2020-24", "Co-Pilot360 Plus", plug_in_hybrid=True), # Hybrid: Grand Touring only
|
||||||
],
|
],
|
||||||
CarSpecs(mass=2050, wheelbase=3.025, steerRatio=16.8),
|
CarSpecs(mass=2050, wheelbase=3.025, steerRatio=16.8),
|
||||||
|
wmis={'1FM', '5LM'}, vds_codes={'5K7', '5K8', '5J7'},
|
||||||
|
years={MY_2020, MY_2021, MY_2022, MY_2023, MY_2024},
|
||||||
)
|
)
|
||||||
FORD_EXPEDITION_MK4 = FordCANFDPlatformConfig(
|
FORD_EXPEDITION_MK4 = FordCANFDPlatformConfig(
|
||||||
[FordCarDocs("Ford Expedition 2022-24", "Co-Pilot360 Assist 2.0", hybrid=False)],
|
[FordCarDocs("Ford Expedition 2022-24", "Co-Pilot360 Assist 2.0", hybrid=False)],
|
||||||
CarSpecs(mass=2000, wheelbase=3.69, steerRatio=17.0),
|
CarSpecs(mass=2000, wheelbase=3.69, steerRatio=17.0),
|
||||||
|
wmis={'1FM'}, vds_codes={'JU1', 'JU2', 'JK1'}, years={MY_2022, MY_2023, MY_2024},
|
||||||
)
|
)
|
||||||
FORD_F_150_MK14 = FordCANFDPlatformConfig(
|
FORD_F_150_MK14 = FordCANFDPlatformConfig(
|
||||||
[FordCarDocs("Ford F-150 2021-23", "Co-Pilot360 Assist 2.0", hybrid=True)],
|
[FordCarDocs("Ford F-150 2021-23", "Co-Pilot360 Assist 2.0", hybrid=True)],
|
||||||
CarSpecs(mass=2000, wheelbase=3.69, steerRatio=17.0),
|
CarSpecs(mass=3334, wheelbase=3.99, steerRatio=17.0),
|
||||||
|
wmis={'1FT'}, vds_codes=F150_VDS_CODES, years={MY_2021, MY_2022, MY_2023},
|
||||||
)
|
)
|
||||||
FORD_F_150_LIGHTNING_MK1 = FordF150LightningPlatform(
|
FORD_F_150_LIGHTNING_MK1 = FordF150LightningPlatform(
|
||||||
[FordCarDocs("Ford F-150 Lightning 2022-23", "Co-Pilot360 Assist 2.0")],
|
[FordCarDocs("Ford F-150 Lightning 2022-25", "Co-Pilot360 Assist 2.0")],
|
||||||
CarSpecs(mass=2948, wheelbase=3.70, steerRatio=16.9),
|
CarSpecs(mass=2948, wheelbase=3.70, steerRatio=16.9),
|
||||||
|
wmis={'1FT'}, vds_codes=F150_VDS_CODES, years={MY_2022, MY_2023, MY_2024, MY_2025},
|
||||||
)
|
)
|
||||||
FORD_FOCUS_MK4 = FordPlatformConfig(
|
FORD_FOCUS_MK4 = FordPlatformConfig(
|
||||||
[FordCarDocs("Ford Focus 2018", "Adaptive Cruise Control with Lane Centering", footnotes=[Footnote.FOCUS], hybrid=True)], # mHEV only
|
[FordCarDocs("Ford Focus 2018-22", "Adaptive Cruise Control with Lane Centering", footnotes=[Footnote.FOCUS], hybrid=True)], # mHEV only
|
||||||
CarSpecs(mass=1350, wheelbase=2.7, steerRatio=15.0),
|
CarSpecs(mass=1350, wheelbase=2.7, steerRatio=15.0),
|
||||||
)
|
)
|
||||||
|
FORD_MONDEO_MK5 = FordCANFDPlatformConfig(
|
||||||
|
[FordCarDocs("Ford Mondeo 2014-22", "Adaptive Cruise Control with Lane Centering")],
|
||||||
|
CarSpecs(mass=1550, wheelbase=2.85, steerRatio=14.8),
|
||||||
|
)
|
||||||
FORD_MAVERICK_MK1 = FordPlatformConfig(
|
FORD_MAVERICK_MK1 = FordPlatformConfig(
|
||||||
[
|
[
|
||||||
FordCarDocs("Ford Maverick 2022", "LARIAT Luxury", hybrid=True),
|
FordCarDocs("Ford Maverick 2022", "LARIAT Luxury", hybrid=True),
|
||||||
FordCarDocs("Ford Maverick 2023-24", "Co-Pilot360 Assist", hybrid=True),
|
FordCarDocs("Ford Maverick 2023-24", "Co-Pilot360 Assist", hybrid=True),
|
||||||
],
|
],
|
||||||
CarSpecs(mass=1650, wheelbase=3.076, steerRatio=17.0),
|
CarSpecs(mass=1650, wheelbase=3.076, steerRatio=17.0),
|
||||||
|
wmis={'3FT'}, vds_codes={'TW8'}, years={MY_2022, MY_2023, MY_2024},
|
||||||
)
|
)
|
||||||
FORD_MUSTANG_MACH_E_MK1 = FordCANFDPlatformConfig(
|
FORD_MUSTANG_MACH_E_MK1 = FordCANFDPlatformConfig(
|
||||||
[FordCarDocs("Ford Mustang Mach-E 2021-24", "All", setup_video="https://www.youtube.com/watch?v=AR4_eTF3b_A")],
|
[FordCarDocs("Ford Mustang Mach-E 2021-24", "All", setup_video="https://www.youtube.com/watch?v=AR4_eTF3b_A")],
|
||||||
CarSpecs(mass=2200, wheelbase=2.984, steerRatio=17.0), # TODO: check steer ratio
|
CarSpecs(mass=2200, wheelbase=2.984, steerRatio=17.0), # TODO: check steer ratio
|
||||||
|
wmis={'3FM'}, vds_codes=MACH_E_VDS_CODES, years={MY_2021, MY_2022, MY_2023, MY_2024},
|
||||||
)
|
)
|
||||||
FORD_RANGER_MK2 = FordCANFDPlatformConfig(
|
FORD_RANGER_MK2 = FordCANFDPlatformConfig(
|
||||||
[FordCarDocs("Ford Ranger 2024", "Adaptive Cruise Control with Lane Centering", setup_video="https://www.youtube.com/watch?v=2oJlXCKYOy0")],
|
[FordCarDocs("Ford Ranger 2024", "Adaptive Cruise Control with Lane Centering", setup_video="https://www.youtube.com/watch?v=2oJlXCKYOy0")],
|
||||||
CarSpecs(mass=2000, wheelbase=3.27, steerRatio=17.0),
|
CarSpecs(mass=2000, wheelbase=3.27, steerRatio=17.0),
|
||||||
|
wmis={'1FT'}, vds_codes={'ER4'}, years={MY_2024},
|
||||||
|
)
|
||||||
|
FORD_TRANSIT_MK5 = FordLKASteeringPlatformConfig(
|
||||||
|
[FordCarDocs("Ford Transit 2025", "Co-Pilot360 Assist+")],
|
||||||
|
CarSpecs(mass=2068, wheelbase=3.302, steerRatio=16.7),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -244,7 +290,25 @@ def match_fw_to_car_fuzzy(live_fw_versions: LiveFwVersions, vin: str, offline_fw
|
|||||||
if valid_expected_ecus.issubset(valid_found_ecus):
|
if valid_expected_ecus.issubset(valid_found_ecus):
|
||||||
candidates.add(candidate)
|
candidates.add(candidate)
|
||||||
|
|
||||||
return candidates
|
return candidates or match_vin_to_car(vin)
|
||||||
|
|
||||||
|
|
||||||
|
def match_vin_to_car(vin: str) -> set[str]:
|
||||||
|
if not is_valid_vin(vin):
|
||||||
|
return set()
|
||||||
|
|
||||||
|
vin_obj = Vin(vin)
|
||||||
|
vds = vin[3:7]
|
||||||
|
model_year = vin[9]
|
||||||
|
candidates = {platform for platform in CAR if vin_obj.wmi in platform.config.wmis and
|
||||||
|
model_year in platform.config.years and
|
||||||
|
any(code in vds for code in platform.config.vds_codes)}
|
||||||
|
|
||||||
|
if {CAR.FORD_F_150_MK14, CAR.FORD_F_150_LIGHTNING_MK1} & candidates:
|
||||||
|
electric = vin[7] in F150_ELECTRIC_CODES
|
||||||
|
candidates.discard(CAR.FORD_F_150_MK14 if electric else CAR.FORD_F_150_LIGHTNING_MK1)
|
||||||
|
|
||||||
|
return {str(candidate) for candidate in candidates}
|
||||||
|
|
||||||
|
|
||||||
# All of these ECUs must be present and are expected to have platform codes we can match
|
# All of these ECUs must be present and are expected to have platform codes we can match
|
||||||
@@ -253,10 +317,10 @@ PLATFORM_CODE_ECUS = (Ecu.abs, Ecu.fwdCamera, Ecu.fwdRadar, Ecu.eps)
|
|||||||
DATA_IDENTIFIER_FORD_ASBUILT = 0xDE00
|
DATA_IDENTIFIER_FORD_ASBUILT = 0xDE00
|
||||||
|
|
||||||
ASBUILT_BLOCKS: list[tuple[int, list]] = [
|
ASBUILT_BLOCKS: list[tuple[int, list]] = [
|
||||||
(1, [Ecu.debug, Ecu.fwdCamera, Ecu.eps]),
|
(1, [Ecu.debug, Ecu.fwdCamera, Ecu.eps, Ecu.hud]),
|
||||||
(2, [Ecu.abs, Ecu.debug, Ecu.eps]),
|
(2, [Ecu.abs, Ecu.debug, Ecu.eps, Ecu.hud]),
|
||||||
(3, [Ecu.abs, Ecu.debug, Ecu.eps]),
|
(3, [Ecu.abs, Ecu.debug, Ecu.eps, Ecu.hud]),
|
||||||
(4, [Ecu.debug, Ecu.fwdCamera]),
|
(4, [Ecu.debug, Ecu.fwdCamera, Ecu.hud]),
|
||||||
(5, [Ecu.debug]),
|
(5, [Ecu.debug]),
|
||||||
(6, [Ecu.debug]),
|
(6, [Ecu.debug]),
|
||||||
(7, [Ecu.debug]),
|
(7, [Ecu.debug]),
|
||||||
@@ -284,13 +348,13 @@ FW_QUERY_CONFIG = FwQueryConfig(
|
|||||||
Request(
|
Request(
|
||||||
[StdQueries.TESTER_PRESENT_REQUEST, StdQueries.MANUFACTURER_SOFTWARE_VERSION_REQUEST],
|
[StdQueries.TESTER_PRESENT_REQUEST, StdQueries.MANUFACTURER_SOFTWARE_VERSION_REQUEST],
|
||||||
[StdQueries.TESTER_PRESENT_RESPONSE, StdQueries.MANUFACTURER_SOFTWARE_VERSION_RESPONSE],
|
[StdQueries.TESTER_PRESENT_RESPONSE, StdQueries.MANUFACTURER_SOFTWARE_VERSION_RESPONSE],
|
||||||
whitelist_ecus=[Ecu.abs, Ecu.debug, Ecu.engine, Ecu.eps, Ecu.fwdCamera, Ecu.fwdRadar, Ecu.shiftByWire],
|
whitelist_ecus=[Ecu.abs, Ecu.debug, Ecu.engine, Ecu.eps, Ecu.fwdCamera, Ecu.fwdRadar, Ecu.shiftByWire, Ecu.hud],
|
||||||
logging=True,
|
logging=True,
|
||||||
),
|
),
|
||||||
Request(
|
Request(
|
||||||
[StdQueries.TESTER_PRESENT_REQUEST, StdQueries.MANUFACTURER_SOFTWARE_VERSION_REQUEST],
|
[StdQueries.TESTER_PRESENT_REQUEST, StdQueries.MANUFACTURER_SOFTWARE_VERSION_REQUEST],
|
||||||
[StdQueries.TESTER_PRESENT_RESPONSE, StdQueries.MANUFACTURER_SOFTWARE_VERSION_RESPONSE],
|
[StdQueries.TESTER_PRESENT_RESPONSE, StdQueries.MANUFACTURER_SOFTWARE_VERSION_RESPONSE],
|
||||||
whitelist_ecus=[Ecu.abs, Ecu.debug, Ecu.engine, Ecu.eps, Ecu.fwdCamera, Ecu.fwdRadar, Ecu.shiftByWire],
|
whitelist_ecus=[Ecu.abs, Ecu.debug, Ecu.engine, Ecu.eps, Ecu.fwdCamera, Ecu.fwdRadar, Ecu.shiftByWire, Ecu.hud],
|
||||||
bus=0,
|
bus=0,
|
||||||
auxiliary=True,
|
auxiliary=True,
|
||||||
),
|
),
|
||||||
@@ -307,7 +371,9 @@ FW_QUERY_CONFIG = FwQueryConfig(
|
|||||||
# Note: We are unlikely to get a response from behind the gateway
|
# Note: We are unlikely to get a response from behind the gateway
|
||||||
(Ecu.shiftByWire, 0x732, None), # Gear Shift Module
|
(Ecu.shiftByWire, 0x732, None), # Gear Shift Module
|
||||||
(Ecu.debug, 0x7d0, None), # Accessory Protocol Interface Module
|
(Ecu.debug, 0x7d0, None), # Accessory Protocol Interface Module
|
||||||
|
(Ecu.hud, 0x720, None), # Instrument Cluster Module
|
||||||
],
|
],
|
||||||
|
non_essential_ecus={Ecu.eps: [CAR.FORD_F_150_LIGHTNING_MK1, CAR.FORD_EXPEDITION_MK4]},
|
||||||
# Custom fuzzy fingerprinting function using platform and model year hints
|
# Custom fuzzy fingerprinting function using platform and model year hints
|
||||||
match_fw_to_car_fuzzy=match_fw_to_car_fuzzy,
|
match_fw_to_car_fuzzy=match_fw_to_car_fuzzy,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ class Request:
|
|||||||
@dataclass
|
@dataclass
|
||||||
class FwQueryConfig:
|
class FwQueryConfig:
|
||||||
requests: list[Request]
|
requests: list[Request]
|
||||||
|
non_tester_present_ecus: list[Ecu] = field(default_factory=list)
|
||||||
# TODO: make this automatic and remove hardcoded lists, or do fingerprinting with ecus
|
# TODO: make this automatic and remove hardcoded lists, or do fingerprinting with ecus
|
||||||
# Overrides and removes from essential ecus for specific models and ecus (exact matching)
|
# Overrides and removes from essential ecus for specific models and ecus (exact matching)
|
||||||
non_essential_ecus: dict[Ecu, list[str]] = field(default_factory=dict)
|
non_essential_ecus: dict[Ecu, list[str]] = field(default_factory=dict)
|
||||||
@@ -109,8 +110,13 @@ class FwQueryConfig:
|
|||||||
# Function a brand can implement to provide better fuzzy matching. Takes in FW versions and VIN,
|
# Function a brand can implement to provide better fuzzy matching. Takes in FW versions and VIN,
|
||||||
# returns set of candidates. Only will match if one candidate is returned
|
# returns set of candidates. Only will match if one candidate is returned
|
||||||
match_fw_to_car_fuzzy: Callable[[LiveFwVersions, str, OfflineFwVersions], set[str]] | None = None
|
match_fw_to_car_fuzzy: Callable[[LiveFwVersions, str, OfflineFwVersions], set[str]] | None = None
|
||||||
|
# Platforms whose shared firmware must be disambiguated by the brand fuzzy matcher.
|
||||||
|
fuzzy_only_platforms: set[str] = field(default_factory=set)
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
|
assert not self.fuzzy_only_platforms or self.match_fw_to_car_fuzzy is not None, \
|
||||||
|
"Fuzzy-only platforms require a brand fuzzy matcher"
|
||||||
|
|
||||||
# Asserts that a request exists if extra ecus are used
|
# Asserts that a request exists if extra ecus are used
|
||||||
if len(self.extra_ecus):
|
if len(self.extra_ecus):
|
||||||
assert len(self.requests), "Must define a request with extra ecus"
|
assert len(self.requests), "Must define a request with extra ecus"
|
||||||
|
|||||||
@@ -111,7 +111,8 @@ def match_fw_to_car_exact(live_fw_versions: LiveFwVersions, match_brand: str = N
|
|||||||
|
|
||||||
invalid = set()
|
invalid = set()
|
||||||
candidates = {c: f for c, f in FW_VERSIONS.items() if
|
candidates = {c: f for c, f in FW_VERSIONS.items() if
|
||||||
is_brand(MODEL_TO_BRAND[c], match_brand)}
|
is_brand(MODEL_TO_BRAND[c], match_brand) and
|
||||||
|
c not in FW_QUERY_CONFIGS[MODEL_TO_BRAND[c]].fuzzy_only_platforms}
|
||||||
|
|
||||||
for candidate, fws in candidates.items():
|
for candidate, fws in candidates.items():
|
||||||
config = FW_QUERY_CONFIGS[MODEL_TO_BRAND[candidate]]
|
config = FW_QUERY_CONFIGS[MODEL_TO_BRAND[candidate]]
|
||||||
@@ -181,6 +182,9 @@ def get_present_ecus(can_recv: CanRecvCallable, can_send: CanSendCallable, set_o
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
for ecu_type, addr, sub_addr in config.get_all_ecus(VERSIONS[brand]):
|
for ecu_type, addr, sub_addr in config.get_all_ecus(VERSIONS[brand]):
|
||||||
|
if ecu_type in config.non_tester_present_ecus:
|
||||||
|
continue
|
||||||
|
|
||||||
# Only query ecus in whitelist if whitelist is not empty
|
# Only query ecus in whitelist if whitelist is not empty
|
||||||
if len(r.whitelist_ecus) == 0 or ecu_type in r.whitelist_ecus:
|
if len(r.whitelist_ecus) == 0 or ecu_type in r.whitelist_ecus:
|
||||||
a = (addr, sub_addr, r.bus)
|
a = (addr, sub_addr, r.bus)
|
||||||
@@ -216,6 +220,9 @@ def get_brand_ecu_matches(ecu_rx_addrs: set[EcuAddrBusType]) -> dict[str, list[b
|
|||||||
# Since we can't know what request an ecu responded to, add matches for all possible rx offsets
|
# Since we can't know what request an ecu responded to, add matches for all possible rx offsets
|
||||||
for brand, config, r in REQUESTS:
|
for brand, config, r in REQUESTS:
|
||||||
for ecu in config.get_all_ecus(VERSIONS[brand]):
|
for ecu in config.get_all_ecus(VERSIONS[brand]):
|
||||||
|
if ecu[0] in config.non_tester_present_ecus:
|
||||||
|
continue
|
||||||
|
|
||||||
if len(r.whitelist_ecus) == 0 or ecu[0] in r.whitelist_ecus:
|
if len(r.whitelist_ecus) == 0 or ecu[0] in r.whitelist_ecus:
|
||||||
brand_rx_addrs[brand].add((uds.get_rx_addr_for_tx_addr(ecu[1], r.rx_offset), ecu[2]))
|
brand_rx_addrs[brand].add((uds.get_rx_addr_for_tx_addr(ecu[1], r.rx_offset), ecu[2]))
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from opendbc.car.lateral import apply_driver_steer_torque_limits
|
|||||||
from opendbc.car.gm import gmcan
|
from opendbc.car.gm import gmcan
|
||||||
from opendbc.car.common.conversions import Conversions as CV
|
from opendbc.car.common.conversions import Conversions as CV
|
||||||
from opendbc.car.gm.values import (
|
from opendbc.car.gm.values import (
|
||||||
ASCM_INT, CAR, CC_ONLY_CAR, CC_REGEN_PADDLE_CAR, DBC, EV_CAR, SDGM_CAR, AccState, CanBus, CarControllerParams,
|
ASCM_INT, CAMERA_ACC_CAR, CAR, CC_ONLY_CAR, CC_REGEN_PADDLE_CAR, DBC, EV_CAR, SDGM_CAR, AccState, CanBus, CarControllerParams,
|
||||||
CruiseButtons, GMFlags, GMSafetyFlags,
|
CruiseButtons, GMFlags, GMSafetyFlags,
|
||||||
)
|
)
|
||||||
from opendbc.car.interfaces import CarControllerBase
|
from opendbc.car.interfaces import CarControllerBase
|
||||||
@@ -66,6 +66,19 @@ TRUCK_LONG_SMOOTH_CARS = {
|
|||||||
CAR.CHEVROLET_SILVERADO,
|
CAR.CHEVROLET_SILVERADO,
|
||||||
CAR.CHEVROLET_SILVERADO_CC,
|
CAR.CHEVROLET_SILVERADO_CC,
|
||||||
}
|
}
|
||||||
|
TRUCK_FRICTION_BRAKE_ENGAGE = 40
|
||||||
|
TRUCK_FRICTION_BRAKE_RELEASE = 8
|
||||||
|
TRUCK_FRICTION_BRAKE_IMMEDIATE_ACCEL = -0.85
|
||||||
|
TRUCK_FOLLOW_MICRO_ACCEL_MAX = 0.55
|
||||||
|
TRUCK_FOLLOW_MICRO_ACCEL_MIN = -0.10
|
||||||
|
TRUCK_FOLLOW_MICRO_ACCEL_SLEW = 1.5
|
||||||
|
ACC_DASHBOARD_ZERO_RESERVED_CARS = {
|
||||||
|
CAR.CHEVROLET_BLAZER,
|
||||||
|
CAR.CHEVROLET_EQUINOX,
|
||||||
|
CAR.CHEVROLET_SILVERADO,
|
||||||
|
CAR.CHEVROLET_TRAILBLAZER,
|
||||||
|
CAR.CHEVROLET_TRAX,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_stock_cc_active_for_cancel(CP, CS):
|
def get_stock_cc_active_for_cancel(CP, CS):
|
||||||
@@ -120,6 +133,10 @@ def get_acc_dashboard_status_active(CP, CC):
|
|||||||
return CP.carFingerprint == CAR.BUICK_LACROSSE_ASCM and CC.latActive
|
return CP.carFingerprint == CAR.BUICK_LACROSSE_ASCM and CC.latActive
|
||||||
|
|
||||||
|
|
||||||
|
def get_acc_dashboard_always_one(CP):
|
||||||
|
return 0 if CP.carFingerprint in ACC_DASHBOARD_ZERO_RESERVED_CARS else 1
|
||||||
|
|
||||||
|
|
||||||
def get_acc_dashboard_fcw_alert(hud_alert, CS):
|
def get_acc_dashboard_fcw_alert(hud_alert, CS):
|
||||||
if hud_alert == VisualAlert.fcw:
|
if hud_alert == VisualAlert.fcw:
|
||||||
return 0x3
|
return 0x3
|
||||||
@@ -183,16 +200,31 @@ def should_send_adas_status(CP, is_kaofui_car):
|
|||||||
return CP.networkLocation != NetworkLocation.fwdCamera and CP.carFingerprint not in SDGM_CAR
|
return CP.networkLocation != NetworkLocation.fwdCamera and CP.carFingerprint not in SDGM_CAR
|
||||||
|
|
||||||
|
|
||||||
|
def should_send_acc_2cd(CP):
|
||||||
|
return (
|
||||||
|
CP.networkLocation == NetworkLocation.fwdCamera and
|
||||||
|
CP.carFingerprint in CAMERA_ACC_CAR and
|
||||||
|
CP.carFingerprint not in (CC_ONLY_CAR | SDGM_CAR) and
|
||||||
|
not bool(getattr(CP, "flags", 0) & GMFlags.NO_CAMERA.value)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_testing_ground_1_brake_switch_bias(v_ego: float) -> int:
|
def get_testing_ground_1_brake_switch_bias(v_ego: float) -> int:
|
||||||
return int(round(np.interp(v_ego, [0.0, 6.0, 15.0, 30.0], [40.0, 85.0, 130.0, 170.0])))
|
return int(round(np.interp(v_ego, [0.0, 6.0, 15.0, 30.0], [40.0, 85.0, 130.0, 170.0])))
|
||||||
|
|
||||||
|
|
||||||
def shape_truck_positive_accel(accel: float, v_ego: float, enabled: bool) -> float:
|
def shape_truck_positive_accel(accel: float, v_ego: float, enabled: bool,
|
||||||
|
lead_visible: bool = False, set_speed_error: float = 0.0) -> float:
|
||||||
if not enabled or accel <= 0.0 or v_ego < 12.0:
|
if not enabled or accel <= 0.0 or v_ego < 12.0:
|
||||||
return accel
|
return accel
|
||||||
|
|
||||||
low_scale = float(np.interp(v_ego, [12.0, 18.0, 25.0, 35.0], [0.95, 0.88, 0.82, 0.76]))
|
low_scale = float(np.interp(v_ego, [12.0, 18.0, 25.0, 35.0], [0.93, 0.84, 0.76, 0.76]))
|
||||||
mid_scale = float(np.interp(v_ego, [12.0, 18.0, 25.0, 35.0], [0.98, 0.94, 0.89, 0.84]))
|
mid_scale = float(np.interp(v_ego, [12.0, 18.0, 25.0, 35.0], [0.97, 0.91, 0.85, 0.85]))
|
||||||
|
|
||||||
|
if lead_visible and set_speed_error > 0.0:
|
||||||
|
follow_relief = float(np.interp(set_speed_error, [0.0, 1.0, 2.5, 4.0, 6.0], [0.0, 0.04, 0.10, 0.24, 0.42]))
|
||||||
|
low_scale += (1.0 - low_scale) * follow_relief
|
||||||
|
mid_scale += (1.0 - mid_scale) * follow_relief
|
||||||
|
|
||||||
if accel <= 0.12:
|
if accel <= 0.12:
|
||||||
return accel * low_scale
|
return accel * low_scale
|
||||||
@@ -203,6 +235,48 @@ def shape_truck_positive_accel(accel: float, v_ego: float, enabled: bool) -> flo
|
|||||||
return accel
|
return accel
|
||||||
|
|
||||||
|
|
||||||
|
def smooth_truck_follow_accel(accel: float, previous_accel: float, v_ego: float,
|
||||||
|
enabled: bool, lead_visible: bool, stopping: bool) -> float:
|
||||||
|
if (
|
||||||
|
not enabled or not lead_visible or stopping or v_ego < 25.0 or
|
||||||
|
accel > TRUCK_FOLLOW_MICRO_ACCEL_MAX or accel < TRUCK_FOLLOW_MICRO_ACCEL_MIN or
|
||||||
|
previous_accel > TRUCK_FOLLOW_MICRO_ACCEL_MAX or previous_accel < TRUCK_FOLLOW_MICRO_ACCEL_MIN
|
||||||
|
):
|
||||||
|
return accel
|
||||||
|
|
||||||
|
max_delta = TRUCK_FOLLOW_MICRO_ACCEL_SLEW * DT_CTRL * 4
|
||||||
|
return previous_accel + float(np.clip(accel - previous_accel, -max_delta, max_delta))
|
||||||
|
|
||||||
|
|
||||||
|
def shape_truck_pitch_accel(pitch_accel: float, v_ego: float, enabled: bool) -> float:
|
||||||
|
if not enabled:
|
||||||
|
return pitch_accel
|
||||||
|
|
||||||
|
scale = float(np.interp(v_ego, [8.0, 15.0, 25.0, 35.0], [0.60, 0.45, 0.30, 0.25]))
|
||||||
|
return pitch_accel * scale
|
||||||
|
|
||||||
|
|
||||||
|
def shape_truck_friction_brake(apply_brake: int, accel_cmd: float, stopping: bool, active: bool) -> tuple[int, bool]:
|
||||||
|
if apply_brake <= 0:
|
||||||
|
return 0, False
|
||||||
|
|
||||||
|
# Preserve full brake response for stop control and meaningful deceleration.
|
||||||
|
if stopping or accel_cmd <= TRUCK_FRICTION_BRAKE_IMMEDIATE_ACCEL:
|
||||||
|
return apply_brake, True
|
||||||
|
|
||||||
|
if active:
|
||||||
|
if apply_brake <= TRUCK_FRICTION_BRAKE_RELEASE:
|
||||||
|
return 0, False
|
||||||
|
return apply_brake, True
|
||||||
|
|
||||||
|
if apply_brake >= TRUCK_FRICTION_BRAKE_ENGAGE:
|
||||||
|
return apply_brake, True
|
||||||
|
|
||||||
|
# Keep tiny corrections in the continuous gas/regen torque path. Switching
|
||||||
|
# to friction also forces max regen, which makes a small request perceptible.
|
||||||
|
return 0, False
|
||||||
|
|
||||||
|
|
||||||
def get_lka_steering_cmd_counter(next_counter: int, CS) -> int:
|
def get_lka_steering_cmd_counter(next_counter: int, CS) -> int:
|
||||||
if getattr(CS, "loopback_lka_steering_cmd_updated", False):
|
if getattr(CS, "loopback_lka_steering_cmd_updated", False):
|
||||||
return (getattr(CS, "loopback_lka_steering_cmd_counter", next_counter) + 1) % 4
|
return (getattr(CS, "loopback_lka_steering_cmd_counter", next_counter) + 1) % 4
|
||||||
@@ -222,6 +296,7 @@ def supports_volt_auto_hold(CP, auto_hold_enabled: bool):
|
|||||||
stock_hold_safety_ready = bool(safety_param & GMSafetyFlags.FLAG_GM_PANDA_PADDLE_SCHED.value)
|
stock_hold_safety_ready = bool(safety_param & GMSafetyFlags.FLAG_GM_PANDA_PADDLE_SCHED.value)
|
||||||
return (
|
return (
|
||||||
auto_hold_enabled and
|
auto_hold_enabled and
|
||||||
|
getattr(CP, "openpilotLongitudinalControl", False) and
|
||||||
stock_hold_safety_ready and
|
stock_hold_safety_ready and
|
||||||
CP.carFingerprint in AUTO_HOLD_VOLT_CARS
|
CP.carFingerprint in AUTO_HOLD_VOLT_CARS
|
||||||
)
|
)
|
||||||
@@ -233,6 +308,7 @@ def supports_volt_one_pedal(CP, one_pedal_enabled: bool):
|
|||||||
stock_hold_safety_ready = bool(safety_param & GMSafetyFlags.FLAG_GM_PANDA_PADDLE_SCHED.value)
|
stock_hold_safety_ready = bool(safety_param & GMSafetyFlags.FLAG_GM_PANDA_PADDLE_SCHED.value)
|
||||||
return (
|
return (
|
||||||
one_pedal_enabled and
|
one_pedal_enabled and
|
||||||
|
getattr(CP, "openpilotLongitudinalControl", False) and
|
||||||
stock_hold_safety_ready and
|
stock_hold_safety_ready and
|
||||||
getattr(CP, "transmissionType", None) == TransmissionType.direct and
|
getattr(CP, "transmissionType", None) == TransmissionType.direct and
|
||||||
CP.carFingerprint in AUTO_HOLD_VOLT_CARS
|
CP.carFingerprint in AUTO_HOLD_VOLT_CARS
|
||||||
@@ -305,6 +381,14 @@ def get_friction_brake_bus(CP):
|
|||||||
|
|
||||||
if CP.networkLocation == NetworkLocation.fwdCamera:
|
if CP.networkLocation == NetworkLocation.fwdCamera:
|
||||||
if CP.carFingerprint in SDGM_CAR:
|
if CP.carFingerprint in SDGM_CAR:
|
||||||
|
# cam-long: 0x315 goes where the panda whitelist allows it and the EBCM hears it
|
||||||
|
safety_cfg = getattr(CP, "safetyConfigs", ())
|
||||||
|
safety_param = safety_cfg[0].safetyParam if safety_cfg else 0
|
||||||
|
if safety_param & GMSafetyFlags.HW_CAM_LONG.value:
|
||||||
|
# SASCM relays 0x315 to the EBCM off its camera-bus (bus2) leg; bare SDGM uses the pt bus
|
||||||
|
if CP.flags & GMFlags.SASCM.value:
|
||||||
|
return CanBus.CAMERA
|
||||||
|
return CanBus.POWERTRAIN
|
||||||
return CanBus.CAMERA
|
return CanBus.CAMERA
|
||||||
return CanBus.POWERTRAIN
|
return CanBus.POWERTRAIN
|
||||||
|
|
||||||
@@ -419,6 +503,15 @@ class CarController(CarControllerBase):
|
|||||||
self.last_steer_frame = 0
|
self.last_steer_frame = 0
|
||||||
self.last_button_frame = 0
|
self.last_button_frame = 0
|
||||||
self.cancel_counter = 0
|
self.cancel_counter = 0
|
||||||
|
self.xt4_cc_button_burst_remaining = 0
|
||||||
|
self.xt4_cc_button_burst_button = CruiseButtons.INIT
|
||||||
|
self.xt4_cc_button_burst_last_counter = -1
|
||||||
|
self.xt4_cc_button_observed_counter = -1
|
||||||
|
self.xt4_cc_button_counter_frame = 0
|
||||||
|
self.gm_cc_last_direction_button = CruiseButtons.INIT
|
||||||
|
self.gm_cc_last_direction_frame = 0
|
||||||
|
self.gm_cc_pending_reverse_button = CruiseButtons.INIT
|
||||||
|
self.gm_cc_pending_reverse_frame = 0
|
||||||
|
|
||||||
self.lka_steering_cmd_counter = 0
|
self.lka_steering_cmd_counter = 0
|
||||||
self.lka_icon_status_last = (False, False)
|
self.lka_icon_status_last = (False, False)
|
||||||
@@ -479,6 +572,8 @@ class CarController(CarControllerBase):
|
|||||||
self.gm_auto_hold_enabled = False
|
self.gm_auto_hold_enabled = False
|
||||||
self.bolt_acc_pedal_friction_release_frames = 0
|
self.bolt_acc_pedal_friction_release_frames = 0
|
||||||
self.bolt_acc_pedal_friction_low_speed_active = False
|
self.bolt_acc_pedal_friction_low_speed_active = False
|
||||||
|
self.truck_friction_brake_active = False
|
||||||
|
self.truck_follow_accel = 0.0
|
||||||
|
|
||||||
def _reset_volt_one_pedal(self):
|
def _reset_volt_one_pedal(self):
|
||||||
self.volt_one_pedal_pid.reset()
|
self.volt_one_pedal_pid.reset()
|
||||||
@@ -869,6 +964,18 @@ class CarController(CarControllerBase):
|
|||||||
can_sends.append(gmcan.create_ecm_cruise_control_command(
|
can_sends.append(gmcan.create_ecm_cruise_control_command(
|
||||||
self.packer_pt, CanBus.POWERTRAIN, True, hud_v_cruise * CV.MS_TO_KPH))
|
self.packer_pt, CanBus.POWERTRAIN, True, hud_v_cruise * CV.MS_TO_KPH))
|
||||||
|
|
||||||
|
xt4_cc_button_spam = (
|
||||||
|
self.CP.carFingerprint == CAR.CADILLAC_XT4_CC and
|
||||||
|
should_send_cc_button_spam(self.CP, CC, CS)
|
||||||
|
)
|
||||||
|
if xt4_cc_button_spam:
|
||||||
|
can_sends.extend(gmcan.create_gm_cc_spam_command(self.packer_pt, self, CS, actuators, starpilot_toggles))
|
||||||
|
elif self.CP.carFingerprint == CAR.CADILLAC_XT4_CC:
|
||||||
|
self.xt4_cc_button_burst_remaining = 0
|
||||||
|
self.xt4_cc_button_burst_button = CruiseButtons.INIT
|
||||||
|
self.xt4_cc_button_burst_last_counter = -1
|
||||||
|
self.xt4_cc_button_observed_counter = -1
|
||||||
|
|
||||||
if self.CP.openpilotLongitudinalControl:
|
if self.CP.openpilotLongitudinalControl:
|
||||||
# Gas/regen, brakes, and UI commands - all at 25Hz
|
# Gas/regen, brakes, and UI commands - all at 25Hz
|
||||||
if self.frame % 4 == 0:
|
if self.frame % 4 == 0:
|
||||||
@@ -888,10 +995,12 @@ class CarController(CarControllerBase):
|
|||||||
self.regen_release_counter = 0
|
self.regen_release_counter = 0
|
||||||
self.regen_min_on_frames = 0
|
self.regen_min_on_frames = 0
|
||||||
self.regen_min_off_frames = 0
|
self.regen_min_off_frames = 0
|
||||||
|
self.truck_follow_accel = 0.0
|
||||||
elif should_use_fixed_stopping_brake(self.CP, near_stop, stopping, CC.cruiseControl.resume):
|
elif should_use_fixed_stopping_brake(self.CP, near_stop, stopping, CC.cruiseControl.resume):
|
||||||
stop_accel = getattr(starpilot_toggles, "stopAccel", self.CP.stopAccel)
|
stop_accel = getattr(starpilot_toggles, "stopAccel", self.CP.stopAccel)
|
||||||
self.apply_gas = self.params.INACTIVE_REGEN
|
self.apply_gas = self.params.INACTIVE_REGEN
|
||||||
self.apply_brake = int(min(-100 * stop_accel, self.params.MAX_BRAKE))
|
self.apply_brake = int(min(-100 * stop_accel, self.params.MAX_BRAKE))
|
||||||
|
self.truck_follow_accel = 0.0
|
||||||
else:
|
else:
|
||||||
long_pitch_enabled = bool(getattr(starpilot_toggles, "long_pitch", True))
|
long_pitch_enabled = bool(getattr(starpilot_toggles, "long_pitch", True))
|
||||||
pedal_long_path = bool(self.CP.enableGasInterceptorDEPRECATED and (self.CP.flags & GMFlags.PEDAL_LONG.value))
|
pedal_long_path = bool(self.CP.enableGasInterceptorDEPRECATED and (self.CP.flags & GMFlags.PEDAL_LONG.value))
|
||||||
@@ -932,16 +1041,34 @@ class CarController(CarControllerBase):
|
|||||||
if testing_ground.use_1:
|
if testing_ground.use_1:
|
||||||
accel_max = min(accel_max, np.interp(CS.out.vEgo, [0.0, 4.0, 12.0], [1.25, 1.6, self.params.ACCEL_MAX]))
|
accel_max = min(accel_max, np.interp(CS.out.vEgo, [0.0, 4.0, 12.0], [1.25, 1.6, self.params.ACCEL_MAX]))
|
||||||
|
|
||||||
accel_input = actuators.accel + accel_due_to_pitch
|
truck_long_smoothing = (
|
||||||
if (
|
|
||||||
getattr(starpilot_toggles, "truck_tuning", False) and
|
getattr(starpilot_toggles, "truck_tuning", False) and
|
||||||
self.CP.carFingerprint in TRUCK_LONG_SMOOTH_CARS and
|
self.CP.carFingerprint in TRUCK_LONG_SMOOTH_CARS and
|
||||||
getattr(self.CP, "transmissionType", None) == TransmissionType.automatic and
|
getattr(self.CP, "transmissionType", None) == TransmissionType.automatic and
|
||||||
not self.CP.enableGasInterceptorDEPRECATED
|
not self.CP.enableGasInterceptorDEPRECATED
|
||||||
):
|
)
|
||||||
accel_input = shape_truck_positive_accel(accel_input, CS.out.vEgo, True)
|
accel_due_to_pitch = shape_truck_pitch_accel(accel_due_to_pitch, CS.out.vEgo, truck_long_smoothing)
|
||||||
|
accel_input = actuators.accel + accel_due_to_pitch
|
||||||
|
if truck_long_smoothing:
|
||||||
|
accel_input = shape_truck_positive_accel(
|
||||||
|
accel_input,
|
||||||
|
CS.out.vEgo,
|
||||||
|
True,
|
||||||
|
lead_visible=CC.hudControl.leadVisible,
|
||||||
|
set_speed_error=max(CC.hudControl.setSpeed - CS.out.vEgo, 0.0),
|
||||||
|
)
|
||||||
|
|
||||||
accel_cmd = float(np.clip(accel_input, self.params.ACCEL_MIN, accel_max))
|
accel_cmd = float(np.clip(accel_input, self.params.ACCEL_MIN, accel_max))
|
||||||
|
if truck_long_smoothing:
|
||||||
|
accel_cmd = smooth_truck_follow_accel(
|
||||||
|
accel_cmd,
|
||||||
|
self.truck_follow_accel,
|
||||||
|
CS.out.vEgo,
|
||||||
|
True,
|
||||||
|
CC.hudControl.leadVisible,
|
||||||
|
stopping,
|
||||||
|
)
|
||||||
|
self.truck_follow_accel = accel_cmd
|
||||||
torque = self.tireRadius * ((self.mass * accel_cmd) + (0.5 * self.coeffDrag * self.frontalArea * self.airDensity * CS.out.vEgo ** 2))
|
torque = self.tireRadius * ((self.mass * accel_cmd) + (0.5 * self.coeffDrag * self.frontalArea * self.airDensity * CS.out.vEgo ** 2))
|
||||||
scaled_torque = torque + self.params.ZERO_GAS
|
scaled_torque = torque + self.params.ZERO_GAS
|
||||||
apply_gas_torque = np.clip(scaled_torque, self.params.MAX_ACC_REGEN, gas_max)
|
apply_gas_torque = np.clip(scaled_torque, self.params.MAX_ACC_REGEN, gas_max)
|
||||||
@@ -957,6 +1084,12 @@ class CarController(CarControllerBase):
|
|||||||
brake_accel = min((scaled_torque - brake_switch) / (self.tireRadius * self.mass), 0)
|
brake_accel = min((scaled_torque - brake_switch) / (self.tireRadius * self.mass), 0)
|
||||||
self.apply_gas = int(round(apply_gas_torque))
|
self.apply_gas = int(round(apply_gas_torque))
|
||||||
self.apply_brake = int(round(np.interp(brake_accel, self.params.BRAKE_LOOKUP_BP, self.params.BRAKE_LOOKUP_V)))
|
self.apply_brake = int(round(np.interp(brake_accel, self.params.BRAKE_LOOKUP_BP, self.params.BRAKE_LOOKUP_V)))
|
||||||
|
if truck_long_smoothing:
|
||||||
|
self.apply_brake, self.truck_friction_brake_active = shape_truck_friction_brake(
|
||||||
|
self.apply_brake, accel_cmd, stopping, self.truck_friction_brake_active,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.truck_friction_brake_active = False
|
||||||
if bolt_acc_pedal_friction_main_on:
|
if bolt_acc_pedal_friction_main_on:
|
||||||
if self.apply_brake > 0:
|
if self.apply_brake > 0:
|
||||||
full_brake_accel = min(
|
full_brake_accel = min(
|
||||||
@@ -1013,17 +1146,19 @@ class CarController(CarControllerBase):
|
|||||||
|
|
||||||
if self.CP.flags & GMFlags.CC_LONG.value:
|
if self.CP.flags & GMFlags.CC_LONG.value:
|
||||||
if should_send_cc_button_spam(self.CP, CC, CS):
|
if should_send_cc_button_spam(self.CP, CC, CS):
|
||||||
# Using extend instead of append since the message is only sent intermittently
|
if self.CP.carFingerprint != CAR.CADILLAC_XT4_CC:
|
||||||
can_sends.extend(gmcan.create_gm_cc_spam_command(self.packer_pt, self, CS, actuators, starpilot_toggles))
|
# Using extend instead of append since the message is only sent intermittently
|
||||||
elif (CS.out.cruiseState.enabled and CC.enabled and self.frame % 52 == 0 and
|
can_sends.extend(gmcan.create_gm_cc_spam_command(self.packer_pt, self, CS, actuators, starpilot_toggles))
|
||||||
|
else:
|
||||||
|
if (CS.out.cruiseState.enabled and CC.enabled and self.frame % 52 == 0 and
|
||||||
CS.cruise_buttons == CruiseButtons.UNPRESS and CS.out.gasPressed and CS.out.cruiseState.speed < CS.out.vEgo < hud_v_cruise):
|
CS.cruise_buttons == CruiseButtons.UNPRESS and CS.out.gasPressed and CS.out.cruiseState.speed < CS.out.vEgo < hud_v_cruise):
|
||||||
if self.CP.carFingerprint == CAR.CHEVROLET_MALIBU_HYBRID_CC:
|
if self.CP.carFingerprint == CAR.CHEVROLET_MALIBU_HYBRID_CC:
|
||||||
can_sends.append(gmcan.create_buttons_malibu(
|
can_sends.append(gmcan.create_buttons_malibu(
|
||||||
self.packer_pt, CanBus.POWERTRAIN, CruiseButtons.DECEL_SET,
|
self.packer_pt, CanBus.POWERTRAIN, CruiseButtons.DECEL_SET,
|
||||||
self.malibu_button_phase, CS.steering_button_prefix))
|
self.malibu_button_phase, CS.steering_button_prefix))
|
||||||
self.malibu_button_phase = (self.malibu_button_phase + 1) % 4
|
self.malibu_button_phase = (self.malibu_button_phase + 1) % 4
|
||||||
else:
|
else:
|
||||||
can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.POWERTRAIN, (CS.buttons_counter + 1) % 4, CruiseButtons.DECEL_SET))
|
can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.POWERTRAIN, (CS.buttons_counter + 1) % 4, CruiseButtons.DECEL_SET))
|
||||||
if self.CP.enableGasInterceptorDEPRECATED:
|
if self.CP.enableGasInterceptorDEPRECATED:
|
||||||
can_sends.append(create_gas_interceptor_command(self.packer_pt, interceptor_gas_cmd, idx))
|
can_sends.append(create_gas_interceptor_command(self.packer_pt, interceptor_gas_cmd, idx))
|
||||||
if bolt_acc_pedal_friction_experiment:
|
if bolt_acc_pedal_friction_experiment:
|
||||||
@@ -1053,6 +1188,8 @@ class CarController(CarControllerBase):
|
|||||||
# TODO: can we always check the longControlState?
|
# TODO: can we always check the longControlState?
|
||||||
if self.CP.networkLocation == NetworkLocation.fwdCamera:
|
if self.CP.networkLocation == NetworkLocation.fwdCamera:
|
||||||
at_full_stop = at_full_stop and stopping
|
at_full_stop = at_full_stop and stopping
|
||||||
|
if should_send_acc_2cd(self.CP):
|
||||||
|
can_sends.append(gmcan.create_acc_2cd_command(CanBus.POWERTRAIN, idx))
|
||||||
|
|
||||||
if self.CP.autoResumeSng:
|
if self.CP.autoResumeSng:
|
||||||
resume = actuators.longControlState != LongCtrlState.starting or CC.cruiseControl.resume
|
resume = actuators.longControlState != LongCtrlState.starting or CC.cruiseControl.resume
|
||||||
@@ -1097,8 +1234,10 @@ class CarController(CarControllerBase):
|
|||||||
if should_send_acc_dashboard_status(self.CP, dash_speed_spoof_active):
|
if should_send_acc_dashboard_status(self.CP, dash_speed_spoof_active):
|
||||||
fcw_alert = get_acc_dashboard_fcw_alert(hud_alert, CS)
|
fcw_alert = get_acc_dashboard_fcw_alert(hud_alert, CS)
|
||||||
acc_dashboard_status_active = get_acc_dashboard_status_active(self.CP, CC)
|
acc_dashboard_status_active = get_acc_dashboard_status_active(self.CP, CC)
|
||||||
|
acc_dashboard_always_one = get_acc_dashboard_always_one(self.CP)
|
||||||
can_sends.append(gmcan.create_acc_dashboard_command(self.packer_pt, CanBus.POWERTRAIN, acc_dashboard_status_active,
|
can_sends.append(gmcan.create_acc_dashboard_command(self.packer_pt, CanBus.POWERTRAIN, acc_dashboard_status_active,
|
||||||
hud_v_cruise * CV.MS_TO_KPH, hud_control, fcw_alert))
|
hud_v_cruise * CV.MS_TO_KPH, hud_control, fcw_alert,
|
||||||
|
acc_dashboard_always_one))
|
||||||
|
|
||||||
# Radar needs to know current speed and yaw rate (50hz),
|
# Radar needs to know current speed and yaw rate (50hz),
|
||||||
# and that ADAS is alive (10hz)
|
# and that ADAS is alive (10hz)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from opendbc.can import CANDefine, CANParser
|
|||||||
from opendbc.car import Bus, create_button_events, structs
|
from opendbc.car import Bus, create_button_events, structs
|
||||||
from opendbc.car import DT_CTRL
|
from opendbc.car import DT_CTRL
|
||||||
from opendbc.car.common.conversions import Conversions as CV
|
from opendbc.car.common.conversions import Conversions as CV
|
||||||
|
from opendbc.car.gps import get_car_gps_config
|
||||||
from opendbc.car.interfaces import CarStateBase
|
from opendbc.car.interfaces import CarStateBase
|
||||||
from opendbc.car.gm.values import (
|
from opendbc.car.gm.values import (
|
||||||
ALT_ACCS,
|
ALT_ACCS,
|
||||||
@@ -104,6 +105,31 @@ class CarState(CarStateBase):
|
|||||||
self.lkas_enabled = 0
|
self.lkas_enabled = 0
|
||||||
self.pcm_acc_status = AccState.OFF
|
self.pcm_acc_status = AccState.OFF
|
||||||
self.stock_fcw_alert = 0
|
self.stock_fcw_alert = 0
|
||||||
|
self.car_gps_config = get_car_gps_config(CP)
|
||||||
|
self.car_gps_supported = self.car_gps_config is not None
|
||||||
|
self.car_gps = None
|
||||||
|
self._car_gps_timestamp_nanos = 0
|
||||||
|
|
||||||
|
def _update_car_gps(self, cp) -> None:
|
||||||
|
if self.car_gps_config is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
timestamps = [max(cp.ts_nanos[name].values(), default=0) for name in self.car_gps_config.messages]
|
||||||
|
if not all(timestamps) or max(timestamps) - min(timestamps) > 2_000_000_000:
|
||||||
|
return
|
||||||
|
|
||||||
|
timestamp_nanos = max(timestamps)
|
||||||
|
if timestamp_nanos <= self._car_gps_timestamp_nanos:
|
||||||
|
return
|
||||||
|
|
||||||
|
gps = self.car_gps_config.decoder(*(cp.vl[name] for name in self.car_gps_config.messages))
|
||||||
|
if gps is not None:
|
||||||
|
gps["timestamp_nanos"] = timestamp_nanos
|
||||||
|
self.car_gps = gps
|
||||||
|
self._car_gps_timestamp_nanos = timestamp_nanos
|
||||||
|
|
||||||
|
def get_car_gps(self):
|
||||||
|
return self.car_gps
|
||||||
|
|
||||||
def update_button_enable(self, buttonEvents: list[structs.CarState.ButtonEvent]):
|
def update_button_enable(self, buttonEvents: list[structs.CarState.ButtonEvent]):
|
||||||
if not self.CP.pcmCruise:
|
if not self.CP.pcmCruise:
|
||||||
@@ -119,6 +145,8 @@ class CarState(CarStateBase):
|
|||||||
cam_cp = can_parsers[Bus.cam]
|
cam_cp = can_parsers[Bus.cam]
|
||||||
loopback_cp = can_parsers[Bus.loopback]
|
loopback_cp = can_parsers[Bus.loopback]
|
||||||
|
|
||||||
|
self._update_car_gps(pt_cp)
|
||||||
|
|
||||||
ret = structs.CarState()
|
ret = structs.CarState()
|
||||||
|
|
||||||
volt_like = {
|
volt_like = {
|
||||||
@@ -428,6 +456,9 @@ class CarState(CarStateBase):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_can_parsers(CP):
|
def get_can_parsers(CP):
|
||||||
|
gps_config = get_car_gps_config(CP)
|
||||||
|
gps_messages = [(name, 0) for name in gps_config.messages] if gps_config is not None else []
|
||||||
|
|
||||||
volt_like = {
|
volt_like = {
|
||||||
CAR.CHEVROLET_VOLT,
|
CAR.CHEVROLET_VOLT,
|
||||||
CAR.CHEVROLET_VOLT_2019,
|
CAR.CHEVROLET_VOLT_2019,
|
||||||
@@ -451,6 +482,7 @@ class CarState(CarStateBase):
|
|||||||
("PSCMSteeringAngle", 100),
|
("PSCMSteeringAngle", 100),
|
||||||
("ECMAcceleratorPos", 80),
|
("ECMAcceleratorPos", 80),
|
||||||
("SportMode", 0),
|
("SportMode", 0),
|
||||||
|
*gps_messages,
|
||||||
]
|
]
|
||||||
|
|
||||||
prndl2_rate = 10 if CP.carFingerprint in kaofui_state_cars else 40
|
prndl2_rate = 10 if CP.carFingerprint in kaofui_state_cars else 40
|
||||||
|
|||||||
@@ -30,20 +30,20 @@ FINGERPRINTS = {
|
|||||||
CAR.BUICK_LACROSSE: [{
|
CAR.BUICK_LACROSSE: [{
|
||||||
190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 288: 5, 298: 8, 304: 1, 309: 8, 311: 8, 313: 8, 320: 3, 322: 7, 328: 1, 352: 5, 353: 3, 381: 6, 386: 8, 388: 8, 393: 7, 398: 8, 407: 7, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 455: 7, 456: 8, 463: 3, 479: 3, 481: 7, 485: 8, 487: 8, 489: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 503: 1, 508: 8, 510: 8, 528: 5, 532: 6, 534: 2, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 567: 5, 573: 1, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 5, 707: 8, 753: 5, 761: 7, 801: 8, 804: 3, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 872: 1, 882: 8, 890: 1, 892: 2, 893: 1, 894: 1, 961: 8, 967: 4, 969: 8, 977: 8, 979: 8, 985: 5, 1001: 8, 1005: 6, 1009: 8, 1011: 6, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1022: 1, 1105: 6, 1217: 8, 1221: 5, 1223: 2, 1225: 7, 1233: 8, 1243: 3, 1249: 8, 1257: 6, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1280: 4, 1300: 8, 1322: 6, 1328: 4, 1417: 8, 1609: 8, 1613: 8, 1649: 8, 1792: 8, 1798: 8, 1824: 8, 1825: 8, 1840: 8, 1842: 8, 1858: 8, 1860: 8, 1863: 8, 1872: 8, 1875: 8, 1882: 8, 1888: 8, 1889: 8, 1892: 8, 1904: 7, 1906: 7, 1907: 7, 1912: 7, 1913: 7, 1914: 7, 1916: 7, 1918: 7, 1919: 7, 1937: 8, 1953: 8, 1968: 8, 2001: 8, 2017: 8, 2018: 8, 2020: 8, 2026: 8
|
190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 288: 5, 298: 8, 304: 1, 309: 8, 311: 8, 313: 8, 320: 3, 322: 7, 328: 1, 352: 5, 353: 3, 381: 6, 386: 8, 388: 8, 393: 7, 398: 8, 407: 7, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 455: 7, 456: 8, 463: 3, 479: 3, 481: 7, 485: 8, 487: 8, 489: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 503: 1, 508: 8, 510: 8, 528: 5, 532: 6, 534: 2, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 567: 5, 573: 1, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 5, 707: 8, 753: 5, 761: 7, 801: 8, 804: 3, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 872: 1, 882: 8, 890: 1, 892: 2, 893: 1, 894: 1, 961: 8, 967: 4, 969: 8, 977: 8, 979: 8, 985: 5, 1001: 8, 1005: 6, 1009: 8, 1011: 6, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1022: 1, 1105: 6, 1217: 8, 1221: 5, 1223: 2, 1225: 7, 1233: 8, 1243: 3, 1249: 8, 1257: 6, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1280: 4, 1300: 8, 1322: 6, 1328: 4, 1417: 8, 1609: 8, 1613: 8, 1649: 8, 1792: 8, 1798: 8, 1824: 8, 1825: 8, 1840: 8, 1842: 8, 1858: 8, 1860: 8, 1863: 8, 1872: 8, 1875: 8, 1882: 8, 1888: 8, 1889: 8, 1892: 8, 1904: 7, 1906: 7, 1907: 7, 1912: 7, 1913: 7, 1914: 7, 1916: 7, 1918: 7, 1919: 7, 1937: 8, 1953: 8, 1968: 8, 2001: 8, 2017: 8, 2018: 8, 2020: 8, 2026: 8
|
||||||
}],
|
}],
|
||||||
# CAR.CHEVROLET_VOLT_CC: [
|
CAR.CHEVROLET_VOLT_CC: [
|
||||||
# FIXME: Need a message to distinguish flashed from non-flashed
|
# Captured no-ACC Volt fingerprints for OBD-C/L&P harness installations
|
||||||
# Volt Premier w/o acc 2016
|
# Volt Premier w/o ACC 2016
|
||||||
# {
|
{
|
||||||
# 170: 8, 171: 8, 189: 7, 190: 6, 192: 5, 193: 8, 197: 8, 199: 4, 201: 6, 209: 7, 211: 2, 241: 6, 288: 5, 289: 1, 290: 1, 298: 2, 304: 8, 308: 4, 309: 8, 311: 8, 313: 8, 320: 8, 328: 1, 352: 5, 368: 8, 381: 6, 384: 8, 386: 5, 388: 8, 389: 2, 390: 7, 417: 7, 419: 1, 426: 7, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 458: 8, 479: 3, 481: 7, 485: 8, 489: 5, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 3, 508: 8, 512: 3, 528: 4, 530: 8, 532: 6, 537: 4, 539: 8, 542: 7, 546: 7, 550: 8, 554: 3, 558: 8, 560: 6, 562: 8, 563: 5, 564: 5, 565: 8, 566: 5, 567: 3, 568: 1, 577: 8, 578: 8, 594: 8, 647: 3, 707: 8, 711: 6, 717: 5, 761: 7, 800: 6, 810: 8, 821: 4, 823: 7, 832: 8, 840: 5, 842: 6, 844: 8, 866: 4, 869: 4, 961: 8, 969: 8, 977: 8, 979: 7, 988: 6, 989: 8, 995: 7, 1001: 5, 1003: 5, 1005: 6, 1009: 8, 1017: 8, 1019: 2, 1020: 8, 1033: 7, 1034: 7, 1105: 6, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1249: 8, 1257: 6, 1265: 8, 1267: 1, 1273: 3, 1275: 3, 1280: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1417: 8, 1601: 8, 1602: 8, 1618: 8, 1906: 7, 1907: 7, 1910: 7, 1912: 7, 1922: 7, 1927: 7, 1928: 7, 1930: 7, 2016: 8, 2017: 8, 2018: 8, 2019: 8, 2020: 8, 2024: 8, 2025: 8, 2028: 8
|
170: 8, 171: 8, 189: 7, 190: 6, 192: 5, 193: 8, 197: 8, 199: 4, 201: 6, 209: 7, 211: 2, 241: 6, 288: 5, 289: 1, 290: 1, 298: 2, 304: 8, 308: 4, 309: 8, 311: 8, 313: 8, 320: 8, 328: 1, 352: 5, 368: 8, 381: 6, 384: 8, 386: 5, 388: 8, 389: 2, 390: 7, 417: 7, 419: 1, 426: 7, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 458: 8, 479: 3, 481: 7, 485: 8, 489: 5, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 3, 508: 8, 512: 3, 528: 4, 530: 8, 532: 6, 537: 4, 539: 8, 542: 7, 546: 7, 550: 8, 554: 3, 558: 8, 560: 6, 562: 8, 563: 5, 564: 5, 565: 8, 566: 5, 567: 3, 568: 1, 577: 8, 578: 8, 594: 8, 647: 3, 707: 8, 711: 6, 717: 5, 761: 7, 800: 6, 810: 8, 821: 4, 823: 7, 832: 8, 840: 5, 842: 6, 844: 8, 866: 4, 869: 4, 961: 8, 969: 8, 977: 8, 979: 7, 988: 6, 989: 8, 995: 7, 1001: 5, 1003: 5, 1005: 6, 1009: 8, 1017: 8, 1019: 2, 1020: 8, 1033: 7, 1034: 7, 1105: 6, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1249: 8, 1257: 6, 1265: 8, 1267: 1, 1273: 3, 1275: 3, 1280: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1417: 8, 1601: 8, 1602: 8, 1618: 8, 1906: 7, 1907: 7, 1910: 7, 1912: 7, 1922: 7, 1927: 7, 1928: 7, 1930: 7, 2016: 8, 2017: 8, 2018: 8, 2019: 8, 2020: 8, 2024: 8, 2025: 8, 2028: 8
|
||||||
# },
|
},
|
||||||
# {
|
{
|
||||||
# 201: 8, 493: 8, 495: 4, 193: 8, 197: 8, 209: 7, 171: 8, 456: 8, 199: 4, 489: 8, 211: 2, 499: 3, 390: 7, 532: 6, 568: 1, 761: 7, 381: 6, 485: 8, 189: 7, 479: 3, 711: 6, 501: 8, 241: 6, 717: 5, 869: 4, 389: 2, 454: 8, 170: 8, 190: 6, 497: 8, 417: 7, 419: 1, 426: 7, 451: 8, 452: 8, 453: 6, 500: 6, 508: 8, 528: 4, 647: 3, 1105: 6, 1005: 6, 481: 7, 844: 8, 866: 4, 564: 5, 969: 8, 388: 8, 352: 5, 562: 8, 961: 8, 386: 8, 707: 8, 977: 8, 979: 7, 298: 8, 840: 5, 842: 5, 988: 6, 1001: 8, 560: 8, 546: 7, 558: 8, 309: 8, 995: 7, 311: 8, 566: 5, 567:3, 989: 8, 384: 4, 800: 6, 1033: 7, 1034: 7, 313: 8, 554: 3, 810: 8, 1017: 8, 1019: 2, 1020: 8, 1217: 8, 1223: 3, 1233: 8, 1227: 4, 1417: 8, 1009: 8, 1221: 5, 1275: 3, 1225: 7, 289: 8, 550: 8, 1273: 3, 1928: 7, 1187: 4, 1265: 8, 1927: 7, 1267: 1, 1906: 7, 288: 5, 304: 1, 328: 1, 1912: 7, 320: 3, 1910: 7, 563: 5, 1249: 8, 1930: 7, 1257: 6, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 565: 5, 1280: 4, 1907: 7
|
201: 8, 493: 8, 495: 4, 193: 8, 197: 8, 209: 7, 171: 8, 456: 8, 199: 4, 489: 8, 211: 2, 499: 3, 390: 7, 532: 6, 568: 1, 761: 7, 381: 6, 485: 8, 189: 7, 479: 3, 711: 6, 501: 8, 241: 6, 717: 5, 869: 4, 389: 2, 454: 8, 170: 8, 190: 6, 497: 8, 417: 7, 419: 1, 426: 7, 451: 8, 452: 8, 453: 6, 500: 6, 508: 8, 528: 4, 647: 3, 1105: 6, 1005: 6, 481: 7, 844: 8, 866: 4, 564: 5, 969: 8, 388: 8, 352: 5, 562: 8, 961: 8, 386: 8, 707: 8, 977: 8, 979: 7, 298: 8, 840: 5, 842: 5, 988: 6, 1001: 8, 560: 8, 546: 7, 558: 8, 309: 8, 995: 7, 311: 8, 566: 5, 567:3, 989: 8, 384: 4, 800: 6, 1033: 7, 1034: 7, 313: 8, 554: 3, 810: 8, 1017: 8, 1019: 2, 1020: 8, 1217: 8, 1223: 3, 1233: 8, 1227: 4, 1417: 8, 1009: 8, 1221: 5, 1275: 3, 1225: 7, 289: 8, 550: 8, 1273: 3, 1928: 7, 1187: 4, 1265: 8, 1927: 7, 1267: 1, 1906: 7, 288: 5, 304: 1, 328: 1, 1912: 7, 320: 3, 1910: 7, 563: 5, 1249: 8, 1930: 7, 1257: 6, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 565: 5, 1280: 4, 1907: 7
|
||||||
# },
|
},
|
||||||
# # Volt Premier w/o ACC 2018 + Pedal
|
# Volt Premier w/o ACC 2018 + Pedal
|
||||||
# {
|
{
|
||||||
# 189: 7, 193: 8, 197: 8, 201: 8, 209: 7, 211: 2, 241: 6, 288: 5, 298: 8, 304: 1, 308: 4, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 6, 384: 4, 386: 8, 388: 8, 451: 8, 452: 8, 453: 6, 479: 3, 481: 7, 485: 8, 489: 8, 493: 8, 497: 8, 500: 6, 501: 8, 513: 6, 528: 4, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 566: 5, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 717: 5, 761: 7, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 869: 4, 977: 8, 1001: 8, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1265: 8, 1267: 1, 1280: 4, 1300: 8, 1922: 7, 1930: 7
|
189: 7, 193: 8, 197: 8, 201: 8, 209: 7, 211: 2, 241: 6, 288: 5, 298: 8, 304: 1, 308: 4, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 6, 384: 4, 386: 8, 388: 8, 451: 8, 452: 8, 453: 6, 479: 3, 481: 7, 485: 8, 489: 8, 493: 8, 497: 8, 500: 6, 501: 8, 513: 6, 528: 4, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 566: 5, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 717: 5, 761: 7, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 869: 4, 977: 8, 1001: 8, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1265: 8, 1267: 1, 1280: 4, 1300: 8, 1922: 7, 1930: 7
|
||||||
# }
|
}
|
||||||
# ],
|
],
|
||||||
CAR.BUICK_REGAL: [{
|
CAR.BUICK_REGAL: [{
|
||||||
190: 8, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 8, 241: 6, 249: 8, 288: 5, 298: 8, 304: 1, 309: 8, 311: 8, 313: 8, 320: 3, 322: 7, 328: 1, 352: 5, 381: 6, 384: 4, 386: 8, 388: 8, 393: 7, 398: 8, 407: 7, 413: 8, 417: 8, 419: 8, 422: 4, 426: 8, 431: 8, 442: 8, 451: 8, 452: 8, 453: 8, 455: 7, 456: 8, 463: 3, 479: 8, 481: 7, 485: 8, 487: 8, 489: 8, 495: 8, 497: 8, 499: 3, 500: 8, 501: 8, 508: 8, 528: 5, 532: 6, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 567: 5, 569: 3, 573: 1, 577: 8, 578: 8, 579: 8, 587: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 3, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 880: 6, 882: 8, 884: 8, 890: 1, 892: 2, 893: 2, 894: 1, 961: 8, 967: 8, 969: 8, 977: 8, 979: 8, 985: 8, 1001: 8, 1005: 6, 1009: 8, 1011: 8, 1013: 3, 1017: 8, 1020: 8, 1024: 8, 1025: 8, 1026: 8, 1027: 8, 1028: 8, 1029: 8, 1030: 8, 1031: 8, 1032: 2, 1033: 7, 1034: 7, 1105: 6, 1217: 8, 1221: 5, 1223: 8, 1225: 7, 1233: 8, 1249: 8, 1257: 6, 1259: 8, 1261: 8, 1263: 8, 1265: 8, 1267: 8, 1271: 8, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1328: 4, 1417: 8, 1601: 8, 1602: 8, 1603: 7, 1611: 8, 1618: 8, 1906: 8, 1907: 7, 1912: 7, 1914: 7, 1916: 7, 1919: 7, 1930: 7, 2016: 8, 2018: 8, 2019: 8, 2024: 8, 2026: 8
|
190: 8, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 8, 241: 6, 249: 8, 288: 5, 298: 8, 304: 1, 309: 8, 311: 8, 313: 8, 320: 3, 322: 7, 328: 1, 352: 5, 381: 6, 384: 4, 386: 8, 388: 8, 393: 7, 398: 8, 407: 7, 413: 8, 417: 8, 419: 8, 422: 4, 426: 8, 431: 8, 442: 8, 451: 8, 452: 8, 453: 8, 455: 7, 456: 8, 463: 3, 479: 8, 481: 7, 485: 8, 487: 8, 489: 8, 495: 8, 497: 8, 499: 3, 500: 8, 501: 8, 508: 8, 528: 5, 532: 6, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 567: 5, 569: 3, 573: 1, 577: 8, 578: 8, 579: 8, 587: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 3, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 880: 6, 882: 8, 884: 8, 890: 1, 892: 2, 893: 2, 894: 1, 961: 8, 967: 8, 969: 8, 977: 8, 979: 8, 985: 8, 1001: 8, 1005: 6, 1009: 8, 1011: 8, 1013: 3, 1017: 8, 1020: 8, 1024: 8, 1025: 8, 1026: 8, 1027: 8, 1028: 8, 1029: 8, 1030: 8, 1031: 8, 1032: 2, 1033: 7, 1034: 7, 1105: 6, 1217: 8, 1221: 5, 1223: 8, 1225: 7, 1233: 8, 1249: 8, 1257: 6, 1259: 8, 1261: 8, 1263: 8, 1265: 8, 1267: 8, 1271: 8, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1328: 4, 1417: 8, 1601: 8, 1602: 8, 1603: 7, 1611: 8, 1618: 8, 1906: 8, 1907: 7, 1912: 7, 1914: 7, 1916: 7, 1919: 7, 1930: 7, 2016: 8, 2018: 8, 2019: 8, 2024: 8, 2026: 8
|
||||||
}],
|
}],
|
||||||
@@ -207,7 +207,6 @@ FINGERPRINTS = {
|
|||||||
FINGERPRINTS.update({
|
FINGERPRINTS.update({
|
||||||
CAR.CHEVROLET_VOLT_ASCM: FINGERPRINTS[CAR.CHEVROLET_VOLT],
|
CAR.CHEVROLET_VOLT_ASCM: FINGERPRINTS[CAR.CHEVROLET_VOLT],
|
||||||
CAR.CHEVROLET_VOLT_CAMERA: [{**fp, CAMERA_DIAGNOSTIC_ADDRESS: 8, CAMERA_DIAGNOSTIC_RX_ADDRESS: 8} for fp in FINGERPRINTS[CAR.CHEVROLET_VOLT]],
|
CAR.CHEVROLET_VOLT_CAMERA: [{**fp, CAMERA_DIAGNOSTIC_ADDRESS: 8, CAMERA_DIAGNOSTIC_RX_ADDRESS: 8} for fp in FINGERPRINTS[CAR.CHEVROLET_VOLT]],
|
||||||
CAR.CHEVROLET_VOLT_CC: FINGERPRINTS[CAR.CHEVROLET_VOLT],
|
|
||||||
CAR.GMC_ACADIA_ASCM: FINGERPRINTS[CAR.GMC_ACADIA],
|
CAR.GMC_ACADIA_ASCM: FINGERPRINTS[CAR.GMC_ACADIA],
|
||||||
CAR.CHEVROLET_MALIBU_ASCM: FINGERPRINTS[CAR.CHEVROLET_MALIBU],
|
CAR.CHEVROLET_MALIBU_ASCM: FINGERPRINTS[CAR.CHEVROLET_MALIBU],
|
||||||
CAR.CADILLAC_ESCALADE_ASCM: FINGERPRINTS[CAR.CADILLAC_ESCALADE],
|
CAR.CADILLAC_ESCALADE_ASCM: FINGERPRINTS[CAR.CADILLAC_ESCALADE],
|
||||||
@@ -220,6 +219,7 @@ FINGERPRINTS.update({
|
|||||||
CAR.CHEVROLET_MALIBU_SDGM: FINGERPRINTS[CAR.CHEVROLET_MALIBU_CC],
|
CAR.CHEVROLET_MALIBU_SDGM: FINGERPRINTS[CAR.CHEVROLET_MALIBU_CC],
|
||||||
CAR.BUICK_BABYENCLAVE: FINGERPRINTS[CAR.CHEVROLET_TRAVERSE],
|
CAR.BUICK_BABYENCLAVE: FINGERPRINTS[CAR.CHEVROLET_TRAVERSE],
|
||||||
CAR.CHEVROLET_SILVERADO_CC: FINGERPRINTS[CAR.CHEVROLET_SILVERADO],
|
CAR.CHEVROLET_SILVERADO_CC: FINGERPRINTS[CAR.CHEVROLET_SILVERADO],
|
||||||
|
CAR.CADILLAC_XT4_CC: FINGERPRINTS[CAR.CADILLAC_XT4],
|
||||||
CAR.BUICK_LACROSSE_ASCM: FINGERPRINTS[CAR.BUICK_LACROSSE],
|
CAR.BUICK_LACROSSE_ASCM: FINGERPRINTS[CAR.BUICK_LACROSSE],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from opendbc.car import DT_CTRL
|
from opendbc.car import DT_CTRL, structs
|
||||||
from opendbc.car.can_definitions import CanData
|
from opendbc.car.can_definitions import CanData
|
||||||
from opendbc.car.common.conversions import Conversions as CV
|
from opendbc.car.common.conversions import Conversions as CV
|
||||||
from opendbc.car.gm.values import CAR, CanBus, CruiseButtons, GMFlags
|
from opendbc.car.gm.values import CAR, CanBus, CruiseButtons, GMFlags
|
||||||
@@ -17,6 +17,18 @@ MALIBU_BUTTON_MAP = {
|
|||||||
CruiseButtons.CANCEL: 5,
|
CruiseButtons.CANCEL: 5,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ACC_CRUISE_STATE_ADAPTIVE = 2
|
||||||
|
XT4_CC_BUTTON_BURST_FRAMES = 6
|
||||||
|
XT4_CC_BUTTON_COUNTER_DELAY_FRAMES = 1
|
||||||
|
BOLT_CC_BUTTON_CARS = {
|
||||||
|
CAR.CHEVROLET_BOLT_CC_2017,
|
||||||
|
CAR.CHEVROLET_BOLT_CC_2018_2021,
|
||||||
|
CAR.CHEVROLET_BOLT_CC_2022_2023,
|
||||||
|
}
|
||||||
|
BOLT_CC_TARGET_DEADBAND_MPH = 0.75
|
||||||
|
BOLT_CC_REVERSE_CONFIRM_S = 0.6
|
||||||
|
BOLT_CC_DIRECTION_MEMORY_S = 1.5
|
||||||
|
|
||||||
|
|
||||||
def malibu_phase_map_for_button(button):
|
def malibu_phase_map_for_button(button):
|
||||||
key = MALIBU_BUTTON_MAP.get(button)
|
key = MALIBU_BUTTON_MAP.get(button)
|
||||||
@@ -215,16 +227,24 @@ def create_friction_brake_command(packer, bus, apply_brake, idx, enabled, near_s
|
|||||||
return packer.make_can_msg("EBCMFrictionBrakeCmd", bus, values)
|
return packer.make_can_msg("EBCMFrictionBrakeCmd", bus, values)
|
||||||
|
|
||||||
|
|
||||||
def create_acc_dashboard_command(packer, bus, enabled, target_speed_kph, hud_control, fcw_alert):
|
def create_acc_2cd_command(bus, idx):
|
||||||
|
dat = bytearray([0x00, 0x2c, 0x03, 0xd3, 0x00])
|
||||||
|
dat[0] = (idx & 0x3) << 6
|
||||||
|
dat[4] = (0xfd - (idx & 0x3)) & 0xff
|
||||||
|
return CanData(0x2CD, bytes(dat), bus)
|
||||||
|
|
||||||
|
|
||||||
|
def create_acc_dashboard_command(packer, bus, enabled, target_speed_kph, hud_control, fcw_alert, acc_always_one=1):
|
||||||
target_speed = min(target_speed_kph, 255)
|
target_speed = min(target_speed_kph, 255)
|
||||||
|
|
||||||
values = {
|
values = {
|
||||||
"ACCAlwaysOne": 1,
|
"ACCAlwaysOne": acc_always_one,
|
||||||
|
"ACCCruiseState": ACC_CRUISE_STATE_ADAPTIVE,
|
||||||
"ACCResumeButton": 0,
|
"ACCResumeButton": 0,
|
||||||
"ACCSpeedSetpoint": target_speed,
|
"ACCSpeedSetpoint": target_speed,
|
||||||
"ACCGapLevel": hud_control.leadDistanceBars * enabled, # 3 "far", 0 "inactive"
|
"ACCGapLevel": hud_control.leadDistanceBars * enabled, # 3 "far", 0 "inactive"
|
||||||
"ACCCmdActive": enabled,
|
"ACCCmdActive": enabled,
|
||||||
"ACCAlwaysOne2": 1,
|
"ACCAlwaysOne2": acc_always_one,
|
||||||
"ACCLeadCar": hud_control.leadVisible,
|
"ACCLeadCar": hud_control.leadVisible,
|
||||||
"FCWAlert": int(fcw_alert) & 0x3,
|
"FCWAlert": int(fcw_alert) & 0x3,
|
||||||
}
|
}
|
||||||
@@ -286,32 +306,110 @@ def create_lka_icon_command(bus, active, critical, steer):
|
|||||||
return CanData(0x104c006c, dat, bus)
|
return CanData(0x104c006c, dat, bus)
|
||||||
|
|
||||||
|
|
||||||
|
def stabilize_bolt_cc_button(controller, CP, requested_button):
|
||||||
|
if CP.carFingerprint not in BOLT_CC_BUTTON_CARS:
|
||||||
|
return requested_button
|
||||||
|
|
||||||
|
direction_buttons = (CruiseButtons.RES_ACCEL, CruiseButtons.DECEL_SET)
|
||||||
|
if requested_button not in direction_buttons:
|
||||||
|
controller.gm_cc_pending_reverse_button = CruiseButtons.INIT
|
||||||
|
return requested_button
|
||||||
|
|
||||||
|
last_button = getattr(controller, "gm_cc_last_direction_button", CruiseButtons.INIT)
|
||||||
|
last_frame = getattr(controller, "gm_cc_last_direction_frame", -int(BOLT_CC_DIRECTION_MEMORY_S / DT_CTRL) - 1)
|
||||||
|
recently_sent = (controller.frame - last_frame) * DT_CTRL <= BOLT_CC_DIRECTION_MEMORY_S
|
||||||
|
reversing_to_accel = (last_button == CruiseButtons.DECEL_SET and
|
||||||
|
requested_button == CruiseButtons.RES_ACCEL and recently_sent)
|
||||||
|
|
||||||
|
if reversing_to_accel:
|
||||||
|
pending_button = getattr(controller, "gm_cc_pending_reverse_button", CruiseButtons.INIT)
|
||||||
|
if pending_button != requested_button:
|
||||||
|
controller.gm_cc_pending_reverse_button = requested_button
|
||||||
|
controller.gm_cc_pending_reverse_frame = controller.frame
|
||||||
|
return CruiseButtons.INIT
|
||||||
|
|
||||||
|
pending_frame = getattr(controller, "gm_cc_pending_reverse_frame", controller.frame)
|
||||||
|
if (controller.frame - pending_frame) * DT_CTRL < BOLT_CC_REVERSE_CONFIRM_S:
|
||||||
|
return CruiseButtons.INIT
|
||||||
|
|
||||||
|
controller.gm_cc_pending_reverse_button = CruiseButtons.INIT
|
||||||
|
return requested_button
|
||||||
|
|
||||||
|
|
||||||
def create_gm_cc_spam_command(packer, controller, CS, actuators, starpilot_toggles):
|
def create_gm_cc_spam_command(packer, controller, CS, actuators, starpilot_toggles):
|
||||||
accel = actuators.accel
|
accel = actuators.accel
|
||||||
v_ego = CS.out.vEgo
|
v_ego = CS.out.vEgo
|
||||||
cruise_btn = CruiseButtons.INIT
|
cruise_btn = CruiseButtons.INIT
|
||||||
rate = 1 if abs(accel) <= 0.15 else 0.2
|
rate = 1 if abs(accel) <= 0.15 else 0.2
|
||||||
ms_convert = CV.MS_TO_KPH if getattr(starpilot_toggles, "is_metric", False) else CV.MS_TO_MPH
|
is_metric = getattr(starpilot_toggles, "is_metric", False)
|
||||||
|
ms_convert = CV.MS_TO_KPH if is_metric else CV.MS_TO_MPH
|
||||||
speed_setpoint = int(round(CS.out.cruiseState.speed * ms_convert))
|
speed_setpoint = int(round(CS.out.cruiseState.speed * ms_convert))
|
||||||
desired_setpoint = int(round((v_ego * 1.01 + 3 * accel) * ms_convert))
|
projected_setpoint = (v_ego * 1.01 + 3 * accel) * ms_convert
|
||||||
|
desired_setpoint = int(round(projected_setpoint))
|
||||||
|
bolt_cc = CS.CP.carFingerprint in BOLT_CC_BUTTON_CARS
|
||||||
|
target_deadband = BOLT_CC_TARGET_DEADBAND_MPH * (CV.MPH_TO_KPH if is_metric else 1.0) if bolt_cc else 0.0
|
||||||
|
comparison_setpoint = projected_setpoint if bolt_cc else desired_setpoint
|
||||||
|
|
||||||
if CS.CP.minEnableSpeed - (desired_setpoint / ms_convert) > 3.25:
|
if CS.CP.minEnableSpeed - (desired_setpoint / ms_convert) > 3.25:
|
||||||
cruise_btn = CruiseButtons.CANCEL
|
cruise_btn = CruiseButtons.CANCEL
|
||||||
controller.apply_speed = 0
|
elif comparison_setpoint < speed_setpoint - target_deadband and speed_setpoint > CS.CP.minEnableSpeed * ms_convert + 1:
|
||||||
elif desired_setpoint < speed_setpoint and speed_setpoint > CS.CP.minEnableSpeed * ms_convert + 1:
|
|
||||||
cruise_btn = CruiseButtons.DECEL_SET
|
cruise_btn = CruiseButtons.DECEL_SET
|
||||||
controller.apply_speed = speed_setpoint - 1
|
elif comparison_setpoint > speed_setpoint + target_deadband:
|
||||||
elif desired_setpoint > speed_setpoint:
|
|
||||||
cruise_btn = CruiseButtons.RES_ACCEL
|
cruise_btn = CruiseButtons.RES_ACCEL
|
||||||
|
|
||||||
|
cruise_btn = stabilize_bolt_cc_button(controller, CS.CP, cruise_btn)
|
||||||
|
if cruise_btn == CruiseButtons.CANCEL:
|
||||||
|
controller.apply_speed = 0
|
||||||
|
elif cruise_btn == CruiseButtons.DECEL_SET:
|
||||||
|
controller.apply_speed = speed_setpoint - 1
|
||||||
|
elif cruise_btn == CruiseButtons.RES_ACCEL:
|
||||||
controller.apply_speed = speed_setpoint + 1
|
controller.apply_speed = speed_setpoint + 1
|
||||||
else:
|
else:
|
||||||
cruise_btn = CruiseButtons.INIT
|
|
||||||
controller.apply_speed = speed_setpoint
|
controller.apply_speed = speed_setpoint
|
||||||
|
|
||||||
|
if CS.CP.carFingerprint == CAR.CADILLAC_XT4_CC:
|
||||||
|
if controller.xt4_cc_button_observed_counter != CS.buttons_counter:
|
||||||
|
controller.xt4_cc_button_observed_counter = CS.buttons_counter
|
||||||
|
controller.xt4_cc_button_counter_frame = controller.frame
|
||||||
|
|
||||||
|
if cruise_btn == CruiseButtons.INIT:
|
||||||
|
controller.xt4_cc_button_burst_remaining = 0
|
||||||
|
controller.xt4_cc_button_burst_button = CruiseButtons.INIT
|
||||||
|
return []
|
||||||
|
|
||||||
|
if (controller.xt4_cc_button_burst_remaining > 0 and
|
||||||
|
controller.xt4_cc_button_burst_button != cruise_btn):
|
||||||
|
controller.xt4_cc_button_burst_remaining = 0
|
||||||
|
|
||||||
|
if controller.xt4_cc_button_burst_remaining == 0:
|
||||||
|
if (controller.frame - controller.last_button_frame) * DT_CTRL <= rate:
|
||||||
|
return []
|
||||||
|
controller.last_button_frame = controller.frame
|
||||||
|
controller.xt4_cc_button_burst_button = cruise_btn
|
||||||
|
controller.xt4_cc_button_burst_remaining = XT4_CC_BUTTON_BURST_FRAMES
|
||||||
|
controller.xt4_cc_button_burst_last_counter = -1
|
||||||
|
|
||||||
|
# XT4 physical taps hold the button for 5-7 consecutive 33 Hz frames.
|
||||||
|
# Sending immediately after the stock frame is too early for the receiving ECU.
|
||||||
|
if controller.frame - controller.xt4_cc_button_counter_frame < XT4_CC_BUTTON_COUNTER_DELAY_FRAMES:
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Send once per observed stock counter so the injected sequence has the same cadence.
|
||||||
|
if controller.xt4_cc_button_burst_last_counter == CS.buttons_counter:
|
||||||
|
return []
|
||||||
|
|
||||||
|
controller.xt4_cc_button_burst_last_counter = CS.buttons_counter
|
||||||
|
controller.xt4_cc_button_burst_remaining -= 1
|
||||||
|
idx = (CS.buttons_counter + 1) % 4
|
||||||
|
return [create_buttons(packer, CanBus.POWERTRAIN, idx, controller.xt4_cc_button_burst_button)]
|
||||||
|
|
||||||
# Check rlogs closely - our message shouldn't show up on the pt bus for us
|
# Check rlogs closely - our message shouldn't show up on the pt bus for us
|
||||||
# Or bus 2, since we're forwarding... but I think it does
|
# Or bus 2, since we're forwarding... but I think it does
|
||||||
if (cruise_btn != CruiseButtons.INIT) and ((controller.frame - controller.last_button_frame) * DT_CTRL > rate):
|
if (cruise_btn != CruiseButtons.INIT) and ((controller.frame - controller.last_button_frame) * DT_CTRL > rate):
|
||||||
controller.last_button_frame = controller.frame
|
controller.last_button_frame = controller.frame
|
||||||
|
if bolt_cc and cruise_btn in (CruiseButtons.RES_ACCEL, CruiseButtons.DECEL_SET):
|
||||||
|
controller.gm_cc_last_direction_button = cruise_btn
|
||||||
|
controller.gm_cc_last_direction_frame = controller.frame
|
||||||
if CS.CP.carFingerprint == CAR.CHEVROLET_MALIBU_HYBRID_CC:
|
if CS.CP.carFingerprint == CAR.CHEVROLET_MALIBU_HYBRID_CC:
|
||||||
phase_map = malibu_phase_map_for_button(cruise_btn)
|
phase_map = malibu_phase_map_for_button(cruise_btn)
|
||||||
if phase_map:
|
if phase_map:
|
||||||
@@ -322,9 +420,11 @@ def create_gm_cc_spam_command(packer, controller, CS, actuators, starpilot_toggl
|
|||||||
idx = (CS.buttons_counter + 1) % 4 # Need to predict the next idx for '22-23 EUV
|
idx = (CS.buttons_counter + 1) % 4 # Need to predict the next idx for '22-23 EUV
|
||||||
msgs = [create_buttons(packer, CanBus.POWERTRAIN, idx, cruise_btn)]
|
msgs = [create_buttons(packer, CanBus.POWERTRAIN, idx, cruise_btn)]
|
||||||
|
|
||||||
# Flashed camera-forward Volt CC installs also need the button spoof on the
|
# A camera-forward Volt CC install needs the button spoof on both sides.
|
||||||
# camera side. Removed-camera installs set NO_CAMERA and keep this PT-only.
|
# The OBD-C/L&P gateway variant has no camera bus and remains PT-only.
|
||||||
if CS.CP.carFingerprint == CAR.CHEVROLET_VOLT_CC and not (CS.CP.flags & GMFlags.NO_CAMERA.value):
|
if (CS.CP.carFingerprint == CAR.CHEVROLET_VOLT_CC and
|
||||||
|
getattr(CS.CP, "networkLocation", None) == structs.CarParams.NetworkLocation.fwdCamera and
|
||||||
|
not (CS.CP.flags & GMFlags.NO_CAMERA.value)):
|
||||||
msgs.append(create_buttons(packer, CanBus.CAMERA, idx, cruise_btn))
|
msgs.append(create_buttons(packer, CanBus.CAMERA, idx, cruise_btn))
|
||||||
return msgs
|
return msgs
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -70,8 +70,24 @@ NON_LINEAR_TORQUE_PARAMS = {
|
|||||||
"left": [1.525, 1.05, 0.155, 0.0],
|
"left": [1.525, 1.05, 0.155, 0.0],
|
||||||
"right": [1.525, 0.95, 0.150, 0.0],
|
"right": [1.525, 0.95, 0.150, 0.0],
|
||||||
},
|
},
|
||||||
|
CAR.CHEVROLET_TRAX: {
|
||||||
|
"left": [3.8060, 0.8282, 0.1702, 0],
|
||||||
|
"right": [3.8060, 0.8282, 0.1702, 0],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NON_LINEAR_TORQUE_PARAM_ALIASES = {
|
||||||
|
CAR.CHEVROLET_VOLT_ASCM: CAR.CHEVROLET_VOLT,
|
||||||
|
CAR.CHEVROLET_VOLT_CAMERA: CAR.CHEVROLET_VOLT,
|
||||||
|
CAR.CHEVROLET_VOLT_CC: CAR.CHEVROLET_VOLT,
|
||||||
|
CAR.CHEVROLET_VOLT_2019: CAR.CHEVROLET_VOLT,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_nonlinear_torque_params(car_fingerprint):
|
||||||
|
source_fingerprint = NON_LINEAR_TORQUE_PARAM_ALIASES.get(car_fingerprint, car_fingerprint)
|
||||||
|
return NON_LINEAR_TORQUE_PARAMS.get(source_fingerprint)
|
||||||
|
|
||||||
PEDAL_MSG = 0x201
|
PEDAL_MSG = 0x201
|
||||||
CAM_MSG = 0x320
|
CAM_MSG = 0x320
|
||||||
ACCELERATOR_POS_MSG = 0xBE
|
ACCELERATOR_POS_MSG = 0xBE
|
||||||
@@ -169,7 +185,7 @@ class CarInterface(CarInterfaceBase):
|
|||||||
# The "lat_accel vs torque" relationship is assumed to be the sum of "sigmoid + linear" curves
|
# The "lat_accel vs torque" relationship is assumed to be the sum of "sigmoid + linear" curves
|
||||||
# An important thing to consider is that the slope at 0 should be > 0 (ideally >1)
|
# An important thing to consider is that the slope at 0 should be > 0 (ideally >1)
|
||||||
# This has big effect on the stability about 0 (noise when going straight)
|
# This has big effect on the stability about 0 (noise when going straight)
|
||||||
non_linear_torque_params = NON_LINEAR_TORQUE_PARAMS.get(self.CP.carFingerprint)
|
non_linear_torque_params = get_nonlinear_torque_params(self.CP.carFingerprint)
|
||||||
assert non_linear_torque_params, "The params are not defined"
|
assert non_linear_torque_params, "The params are not defined"
|
||||||
if isinstance(non_linear_torque_params, dict):
|
if isinstance(non_linear_torque_params, dict):
|
||||||
side_key = "left" if lateral_acceleration >= 0 else "right"
|
side_key = "left" if lateral_acceleration >= 0 else "right"
|
||||||
@@ -187,7 +203,7 @@ class CarInterface(CarInterfaceBase):
|
|||||||
return torque_values, lataccel_values
|
return torque_values, lataccel_values
|
||||||
|
|
||||||
def torque_from_lateral_accel(self) -> TorqueFromLateralAccelCallbackType:
|
def torque_from_lateral_accel(self) -> TorqueFromLateralAccelCallbackType:
|
||||||
if self.CP.carFingerprint in NON_LINEAR_TORQUE_PARAMS:
|
if get_nonlinear_torque_params(self.CP.carFingerprint) is not None:
|
||||||
torque_values, lataccel_values = self.get_lataccel_torque_siglin()
|
torque_values, lataccel_values = self.get_lataccel_torque_siglin()
|
||||||
|
|
||||||
def torque_from_lateral_accel_siglin(lateral_acceleration: float, torque_params: structs.CarParams.LateralTorqueTuning):
|
def torque_from_lateral_accel_siglin(lateral_acceleration: float, torque_params: structs.CarParams.LateralTorqueTuning):
|
||||||
@@ -197,7 +213,7 @@ class CarInterface(CarInterfaceBase):
|
|||||||
return self.torque_from_lateral_accel_linear
|
return self.torque_from_lateral_accel_linear
|
||||||
|
|
||||||
def lateral_accel_from_torque(self) -> LateralAccelFromTorqueCallbackType:
|
def lateral_accel_from_torque(self) -> LateralAccelFromTorqueCallbackType:
|
||||||
if self.CP.carFingerprint in NON_LINEAR_TORQUE_PARAMS:
|
if get_nonlinear_torque_params(self.CP.carFingerprint) is not None:
|
||||||
torque_values, lataccel_values = self.get_lataccel_torque_siglin()
|
torque_values, lataccel_values = self.get_lataccel_torque_siglin()
|
||||||
|
|
||||||
def lateral_accel_from_torque_siglin(torque: float, torque_params: structs.CarParams.LateralTorqueTuning):
|
def lateral_accel_from_torque_siglin(torque: float, torque_params: structs.CarParams.LateralTorqueTuning):
|
||||||
@@ -257,7 +273,6 @@ class CarInterface(CarInterfaceBase):
|
|||||||
|
|
||||||
kaofui_camera_cars = {
|
kaofui_camera_cars = {
|
||||||
CAR.CHEVROLET_VOLT_CAMERA,
|
CAR.CHEVROLET_VOLT_CAMERA,
|
||||||
CAR.CHEVROLET_VOLT_CC,
|
|
||||||
CAR.CHEVROLET_MALIBU_HYBRID_CC,
|
CAR.CHEVROLET_MALIBU_HYBRID_CC,
|
||||||
}
|
}
|
||||||
bolt_cc_camera_cars = {
|
bolt_cc_camera_cars = {
|
||||||
@@ -422,8 +437,10 @@ class CarInterface(CarInterfaceBase):
|
|||||||
ret.steerActuatorDelay = 0.2
|
ret.steerActuatorDelay = 0.2
|
||||||
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
|
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
|
||||||
|
|
||||||
elif candidate in (CAR.BUICK_LACROSSE, CAR.BUICK_LACROSSE_ASCM):
|
elif candidate in (CAR.BUICK_LACROSSE, CAR.BUICK_LACROSSE_ASCM, CAR.BUICK_LACROSSE_ASCM_19US):
|
||||||
CarInterfaceBase.configure_torque_tune(CAR.BUICK_LACROSSE, ret.lateralTuning)
|
CarInterfaceBase.configure_torque_tune(CAR.BUICK_LACROSSE, ret.lateralTuning)
|
||||||
|
if candidate == CAR.BUICK_LACROSSE_ASCM_19US:
|
||||||
|
ret.minSteerSpeed = 27 * CV.MPH_TO_MS
|
||||||
|
|
||||||
elif candidate == CAR.CADILLAC_ESCALADE:
|
elif candidate == CAR.CADILLAC_ESCALADE:
|
||||||
ret.minEnableSpeed = -1. # engage speed is decided by pcm
|
ret.minEnableSpeed = -1. # engage speed is decided by pcm
|
||||||
@@ -495,7 +512,7 @@ class CarInterface(CarInterfaceBase):
|
|||||||
ret.steerActuatorDelay = 0.2
|
ret.steerActuatorDelay = 0.2
|
||||||
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
|
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
|
||||||
|
|
||||||
elif candidate == CAR.CADILLAC_XT4:
|
elif candidate in (CAR.CADILLAC_XT4, CAR.CADILLAC_XT4_CC):
|
||||||
ret.steerActuatorDelay = 0.2
|
ret.steerActuatorDelay = 0.2
|
||||||
if not ret.openpilotLongitudinalControl:
|
if not ret.openpilotLongitudinalControl:
|
||||||
ret.minEnableSpeed = -1.
|
ret.minEnableSpeed = -1.
|
||||||
@@ -589,12 +606,16 @@ class CarInterface(CarInterfaceBase):
|
|||||||
ret.longitudinalTuning.kpV = [0.095, 0.085, 0.065, 0.050]
|
ret.longitudinalTuning.kpV = [0.095, 0.085, 0.065, 0.050]
|
||||||
ret.longitudinalTuning.kiV = [0.07, 0.10, 0.15, 0.24]
|
ret.longitudinalTuning.kiV = [0.07, 0.10, 0.15, 0.24]
|
||||||
ret.longitudinalTuning.kfDEPRECATED = 0.20
|
ret.longitudinalTuning.kfDEPRECATED = 0.20
|
||||||
|
ret.longitudinalActuatorDelay = 0.6
|
||||||
else:
|
else:
|
||||||
ret.longitudinalTuning.kfDEPRECATED = 0.25
|
ret.longitudinalTuning.kfDEPRECATED = 0.25
|
||||||
|
|
||||||
if is_bolt_2022_2023_pedal:
|
if is_bolt_2022_2023_pedal:
|
||||||
# Gen2 Bolt pedal-long should follow the no-ACC panda path.
|
# Gen2 Bolt pedal-long should follow the no-ACC panda path.
|
||||||
ret.safetyConfigs[0].safetyParam |= GMSafetyFlags.FLAG_GM_NO_ACC.value
|
ret.safetyConfigs[0].safetyParam |= GMSafetyFlags.FLAG_GM_NO_ACC.value
|
||||||
|
ret.startingState = True
|
||||||
|
ret.startAccel = 0.55
|
||||||
|
ret.vEgoStarting = max(ret.vEgoStarting, 0.35)
|
||||||
|
|
||||||
if candidate in (CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL, CAR.CHEVROLET_MALIBU_HYBRID_CC):
|
if candidate in (CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL, CAR.CHEVROLET_MALIBU_HYBRID_CC):
|
||||||
ret.safetyConfigs[0].safetyParam |= GMSafetyFlags.FLAG_GM_BOLT_2022_PEDAL.value
|
ret.safetyConfigs[0].safetyParam |= GMSafetyFlags.FLAG_GM_BOLT_2022_PEDAL.value
|
||||||
@@ -638,7 +659,7 @@ class CarInterface(CarInterfaceBase):
|
|||||||
ret.longitudinalTuning.kpBP = [0.0, 5.0, 15.0, 35.0]
|
ret.longitudinalTuning.kpBP = [0.0, 5.0, 15.0, 35.0]
|
||||||
ret.longitudinalTuning.kpV = [0.02, 0.03, 0.028, 0.022]
|
ret.longitudinalTuning.kpV = [0.02, 0.03, 0.028, 0.022]
|
||||||
ret.longitudinalTuning.kiBP = [0.0, 5.0, 15.0, 35.0]
|
ret.longitudinalTuning.kiBP = [0.0, 5.0, 15.0, 35.0]
|
||||||
ret.longitudinalTuning.kiV = [0.28, 0.26, 0.20, 0.16]
|
ret.longitudinalTuning.kiV = [0.20, 0.18, 0.13, 0.08]
|
||||||
|
|
||||||
elif candidate in CC_ONLY_CAR and not ret.enableGasInterceptorDEPRECATED:
|
elif candidate in CC_ONLY_CAR and not ret.enableGasInterceptorDEPRECATED:
|
||||||
ret.flags |= GMFlags.CC_LONG.value
|
ret.flags |= GMFlags.CC_LONG.value
|
||||||
@@ -663,6 +684,8 @@ class CarInterface(CarInterfaceBase):
|
|||||||
|
|
||||||
if candidate in CC_ONLY_CAR:
|
if candidate in CC_ONLY_CAR:
|
||||||
ret.safetyConfigs[0].safetyParam |= GMSafetyFlags.FLAG_GM_NO_ACC.value
|
ret.safetyConfigs[0].safetyParam |= GMSafetyFlags.FLAG_GM_NO_ACC.value
|
||||||
|
if candidate == CAR.CHEVROLET_VOLT_CC and ret.networkLocation == NetworkLocation.gateway:
|
||||||
|
ret.safetyConfigs[0].safetyParam |= GMSafetyFlags.FLAG_GM_VOLT_CC_GATEWAY.value
|
||||||
|
|
||||||
if candidate in SDGM_CAR and ACCELERATOR_POS_MSG not in fingerprint[CanBus.POWERTRAIN]:
|
if candidate in SDGM_CAR and ACCELERATOR_POS_MSG not in fingerprint[CanBus.POWERTRAIN]:
|
||||||
ret.flags |= GMFlags.FORCE_BRAKE_C9.value
|
ret.flags |= GMFlags.FORCE_BRAKE_C9.value
|
||||||
@@ -676,7 +699,7 @@ class CarInterface(CarInterfaceBase):
|
|||||||
|
|
||||||
if ACCELERATOR_POS_MSG not in fingerprint[CanBus.POWERTRAIN]:
|
if ACCELERATOR_POS_MSG not in fingerprint[CanBus.POWERTRAIN]:
|
||||||
ret.flags |= GMFlags.NO_ACCELERATOR_POS_MSG.value
|
ret.flags |= GMFlags.NO_ACCELERATOR_POS_MSG.value
|
||||||
if candidate == CAR.CHEVROLET_VOLT and ret.networkLocation == NetworkLocation.gateway:
|
if candidate in (CAR.CHEVROLET_VOLT, CAR.CHEVROLET_VOLT_CC) and ret.networkLocation == NetworkLocation.gateway:
|
||||||
# Reuse the no-camera safety bit as an ASCM Volt selector for the alternate EBCM brake path.
|
# Reuse the no-camera safety bit as an ASCM Volt selector for the alternate EBCM brake path.
|
||||||
ret.safetyConfigs[0].safetyParam |= GMSafetyFlags.FLAG_GM_NO_CAMERA.value
|
ret.safetyConfigs[0].safetyParam |= GMSafetyFlags.FLAG_GM_NO_CAMERA.value
|
||||||
|
|
||||||
@@ -689,6 +712,7 @@ class CarInterface(CarInterfaceBase):
|
|||||||
ret.safetyConfigs[0].safetyParam |= GMSafetyFlags.FLAG_GM_REMOTE_START_BOOTS_COMMA.value
|
ret.safetyConfigs[0].safetyParam |= GMSafetyFlags.FLAG_GM_REMOTE_START_BOOTS_COMMA.value
|
||||||
|
|
||||||
volt_stock_friction_brake_safety = (
|
volt_stock_friction_brake_safety = (
|
||||||
|
ret.openpilotLongitudinalControl and
|
||||||
(gm_auto_hold or volt_one_pedal_mode) and
|
(gm_auto_hold or volt_one_pedal_mode) and
|
||||||
candidate in {
|
candidate in {
|
||||||
CAR.CHEVROLET_VOLT,
|
CAR.CHEVROLET_VOLT,
|
||||||
@@ -699,12 +723,14 @@ class CarInterface(CarInterfaceBase):
|
|||||||
)
|
)
|
||||||
if volt_stock_friction_brake_safety:
|
if volt_stock_friction_brake_safety:
|
||||||
# Reuse the paddle-scheduler safety bit as a Volt stock friction-brake
|
# Reuse the paddle-scheduler safety bit as a Volt stock friction-brake
|
||||||
# marker on non-pedal paths. Both auto hold and one-pedal can run while
|
# marker on non-pedal paths. Auto hold and one-pedal can run while OP
|
||||||
# OP longitudinal is configured but not currently active, so the bit must
|
# longitudinal is configured but not currently active, so the bit must
|
||||||
# be present regardless of the current long-control mode.
|
# be present regardless of the current long-control mode. Do not expose
|
||||||
|
# the path at all when OP long is disabled in CarParams.
|
||||||
ret.safetyConfigs[0].safetyParam |= GMSafetyFlags.FLAG_GM_PANDA_PADDLE_SCHED.value
|
ret.safetyConfigs[0].safetyParam |= GMSafetyFlags.FLAG_GM_PANDA_PADDLE_SCHED.value
|
||||||
|
|
||||||
volt_stock_one_pedal_safety = (
|
volt_stock_one_pedal_safety = (
|
||||||
|
ret.openpilotLongitudinalControl and
|
||||||
volt_one_pedal_mode and
|
volt_one_pedal_mode and
|
||||||
candidate in {
|
candidate in {
|
||||||
CAR.CHEVROLET_VOLT,
|
CAR.CHEVROLET_VOLT,
|
||||||
@@ -717,6 +743,7 @@ class CarInterface(CarInterfaceBase):
|
|||||||
# Reuse the 3D1 scheduler bit as a Volt one-pedal marker on non-pedal
|
# Reuse the 3D1 scheduler bit as a Volt one-pedal marker on non-pedal
|
||||||
# ACC paths. The bit is ignored by the actual 3D1 scheduler unless the
|
# ACC paths. The bit is ignored by the actual 3D1 scheduler unless the
|
||||||
# car is on a pedal-long CC-only path, so this stays isolated from Bolt.
|
# car is on a pedal-long CC-only path, so this stays isolated from Bolt.
|
||||||
|
# Do not expose the path at all when OP long is disabled in CarParams.
|
||||||
ret.safetyConfigs[0].safetyParam |= GMSafetyFlags.FLAG_GM_PANDA_3D1_SCHED.value
|
ret.safetyConfigs[0].safetyParam |= GMSafetyFlags.FLAG_GM_PANDA_3D1_SCHED.value
|
||||||
|
|
||||||
use_panda_3d1_sched = (
|
use_panda_3d1_sched = (
|
||||||
@@ -758,6 +785,7 @@ class CarInterface(CarInterfaceBase):
|
|||||||
ret.alternativeExperience |= ALTERNATIVE_EXPERIENCE.GM_REMAP_CANCEL_TO_DISTANCE
|
ret.alternativeExperience |= ALTERNATIVE_EXPERIENCE.GM_REMAP_CANCEL_TO_DISTANCE
|
||||||
|
|
||||||
if candidate == CAR.CHEVROLET_TRAX:
|
if candidate == CAR.CHEVROLET_TRAX:
|
||||||
|
ret.steerActuatorDelay = 0.46
|
||||||
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
|
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|||||||
@@ -54,10 +54,14 @@ from opendbc.car.gm.carcontroller import (
|
|||||||
get_acc_dashboard_status_active,
|
get_acc_dashboard_status_active,
|
||||||
get_stock_cc_active_for_cancel,
|
get_stock_cc_active_for_cancel,
|
||||||
shape_bolt_acc_pedal_low_speed_friction,
|
shape_bolt_acc_pedal_low_speed_friction,
|
||||||
|
shape_truck_friction_brake,
|
||||||
|
shape_truck_pitch_accel,
|
||||||
shape_truck_positive_accel,
|
shape_truck_positive_accel,
|
||||||
|
smooth_truck_follow_accel,
|
||||||
should_use_fixed_stopping_brake,
|
should_use_fixed_stopping_brake,
|
||||||
should_activate_auto_hold,
|
should_activate_auto_hold,
|
||||||
should_activate_volt_one_pedal,
|
should_activate_volt_one_pedal,
|
||||||
|
should_send_acc_2cd,
|
||||||
should_send_adas_status,
|
should_send_adas_status,
|
||||||
should_send_stock_long_cancel,
|
should_send_stock_long_cancel,
|
||||||
should_spoof_dash_speed,
|
should_spoof_dash_speed,
|
||||||
@@ -356,6 +360,21 @@ def test_live_camera_path_does_not_send_pt_keepalive():
|
|||||||
assert get_adas_keepalive_step(cp, is_kaofui_car=True) is None
|
assert get_adas_keepalive_step(cp, is_kaofui_car=True) is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_acc_2cd_replacement_only_used_with_live_camera_path():
|
||||||
|
assert should_send_acc_2cd(SimpleNamespace(
|
||||||
|
carFingerprint=CAR.CHEVROLET_TRAILBLAZER, networkLocation=CarParams.NetworkLocation.fwdCamera, flags=0))
|
||||||
|
assert should_send_acc_2cd(SimpleNamespace(
|
||||||
|
carFingerprint=CAR.CHEVROLET_SILVERADO, networkLocation=CarParams.NetworkLocation.fwdCamera, flags=0))
|
||||||
|
assert not should_send_acc_2cd(SimpleNamespace(
|
||||||
|
carFingerprint=CAR.CHEVROLET_TRAILBLAZER, networkLocation=CarParams.NetworkLocation.fwdCamera, flags=GMFlags.NO_CAMERA.value))
|
||||||
|
assert not should_send_acc_2cd(SimpleNamespace(
|
||||||
|
carFingerprint=CAR.CHEVROLET_TRAILBLAZER, networkLocation=CarParams.NetworkLocation.gateway, flags=0))
|
||||||
|
assert not should_send_acc_2cd(SimpleNamespace(
|
||||||
|
carFingerprint=CAR.CHEVROLET_TRAILBLAZER_CC, networkLocation=CarParams.NetworkLocation.fwdCamera, flags=0))
|
||||||
|
assert not should_send_acc_2cd(SimpleNamespace(
|
||||||
|
carFingerprint=CAR.CHEVROLET_BLAZER, networkLocation=CarParams.NetworkLocation.fwdCamera, flags=0))
|
||||||
|
|
||||||
|
|
||||||
def test_ascm_int_cars_do_not_send_radar_status():
|
def test_ascm_int_cars_do_not_send_radar_status():
|
||||||
common = {
|
common = {
|
||||||
"networkLocation": CarParams.NetworkLocation.fwdCamera,
|
"networkLocation": CarParams.NetworkLocation.fwdCamera,
|
||||||
@@ -411,7 +430,7 @@ def test_volt_auto_hold_requires_toggle_supported_non_cc_only_volt_and_stock_saf
|
|||||||
),
|
),
|
||||||
True,
|
True,
|
||||||
)
|
)
|
||||||
assert supports_volt_auto_hold(
|
assert not supports_volt_auto_hold(
|
||||||
SimpleNamespace(
|
SimpleNamespace(
|
||||||
carFingerprint=CAR.CHEVROLET_VOLT,
|
carFingerprint=CAR.CHEVROLET_VOLT,
|
||||||
openpilotLongitudinalControl=False,
|
openpilotLongitudinalControl=False,
|
||||||
@@ -420,7 +439,7 @@ def test_volt_auto_hold_requires_toggle_supported_non_cc_only_volt_and_stock_saf
|
|||||||
),
|
),
|
||||||
True,
|
True,
|
||||||
)
|
)
|
||||||
assert supports_volt_auto_hold(
|
assert not supports_volt_auto_hold(
|
||||||
SimpleNamespace(
|
SimpleNamespace(
|
||||||
carFingerprint=CAR.CHEVROLET_VOLT_2019,
|
carFingerprint=CAR.CHEVROLET_VOLT_2019,
|
||||||
openpilotLongitudinalControl=False,
|
openpilotLongitudinalControl=False,
|
||||||
@@ -464,6 +483,7 @@ def test_volt_one_pedal_requires_toggle_supported_volt_stock_safety_and_ev_trans
|
|||||||
assert supports_volt_one_pedal(
|
assert supports_volt_one_pedal(
|
||||||
SimpleNamespace(
|
SimpleNamespace(
|
||||||
carFingerprint=CAR.CHEVROLET_VOLT_CAMERA,
|
carFingerprint=CAR.CHEVROLET_VOLT_CAMERA,
|
||||||
|
openpilotLongitudinalControl=True,
|
||||||
safetyConfigs=stock_safety,
|
safetyConfigs=stock_safety,
|
||||||
transmissionType=structs.CarParams.TransmissionType.direct,
|
transmissionType=structs.CarParams.TransmissionType.direct,
|
||||||
),
|
),
|
||||||
@@ -472,6 +492,7 @@ def test_volt_one_pedal_requires_toggle_supported_volt_stock_safety_and_ev_trans
|
|||||||
assert not supports_volt_one_pedal(
|
assert not supports_volt_one_pedal(
|
||||||
SimpleNamespace(
|
SimpleNamespace(
|
||||||
carFingerprint=CAR.CHEVROLET_VOLT_CAMERA,
|
carFingerprint=CAR.CHEVROLET_VOLT_CAMERA,
|
||||||
|
openpilotLongitudinalControl=True,
|
||||||
safetyConfigs=no_safety,
|
safetyConfigs=no_safety,
|
||||||
transmissionType=structs.CarParams.TransmissionType.direct,
|
transmissionType=structs.CarParams.TransmissionType.direct,
|
||||||
),
|
),
|
||||||
@@ -480,6 +501,7 @@ def test_volt_one_pedal_requires_toggle_supported_volt_stock_safety_and_ev_trans
|
|||||||
assert not supports_volt_one_pedal(
|
assert not supports_volt_one_pedal(
|
||||||
SimpleNamespace(
|
SimpleNamespace(
|
||||||
carFingerprint=CAR.CHEVROLET_VOLT_CC,
|
carFingerprint=CAR.CHEVROLET_VOLT_CC,
|
||||||
|
openpilotLongitudinalControl=True,
|
||||||
safetyConfigs=stock_safety,
|
safetyConfigs=stock_safety,
|
||||||
transmissionType=structs.CarParams.TransmissionType.direct,
|
transmissionType=structs.CarParams.TransmissionType.direct,
|
||||||
),
|
),
|
||||||
@@ -488,6 +510,7 @@ def test_volt_one_pedal_requires_toggle_supported_volt_stock_safety_and_ev_trans
|
|||||||
assert not supports_volt_one_pedal(
|
assert not supports_volt_one_pedal(
|
||||||
SimpleNamespace(
|
SimpleNamespace(
|
||||||
carFingerprint=CAR.CHEVROLET_VOLT_CAMERA,
|
carFingerprint=CAR.CHEVROLET_VOLT_CAMERA,
|
||||||
|
openpilotLongitudinalControl=True,
|
||||||
safetyConfigs=stock_safety,
|
safetyConfigs=stock_safety,
|
||||||
transmissionType=structs.CarParams.TransmissionType.automatic,
|
transmissionType=structs.CarParams.TransmissionType.automatic,
|
||||||
),
|
),
|
||||||
@@ -496,6 +519,16 @@ def test_volt_one_pedal_requires_toggle_supported_volt_stock_safety_and_ev_trans
|
|||||||
assert not supports_volt_one_pedal(
|
assert not supports_volt_one_pedal(
|
||||||
SimpleNamespace(
|
SimpleNamespace(
|
||||||
carFingerprint=CAR.CHEVROLET_VOLT_CAMERA,
|
carFingerprint=CAR.CHEVROLET_VOLT_CAMERA,
|
||||||
|
openpilotLongitudinalControl=False,
|
||||||
|
safetyConfigs=stock_safety,
|
||||||
|
transmissionType=structs.CarParams.TransmissionType.direct,
|
||||||
|
),
|
||||||
|
True,
|
||||||
|
)
|
||||||
|
assert not supports_volt_one_pedal(
|
||||||
|
SimpleNamespace(
|
||||||
|
carFingerprint=CAR.CHEVROLET_VOLT_CAMERA,
|
||||||
|
openpilotLongitudinalControl=True,
|
||||||
safetyConfigs=stock_safety,
|
safetyConfigs=stock_safety,
|
||||||
transmissionType=structs.CarParams.TransmissionType.direct,
|
transmissionType=structs.CarParams.TransmissionType.direct,
|
||||||
),
|
),
|
||||||
@@ -799,7 +832,7 @@ def test_calc_pedal_command_keeps_strong_positive_requests_responsive():
|
|||||||
def test_shape_truck_positive_accel_softens_small_highway_requests():
|
def test_shape_truck_positive_accel_softens_small_highway_requests():
|
||||||
shaped = shape_truck_positive_accel(0.12, 26.0, True)
|
shaped = shape_truck_positive_accel(0.12, 26.0, True)
|
||||||
|
|
||||||
assert 0.09 < shaped < 0.10
|
assert 0.08 < shaped < 0.095
|
||||||
|
|
||||||
|
|
||||||
def test_shape_truck_positive_accel_keeps_mid_follow_requests_available():
|
def test_shape_truck_positive_accel_keeps_mid_follow_requests_available():
|
||||||
@@ -817,6 +850,67 @@ def test_shape_truck_positive_accel_is_inactive_when_disabled_or_low_speed():
|
|||||||
assert shape_truck_positive_accel(0.12, 6.0, True) == 0.12
|
assert shape_truck_positive_accel(0.12, 6.0, True) == 0.12
|
||||||
|
|
||||||
|
|
||||||
|
def test_shape_truck_positive_accel_preserves_more_follow_authority_with_lead():
|
||||||
|
base = shape_truck_positive_accel(0.28, 26.0, True)
|
||||||
|
relieved = shape_truck_positive_accel(0.28, 26.0, True, lead_visible=True, set_speed_error=6.0)
|
||||||
|
|
||||||
|
assert relieved > base
|
||||||
|
assert relieved < 0.28
|
||||||
|
|
||||||
|
|
||||||
|
def test_shape_truck_positive_accel_does_not_relax_without_speed_error():
|
||||||
|
base = shape_truck_positive_accel(0.28, 26.0, True)
|
||||||
|
no_error = shape_truck_positive_accel(0.28, 26.0, True, lead_visible=True, set_speed_error=0.0)
|
||||||
|
|
||||||
|
assert no_error == base
|
||||||
|
|
||||||
|
|
||||||
|
def test_shape_truck_positive_accel_keeps_more_highway_follow_authority():
|
||||||
|
city = shape_truck_positive_accel(0.28, 26.0, True)
|
||||||
|
highway = shape_truck_positive_accel(0.28, 34.0, True)
|
||||||
|
|
||||||
|
assert highway >= city
|
||||||
|
|
||||||
|
|
||||||
|
def test_smooth_truck_follow_accel_slews_small_highway_commands():
|
||||||
|
shaped = smooth_truck_follow_accel(0.50, 0.0, 30.0, True, True, False)
|
||||||
|
|
||||||
|
assert shaped == pytest.approx(0.06)
|
||||||
|
|
||||||
|
|
||||||
|
def test_smooth_truck_follow_accel_does_not_delay_safety_requests():
|
||||||
|
assert smooth_truck_follow_accel(-0.40, 0.20, 30.0, True, True, False) == -0.40
|
||||||
|
assert smooth_truck_follow_accel(0.20, -0.40, 30.0, True, True, False) == 0.20
|
||||||
|
assert smooth_truck_follow_accel(-0.20, 0.20, 30.0, True, True, True) == -0.20
|
||||||
|
assert smooth_truck_follow_accel(-0.20, 0.20, 20.0, True, True, False) == -0.20
|
||||||
|
assert smooth_truck_follow_accel(-0.20, 0.20, 30.0, True, False, False) == -0.20
|
||||||
|
|
||||||
|
|
||||||
|
def test_shape_truck_pitch_accel_attenuates_highway_grade_feedforward():
|
||||||
|
assert shape_truck_pitch_accel(-0.30, 30.0, True) == pytest.approx(-0.0825)
|
||||||
|
assert shape_truck_pitch_accel(0.30, 30.0, True) == pytest.approx(0.0825)
|
||||||
|
|
||||||
|
|
||||||
|
def test_shape_truck_pitch_accel_is_inactive_without_truck_tuning():
|
||||||
|
assert shape_truck_pitch_accel(-0.30, 30.0, False) == pytest.approx(-0.30)
|
||||||
|
|
||||||
|
|
||||||
|
def test_shape_truck_friction_brake_suppresses_boundary_chatter():
|
||||||
|
assert shape_truck_friction_brake(14, -0.3, False, False) == (0, False)
|
||||||
|
|
||||||
|
|
||||||
|
def test_shape_truck_friction_brake_uses_hysteresis_once_engaged():
|
||||||
|
assert shape_truck_friction_brake(39, -0.3, False, False) == (0, False)
|
||||||
|
assert shape_truck_friction_brake(40, -0.3, False, False) == (40, True)
|
||||||
|
assert shape_truck_friction_brake(14, -0.3, False, True) == (14, True)
|
||||||
|
assert shape_truck_friction_brake(8, -0.3, False, True) == (0, False)
|
||||||
|
|
||||||
|
|
||||||
|
def test_shape_truck_friction_brake_never_delays_meaningful_braking():
|
||||||
|
assert shape_truck_friction_brake(5, -0.85, False, False) == (5, True)
|
||||||
|
assert shape_truck_friction_brake(5, -0.2, True, False) == (5, True)
|
||||||
|
|
||||||
|
|
||||||
def test_use_interceptor_sng_launch_requires_actual_near_stop():
|
def test_use_interceptor_sng_launch_requires_actual_near_stop():
|
||||||
CP = SimpleNamespace(vEgoStarting=0.25)
|
CP = SimpleNamespace(vEgoStarting=0.25)
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ from opendbc.car.gm import gmcan
|
|||||||
from opendbc.car.gm.carstate import CarState as GMCarState, get_hard_cruise_buttons, update_auto_hold_drive_timers
|
from opendbc.car.gm.carstate import CarState as GMCarState, get_hard_cruise_buttons, update_auto_hold_drive_timers
|
||||||
from opendbc.car.gm.carcontroller import (
|
from opendbc.car.gm.carcontroller import (
|
||||||
VisualAlert,
|
VisualAlert,
|
||||||
|
get_acc_dashboard_always_one,
|
||||||
get_acc_dashboard_fcw_alert,
|
get_acc_dashboard_fcw_alert,
|
||||||
get_volt_one_pedal_lift_brake,
|
get_volt_one_pedal_lift_brake,
|
||||||
should_send_acc_dashboard_status,
|
should_send_acc_dashboard_status,
|
||||||
@@ -19,6 +20,7 @@ from opendbc.car.gm.carcontroller import (
|
|||||||
)
|
)
|
||||||
import opendbc.car.gm.interface as gm_interface
|
import opendbc.car.gm.interface as gm_interface
|
||||||
from opendbc.car.common.conversions import Conversions as CV
|
from opendbc.car.common.conversions import Conversions as CV
|
||||||
|
from opendbc.car.gps import CHEVROLET_BOLT_GPS_CARS, CHEVROLET_BOLT_GPS_MESSAGES, get_car_gps_config, parse_chevrolet_bolt_can_gps
|
||||||
from opendbc.car.gm.fingerprints import FINGERPRINTS
|
from opendbc.car.gm.fingerprints import FINGERPRINTS
|
||||||
from opendbc.car.gm.values import ASCM_INT, CAMERA_ACC_CAR, CAR, CC_ONLY_CAR, DBC, GM_RX_OFFSET, CarControllerParams, CruiseButtons, GMFlags, GMSafetyFlags
|
from opendbc.car.gm.values import ASCM_INT, CAMERA_ACC_CAR, CAR, CC_ONLY_CAR, DBC, GM_RX_OFFSET, CarControllerParams, CruiseButtons, GMFlags, GMSafetyFlags
|
||||||
from opendbc.safety import ALTERNATIVE_EXPERIENCE
|
from opendbc.safety import ALTERNATIVE_EXPERIENCE
|
||||||
@@ -64,7 +66,76 @@ class TestGMFingerprint:
|
|||||||
assert finger.get(required_addr) == 8, required_addr
|
assert finger.get(required_addr) == 8, required_addr
|
||||||
|
|
||||||
|
|
||||||
|
class TestBoltGps:
|
||||||
|
@parameterized.expand(CHEVROLET_BOLT_GPS_CARS)
|
||||||
|
def test_all_bolt_generations_are_registered(self, car_model):
|
||||||
|
config = get_car_gps_config(SimpleNamespace(carFingerprint=car_model, brand="gm"))
|
||||||
|
assert config is not None
|
||||||
|
assert config.messages == CHEVROLET_BOLT_GPS_MESSAGES
|
||||||
|
gps = parse_chevrolet_bolt_can_gps({
|
||||||
|
"GPSLatitude": 145292743.0,
|
||||||
|
"GPSLongitude": -267520892.0,
|
||||||
|
})
|
||||||
|
assert gps is not None
|
||||||
|
assert gps["hasFix"]
|
||||||
|
assert gps["latitude"] == pytest.approx(40.3590953)
|
||||||
|
assert gps["longitude"] == pytest.approx(-74.3113589)
|
||||||
|
|
||||||
|
def test_invalid_bolt_position_does_not_become_a_fix(self):
|
||||||
|
gps = parse_chevrolet_bolt_can_gps({"GPSLatitude": 0.0, "GPSLongitude": -2147483648.0})
|
||||||
|
assert gps is not None
|
||||||
|
assert not gps["hasFix"]
|
||||||
|
assert gps["latitude"] == 0.0
|
||||||
|
assert gps["longitude"] == 0.0
|
||||||
|
|
||||||
|
@parameterized.expand(CHEVROLET_BOLT_GPS_CARS)
|
||||||
|
def test_gps_message_is_added_to_powertrain_parser(self, car_model):
|
||||||
|
cp = SimpleNamespace(
|
||||||
|
brand="gm",
|
||||||
|
carFingerprint=car_model,
|
||||||
|
flags=0,
|
||||||
|
networkLocation=structs.CarParams.NetworkLocation.gateway,
|
||||||
|
transmissionType=structs.CarParams.TransmissionType.direct,
|
||||||
|
enableBsm=False,
|
||||||
|
enableGasInterceptorDEPRECATED=False,
|
||||||
|
)
|
||||||
|
parsers = GMCarState.get_can_parsers(cp)
|
||||||
|
assert all(message in parsers[Bus.pt].vl for message in CHEVROLET_BOLT_GPS_MESSAGES)
|
||||||
|
|
||||||
|
|
||||||
class TestGMInterface:
|
class TestGMInterface:
|
||||||
|
@parameterized.expand([
|
||||||
|
CAR.CHEVROLET_BOLT_CC_2017,
|
||||||
|
CAR.CHEVROLET_BOLT_CC_2018_2021,
|
||||||
|
CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL,
|
||||||
|
CAR.CHEVROLET_BOLT_CC_2022_2023,
|
||||||
|
CAR.CHEVROLET_MALIBU_HYBRID_CC,
|
||||||
|
])
|
||||||
|
def test_bolt_pedal_long_uses_shared_planning_delay_without_retuning_pid(self, car_model):
|
||||||
|
CarInterface = interfaces[car_model]
|
||||||
|
fingerprint = _empty_fingerprint()
|
||||||
|
fingerprint[0][0x201] = 8
|
||||||
|
params = Params()
|
||||||
|
|
||||||
|
try:
|
||||||
|
params.put_bool("GMPedalLongitudinal", True)
|
||||||
|
car_params = CarInterface.get_params(
|
||||||
|
car_model,
|
||||||
|
fingerprint,
|
||||||
|
[],
|
||||||
|
alpha_long=False,
|
||||||
|
is_release=False,
|
||||||
|
docs=False,
|
||||||
|
starpilot_toggles=_test_starpilot_toggles(),
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
params.remove("GMPedalLongitudinal")
|
||||||
|
|
||||||
|
assert car_params.longitudinalActuatorDelay == pytest.approx(0.6)
|
||||||
|
assert list(car_params.longitudinalTuning.kpV) == pytest.approx([0.095, 0.085, 0.065, 0.050])
|
||||||
|
assert list(car_params.longitudinalTuning.kiV) == pytest.approx([0.07, 0.10, 0.15, 0.24])
|
||||||
|
assert car_params.longitudinalTuning.kfDEPRECATED == pytest.approx(0.20)
|
||||||
|
|
||||||
def test_bolt_acc_pedal_pid_accel_limits_keep_full_negative_authority(self):
|
def test_bolt_acc_pedal_pid_accel_limits_keep_full_negative_authority(self):
|
||||||
cp = SimpleNamespace(
|
cp = SimpleNamespace(
|
||||||
enableGasInterceptorDEPRECATED=True,
|
enableGasInterceptorDEPRECATED=True,
|
||||||
@@ -168,6 +239,60 @@ class TestGMInterface:
|
|||||||
assert car_params.flags & GMFlags.NO_CAMERA.value
|
assert car_params.flags & GMFlags.NO_CAMERA.value
|
||||||
assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_NO_CAMERA.value
|
assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_NO_CAMERA.value
|
||||||
|
|
||||||
|
def test_volt_cc_obd_gateway_uses_cc_long_no_camera_path(self):
|
||||||
|
CarInterface = interfaces[CAR.CHEVROLET_VOLT_CC]
|
||||||
|
car_params = CarInterface.get_params(
|
||||||
|
CAR.CHEVROLET_VOLT_CC,
|
||||||
|
_empty_fingerprint(),
|
||||||
|
[],
|
||||||
|
alpha_long=False,
|
||||||
|
is_release=False,
|
||||||
|
docs=False,
|
||||||
|
starpilot_toggles=_test_starpilot_toggles(),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert car_params.networkLocation == structs.CarParams.NetworkLocation.gateway
|
||||||
|
assert car_params.flags & GMFlags.CC_LONG.value
|
||||||
|
assert car_params.flags & GMFlags.NO_CAMERA.value
|
||||||
|
assert not (car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.HW_CAM.value)
|
||||||
|
assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_CC_LONG.value
|
||||||
|
assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_NO_ACC.value
|
||||||
|
assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_NO_CAMERA.value
|
||||||
|
|
||||||
|
parsers = CarInterface.CarState.get_can_parsers(car_params)
|
||||||
|
assert "ECMCruiseControl" in parsers[Bus.pt].vl
|
||||||
|
assert not parsers[Bus.cam].vl
|
||||||
|
|
||||||
|
def test_other_cc_only_gateway_does_not_use_volt_cc_safety_path(self):
|
||||||
|
CarInterface = interfaces[CAR.CHEVROLET_SILVERADO_CC]
|
||||||
|
car_params = CarInterface.get_params(
|
||||||
|
CAR.CHEVROLET_SILVERADO_CC,
|
||||||
|
_empty_fingerprint(),
|
||||||
|
[],
|
||||||
|
alpha_long=False,
|
||||||
|
is_release=False,
|
||||||
|
docs=False,
|
||||||
|
starpilot_toggles=_test_starpilot_toggles(),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert car_params.networkLocation == structs.CarParams.NetworkLocation.gateway
|
||||||
|
assert not (car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_VOLT_CC_GATEWAY.value)
|
||||||
|
|
||||||
|
def test_volt_ascm_sparse_fingerprint_without_camera_does_not_set_no_camera(self):
|
||||||
|
CarInterface = interfaces[CAR.CHEVROLET_VOLT_ASCM]
|
||||||
|
fingerprint = {
|
||||||
|
0: FINGERPRINTS[CAR.CHEVROLET_VOLT][0].copy(),
|
||||||
|
1: {},
|
||||||
|
}
|
||||||
|
fingerprint[0][0x2FF] = 8 # SASCM detected
|
||||||
|
|
||||||
|
car_params = CarInterface.get_params(CAR.CHEVROLET_VOLT_ASCM, fingerprint, [], alpha_long=False, is_release=False,
|
||||||
|
docs=False, starpilot_toggles=_test_starpilot_toggles())
|
||||||
|
|
||||||
|
assert not (car_params.flags & GMFlags.NO_CAMERA.value)
|
||||||
|
assert not (car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_NO_CAMERA.value)
|
||||||
|
assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.HW_ASCM_INT.value
|
||||||
|
|
||||||
def test_silverado_alpha_long_uses_trimmed_longitudinal_tune(self):
|
def test_silverado_alpha_long_uses_trimmed_longitudinal_tune(self):
|
||||||
CarInterface = interfaces[CAR.CHEVROLET_SILVERADO]
|
CarInterface = interfaces[CAR.CHEVROLET_SILVERADO]
|
||||||
fingerprint = _empty_fingerprint()
|
fingerprint = _empty_fingerprint()
|
||||||
@@ -181,7 +306,7 @@ class TestGMInterface:
|
|||||||
assert list(car_params.longitudinalTuning.kpBP) == pytest.approx([0.0, 5.0, 15.0, 35.0])
|
assert list(car_params.longitudinalTuning.kpBP) == pytest.approx([0.0, 5.0, 15.0, 35.0])
|
||||||
assert list(car_params.longitudinalTuning.kpV) == pytest.approx([0.02, 0.03, 0.028, 0.022])
|
assert list(car_params.longitudinalTuning.kpV) == pytest.approx([0.02, 0.03, 0.028, 0.022])
|
||||||
assert list(car_params.longitudinalTuning.kiBP) == pytest.approx([0.0, 5.0, 15.0, 35.0])
|
assert list(car_params.longitudinalTuning.kiBP) == pytest.approx([0.0, 5.0, 15.0, 35.0])
|
||||||
assert list(car_params.longitudinalTuning.kiV) == pytest.approx([0.28, 0.26, 0.20, 0.16])
|
assert list(car_params.longitudinalTuning.kiV) == pytest.approx([0.20, 0.18, 0.13, 0.08])
|
||||||
|
|
||||||
def test_blazer_uses_softer_low_speed_stop_hold_tune(self):
|
def test_blazer_uses_softer_low_speed_stop_hold_tune(self):
|
||||||
CarInterface = interfaces[CAR.CHEVROLET_BLAZER]
|
CarInterface = interfaces[CAR.CHEVROLET_BLAZER]
|
||||||
@@ -235,6 +360,22 @@ class TestGMInterface:
|
|||||||
assert car_params.openpilotLongitudinalControl
|
assert car_params.openpilotLongitudinalControl
|
||||||
assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_PANDA_PADDLE_SCHED.value
|
assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_PANDA_PADDLE_SCHED.value
|
||||||
|
|
||||||
|
def test_volt_auto_hold_does_not_set_stock_hold_safety_bit_with_op_long_disabled(self):
|
||||||
|
CarInterface = interfaces[CAR.CHEVROLET_VOLT_ASCM]
|
||||||
|
fingerprint = _empty_fingerprint()
|
||||||
|
fingerprint[0][0x2FF] = 8
|
||||||
|
|
||||||
|
params = Params()
|
||||||
|
try:
|
||||||
|
params.put_bool("GMAutoHold", True)
|
||||||
|
car_params = CarInterface.get_params(CAR.CHEVROLET_VOLT_ASCM, fingerprint, [], alpha_long=False, is_release=False,
|
||||||
|
docs=False, starpilot_toggles=_test_starpilot_toggles())
|
||||||
|
finally:
|
||||||
|
params.remove("GMAutoHold")
|
||||||
|
|
||||||
|
assert not car_params.openpilotLongitudinalControl
|
||||||
|
assert not (car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_PANDA_PADDLE_SCHED.value)
|
||||||
|
|
||||||
def test_volt_one_pedal_sets_stock_hold_safety_bit_without_auto_hold(self):
|
def test_volt_one_pedal_sets_stock_hold_safety_bit_without_auto_hold(self):
|
||||||
CarInterface = interfaces[CAR.CHEVROLET_VOLT_ASCM]
|
CarInterface = interfaces[CAR.CHEVROLET_VOLT_ASCM]
|
||||||
fingerprint = _empty_fingerprint()
|
fingerprint = _empty_fingerprint()
|
||||||
@@ -254,6 +395,25 @@ class TestGMInterface:
|
|||||||
assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_PANDA_PADDLE_SCHED.value
|
assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_PANDA_PADDLE_SCHED.value
|
||||||
assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_PANDA_3D1_SCHED.value
|
assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_PANDA_3D1_SCHED.value
|
||||||
|
|
||||||
|
def test_volt_one_pedal_does_not_set_stock_hold_safety_bits_with_op_long_disabled(self):
|
||||||
|
CarInterface = interfaces[CAR.CHEVROLET_VOLT_ASCM]
|
||||||
|
fingerprint = _empty_fingerprint()
|
||||||
|
fingerprint[0][0x2FF] = 8
|
||||||
|
|
||||||
|
params = Params()
|
||||||
|
try:
|
||||||
|
params.put_bool("GMAutoHold", False)
|
||||||
|
params.put_bool("VoltOnePedalMode", True)
|
||||||
|
car_params = CarInterface.get_params(CAR.CHEVROLET_VOLT_ASCM, fingerprint, [], alpha_long=False, is_release=False,
|
||||||
|
docs=False, starpilot_toggles=_test_starpilot_toggles())
|
||||||
|
finally:
|
||||||
|
params.remove("GMAutoHold")
|
||||||
|
params.remove("VoltOnePedalMode")
|
||||||
|
|
||||||
|
assert not car_params.openpilotLongitudinalControl
|
||||||
|
assert not (car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_PANDA_PADDLE_SCHED.value)
|
||||||
|
assert not (car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_PANDA_3D1_SCHED.value)
|
||||||
|
|
||||||
@parameterized.expand(VOLT_CARS)
|
@parameterized.expand(VOLT_CARS)
|
||||||
def test_volt_bsm_is_enabled_without_fingerprint_match(self, car_model):
|
def test_volt_bsm_is_enabled_without_fingerprint_match(self, car_model):
|
||||||
CarInterface = interfaces[car_model]
|
CarInterface = interfaces[car_model]
|
||||||
@@ -311,6 +471,9 @@ class TestGMInterface:
|
|||||||
assert car_params.alternativeExperience & ALTERNATIVE_EXPERIENCE.GM_REMAP_CANCEL_TO_DISTANCE
|
assert car_params.alternativeExperience & ALTERNATIVE_EXPERIENCE.GM_REMAP_CANCEL_TO_DISTANCE
|
||||||
assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_BOLT_2022_PEDAL.value
|
assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_BOLT_2022_PEDAL.value
|
||||||
assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_PANDA_PADDLE_SCHED.value
|
assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_PANDA_PADDLE_SCHED.value
|
||||||
|
assert car_params.startingState
|
||||||
|
assert car_params.startAccel == pytest.approx(0.55)
|
||||||
|
assert car_params.vEgoStarting == pytest.approx(0.35)
|
||||||
|
|
||||||
def test_cadillac_xt5_sdgm_sascm_gates_alpha_long(self):
|
def test_cadillac_xt5_sdgm_sascm_gates_alpha_long(self):
|
||||||
CarInterface = interfaces[CAR.CADILLAC_XT5]
|
CarInterface = interfaces[CAR.CADILLAC_XT5]
|
||||||
@@ -379,6 +542,19 @@ class TestGMInterface:
|
|||||||
assert high_torque == pytest.approx(linear_high_torque, rel=0.03)
|
assert high_torque == pytest.approx(linear_high_torque, rel=0.03)
|
||||||
assert torque_from_lataccel(-low_lataccel, car_params.lateralTuning.torque) == pytest.approx(-low_torque, rel=1e-6)
|
assert torque_from_lataccel(-low_lataccel, car_params.lateralTuning.torque) == pytest.approx(-low_torque, rel=1e-6)
|
||||||
|
|
||||||
|
@parameterized.expand((CAR.CHEVROLET_VOLT_ASCM, CAR.CHEVROLET_VOLT_CAMERA, CAR.CHEVROLET_VOLT_CC, CAR.CHEVROLET_VOLT_2019))
|
||||||
|
def test_volt_integration_variants_share_nonlinear_torque_curve(self, candidate):
|
||||||
|
assert gm_interface.get_nonlinear_torque_params(candidate) == gm_interface.NON_LINEAR_TORQUE_PARAMS[CAR.CHEVROLET_VOLT]
|
||||||
|
|
||||||
|
CarInterface = interfaces[candidate]
|
||||||
|
car_params = CarInterface.get_non_essential_params(candidate)
|
||||||
|
ci = CarInterface(car_params, custom.StarPilotCarParams.new_message())
|
||||||
|
torque_from_lataccel = ci.torque_from_lateral_accel()
|
||||||
|
|
||||||
|
left_torque = torque_from_lataccel(0.5, car_params.lateralTuning.torque)
|
||||||
|
right_torque = torque_from_lataccel(-0.5, car_params.lateralTuning.torque)
|
||||||
|
assert left_torque > abs(right_torque)
|
||||||
|
|
||||||
|
|
||||||
class TestGMCarController:
|
class TestGMCarController:
|
||||||
def test_dash_speed_spoof_respects_live_stock_acc_toggles(self):
|
def test_dash_speed_spoof_respects_live_stock_acc_toggles(self):
|
||||||
@@ -434,6 +610,7 @@ class TestGMCarController:
|
|||||||
CP=SimpleNamespace(
|
CP=SimpleNamespace(
|
||||||
carFingerprint=CAR.CHEVROLET_VOLT_CC,
|
carFingerprint=CAR.CHEVROLET_VOLT_CC,
|
||||||
flags=0,
|
flags=0,
|
||||||
|
networkLocation=structs.CarParams.NetworkLocation.fwdCamera,
|
||||||
minEnableSpeed=24 * CV.MPH_TO_MS,
|
minEnableSpeed=24 * CV.MPH_TO_MS,
|
||||||
),
|
),
|
||||||
buttons_counter=2,
|
buttons_counter=2,
|
||||||
@@ -455,6 +632,7 @@ class TestGMCarController:
|
|||||||
CP=SimpleNamespace(
|
CP=SimpleNamespace(
|
||||||
carFingerprint=CAR.CHEVROLET_VOLT_CC,
|
carFingerprint=CAR.CHEVROLET_VOLT_CC,
|
||||||
flags=GMFlags.NO_CAMERA.value,
|
flags=GMFlags.NO_CAMERA.value,
|
||||||
|
networkLocation=structs.CarParams.NetworkLocation.gateway,
|
||||||
minEnableSpeed=24 * CV.MPH_TO_MS,
|
minEnableSpeed=24 * CV.MPH_TO_MS,
|
||||||
),
|
),
|
||||||
buttons_counter=2,
|
buttons_counter=2,
|
||||||
@@ -490,6 +668,127 @@ class TestGMCarController:
|
|||||||
|
|
||||||
assert [msg[2] for msg in msgs] == [0]
|
assert [msg[2] for msg in msgs] == [0]
|
||||||
|
|
||||||
|
@parameterized.expand([
|
||||||
|
CAR.CHEVROLET_BOLT_CC_2017,
|
||||||
|
CAR.CHEVROLET_BOLT_CC_2018_2021,
|
||||||
|
CAR.CHEVROLET_BOLT_CC_2022_2023,
|
||||||
|
])
|
||||||
|
def test_bolt_cc_redneck_ignores_small_setpoint_error(self, car_model):
|
||||||
|
packer = CANPacker(DBC[car_model][Bus.pt])
|
||||||
|
controller = SimpleNamespace(frame=int(2.0 / DT_CTRL), last_button_frame=0, apply_speed=0)
|
||||||
|
cs = SimpleNamespace(
|
||||||
|
CP=SimpleNamespace(
|
||||||
|
carFingerprint=car_model,
|
||||||
|
minEnableSpeed=24 * CV.MPH_TO_MS,
|
||||||
|
),
|
||||||
|
buttons_counter=2,
|
||||||
|
out=SimpleNamespace(
|
||||||
|
vEgo=(60.6 * CV.MPH_TO_MS) / 1.01,
|
||||||
|
cruiseState=SimpleNamespace(speed=60 * CV.MPH_TO_MS),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
msgs = gmcan.create_gm_cc_spam_command(packer, controller, cs, SimpleNamespace(accel=0.0), SimpleNamespace(is_metric=False))
|
||||||
|
|
||||||
|
assert msgs == []
|
||||||
|
assert controller.apply_speed == 60
|
||||||
|
|
||||||
|
def test_non_bolt_cc_redneck_keeps_existing_setpoint_selector(self):
|
||||||
|
packer = CANPacker(DBC[CAR.CHEVROLET_EQUINOX_CC][Bus.pt])
|
||||||
|
controller = SimpleNamespace(frame=int(2.0 / DT_CTRL), last_button_frame=0, apply_speed=0)
|
||||||
|
cs = SimpleNamespace(
|
||||||
|
CP=SimpleNamespace(
|
||||||
|
carFingerprint=CAR.CHEVROLET_EQUINOX_CC,
|
||||||
|
flags=GMFlags.CC_LONG.value,
|
||||||
|
minEnableSpeed=24 * CV.MPH_TO_MS,
|
||||||
|
),
|
||||||
|
buttons_counter=2,
|
||||||
|
out=SimpleNamespace(
|
||||||
|
vEgo=(60.6 * CV.MPH_TO_MS) / 1.01,
|
||||||
|
cruiseState=SimpleNamespace(speed=60 * CV.MPH_TO_MS),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
msgs = gmcan.create_gm_cc_spam_command(packer, controller, cs, SimpleNamespace(accel=0.0), SimpleNamespace(is_metric=False))
|
||||||
|
|
||||||
|
assert len(msgs) == 1
|
||||||
|
assert controller.apply_speed == 61
|
||||||
|
|
||||||
|
def test_bolt_cc_redneck_requires_persistent_acceleration_after_deceleration(self):
|
||||||
|
cp = SimpleNamespace(carFingerprint=CAR.CHEVROLET_BOLT_CC_2018_2021)
|
||||||
|
controller = SimpleNamespace(
|
||||||
|
frame=100,
|
||||||
|
gm_cc_last_direction_button=CruiseButtons.DECEL_SET,
|
||||||
|
gm_cc_last_direction_frame=100,
|
||||||
|
gm_cc_pending_reverse_button=CruiseButtons.INIT,
|
||||||
|
gm_cc_pending_reverse_frame=0,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert gmcan.stabilize_bolt_cc_button(controller, cp, CruiseButtons.RES_ACCEL) == CruiseButtons.INIT
|
||||||
|
controller.frame += int(0.5 / DT_CTRL)
|
||||||
|
assert gmcan.stabilize_bolt_cc_button(controller, cp, CruiseButtons.RES_ACCEL) == CruiseButtons.INIT
|
||||||
|
controller.frame += int(0.11 / DT_CTRL)
|
||||||
|
assert gmcan.stabilize_bolt_cc_button(controller, cp, CruiseButtons.RES_ACCEL) == CruiseButtons.RES_ACCEL
|
||||||
|
|
||||||
|
def test_bolt_cc_redneck_deceleration_is_not_debounced(self):
|
||||||
|
cp = SimpleNamespace(carFingerprint=CAR.CHEVROLET_BOLT_CC_2018_2021)
|
||||||
|
controller = SimpleNamespace(
|
||||||
|
frame=100,
|
||||||
|
gm_cc_last_direction_button=CruiseButtons.RES_ACCEL,
|
||||||
|
gm_cc_last_direction_frame=100,
|
||||||
|
gm_cc_pending_reverse_button=CruiseButtons.INIT,
|
||||||
|
gm_cc_pending_reverse_frame=0,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert gmcan.stabilize_bolt_cc_button(controller, cp, CruiseButtons.DECEL_SET) == CruiseButtons.DECEL_SET
|
||||||
|
|
||||||
|
def test_xt4_cc_redneck_spam_matches_physical_button_burst(self):
|
||||||
|
packer = CANPacker(DBC[CAR.CADILLAC_XT4_CC][Bus.pt])
|
||||||
|
controller = SimpleNamespace(
|
||||||
|
frame=int(0.3 / DT_CTRL),
|
||||||
|
last_button_frame=0,
|
||||||
|
apply_speed=0,
|
||||||
|
malibu_button_phase=0,
|
||||||
|
xt4_cc_button_burst_remaining=0,
|
||||||
|
xt4_cc_button_burst_button=CruiseButtons.INIT,
|
||||||
|
xt4_cc_button_burst_last_counter=-1,
|
||||||
|
xt4_cc_button_observed_counter=-1,
|
||||||
|
xt4_cc_button_counter_frame=0,
|
||||||
|
)
|
||||||
|
cs = SimpleNamespace(
|
||||||
|
CP=SimpleNamespace(
|
||||||
|
carFingerprint=CAR.CADILLAC_XT4_CC,
|
||||||
|
flags=GMFlags.CC_LONG.value,
|
||||||
|
minEnableSpeed=24 * CV.MPH_TO_MS,
|
||||||
|
),
|
||||||
|
buttons_counter=0,
|
||||||
|
out=SimpleNamespace(
|
||||||
|
vEgo=25.0,
|
||||||
|
cruiseState=SimpleNamespace(speed=20.0),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
actuators = SimpleNamespace(accel=1.0)
|
||||||
|
|
||||||
|
dats = []
|
||||||
|
send_counts = []
|
||||||
|
for counter in (0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 0, 0, 0, 1, 1, 1):
|
||||||
|
cs.buttons_counter = counter
|
||||||
|
msgs = gmcan.create_gm_cc_spam_command(packer, controller, cs, actuators, SimpleNamespace(is_metric=False))
|
||||||
|
send_counts.append(len(msgs))
|
||||||
|
dats.extend(bytes(msg[1]).hex() for msg in msgs)
|
||||||
|
controller.frame += 1
|
||||||
|
|
||||||
|
assert send_counts == [0, 1, 0] * gmcan.XT4_CC_BUTTON_BURST_FRAMES
|
||||||
|
assert dats == [
|
||||||
|
"000000010125de",
|
||||||
|
"00000001022acd",
|
||||||
|
"00000001032fbc",
|
||||||
|
"000000010020ef",
|
||||||
|
"000000010125de",
|
||||||
|
"00000001022acd",
|
||||||
|
]
|
||||||
|
assert controller.xt4_cc_button_burst_remaining == 0
|
||||||
|
|
||||||
def test_acc_dashboard_command_preserves_raw_fcw_alert_level(self):
|
def test_acc_dashboard_command_preserves_raw_fcw_alert_level(self):
|
||||||
packer = CANPacker(DBC[CAR.CHEVROLET_BOLT_ACC_2022_2023][Bus.pt])
|
packer = CANPacker(DBC[CAR.CHEVROLET_BOLT_ACC_2022_2023][Bus.pt])
|
||||||
parser = CANParser(DBC[CAR.CHEVROLET_BOLT_ACC_2022_2023][Bus.pt], [("ASCMActiveCruiseControlStatus", 0)], 0)
|
parser = CANParser(DBC[CAR.CHEVROLET_BOLT_ACC_2022_2023][Bus.pt], [("ASCMActiveCruiseControlStatus", 0)], 0)
|
||||||
@@ -504,7 +803,39 @@ class TestGMCarController:
|
|||||||
|
|
||||||
parser.update([0, [msg]])
|
parser.update([0, [msg]])
|
||||||
|
|
||||||
assert parser.vl["ASCMActiveCruiseControlStatus"]["FCWAlert"] == 2
|
values = parser.vl["ASCMActiveCruiseControlStatus"]
|
||||||
|
|
||||||
|
assert values["ACCAlwaysOne"] == 1
|
||||||
|
assert values["ACCAlwaysOne2"] == 1
|
||||||
|
assert values["ACCCruiseState"] == 2
|
||||||
|
assert values["ACCCmdActive"] == 1
|
||||||
|
assert values["FCWAlert"] == 2
|
||||||
|
|
||||||
|
def test_acc_dashboard_command_allows_camera_acc_zero_reserved_bits(self):
|
||||||
|
packer = CANPacker(DBC[CAR.CHEVROLET_TRAILBLAZER][Bus.pt])
|
||||||
|
parser = CANParser(DBC[CAR.CHEVROLET_TRAILBLAZER][Bus.pt], [("ASCMActiveCruiseControlStatus", 0)], 0)
|
||||||
|
msg = gmcan.create_acc_dashboard_command(
|
||||||
|
packer,
|
||||||
|
0,
|
||||||
|
True,
|
||||||
|
67.1875,
|
||||||
|
SimpleNamespace(leadDistanceBars=1, leadVisible=False),
|
||||||
|
0,
|
||||||
|
acc_always_one=0,
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.update([0, [msg]])
|
||||||
|
values = parser.vl["ASCMActiveCruiseControlStatus"]
|
||||||
|
|
||||||
|
assert msg[1] == b"\x00\x02\x94\x33\x00\x00"
|
||||||
|
assert values["ACCAlwaysOne"] == 0
|
||||||
|
assert values["ACCAlwaysOne2"] == 0
|
||||||
|
assert values["ACCCruiseState"] == 2
|
||||||
|
assert values["ACCCmdActive"] == 1
|
||||||
|
|
||||||
|
def test_acc_dashboard_always_one_matches_camera_acc_platforms(self):
|
||||||
|
assert get_acc_dashboard_always_one(SimpleNamespace(carFingerprint=CAR.CHEVROLET_TRAILBLAZER)) == 0
|
||||||
|
assert get_acc_dashboard_always_one(SimpleNamespace(carFingerprint=CAR.CHEVROLET_BOLT_ACC_2022_2023)) == 1
|
||||||
|
|
||||||
def test_acc_dashboard_command_uses_openpilot_hud_when_disengaged(self):
|
def test_acc_dashboard_command_uses_openpilot_hud_when_disengaged(self):
|
||||||
packer = CANPacker(DBC[CAR.CHEVROLET_VOLT_ASCM][Bus.pt])
|
packer = CANPacker(DBC[CAR.CHEVROLET_VOLT_ASCM][Bus.pt])
|
||||||
@@ -522,6 +853,7 @@ class TestGMCarController:
|
|||||||
values = parser.vl["ASCMActiveCruiseControlStatus"]
|
values = parser.vl["ASCMActiveCruiseControlStatus"]
|
||||||
|
|
||||||
assert values["ACCSpeedSetpoint"] == 50
|
assert values["ACCSpeedSetpoint"] == 50
|
||||||
|
assert values["ACCCruiseState"] == 2
|
||||||
assert values["ACCGapLevel"] == 0
|
assert values["ACCGapLevel"] == 0
|
||||||
assert values["ACCCmdActive"] == 0
|
assert values["ACCCmdActive"] == 0
|
||||||
assert values["ACCLeadCar"] == 1
|
assert values["ACCLeadCar"] == 1
|
||||||
|
|||||||
@@ -28,6 +28,14 @@ class TestGMCan:
|
|||||||
assert dat[1] & 0x1
|
assert dat[1] & 0x1
|
||||||
assert decoded == 8848
|
assert decoded == 8848
|
||||||
|
|
||||||
|
def test_acc_2cd_command_matches_stock_camera_counter_layout(self):
|
||||||
|
assert [gmcan.create_acc_2cd_command(0, idx)[1].hex() for idx in range(4)] == [
|
||||||
|
"002c03d3fd",
|
||||||
|
"402c03d3fc",
|
||||||
|
"802c03d3fb",
|
||||||
|
"c02c03d3fa",
|
||||||
|
]
|
||||||
|
|
||||||
def test_prndl2_command_matches_bolt_gen2_regen_paddle_spoof(self):
|
def test_prndl2_command_matches_bolt_gen2_regen_paddle_spoof(self):
|
||||||
CP = SimpleNamespace(carFingerprint=CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL)
|
CP = SimpleNamespace(carFingerprint=CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL)
|
||||||
|
|
||||||
@@ -61,7 +69,6 @@ class TestGMCan:
|
|||||||
assert bus == 0
|
assert bus == 0
|
||||||
assert dat.hex() == "20000000000000"
|
assert dat.hex() == "20000000000000"
|
||||||
|
|
||||||
|
|
||||||
def test_gas_regen_command_matches_starpilot_volt_2019(self):
|
def test_gas_regen_command_matches_starpilot_volt_2019(self):
|
||||||
packer = CANPacker(DBC[CAR.CHEVROLET_VOLT_2019]["pt"])
|
packer = CANPacker(DBC[CAR.CHEVROLET_VOLT_2019]["pt"])
|
||||||
addr, dat, bus = gmcan.create_gas_regen_command(packer, 0, 5000, 1, True, False, include_always_one3=True, use_volt_layout=True)
|
addr, dat, bus = gmcan.create_gas_regen_command(packer, 0, 5000, 1, True, False, include_always_one3=True, use_volt_layout=True)
|
||||||
|
|||||||
@@ -175,6 +175,7 @@ class GMSafetyFlags(IntFlag):
|
|||||||
FLAG_GM_REMOTE_START_BOOTS_COMMA = 8192
|
FLAG_GM_REMOTE_START_BOOTS_COMMA = 8192
|
||||||
FLAG_GM_PANDA_3D1_SCHED = 16384
|
FLAG_GM_PANDA_3D1_SCHED = 16384
|
||||||
FLAG_GM_PANDA_PADDLE_SCHED = 32768
|
FLAG_GM_PANDA_PADDLE_SCHED = 32768
|
||||||
|
FLAG_GM_VOLT_CC_GATEWAY = 16384
|
||||||
|
|
||||||
|
|
||||||
class Footnote(Enum):
|
class Footnote(Enum):
|
||||||
@@ -214,16 +215,12 @@ class GMPlatformConfig(PlatformConfig):
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class GMASCMPlatformConfig(GMPlatformConfig):
|
class GMASCMPlatformConfig(GMPlatformConfig):
|
||||||
def init(self):
|
pass
|
||||||
# ASCM is supported, but due to a janky install and hardware configuration, we are not showing in the car docs
|
|
||||||
self.car_docs = []
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class GMSDGMPlatformConfig(GMPlatformConfig):
|
class GMSDGMPlatformConfig(GMPlatformConfig):
|
||||||
def init(self):
|
pass
|
||||||
# Don't show in docs until the harness is sold. See https://github.com/commaai/openpilot/issues/32471
|
|
||||||
self.car_docs = []
|
|
||||||
|
|
||||||
|
|
||||||
class CAR(Platforms):
|
class CAR(Platforms):
|
||||||
@@ -241,17 +238,17 @@ class CAR(Platforms):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
CHEVROLET_VOLT_ASCM = GMPlatformConfig(
|
CHEVROLET_VOLT_ASCM = GMPlatformConfig(
|
||||||
[GMCarDocs("Chevrolet Volt 2017-18 ASCM Harness", min_enable_speed=0, video="https://youtu.be/QeMCN_4TFfQ")],
|
[GMCarDocs("Chevrolet Volt ASCM Harness 2017-18", min_enable_speed=0, video="https://youtu.be/QeMCN_4TFfQ")],
|
||||||
CHEVROLET_VOLT.specs,
|
CHEVROLET_VOLT.specs,
|
||||||
dbc_dict=CHEVROLET_VOLT.dbc_dict,
|
dbc_dict=CHEVROLET_VOLT.dbc_dict,
|
||||||
)
|
)
|
||||||
CHEVROLET_VOLT_CAMERA = GMPlatformConfig(
|
CHEVROLET_VOLT_CAMERA = GMPlatformConfig(
|
||||||
[GMCarDocs("Chevrolet Volt 2017-18 Camera Harness", "Flashed camera-forward integration with ACC")],
|
[GMCarDocs("Chevrolet Volt Camera Harness 2017-18", "Flashed camera-forward integration with ACC")],
|
||||||
CHEVROLET_VOLT.specs,
|
CHEVROLET_VOLT.specs,
|
||||||
dbc_dict=CHEVROLET_VOLT.dbc_dict,
|
dbc_dict=CHEVROLET_VOLT.dbc_dict,
|
||||||
)
|
)
|
||||||
CHEVROLET_VOLT_CC = GMPlatformConfig(
|
CHEVROLET_VOLT_CC = GMPlatformConfig(
|
||||||
[GMCarDocs("Chevrolet Volt 2017-18 - No-ACC", min_enable_speed=0)],
|
[GMCarDocs("Chevrolet Volt No-ACC 2016-18 (OBD Harness)", "Redneck ACC", min_enable_speed=0)],
|
||||||
CHEVROLET_VOLT.specs,
|
CHEVROLET_VOLT.specs,
|
||||||
dbc_dict=CHEVROLET_VOLT.dbc_dict,
|
dbc_dict=CHEVROLET_VOLT.dbc_dict,
|
||||||
)
|
)
|
||||||
@@ -264,7 +261,7 @@ class CAR(Platforms):
|
|||||||
GMCarSpecs(mass=1496, wheelbase=2.83, steerRatio=15.8, centerToFrontRatio=0.4),
|
GMCarSpecs(mass=1496, wheelbase=2.83, steerRatio=15.8, centerToFrontRatio=0.4),
|
||||||
)
|
)
|
||||||
CHEVROLET_MALIBU_ASCM = GMPlatformConfig(
|
CHEVROLET_MALIBU_ASCM = GMPlatformConfig(
|
||||||
[GMCarDocs("Chevrolet Malibu 2017-19 ASCM Harness")],
|
[GMCarDocs("Chevrolet Malibu ASCM Harness 2017-19")],
|
||||||
CHEVROLET_MALIBU.specs,
|
CHEVROLET_MALIBU.specs,
|
||||||
)
|
)
|
||||||
GMC_ACADIA = GMASCMPlatformConfig(
|
GMC_ACADIA = GMASCMPlatformConfig(
|
||||||
@@ -272,7 +269,7 @@ class CAR(Platforms):
|
|||||||
GMCarSpecs(mass=1975, wheelbase=2.86, steerRatio=14.4, centerToFrontRatio=0.4),
|
GMCarSpecs(mass=1975, wheelbase=2.86, steerRatio=14.4, centerToFrontRatio=0.4),
|
||||||
)
|
)
|
||||||
GMC_ACADIA_ASCM = GMPlatformConfig(
|
GMC_ACADIA_ASCM = GMPlatformConfig(
|
||||||
[GMCarDocs("GMC Acadia 2018 ASCM Harness", video="https://www.youtube.com/watch?v=0ZN6DdsBUZo")],
|
[GMCarDocs("GMC Acadia ASCM Harness 2018", video="https://www.youtube.com/watch?v=0ZN6DdsBUZo")],
|
||||||
GMC_ACADIA.specs,
|
GMC_ACADIA.specs,
|
||||||
)
|
)
|
||||||
BUICK_LACROSSE = GMASCMPlatformConfig(
|
BUICK_LACROSSE = GMASCMPlatformConfig(
|
||||||
@@ -280,7 +277,11 @@ class CAR(Platforms):
|
|||||||
GMCarSpecs(mass=1712, wheelbase=2.91, steerRatio=15.8, centerToFrontRatio=0.4),
|
GMCarSpecs(mass=1712, wheelbase=2.91, steerRatio=15.8, centerToFrontRatio=0.4),
|
||||||
)
|
)
|
||||||
BUICK_LACROSSE_ASCM = GMPlatformConfig(
|
BUICK_LACROSSE_ASCM = GMPlatformConfig(
|
||||||
[GMCarDocs("Buick LaCrosse 2017-19 ASCM Harness")],
|
[GMCarDocs("Buick LaCrosse ASCM Harness 2017-19")],
|
||||||
|
BUICK_LACROSSE.specs,
|
||||||
|
)
|
||||||
|
BUICK_LACROSSE_ASCM_19US = GMPlatformConfig(
|
||||||
|
[GMCarDocs("Buick LaCrosse US ASCM Harness 2019")],
|
||||||
BUICK_LACROSSE.specs,
|
BUICK_LACROSSE.specs,
|
||||||
)
|
)
|
||||||
BUICK_REGAL = GMASCMPlatformConfig(
|
BUICK_REGAL = GMASCMPlatformConfig(
|
||||||
@@ -292,7 +293,7 @@ class CAR(Platforms):
|
|||||||
GMCarSpecs(mass=2564, wheelbase=2.95, steerRatio=17.3),
|
GMCarSpecs(mass=2564, wheelbase=2.95, steerRatio=17.3),
|
||||||
)
|
)
|
||||||
CADILLAC_ESCALADE_ASCM = GMPlatformConfig(
|
CADILLAC_ESCALADE_ASCM = GMPlatformConfig(
|
||||||
[GMCarDocs("Cadillac Escalade 2018 ASCM Harness", "Driver Assist Package")],
|
[GMCarDocs("Cadillac Escalade ASCM Harness 2018", "Driver Assist Package")],
|
||||||
CADILLAC_ESCALADE.specs,
|
CADILLAC_ESCALADE.specs,
|
||||||
)
|
)
|
||||||
CADILLAC_ESCALADE_ESV = GMASCMPlatformConfig(
|
CADILLAC_ESCALADE_ESV = GMASCMPlatformConfig(
|
||||||
@@ -304,29 +305,29 @@ class CAR(Platforms):
|
|||||||
CADILLAC_ESCALADE_ESV.specs,
|
CADILLAC_ESCALADE_ESV.specs,
|
||||||
)
|
)
|
||||||
CADILLAC_ESCALADE_ESV_2019_ASCM = GMPlatformConfig(
|
CADILLAC_ESCALADE_ESV_2019_ASCM = GMPlatformConfig(
|
||||||
[GMCarDocs("Cadillac Escalade ESV Platinum 2019 ASCM Harness", "Adaptive Cruise Control (ACC) & LKAS")],
|
[GMCarDocs("Cadillac Escalade ESV Platinum ASCM Harness 2019", "Adaptive Cruise Control (ACC) & LKAS")],
|
||||||
CADILLAC_ESCALADE_ESV_2019.specs,
|
CADILLAC_ESCALADE_ESV_2019.specs,
|
||||||
)
|
)
|
||||||
CHEVROLET_BOLT_ACC_2022_2023 = GMPlatformConfig(
|
CHEVROLET_BOLT_ACC_2022_2023 = GMPlatformConfig(
|
||||||
[
|
[
|
||||||
GMCarDocs("Chevrolet Bolt ACC 2022-23", "Premier or Premier Redline Trim without Super Cruise Package", video="https://youtu.be/xvwzGMUA210"),
|
GMCarDocs("Chevrolet Bolt EV & EUV ACC 2022-23", "Premier or Premier Redline Trim without Super Cruise Package", video="https://youtu.be/xvwzGMUA210"),
|
||||||
],
|
],
|
||||||
GMCarSpecs(mass=1669, wheelbase=2.63779, steerRatio=16.8, centerToFrontRatio=0.4, tireStiffnessFactor=1.0),
|
GMCarSpecs(mass=1669, wheelbase=2.63779, steerRatio=16.8, centerToFrontRatio=0.4, tireStiffnessFactor=1.0),
|
||||||
)
|
)
|
||||||
CHEVROLET_BOLT_ACC_2022_2023_PEDAL = GMPlatformConfig(
|
CHEVROLET_BOLT_ACC_2022_2023_PEDAL = GMPlatformConfig(
|
||||||
[GMCarDocs("Chevrolet Bolt EV 2022-23 ACC w Pedal")],
|
[GMCarDocs("Chevrolet Bolt EV & EUV ACC w Pedal 2022-23")],
|
||||||
CHEVROLET_BOLT_ACC_2022_2023.specs,
|
CHEVROLET_BOLT_ACC_2022_2023.specs,
|
||||||
)
|
)
|
||||||
CHEVROLET_BOLT_CC_2022_2023 = GMPlatformConfig(
|
CHEVROLET_BOLT_CC_2022_2023 = GMPlatformConfig(
|
||||||
[GMCarDocs("Chevrolet Bolt EV 2022-23 - No-ACC")],
|
[GMCarDocs("Chevrolet Bolt EV & EUV No-ACC 2022-23")],
|
||||||
CHEVROLET_BOLT_ACC_2022_2023.specs,
|
CHEVROLET_BOLT_ACC_2022_2023.specs,
|
||||||
)
|
)
|
||||||
CHEVROLET_BOLT_CC_2018_2021 = GMPlatformConfig(
|
CHEVROLET_BOLT_CC_2018_2021 = GMPlatformConfig(
|
||||||
[GMCarDocs("Chevrolet Bolt EV 2018-21 - No-ACC")],
|
[GMCarDocs("Chevrolet Bolt EV No-ACC 2018-21")],
|
||||||
CHEVROLET_BOLT_ACC_2022_2023.specs,
|
CHEVROLET_BOLT_ACC_2022_2023.specs,
|
||||||
)
|
)
|
||||||
CHEVROLET_BOLT_CC_2017 = GMPlatformConfig(
|
CHEVROLET_BOLT_CC_2017 = GMPlatformConfig(
|
||||||
[GMCarDocs("Chevrolet Bolt EV 2017 - No-ACC")],
|
[GMCarDocs("Chevrolet Bolt EV No-ACC 2017")],
|
||||||
CHEVROLET_BOLT_ACC_2022_2023.specs,
|
CHEVROLET_BOLT_ACC_2022_2023.specs,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -339,8 +340,8 @@ class CAR(Platforms):
|
|||||||
)
|
)
|
||||||
CHEVROLET_SILVERADO_CC = GMPlatformConfig(
|
CHEVROLET_SILVERADO_CC = GMPlatformConfig(
|
||||||
[
|
[
|
||||||
GMCarDocs("Chevrolet Silverado 1500 - No-ACC"),
|
GMCarDocs("Chevrolet Silverado 1500 No-ACC 2020-21"),
|
||||||
GMCarDocs("GMC Sierra 1500 - No-ACC"),
|
GMCarDocs("GMC Sierra 1500 No-ACC 2020-21"),
|
||||||
],
|
],
|
||||||
CHEVROLET_SILVERADO.specs,
|
CHEVROLET_SILVERADO.specs,
|
||||||
)
|
)
|
||||||
@@ -357,7 +358,7 @@ class CAR(Platforms):
|
|||||||
CarSpecs(mass=2731, wheelbase=3.302, steerRatio=17.3, centerToFrontRatio=0.49),
|
CarSpecs(mass=2731, wheelbase=3.302, steerRatio=17.3, centerToFrontRatio=0.49),
|
||||||
)
|
)
|
||||||
GMC_YUKON_CC = GMPlatformConfig(
|
GMC_YUKON_CC = GMPlatformConfig(
|
||||||
[GMCarDocs("GMC Yukon - No-ACC")],
|
[GMCarDocs("GMC Yukon No-ACC 2019-20")],
|
||||||
CarSpecs(mass=2541, wheelbase=2.95, steerRatio=16.3, centerToFrontRatio=0.4),
|
CarSpecs(mass=2541, wheelbase=2.95, steerRatio=16.3, centerToFrontRatio=0.4),
|
||||||
)
|
)
|
||||||
GMC_YUKON = GMPlatformConfig(
|
GMC_YUKON = GMPlatformConfig(
|
||||||
@@ -368,6 +369,10 @@ class CAR(Platforms):
|
|||||||
[GMCarDocs("Cadillac XT4 2023", "Driver Assist Package")],
|
[GMCarDocs("Cadillac XT4 2023", "Driver Assist Package")],
|
||||||
GMCarSpecs(mass=1660, wheelbase=2.78, steerRatio=14.4, centerToFrontRatio=0.4),
|
GMCarSpecs(mass=1660, wheelbase=2.78, steerRatio=14.4, centerToFrontRatio=0.4),
|
||||||
)
|
)
|
||||||
|
CADILLAC_XT4_CC = GMPlatformConfig(
|
||||||
|
[GMCarDocs("Cadillac XT4 No-ACC 2023")],
|
||||||
|
CADILLAC_XT4.specs,
|
||||||
|
)
|
||||||
CADILLAC_XT5 = GMSDGMPlatformConfig(
|
CADILLAC_XT5 = GMSDGMPlatformConfig(
|
||||||
[GMCarDocs("Cadillac XT5 2022", "Driver Assist Package")],
|
[GMCarDocs("Cadillac XT5 2022", "Driver Assist Package")],
|
||||||
CarSpecs(mass=1810, wheelbase=2.86, steerRatio=16.34, centerToFrontRatio=0.5),
|
CarSpecs(mass=1810, wheelbase=2.86, steerRatio=16.34, centerToFrontRatio=0.5),
|
||||||
@@ -397,35 +402,35 @@ class CAR(Platforms):
|
|||||||
CarSpecs(mass=2050, wheelbase=2.86, steerRatio=16.0, centerToFrontRatio=0.5),
|
CarSpecs(mass=2050, wheelbase=2.86, steerRatio=16.0, centerToFrontRatio=0.5),
|
||||||
)
|
)
|
||||||
CADILLAC_CT6_CC = GMPlatformConfig(
|
CADILLAC_CT6_CC = GMPlatformConfig(
|
||||||
[GMCarDocs("Cadillac CT6 - No-ACC")],
|
[GMCarDocs("Cadillac CT6 No-ACC 2016-20")],
|
||||||
CarSpecs(mass=2358, wheelbase=3.11, steerRatio=17.7, centerToFrontRatio=0.4),
|
CarSpecs(mass=2358, wheelbase=3.11, steerRatio=17.7, centerToFrontRatio=0.4),
|
||||||
)
|
)
|
||||||
CADILLAC_XT5_CC = GMPlatformConfig(
|
CADILLAC_XT5_CC = GMPlatformConfig(
|
||||||
[GMCarDocs("Cadillac XT5 - No-ACC")],
|
[GMCarDocs("Cadillac XT5 No-ACC 2022")],
|
||||||
CADILLAC_XT5.specs,
|
CADILLAC_XT5.specs,
|
||||||
)
|
)
|
||||||
CHEVROLET_EQUINOX_CC = GMPlatformConfig(
|
CHEVROLET_EQUINOX_CC = GMPlatformConfig(
|
||||||
[GMCarDocs("Chevrolet Equinox 2019-22 - No-ACC")],
|
[GMCarDocs("Chevrolet Equinox No-ACC 2019-22")],
|
||||||
CHEVROLET_EQUINOX.specs,
|
CHEVROLET_EQUINOX.specs,
|
||||||
)
|
)
|
||||||
CHEVROLET_MALIBU_CC = GMPlatformConfig(
|
CHEVROLET_MALIBU_CC = GMPlatformConfig(
|
||||||
[GMCarDocs("Chevrolet Malibu 2023 - No-ACC")],
|
[GMCarDocs("Chevrolet Malibu No-ACC 2023")],
|
||||||
CarSpecs(mass=1450, wheelbase=2.8, steerRatio=18.25, centerToFrontRatio=0.4, tireStiffnessFactor=0.997),
|
CarSpecs(mass=1450, wheelbase=2.8, steerRatio=18.25, centerToFrontRatio=0.4, tireStiffnessFactor=0.997),
|
||||||
)
|
)
|
||||||
CHEVROLET_MALIBU_HYBRID_CC = GMPlatformConfig(
|
CHEVROLET_MALIBU_HYBRID_CC = GMPlatformConfig(
|
||||||
[GMCarDocs("Chevrolet Malibu Hybrid 2017 - No-ACC")],
|
[GMCarDocs("Chevrolet Malibu Hybrid No-ACC 2017")],
|
||||||
CarSpecs(mass=1450, wheelbase=2.8, steerRatio=15.8, centerToFrontRatio=0.4),
|
CarSpecs(mass=1450, wheelbase=2.8, steerRatio=15.8, centerToFrontRatio=0.4),
|
||||||
)
|
)
|
||||||
CHEVROLET_SUBURBAN_CC = GMPlatformConfig(
|
CHEVROLET_SUBURBAN_CC = GMPlatformConfig(
|
||||||
[GMCarDocs("Chevrolet Suburban Premier 2016-20 - No-ACC")],
|
[GMCarDocs("Chevrolet Suburban Premier No-ACC 2016-20")],
|
||||||
CHEVROLET_SUBURBAN.specs,
|
CHEVROLET_SUBURBAN.specs,
|
||||||
)
|
)
|
||||||
CHEVROLET_TRAILBLAZER_CC = GMPlatformConfig(
|
CHEVROLET_TRAILBLAZER_CC = GMPlatformConfig(
|
||||||
[GMCarDocs("Chevrolet Trailblazer 2021-22 - No-ACC")],
|
[GMCarDocs("Chevrolet Trailblazer No-ACC 2021-22")],
|
||||||
CHEVROLET_TRAILBLAZER.specs,
|
CHEVROLET_TRAILBLAZER.specs,
|
||||||
)
|
)
|
||||||
CHEVROLET_TRAX = GMPlatformConfig(
|
CHEVROLET_TRAX = GMPlatformConfig(
|
||||||
[GMCarDocs("Chevrolet TRAX 2024")],
|
[GMCarDocs("Chevrolet TRAX 2024-25")],
|
||||||
CarSpecs(mass=1365, wheelbase=2.7, steerRatio=16.4, centerToFrontRatio=0.4),
|
CarSpecs(mass=1365, wheelbase=2.7, steerRatio=16.4, centerToFrontRatio=0.4),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -570,6 +575,7 @@ CC_ONLY_CAR = {
|
|||||||
CAR.CHEVROLET_MALIBU_CC,
|
CAR.CHEVROLET_MALIBU_CC,
|
||||||
CAR.CHEVROLET_MALIBU_HYBRID_CC,
|
CAR.CHEVROLET_MALIBU_HYBRID_CC,
|
||||||
CAR.CHEVROLET_SILVERADO_CC,
|
CAR.CHEVROLET_SILVERADO_CC,
|
||||||
|
CAR.CADILLAC_XT4_CC,
|
||||||
}
|
}
|
||||||
CC_REGEN_PADDLE_CAR = {
|
CC_REGEN_PADDLE_CAR = {
|
||||||
CAR.CHEVROLET_BOLT_CC_2018_2021,
|
CAR.CHEVROLET_BOLT_CC_2018_2021,
|
||||||
@@ -587,6 +593,7 @@ ASCM_INT = {
|
|||||||
CAR.CADILLAC_ESCALADE_ASCM,
|
CAR.CADILLAC_ESCALADE_ASCM,
|
||||||
CAR.CADILLAC_ESCALADE_ESV_2019_ASCM,
|
CAR.CADILLAC_ESCALADE_ESV_2019_ASCM,
|
||||||
CAR.BUICK_LACROSSE_ASCM,
|
CAR.BUICK_LACROSSE_ASCM,
|
||||||
|
CAR.BUICK_LACROSSE_ASCM_19US,
|
||||||
}
|
}
|
||||||
|
|
||||||
STEER_THRESHOLD = 1.0
|
STEER_THRESHOLD = 1.0
|
||||||
|
|||||||
@@ -0,0 +1,166 @@
|
|||||||
|
import math
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from datetime import UTC, datetime
|
||||||
|
from collections.abc import Callable, Mapping
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from opendbc.car.common.conversions import Conversions as CV
|
||||||
|
from opendbc.car.ford.values import CAR as FORD_CAR
|
||||||
|
from opendbc.car.gm.values import CAR as GM_CAR
|
||||||
|
|
||||||
|
|
||||||
|
CarGpsSample = dict[str, Any]
|
||||||
|
CanGpsDecoder = Callable[..., CarGpsSample | None]
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class CarGpsConfig:
|
||||||
|
"""Vehicle-specific CAN GPS inputs and decoder."""
|
||||||
|
|
||||||
|
brand: str
|
||||||
|
messages: tuple[str, ...]
|
||||||
|
decoder: CanGpsDecoder
|
||||||
|
|
||||||
|
|
||||||
|
def _dop_accuracy(dop: float, default: float = 500.0) -> float:
|
||||||
|
"""Convert Ford's dimensionless DOP into a conservative meter estimate."""
|
||||||
|
return max(1.0, dop * 5.0) if 0.0 <= dop <= 5.8 else default
|
||||||
|
|
||||||
|
|
||||||
|
def parse_ford_can_gps(nav1: Mapping[str, float], nav2: Mapping[str, float], nav3: Mapping[str, float]) -> CarGpsSample | None:
|
||||||
|
"""Decode the Ford APIM GPS messages into the fields used by gpsLocationExternal."""
|
||||||
|
year = int(nav2["GpsUtcYr_No_Actl"])
|
||||||
|
month = int(nav2["GpsUtcMnth_No_Actl"])
|
||||||
|
day = int(nav2["GpsUtcDay_No_Actl"])
|
||||||
|
hour = int(nav2["GPS_UTC_hours"])
|
||||||
|
minute = int(nav2["GPS_UTC_minutes"])
|
||||||
|
second = int(nav2["GPS_UTC_seconds"])
|
||||||
|
try:
|
||||||
|
timestamp_ms = int(datetime(year, month, day, hour, minute, second, tzinfo=UTC).timestamp() * 1000)
|
||||||
|
except ValueError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
latitude_direction = int(nav1["GpsHsphLattSth_D_Actl"])
|
||||||
|
longitude_direction = int(nav1["GpsHsphLongEast_D_Actl"])
|
||||||
|
latitude_degrees = abs(float(nav1["GPS_Latitude_Degrees"]))
|
||||||
|
longitude_degrees = abs(float(nav1["GPS_Longitude_Degrees"]))
|
||||||
|
latitude_minutes = float(nav1["GPS_Latitude_Minutes"]) + float(nav1["GPS_Latitude_Min_dec"])
|
||||||
|
longitude_minutes = float(nav1["GPS_Longitude_Minutes"]) + float(nav1["GPS_Longitude_Min_dec"])
|
||||||
|
|
||||||
|
coordinates_valid = (
|
||||||
|
latitude_direction in (1, 2) and longitude_direction in (1, 2) and
|
||||||
|
0.0 <= latitude_degrees <= 90.0 and 0.0 <= longitude_degrees <= 180.0 and
|
||||||
|
0.0 <= latitude_minutes < 60.0 and 0.0 <= longitude_minutes < 60.0
|
||||||
|
)
|
||||||
|
latitude = (1.0 if latitude_direction == 2 else -1.0) * (latitude_degrees + latitude_minutes / 60.0) if coordinates_valid else 0.0
|
||||||
|
longitude = (1.0 if longitude_direction == 1 else -1.0) * (longitude_degrees + longitude_minutes / 60.0) if coordinates_valid else 0.0
|
||||||
|
|
||||||
|
dimension = int(nav3["GPS_dimension"])
|
||||||
|
has_fix = coordinates_valid and dimension in (1, 2) and int(nav2["Gps_B_Falt"]) == 0
|
||||||
|
|
||||||
|
speed_mph = float(nav3["GPS_Speed"])
|
||||||
|
speed_mps = speed_mph * CV.MPH_TO_MS
|
||||||
|
heading = float(nav3["GPS_Heading"])
|
||||||
|
if speed_mph in (254.0, 255.0) or not math.isfinite(speed_mps) or not 0.0 <= speed_mps <= 200.0:
|
||||||
|
speed_mps = 0.0
|
||||||
|
if not math.isfinite(heading) or not 0.0 <= heading < 360.0:
|
||||||
|
heading = 0.0
|
||||||
|
|
||||||
|
vertical_accuracy = _dop_accuracy(float(nav3["GPS_Vdop"]))
|
||||||
|
horizontal_accuracy = _dop_accuracy(float(nav3["GPS_Hdop"]))
|
||||||
|
satellite_count = int(nav3["GPS_Sat_num_in_view"])
|
||||||
|
if not 0 <= satellite_count < 30: # 30 and 31 are Ford's unknown/invalid values.
|
||||||
|
satellite_count = 0
|
||||||
|
|
||||||
|
heading_rad = math.radians(heading)
|
||||||
|
return {
|
||||||
|
"latitude": latitude,
|
||||||
|
"longitude": longitude,
|
||||||
|
"altitude": (float(nav3["GPS_MSL_altitude"]) * 0.3048) if has_fix else 0.0,
|
||||||
|
"speed": speed_mps,
|
||||||
|
"bearingDeg": heading,
|
||||||
|
"horizontalAccuracy": horizontal_accuracy,
|
||||||
|
"unixTimestampMillis": timestamp_ms,
|
||||||
|
"verticalAccuracy": vertical_accuracy,
|
||||||
|
"bearingAccuracyDeg": max(5.0, horizontal_accuracy * 2.0) if speed_mps > 1.0 else 180.0,
|
||||||
|
"speedAccuracy": max(0.5, horizontal_accuracy),
|
||||||
|
"hasFix": has_fix,
|
||||||
|
"satelliteCount": satellite_count,
|
||||||
|
"vNED": [speed_mps * math.cos(heading_rad), speed_mps * math.sin(heading_rad), 0.0],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def parse_chevrolet_bolt_can_gps(position: Mapping[str, float]) -> CarGpsSample | None:
|
||||||
|
"""Decode the Bolt's OnStar GPS position message."""
|
||||||
|
try:
|
||||||
|
latitude = float(position["GPSLatitude"]) / 3_600_000.0
|
||||||
|
longitude = float(position["GPSLongitude"]) / 3_600_000.0
|
||||||
|
except (KeyError, TypeError, ValueError):
|
||||||
|
return None
|
||||||
|
|
||||||
|
coordinates_valid = (
|
||||||
|
math.isfinite(latitude) and math.isfinite(longitude) and
|
||||||
|
-90.0 <= latitude <= 90.0 and -180.0 <= longitude <= 180.0 and
|
||||||
|
(latitude != 0.0 or longitude != 0.0)
|
||||||
|
)
|
||||||
|
if not coordinates_valid:
|
||||||
|
latitude = longitude = 0.0
|
||||||
|
|
||||||
|
return {
|
||||||
|
"latitude": latitude,
|
||||||
|
"longitude": longitude,
|
||||||
|
"altitude": 0.0,
|
||||||
|
"speed": 0.0,
|
||||||
|
"bearingDeg": 0.0,
|
||||||
|
"horizontalAccuracy": 100.0,
|
||||||
|
"unixTimestampMillis": int(datetime.now(UTC).timestamp() * 1000),
|
||||||
|
"verticalAccuracy": 100.0,
|
||||||
|
"bearingAccuracyDeg": 180.0,
|
||||||
|
"speedAccuracy": 100.0,
|
||||||
|
"hasFix": coordinates_valid,
|
||||||
|
"satelliteCount": 0,
|
||||||
|
"vNED": [0.0, 0.0, 0.0],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FORD_MACH_E_GPS_MESSAGES = (
|
||||||
|
"APIMGPS_Data_Nav_1_FD1",
|
||||||
|
"APIMGPS_Data_Nav_2_FD1",
|
||||||
|
"APIMGPS_Data_Nav_3_FD1",
|
||||||
|
)
|
||||||
|
CHEVROLET_BOLT_GPS_MESSAGES = ("TCICOnStarGPSPosition",)
|
||||||
|
|
||||||
|
CHEVROLET_BOLT_GPS_CARS = (
|
||||||
|
GM_CAR.CHEVROLET_BOLT_ACC_2022_2023,
|
||||||
|
GM_CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL,
|
||||||
|
GM_CAR.CHEVROLET_BOLT_CC_2022_2023,
|
||||||
|
GM_CAR.CHEVROLET_BOLT_CC_2018_2021,
|
||||||
|
GM_CAR.CHEVROLET_BOLT_CC_2017,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
CAR_GPS_CONFIGS: dict[str, CarGpsConfig] = {
|
||||||
|
FORD_CAR.FORD_MUSTANG_MACH_E_MK1: CarGpsConfig(
|
||||||
|
brand="ford",
|
||||||
|
messages=FORD_MACH_E_GPS_MESSAGES,
|
||||||
|
decoder=parse_ford_can_gps,
|
||||||
|
),
|
||||||
|
**{
|
||||||
|
car: CarGpsConfig(
|
||||||
|
brand="gm",
|
||||||
|
messages=CHEVROLET_BOLT_GPS_MESSAGES,
|
||||||
|
decoder=parse_chevrolet_bolt_can_gps,
|
||||||
|
)
|
||||||
|
for car in CHEVROLET_BOLT_GPS_CARS
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_car_gps_config(CP) -> CarGpsConfig | None:
|
||||||
|
config = CAR_GPS_CONFIGS.get(CP.carFingerprint)
|
||||||
|
return config if config is not None and config.brand == CP.brand else None
|
||||||
|
|
||||||
|
|
||||||
|
def car_gps_available(CP) -> bool:
|
||||||
|
return get_car_gps_config(CP) is not None
|
||||||
@@ -7,6 +7,7 @@ from opendbc.car.honda import hondacan
|
|||||||
from opendbc.car.honda.values import (
|
from opendbc.car.honda.values import (
|
||||||
CAR,
|
CAR,
|
||||||
CruiseButtons,
|
CruiseButtons,
|
||||||
|
CruiseSettings,
|
||||||
HONDA_BOSCH,
|
HONDA_BOSCH,
|
||||||
HONDA_BOSCH_CANFD,
|
HONDA_BOSCH_CANFD,
|
||||||
HONDA_BOSCH_RADARLESS,
|
HONDA_BOSCH_RADARLESS,
|
||||||
@@ -16,6 +17,7 @@ from opendbc.car.honda.values import (
|
|||||||
HondaFlags,
|
HondaFlags,
|
||||||
)
|
)
|
||||||
from opendbc.car.interfaces import CarControllerBase
|
from opendbc.car.interfaces import CarControllerBase
|
||||||
|
from opendbc.car.common.pid import PIDController
|
||||||
from openpilot.common.params import Params
|
from openpilot.common.params import Params
|
||||||
|
|
||||||
VisualAlert = structs.CarControl.HUDControl.VisualAlert
|
VisualAlert = structs.CarControl.HUDControl.VisualAlert
|
||||||
@@ -211,6 +213,14 @@ class CarController(CarControllerBase):
|
|||||||
self.CAN = hondacan.CanBus(CP)
|
self.CAN = hondacan.CanBus(CP)
|
||||||
self.tja_control = CP.carFingerprint in HONDA_BOSCH_TJA_CONTROL
|
self.tja_control = CP.carFingerprint in HONDA_BOSCH_TJA_CONTROL
|
||||||
|
|
||||||
|
# MVL CAN-FD ownership state. These do not affect non-CANFD vehicles.
|
||||||
|
self.radar_disable_counter = 0
|
||||||
|
self.radar_mux = 0
|
||||||
|
self.radar_hud_pulse = 0
|
||||||
|
self.last_acc_enabled = False
|
||||||
|
self.lkas_button_send_remaining = 0
|
||||||
|
self.last_lkas_button_frame = 0
|
||||||
|
|
||||||
self.braking = False
|
self.braking = False
|
||||||
self.brake_steady = 0.0
|
self.brake_steady = 0.0
|
||||||
self.brake_last = 0.0
|
self.brake_last = 0.0
|
||||||
@@ -234,6 +244,10 @@ class CarController(CarControllerBase):
|
|||||||
self.bosch_gas_factor_before_gasmax = self.bosch_gas_factor
|
self.bosch_gas_factor_before_gasmax = self.bosch_gas_factor
|
||||||
self.bosch_wind_factor_before_gasmax = self.bosch_wind_factor
|
self.bosch_wind_factor_before_gasmax = self.bosch_wind_factor
|
||||||
self.pitch = 0.0
|
self.pitch = 0.0
|
||||||
|
self.mvl_accord_mode = CP.carFingerprint == CAR.HONDA_ACCORD_11G
|
||||||
|
# MVL Bosch low-speed extra-brake integrator. Active only for Accord 11G MVL mode.
|
||||||
|
self.mvl_brake_pid = PIDController(k_p=0.0, k_i=1.0, pos_limit=0.0, neg_limit=-2.0, rate=50)
|
||||||
|
self.mvl_brake_pid.reset()
|
||||||
|
|
||||||
def _modified_civic_standard_active(self) -> bool:
|
def _modified_civic_standard_active(self) -> bool:
|
||||||
return self.CP.carFingerprint == CAR.HONDA_CIVIC_BOSCH and bool(self.CP.flags & HondaFlags.EPS_MODIFIED)
|
return self.CP.carFingerprint == CAR.HONDA_CIVIC_BOSCH and bool(self.CP.flags & HondaFlags.EPS_MODIFIED)
|
||||||
@@ -255,6 +269,7 @@ class CarController(CarControllerBase):
|
|||||||
hud_v_cruise = hud_control.setSpeed / CS.v_cruise_factor if hud_control.speedVisible else 255
|
hud_v_cruise = hud_control.setSpeed / CS.v_cruise_factor if hud_control.speedVisible else 255
|
||||||
pcm_cancel_cmd = CC.cruiseControl.cancel
|
pcm_cancel_cmd = CC.cruiseControl.cancel
|
||||||
gas_interceptor_command = 0.0
|
gas_interceptor_command = 0.0
|
||||||
|
min_gas = self.params.BOSCH_GAS_LOOKUP_BP[0]
|
||||||
if len(CC.orientationNED) == 3:
|
if len(CC.orientationNED) == 3:
|
||||||
self.pitch = CC.orientationNED[1]
|
self.pitch = CC.orientationNED[1]
|
||||||
hill_brake = math.sin(self.pitch) * ACCELERATION_DUE_TO_GRAVITY
|
hill_brake = math.sin(self.pitch) * ACCELERATION_DUE_TO_GRAVITY
|
||||||
@@ -308,11 +323,56 @@ class CarController(CarControllerBase):
|
|||||||
# Send CAN commands
|
# Send CAN commands
|
||||||
can_sends = []
|
can_sends = []
|
||||||
|
|
||||||
# tester present - w/ no response (keeps radar disabled)
|
# Bosch radar ownership. On CAN-FD, leave the stock radar active until the comma relay is open,
|
||||||
|
# then enter extended diagnostics and disable radar RX/TX. This prevents a gap between stock
|
||||||
|
# ACC_CONTROL disappearing and panda permitting openpilot's replacement stream.
|
||||||
if self.CP.carFingerprint in (HONDA_BOSCH - HONDA_BOSCH_RADARLESS) and self.CP.openpilotLongitudinalControl:
|
if self.CP.carFingerprint in (HONDA_BOSCH - HONDA_BOSCH_RADARLESS) and self.CP.openpilotLongitudinalControl:
|
||||||
if self.frame % 10 == 0:
|
if self.mvl_accord_mode and CS.stock_acc_alive:
|
||||||
|
if CS.canfd_relay_open:
|
||||||
|
if self.radar_disable_counter % 50 == 0:
|
||||||
|
can_sends.append((0x18DAB0F1, b'\x02\x10\x03\x00\x00\x00\x00\x00', self.CAN.pt))
|
||||||
|
elif self.radar_disable_counter % 50 == 5:
|
||||||
|
can_sends.append((0x18DAB0F1, b'\x03\x28\x83\x03\x00\x00\x00\x00', self.CAN.pt))
|
||||||
|
self.radar_disable_counter += 1
|
||||||
|
elif self.frame % 10 == 0:
|
||||||
can_sends.append(make_tester_present_msg(0x18DAB0F1, self.CAN.pt, suppress_response=True))
|
can_sends.append(make_tester_present_msg(0x18DAB0F1, self.CAN.pt, suppress_response=True))
|
||||||
|
|
||||||
|
# After the stock CAN-FD radar is silent, reproduce its low-rate/tick-aligned messages on both
|
||||||
|
# the PT and camera sides of the open relay. Pack once and mirror identical bytes so counters and
|
||||||
|
# checksums stay synchronized. v3 deliberately uses an idle lane/object payload first; model-based
|
||||||
|
# cluster rendering is deferred until the ownership/DTC handover is proven.
|
||||||
|
mvl_radar_owned = self.mvl_accord_mode and CS.canfd_relay_open and not CS.stock_acc_alive
|
||||||
|
if mvl_radar_owned and self.CP.openpilotLongitudinalControl:
|
||||||
|
if CC.enabled and not self.last_acc_enabled:
|
||||||
|
self.radar_hud_pulse = 30
|
||||||
|
self.last_acc_enabled = CC.enabled
|
||||||
|
|
||||||
|
radar_msgs = []
|
||||||
|
if CS.hud_tick:
|
||||||
|
radar_msgs.append(hondacan.create_radar_hud_canfd(self.packer, self.CAN.pt, CC.enabled, self.radar_hud_pulse > 0))
|
||||||
|
if self.radar_hud_pulse > 0:
|
||||||
|
self.radar_hud_pulse -= 1
|
||||||
|
if CS.supp_tick:
|
||||||
|
radar_msgs.append(hondacan.create_canfd_supplemental(self.packer, self.CAN.pt))
|
||||||
|
if CS.radar_50hz_tick:
|
||||||
|
if self.radar_mux >= 58:
|
||||||
|
self.radar_mux = 1
|
||||||
|
elif self.radar_mux == 10:
|
||||||
|
self.radar_mux = 17
|
||||||
|
elif self.radar_mux == 26:
|
||||||
|
self.radar_mux = 33
|
||||||
|
elif self.radar_mux == 42:
|
||||||
|
self.radar_mux = 49
|
||||||
|
else:
|
||||||
|
self.radar_mux += 1
|
||||||
|
radar_msgs.extend(hondacan.create_canfd_50hz_radar_messages(self.packer, self.CAN.pt, self.radar_mux))
|
||||||
|
if CS.radar_5hz_tick:
|
||||||
|
radar_msgs.extend(hondacan.create_canfd_5hz_radar_messages(self.packer, self.CAN.pt, CS.radar_ref_counter))
|
||||||
|
|
||||||
|
for addr, dat, _ in radar_msgs:
|
||||||
|
can_sends.append((addr, dat, self.CAN.pt))
|
||||||
|
can_sends.append((addr, dat, self.CAN.camera))
|
||||||
|
|
||||||
# Send steering command.
|
# Send steering command.
|
||||||
can_sends.append(hondacan.create_steering_control(self.packer, self.CAN, apply_torque, CC.latActive, self.tja_control))
|
can_sends.append(hondacan.create_steering_control(self.packer, self.CAN, apply_torque, CC.latActive, self.tja_control))
|
||||||
|
|
||||||
@@ -352,23 +412,37 @@ class CarController(CarControllerBase):
|
|||||||
ts = self.frame * DT_CTRL
|
ts = self.frame * DT_CTRL
|
||||||
|
|
||||||
if self.CP.carFingerprint in HONDA_BOSCH:
|
if self.CP.carFingerprint in HONDA_BOSCH:
|
||||||
self.accel = float(np.clip(accel, self.params.BOSCH_ACCEL_MIN, self.params.BOSCH_ACCEL_MAX))
|
if self.mvl_accord_mode and (accel < min_gas) and (1e-3 < CS.out.vEgo < 3.0):
|
||||||
gas_pedal_force = self.accel + hill_brake
|
brake_addon = self.mvl_brake_pid.update(error=accel - CS.out.aEgo, speed=CS.out.vEgo)
|
||||||
|
target_accel = min(accel, accel + brake_addon)
|
||||||
|
else:
|
||||||
|
if self.mvl_accord_mode:
|
||||||
|
self.mvl_brake_pid.reset()
|
||||||
|
target_accel = accel
|
||||||
|
|
||||||
|
self.accel = float(np.clip(target_accel, self.params.BOSCH_ACCEL_MIN, self.params.BOSCH_ACCEL_MAX))
|
||||||
|
# MVL uses requested accel (not extra-brake-adjusted accel) to decide propulsion crossover.
|
||||||
|
gas_pedal_force = (accel if self.mvl_accord_mode else self.accel) + hill_brake
|
||||||
|
|
||||||
if self.CP.carFingerprint not in HONDA_BOSCH_RADARLESS:
|
if self.CP.carFingerprint not in HONDA_BOSCH_RADARLESS:
|
||||||
gas_pedal_force += wind_brake_mps2 * self.bosch_wind_factor
|
gas_pedal_force += wind_brake_mps2 * self.bosch_wind_factor
|
||||||
|
|
||||||
if actuators.longControlState == LongCtrlState.pid and not CS.out.gasPressed:
|
if actuators.longControlState == LongCtrlState.pid and not CS.out.gasPressed:
|
||||||
gas_error = self.accel - CS.out.aEgo
|
gas_error = (accel if self.mvl_accord_mode else self.accel) - CS.out.aEgo
|
||||||
|
|
||||||
if gas_error != 0.0 and gas_pedal_force > 0.0:
|
if gas_error != 0.0 and gas_pedal_force > min_gas:
|
||||||
if self.CP.carFingerprint == CAR.HONDA_INSIGHT:
|
if self.CP.carFingerprint == CAR.HONDA_INSIGHT:
|
||||||
gas_learn_speed = 150.0
|
gas_learn_speed = 150.0
|
||||||
elif self.CP.carFingerprint in (CAR.ACURA_RDX_3G, CAR.ACURA_RDX_3G_MMR):
|
elif self.CP.carFingerprint in (CAR.ACURA_RDX_3G, CAR.ACURA_RDX_3G_MMR):
|
||||||
gas_learn_speed = 300.0
|
gas_learn_speed = 300.0
|
||||||
else:
|
else:
|
||||||
gas_learn_speed = 50.0
|
gas_learn_speed = 50.0
|
||||||
self.bosch_gas_factor = float(np.clip(self.bosch_gas_factor + gas_error / gas_learn_speed * gas_pedal_force, 0.1, 3.0))
|
gas_factor_floor = 0.01 if self.mvl_accord_mode else 0.1
|
||||||
|
gas_learn_force = (gas_pedal_force - min_gas) if self.mvl_accord_mode else gas_pedal_force
|
||||||
|
self.bosch_gas_factor = float(np.clip(
|
||||||
|
self.bosch_gas_factor + gas_error / gas_learn_speed * gas_learn_force,
|
||||||
|
gas_factor_floor, 3.0,
|
||||||
|
))
|
||||||
|
|
||||||
if gas_error != 0.0 and not CS.out.brakePressed and CS.out.vEgo > 0.0:
|
if gas_error != 0.0 and not CS.out.brakePressed and CS.out.vEgo > 0.0:
|
||||||
wind_learn_speed = 100.0 if self.CP.carFingerprint in (CAR.ACURA_RDX_3G, CAR.ACURA_RDX_3G_MMR) else 1000.0
|
wind_learn_speed = 100.0 if self.CP.carFingerprint in (CAR.ACURA_RDX_3G, CAR.ACURA_RDX_3G_MMR) else 1000.0
|
||||||
@@ -378,7 +452,8 @@ class CarController(CarControllerBase):
|
|||||||
else:
|
else:
|
||||||
self.bosch_wind_factor = float(np.clip(self.bosch_wind_factor / wind_adjust, 0.1, 3.0))
|
self.bosch_wind_factor = float(np.clip(self.bosch_wind_factor / wind_adjust, 0.1, 3.0))
|
||||||
|
|
||||||
if gas_pedal_force <= 0.0:
|
wind_brake_threshold = min_gas if self.mvl_accord_mode else 0.0
|
||||||
|
if gas_pedal_force <= wind_brake_threshold:
|
||||||
self.bosch_wind_factor = max(self.bosch_wind_factor, self.bosch_wind_factor_before_brake)
|
self.bosch_wind_factor = max(self.bosch_wind_factor, self.bosch_wind_factor_before_brake)
|
||||||
else:
|
else:
|
||||||
self.bosch_wind_factor_before_brake = self.bosch_wind_factor
|
self.bosch_wind_factor_before_brake = self.bosch_wind_factor
|
||||||
@@ -390,15 +465,21 @@ class CarController(CarControllerBase):
|
|||||||
self.bosch_gas_factor_before_gasmax = self.bosch_gas_factor
|
self.bosch_gas_factor_before_gasmax = self.bosch_gas_factor
|
||||||
self.bosch_wind_factor_before_gasmax = self.bosch_wind_factor
|
self.bosch_wind_factor_before_gasmax = self.bosch_wind_factor
|
||||||
|
|
||||||
self.gas = float(np.interp(gas_pedal_force * self.bosch_gas_factor, self.params.BOSCH_GAS_LOOKUP_BP, self.params.BOSCH_GAS_LOOKUP_V))
|
gas_lookup_input = ((gas_pedal_force - min_gas) * self.bosch_gas_factor + min_gas) if self.mvl_accord_mode else \
|
||||||
|
gas_pedal_force * self.bosch_gas_factor
|
||||||
|
self.gas = float(np.interp(gas_lookup_input, self.params.BOSCH_GAS_LOOKUP_BP, self.params.BOSCH_GAS_LOOKUP_V))
|
||||||
self.gas = min(self.gas, max(60.0, self.bosch_last_gas + 60.0))
|
self.gas = min(self.gas, max(60.0, self.bosch_last_gas + 60.0))
|
||||||
self.bosch_last_gas = self.gas
|
self.bosch_last_gas = self.gas
|
||||||
|
|
||||||
stopping = actuators.longControlState == LongCtrlState.stopping
|
stopping = actuators.longControlState == LongCtrlState.stopping
|
||||||
self.stopping_counter = self.stopping_counter + 1 if stopping else 0
|
self.stopping_counter = self.stopping_counter + 1 if stopping else 0
|
||||||
can_sends.extend(
|
if not self.mvl_accord_mode or mvl_radar_owned:
|
||||||
hondacan.create_acc_commands(self.packer, self.CAN, CC.enabled, CC.longActive, self.accel, self.gas, self.stopping_counter, self.CP.carFingerprint)
|
can_sends.extend(
|
||||||
)
|
hondacan.create_acc_commands(
|
||||||
|
self.packer, self.CAN, CC.enabled, CC.longActive, self.accel, self.gas, self.stopping_counter, self.CP,
|
||||||
|
gas_force=gas_pedal_force if self.mvl_accord_mode else None,
|
||||||
|
)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
apply_brake = np.clip(self.brake_last - wind_brake, 0.0, 1.0)
|
apply_brake = np.clip(self.brake_last - wind_brake, 0.0, 1.0)
|
||||||
apply_brake = int(np.clip(apply_brake * self.params.NIDEC_BRAKE_MAX, 0, self.params.NIDEC_BRAKE_MAX - 1))
|
apply_brake = int(np.clip(apply_brake * self.params.NIDEC_BRAKE_MAX, 0, self.params.NIDEC_BRAKE_MAX - 1))
|
||||||
@@ -440,9 +521,16 @@ class CarController(CarControllerBase):
|
|||||||
idx = (self.frame // 2) % 0x10
|
idx = (self.frame // 2) % 0x10
|
||||||
can_sends.append(create_gas_interceptor_command(self.packer, gas_interceptor_command, idx))
|
can_sends.append(create_gas_interceptor_command(self.packer, gas_interceptor_command, idx))
|
||||||
|
|
||||||
# Send dashboard UI commands.
|
# Send dashboard UI commands. On CAN-FD, ACC_HUD is owned by the radar and must only start
|
||||||
|
# after the handover, aligned to the radar's 10 Hz HUD tick.
|
||||||
|
if (mvl_radar_owned and CS.hud_tick and self.CP.openpilotLongitudinalControl):
|
||||||
|
can_sends.append(
|
||||||
|
hondacan.create_acc_hud(self.packer, self.CAN.pt, self.CP, CC.enabled, pcm_speed, actuators.accel,
|
||||||
|
hud_control, hud_v_cruise, CS.is_metric, CS.acc_hud)
|
||||||
|
)
|
||||||
|
|
||||||
if self.frame % 10 == 0:
|
if self.frame % 10 == 0:
|
||||||
if self.CP.openpilotLongitudinalControl:
|
if self.CP.openpilotLongitudinalControl and not self.mvl_accord_mode:
|
||||||
# On Nidec, this also controls longitudinal positive acceleration
|
# On Nidec, this also controls longitudinal positive acceleration
|
||||||
can_sends.append(
|
can_sends.append(
|
||||||
hondacan.create_acc_hud(self.packer, self.CAN.pt, self.CP, CC.enabled, pcm_speed, pcm_accel, hud_control, hud_v_cruise, CS.is_metric, CS.acc_hud)
|
hondacan.create_acc_hud(self.packer, self.CAN.pt, self.CP, CC.enabled, pcm_speed, pcm_accel, hud_control, hud_v_cruise, CS.is_metric, CS.acc_hud)
|
||||||
@@ -458,7 +546,7 @@ class CarController(CarControllerBase):
|
|||||||
|
|
||||||
if self.CP.openpilotLongitudinalControl:
|
if self.CP.openpilotLongitudinalControl:
|
||||||
# TODO: combining with create_acc_hud block above will change message order and will need replay logs regenerated
|
# TODO: combining with create_acc_hud block above will change message order and will need replay logs regenerated
|
||||||
if self.CP.carFingerprint in (HONDA_BOSCH - HONDA_BOSCH_RADARLESS):
|
if self.CP.carFingerprint in (HONDA_BOSCH - HONDA_BOSCH_RADARLESS - {CAR.HONDA_ACCORD_11G}):
|
||||||
can_sends.append(hondacan.create_radar_hud(self.packer, self.CAN.pt))
|
can_sends.append(hondacan.create_radar_hud(self.packer, self.CAN.pt))
|
||||||
if self.CP.carFingerprint == CAR.HONDA_CIVIC_BOSCH:
|
if self.CP.carFingerprint == CAR.HONDA_CIVIC_BOSCH:
|
||||||
can_sends.append(hondacan.create_legacy_brake_command(self.packer, self.CAN.pt))
|
can_sends.append(hondacan.create_legacy_brake_command(self.packer, self.CAN.pt))
|
||||||
@@ -469,6 +557,29 @@ class CarController(CarControllerBase):
|
|||||||
else:
|
else:
|
||||||
self.gas = pcm_accel / self.params.NIDEC_GAS_MAX
|
self.gas = pcm_accel / self.params.NIDEC_GAS_MAX
|
||||||
|
|
||||||
|
# CAN-FD: while engaged, the camera still needs a valid SCM_BUTTONS stream behind the open relay.
|
||||||
|
# Take over that stream, echoing the live ambient-light byte. Also send a short LKAS-setting pulse
|
||||||
|
# when stock LKAS is ready, matching MVL's workaround for the Honda touch-steering-wheel timer.
|
||||||
|
if (self.mvl_accord_mode and CC.enabled and self.frame % 4 == 0
|
||||||
|
and not pcm_cancel_cmd and not CC.cruiseControl.resume):
|
||||||
|
if (self.lkas_button_send_remaining == 0 and CS.lkas_hud["LKAS_READY"]
|
||||||
|
and self.frame >= self.last_lkas_button_frame + 500):
|
||||||
|
self.lkas_button_send_remaining = 3
|
||||||
|
|
||||||
|
if self.lkas_button_send_remaining > 0:
|
||||||
|
self.last_lkas_button_frame = self.frame
|
||||||
|
self.lkas_button_send_remaining -= 1
|
||||||
|
cruise_setting = CruiseSettings.LKAS
|
||||||
|
elif CS.cruise_setting == CruiseSettings.LKAS:
|
||||||
|
cruise_setting = 0
|
||||||
|
else:
|
||||||
|
cruise_setting = CS.cruise_setting
|
||||||
|
|
||||||
|
can_sends.append(hondacan.spam_buttons_command(
|
||||||
|
self.packer, self.CAN, CS.cruise_buttons, self.CP.carFingerprint,
|
||||||
|
cruise_setting=cruise_setting, ambient_light=CS.scm_ambient_light, bus=self.CAN.camera,
|
||||||
|
))
|
||||||
|
|
||||||
if self.frame > 0 and self.frame % 6000 == 0:
|
if self.frame > 0 and self.frame % 6000 == 0:
|
||||||
self.param_store.put_float("HondaGasFactorParams", self.bosch_gas_factor)
|
self.param_store.put_float("HondaGasFactorParams", self.bosch_gas_factor)
|
||||||
self.param_store.put_float("HondaWindFactorParams", self.bosch_wind_factor)
|
self.param_store.put_float("HondaWindFactorParams", self.bosch_wind_factor)
|
||||||
|
|||||||
@@ -68,11 +68,33 @@ class CarState(CarStateBase):
|
|||||||
self.initial_accFault_cleared = False
|
self.initial_accFault_cleared = False
|
||||||
self.initial_accFault_cleared_timer = int(10 / DT_CTRL)
|
self.initial_accFault_cleared_timer = int(10 / DT_CTRL)
|
||||||
|
|
||||||
|
# CAN-FD deferred radar handover state. The stock radar remains responsible for ACC_CONTROL
|
||||||
|
# until the relay is open and the controller has silenced it; radar reference/tick messages are
|
||||||
|
# used to keep the replacement radar look-alikes on the stock cadence after the handover.
|
||||||
|
self.radar_ref_counter = 0
|
||||||
|
self.radar_5hz_tick_counter = 0
|
||||||
|
self.radar_5hz_tick = False
|
||||||
|
self.supp_tick_counter = 0
|
||||||
|
self.supp_tick = False
|
||||||
|
self.hud_tick_counter = 0
|
||||||
|
self.hud_tick = False
|
||||||
|
self.radar_50hz_tick_counter = 0
|
||||||
|
self.radar_50hz_tick = False
|
||||||
|
self.scm_ambient_light = 0
|
||||||
|
self.stock_acc_counter = 0
|
||||||
|
self.stock_acc_alive = False
|
||||||
|
self.camera_steer_counter = 0
|
||||||
|
self.camera_steer_seen = False
|
||||||
|
self.canfd_frames = 0
|
||||||
|
self.canfd_relay_open = False
|
||||||
|
|
||||||
def update(self, can_parsers, starpilot_toggles) -> structs.CarState:
|
def update(self, can_parsers, starpilot_toggles) -> structs.CarState:
|
||||||
cp = can_parsers[Bus.pt]
|
cp = can_parsers[Bus.pt]
|
||||||
cp_cam = can_parsers[Bus.cam]
|
cp_cam = can_parsers[Bus.cam]
|
||||||
if self.CP.enableBsm:
|
if self.CP.enableBsm:
|
||||||
cp_body = can_parsers[Bus.body]
|
cp_body = can_parsers[Bus.body]
|
||||||
|
if self.CP.carFingerprint == CAR.HONDA_ACCORD_11G:
|
||||||
|
cp_radar = can_parsers[Bus.radar]
|
||||||
|
|
||||||
ret = structs.CarState()
|
ret = structs.CarState()
|
||||||
|
|
||||||
@@ -85,6 +107,10 @@ class CarState(CarStateBase):
|
|||||||
prev_cruise_setting = self.cruise_setting
|
prev_cruise_setting = self.cruise_setting
|
||||||
self.cruise_setting = cp.vl["SCM_BUTTONS"]["CRUISE_SETTING"]
|
self.cruise_setting = cp.vl["SCM_BUTTONS"]["CRUISE_SETTING"]
|
||||||
self.cruise_buttons = cp.vl["SCM_BUTTONS"]["CRUISE_BUTTONS"]
|
self.cruise_buttons = cp.vl["SCM_BUTTONS"]["CRUISE_BUTTONS"]
|
||||||
|
if self.CP.carFingerprint in (HONDA_BOSCH_RADARLESS | {CAR.HONDA_ACCORD_11G}):
|
||||||
|
# The camera consumes this byte in SCM_BUTTONS too (adaptive high beam); preserve it when
|
||||||
|
# openpilot temporarily takes over SCM_BUTTONS toward the camera.
|
||||||
|
self.scm_ambient_light = cp.vl["SCM_BUTTONS"]["AMBIENT_LIGHT_MAYBE"]
|
||||||
|
|
||||||
# used for car hud message
|
# used for car hud message
|
||||||
self.is_metric = self.CP.carFingerprint in (CAR.HONDA_ODYSSEY_TWN,) or not cp.vl["CAR_SPEED"]["IMPERIAL_UNIT"]
|
self.is_metric = self.CP.carFingerprint in (CAR.HONDA_ODYSSEY_TWN,) or not cp.vl["CAR_SPEED"]["IMPERIAL_UNIT"]
|
||||||
@@ -116,8 +142,8 @@ class CarState(CarStateBase):
|
|||||||
steer_status = self.steer_status_values[cp.vl["STEER_STATUS"]["STEER_STATUS"]]
|
steer_status = self.steer_status_values[cp.vl["STEER_STATUS"]["STEER_STATUS"]]
|
||||||
ret.steerFaultPermanent = steer_status not in ("NORMAL", "NO_TORQUE_ALERT_1", "NO_TORQUE_ALERT_2", "LOW_SPEED_LOCKOUT", "TJA_LOW_SPEED_LOCKOUT",
|
ret.steerFaultPermanent = steer_status not in ("NORMAL", "NO_TORQUE_ALERT_1", "NO_TORQUE_ALERT_2", "LOW_SPEED_LOCKOUT", "TJA_LOW_SPEED_LOCKOUT",
|
||||||
"TMP_FAULT")
|
"TMP_FAULT")
|
||||||
if self.CP.carFingerprint in HONDA_BOSCH_ALT_RADAR:
|
if self.CP.carFingerprint in (HONDA_BOSCH_ALT_RADAR | {CAR.HONDA_ACCORD_11G}):
|
||||||
# TODO: See if this logic works for all other Honda
|
# MVL treats CAN-FD low-speed lockout as an expected EPS state too.
|
||||||
min_steer_speed = max(CarControllerParams.STEER_GLOBAL_MIN_SPEED, self.CP.minSteerSpeed)
|
min_steer_speed = max(CarControllerParams.STEER_GLOBAL_MIN_SPEED, self.CP.minSteerSpeed)
|
||||||
expected_low_speed_lockout = steer_status == "LOW_SPEED_LOCKOUT" and ret.vEgo < min_steer_speed
|
expected_low_speed_lockout = steer_status == "LOW_SPEED_LOCKOUT" and ret.vEgo < min_steer_speed
|
||||||
ret.steerFaultTemporary = steer_status != "NORMAL" and not expected_low_speed_lockout
|
ret.steerFaultTemporary = steer_status != "NORMAL" and not expected_low_speed_lockout
|
||||||
@@ -201,17 +227,18 @@ class CarState(CarStateBase):
|
|||||||
if self.CP.flags & HondaFlags.BOSCH_ALT_BRAKE:
|
if self.CP.flags & HondaFlags.BOSCH_ALT_BRAKE:
|
||||||
ret.brakePressed = cp.vl["BRAKE_MODULE"]["BRAKE_PRESSED"] != 0
|
ret.brakePressed = cp.vl["BRAKE_MODULE"]["BRAKE_PRESSED"] != 0
|
||||||
else:
|
else:
|
||||||
|
powertrain_data = cp.vl["POWERTRAIN_DATA"]
|
||||||
# brake switch has shown some single time step noise, so only considered when
|
# brake switch has shown some single time step noise, so only considered when
|
||||||
# switch is on for at least 2 consecutive CAN samples
|
# switch is on for at least 2 consecutive CAN samples
|
||||||
# brake switch rises earlier than brake pressed but is never 1 when in park
|
# brake switch rises earlier than brake pressed but is never 1 when in park
|
||||||
brake_switch_vals = cp.vl_all["POWERTRAIN_DATA"]["BRAKE_SWITCH"]
|
brake_switch_vals = cp.vl_all["POWERTRAIN_DATA"]["BRAKE_SWITCH"]
|
||||||
if len(brake_switch_vals):
|
if len(brake_switch_vals):
|
||||||
brake_switch = cp.vl["POWERTRAIN_DATA"]["BRAKE_SWITCH"] != 0
|
brake_switch = powertrain_data["BRAKE_SWITCH"] != 0
|
||||||
if len(brake_switch_vals) > 1:
|
if len(brake_switch_vals) > 1:
|
||||||
self.brake_switch_prev = brake_switch_vals[-2] != 0
|
self.brake_switch_prev = brake_switch_vals[-2] != 0
|
||||||
self.brake_switch_active = brake_switch and self.brake_switch_prev
|
self.brake_switch_active = brake_switch and self.brake_switch_prev
|
||||||
self.brake_switch_prev = brake_switch
|
self.brake_switch_prev = brake_switch
|
||||||
ret.brakePressed = (cp.vl["POWERTRAIN_DATA"]["BRAKE_PRESSED"] != 0) or self.brake_switch_active
|
ret.brakePressed = (powertrain_data["BRAKE_PRESSED"] != 0) or self.brake_switch_active
|
||||||
|
|
||||||
ret.brake = cp.vl["VSA_STATUS"]["USER_BRAKE"]
|
ret.brake = cp.vl["VSA_STATUS"]["USER_BRAKE"]
|
||||||
ret.cruiseState.enabled = cp.vl["POWERTRAIN_DATA"]["ACC_STATUS"] != 0
|
ret.cruiseState.enabled = cp.vl["POWERTRAIN_DATA"]["ACC_STATUS"] != 0
|
||||||
@@ -248,6 +275,63 @@ class CarState(CarStateBase):
|
|||||||
if self.CP.carFingerprint in (HONDA_BOSCH_RADARLESS | HONDA_BOSCH_CANFD):
|
if self.CP.carFingerprint in (HONDA_BOSCH_RADARLESS | HONDA_BOSCH_CANFD):
|
||||||
self.lkas_hud = cp_cam.vl["LKAS_HUD"]
|
self.lkas_hud = cp_cam.vl["LKAS_HUD"]
|
||||||
|
|
||||||
|
if self.CP.carFingerprint == CAR.HONDA_ACCORD_11G:
|
||||||
|
# Phase replacement radar messages from the stock radar's tick references. CarState reads the
|
||||||
|
# tick in one 100 Hz cycle and CarController transmits on the next, so pulse one frame before
|
||||||
|
# the expected next stock tick.
|
||||||
|
self.radar_ref_counter = cp.vl["RADAR_REFERENCE"]["COUNTER"]
|
||||||
|
|
||||||
|
ref_tick_vals = cp.vl_all.get("RADAR_REFERENCE", {}).get("COUNTER", [])
|
||||||
|
if len(ref_tick_vals) > 0:
|
||||||
|
self.radar_5hz_tick_counter = 0
|
||||||
|
else:
|
||||||
|
self.radar_5hz_tick_counter += 1
|
||||||
|
self.radar_5hz_tick = self.radar_5hz_tick_counter == 11
|
||||||
|
|
||||||
|
supp_tick_vals = cp_radar.vl_all.get("RADAR_SUPP_TICK_REFERENCE", {}).get("IGNORE", [])
|
||||||
|
if len(supp_tick_vals) > 0:
|
||||||
|
self.supp_tick_counter = 0
|
||||||
|
else:
|
||||||
|
self.supp_tick_counter += 1
|
||||||
|
self.supp_tick = self.supp_tick_counter == 99
|
||||||
|
|
||||||
|
hud_tick_vals = cp_radar.vl_all.get("RADAR_HUD_TICK_REFERENCE", {}).get("IGNORE", [])
|
||||||
|
if len(hud_tick_vals) > 0:
|
||||||
|
self.hud_tick_counter = 0
|
||||||
|
else:
|
||||||
|
self.hud_tick_counter += 1
|
||||||
|
self.hud_tick = self.hud_tick_counter == 9
|
||||||
|
|
||||||
|
tick_50hz_vals = cp_radar.vl_all.get("RADAR_50HZ_TICK_REFERENCE", {}).get("IGNORE", [])
|
||||||
|
if len(tick_50hz_vals) > 0:
|
||||||
|
self.radar_50hz_tick_counter = 0
|
||||||
|
else:
|
||||||
|
self.radar_50hz_tick_counter += 1
|
||||||
|
self.radar_50hz_tick = self.radar_50hz_tick_counter == 1
|
||||||
|
|
||||||
|
# ACC_CONTROL is normally present every 2 frames. Keep treating the stock radar as alive until
|
||||||
|
# four consecutive frames have passed without it, preventing overlap between stock and OP ACC.
|
||||||
|
self.canfd_frames += 1
|
||||||
|
if len(cp.vl_all.get("ACC_CONTROL", {}).get("COUNTER", [])) > 0:
|
||||||
|
self.stock_acc_counter = 0
|
||||||
|
else:
|
||||||
|
self.stock_acc_counter += 1
|
||||||
|
self.stock_acc_alive = self.stock_acc_counter < 4
|
||||||
|
|
||||||
|
# Before the relay opens, the camera's STEERING_CONTROL is physically visible on PT. Once the
|
||||||
|
# relay opens it disappears. Fallback to 5 seconds in case the camera frame was never observed.
|
||||||
|
if len(cp.vl_all.get("STEERING_CONTROL", {}).get("COUNTER", [])) > 0:
|
||||||
|
self.camera_steer_counter = 0
|
||||||
|
self.camera_steer_seen = True
|
||||||
|
else:
|
||||||
|
self.camera_steer_counter += 1
|
||||||
|
self.canfd_relay_open = (self.camera_steer_seen and self.camera_steer_counter >= 5) or self.canfd_frames >= 500
|
||||||
|
else:
|
||||||
|
self.supp_tick = False
|
||||||
|
self.hud_tick = False
|
||||||
|
self.radar_5hz_tick = False
|
||||||
|
self.radar_50hz_tick = False
|
||||||
|
|
||||||
if self.CP.enableBsm:
|
if self.CP.enableBsm:
|
||||||
# BSM messages are on B-CAN, requires a panda forwarding B-CAN messages to CAN 0
|
# BSM messages are on B-CAN, requires a panda forwarding B-CAN messages to CAN 0
|
||||||
# more info here: https://github.com/commaai/openpilot/pull/1867
|
# more info here: https://github.com/commaai/openpilot/pull/1867
|
||||||
@@ -269,11 +353,27 @@ class CarState(CarStateBase):
|
|||||||
return ret, fp_ret
|
return ret, fp_ret
|
||||||
|
|
||||||
def get_can_parsers(self, CP):
|
def get_can_parsers(self, CP):
|
||||||
|
pt_messages = [("GAS_SENSOR", 0)] if CP.enableGasInterceptorDEPRECATED else []
|
||||||
|
if CP.carFingerprint == CAR.HONDA_ACCORD_11G:
|
||||||
|
# Both deliberately go silent during the handover, so skip alive/timeout checks.
|
||||||
|
pt_messages += [("ACC_CONTROL", float("nan")), ("STEERING_CONTROL", float("nan"))]
|
||||||
|
|
||||||
|
pt_parser = CANParser(DBC[CP.carFingerprint][Bus.pt], pt_messages, CanBus(CP).pt)
|
||||||
|
if CP.enableGasInterceptorDEPRECATED:
|
||||||
|
pt_parser.message_states[0x201].ignore_checksum = True
|
||||||
|
pt_parser.message_states[0x201].ignore_counter = True
|
||||||
|
|
||||||
parsers = {
|
parsers = {
|
||||||
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], [], CanBus(CP).pt),
|
Bus.pt: pt_parser,
|
||||||
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], [], CanBus(CP).camera),
|
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], [], CanBus(CP).camera),
|
||||||
}
|
}
|
||||||
if CP.enableBsm:
|
if CP.enableBsm:
|
||||||
parsers[Bus.body] = CANParser(DBC[CP.carFingerprint][Bus.body], [], CanBus(CP).radar)
|
parsers[Bus.body] = CANParser(DBC[CP.carFingerprint][Bus.body], [], CanBus(CP).radar)
|
||||||
|
if CP.carFingerprint == CAR.HONDA_ACCORD_11G:
|
||||||
|
parsers[Bus.radar] = CANParser(DBC[CP.carFingerprint][Bus.radar], [
|
||||||
|
("RADAR_SUPP_TICK_REFERENCE", 0),
|
||||||
|
("RADAR_HUD_TICK_REFERENCE", 0),
|
||||||
|
("RADAR_50HZ_TICK_REFERENCE", 0),
|
||||||
|
], CanBus(CP).radar)
|
||||||
|
|
||||||
return parsers
|
return parsers
|
||||||
|
|||||||
@@ -257,7 +257,6 @@ FW_VERSIONS = {
|
|||||||
(Ecu.eps, 0x18da30f1, None): [
|
(Ecu.eps, 0x18da30f1, None): [
|
||||||
b'39990-TBA-C120\x00\x00',
|
b'39990-TBA-C120\x00\x00',
|
||||||
b'39990-TBA-C020\x00\x00',
|
b'39990-TBA-C020\x00\x00',
|
||||||
b'39990-TBA-C120\x00\x00',
|
|
||||||
b'39990-TEA-T330\x00\x00',
|
b'39990-TEA-T330\x00\x00',
|
||||||
b'39990-TEA-T820\x00\x00',
|
b'39990-TEA-T820\x00\x00',
|
||||||
b'39990-TEZ-T020\x00\x00',
|
b'39990-TEZ-T020\x00\x00',
|
||||||
@@ -994,6 +993,7 @@ FW_VERSIONS = {
|
|||||||
b'36161-T47-A060\x00\x00',
|
b'36161-T47-A060\x00\x00',
|
||||||
b'36161-T47-A070\x00\x00',
|
b'36161-T47-A070\x00\x00',
|
||||||
b'8S102-T20-AA10\x00\x00',
|
b'8S102-T20-AA10\x00\x00',
|
||||||
|
b'8S102-T20-AA20\x00\x00',
|
||||||
b'8S102-T43-J540\x00\x00',
|
b'8S102-T43-J540\x00\x00',
|
||||||
b'8S102-T47-AA10\x00\x00',
|
b'8S102-T47-AA10\x00\x00',
|
||||||
b'8S102-T47-AA20\x00\x00',
|
b'8S102-T47-AA20\x00\x00',
|
||||||
@@ -1002,6 +1002,7 @@ FW_VERSIONS = {
|
|||||||
b'8S102-T56-A070\x00\x00',
|
b'8S102-T56-A070\x00\x00',
|
||||||
b'8S102-T60-AA10\x00\x00',
|
b'8S102-T60-AA10\x00\x00',
|
||||||
b'8S102-T64-A040\x00\x00',
|
b'8S102-T64-A040\x00\x00',
|
||||||
|
b'8S102-T64-A050\x00\x00',
|
||||||
],
|
],
|
||||||
(Ecu.vsa, 0x18da28f1, None): [
|
(Ecu.vsa, 0x18da28f1, None): [
|
||||||
b'57114-T20-AB40\x00\x00',
|
b'57114-T20-AB40\x00\x00',
|
||||||
@@ -1038,6 +1039,8 @@ FW_VERSIONS = {
|
|||||||
(Ecu.fwdCamera, 0x18dab5f1, None): [
|
(Ecu.fwdCamera, 0x18dab5f1, None): [
|
||||||
b'8S102-30A-A050\x00\x00',
|
b'8S102-30A-A050\x00\x00',
|
||||||
b'8S102-30A-A060\x00\x00',
|
b'8S102-30A-A060\x00\x00',
|
||||||
|
b'8S102-30A-A070\x00\x00',
|
||||||
|
b'8S102-30A-A080\x00\x00',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
CAR.HONDA_CRV_6G: {
|
CAR.HONDA_CRV_6G: {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user