mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-07-17 02:02:05 +08:00
Compare commits
1225 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f90175833d | |||
| 14318d2f09 | |||
| 70f2c3ac79 | |||
| a43fc920b5 | |||
| 91b067cca0 | |||
| 41886a90da | |||
| 680dd7cf3b | |||
| db99c8e5a6 | |||
| 48a5bdc8e4 | |||
| 79b79edd2f | |||
| 2b1fd89064 | |||
| ec72ee096d | |||
| eee13472ce | |||
| d275c65f75 | |||
| a9ffebe96e | |||
| 45661ee8c0 | |||
| c16039e0bc | |||
| d1e143ac98 | |||
| 45b53cf66a | |||
| cf8371c2c5 | |||
| f42dbbb01c | |||
| 4fd4ddb438 | |||
| 503531ab38 | |||
| a52da0d3df | |||
| a26254304f | |||
| c91731b13a | |||
| 60924556f6 | |||
| ee11c24cf4 | |||
| 6392096de5 | |||
| 39117a5879 | |||
| 1478d0c476 | |||
| f283f6703c | |||
| b827c0f55e | |||
| bf5540c364 | |||
| 3b3f5967ec | |||
| 1e49eac4d1 | |||
| 9877f6ac0e | |||
| 1ab1ed7453 | |||
| cb82722dd5 | |||
| 960c988355 | |||
| 05cf8023a9 | |||
| 1b6e127e68 | |||
| c02cf706a6 | |||
| 0d93f0e820 | |||
| 6de5d2c23a | |||
| 92f3d24c8a | |||
| d606014ce2 | |||
| 2aa934e7c2 | |||
| 70a6efb8fc | |||
| 07ec389f4c | |||
| 9d03e737dd | |||
| 4532320fb3 | |||
| 4c5bef5840 | |||
| 8e0ba7a91e | |||
| fa0c6876d3 | |||
| a2c554805b | |||
| e1e9efb965 | |||
| 8196b743af | |||
| 724971afc3 | |||
| 4fc5e308f3 | |||
| 8a3bbcdd4e | |||
| 8c927d0fc2 | |||
| 97215b17d7 | |||
| 31dc4d8e52 | |||
| 61b6d52b01 | |||
| da6313dbe9 | |||
| e9e5548edc | |||
| f9c555a3fe | |||
| 069506aa36 | |||
| 5629b5a83d | |||
| addca46f68 | |||
| 7d325d6650 | |||
| 288aa60bf4 | |||
| cddb6103eb | |||
| 1474d5474d | |||
| 2e9fa514bb | |||
| 8a9ca15464 | |||
| 5edc0bd89d | |||
| 20e0f21b58 | |||
| 37eda06c95 | |||
| df1663c58d | |||
| bc168bb33a | |||
| d79267fa22 | |||
| cea5273f1f | |||
| d8bd6c784e | |||
| ad5151b38b | |||
| fddb9fb31c | |||
| b871364e1f | |||
| f0831e549b | |||
| 7cee534b72 | |||
| e0e9f1a4d3 | |||
| 160942dfde | |||
| 52e25ebe4e | |||
| 3b4077d31b | |||
| f0f7b877c3 | |||
| cb6e422c91 | |||
| f48e99b335 | |||
| b2a7084906 | |||
| 62b97fabf7 | |||
| f257544f1b | |||
| 45d8bcd7f3 | |||
| 0038d84e13 | |||
| cd2c590d50 | |||
| ddc8d37136 | |||
| d4db600d4b | |||
| 5ab7e48479 | |||
| e2e3703ae4 | |||
| 3939f1e92c | |||
| 82a945d145 | |||
| 93224b3c05 | |||
| 8a80bd70e7 | |||
| 29e7f362ed | |||
| 3c4790c089 | |||
| c0456590f6 | |||
| f3b1f97afa | |||
| 4cefe7239d | |||
| 586dd4c611 | |||
| 291315ab25 | |||
| 37390743c1 | |||
| 15fb1a809d | |||
| 0240a62fd9 | |||
| fafcee04f4 | |||
| 2feca929ab | |||
| a40fa3a0b0 | |||
| f9cc67896c | |||
| cd052f124e | |||
| 14cff000e9 | |||
| 9ef3cfdf9a | |||
| 4024d13dda | |||
| b2bb71b4b7 | |||
| 98e5f547ea | |||
| 5a7b710d90 | |||
| 7661e03d1e | |||
| bdac9efa1e | |||
| 433c52f623 | |||
| 24d373062d | |||
| 41390a95b8 | |||
| 57b5eb3113 | |||
| 01a843e0ac | |||
| 097dd9b5f2 | |||
| 122ac986de | |||
| bc27262a92 | |||
| 7abe0205fd | |||
| ef3ec30fe2 | |||
| 066ba92e77 | |||
| dfb21bd53e | |||
| b0600a4225 | |||
| cc110d1eb1 | |||
| bfd8d4868d | |||
| 14a00e0cc8 | |||
| 46b9253729 | |||
| 40875ef72f | |||
| 268126f376 | |||
| 900a896c63 | |||
| c01b8be968 | |||
| 094591793a | |||
| f02d134f40 | |||
| 36a9c02b8f | |||
| 3137a32db4 | |||
| 5b3d5f74ed | |||
| 866cd01f32 | |||
| d09a411cb4 | |||
| 69e2c321e4 | |||
| c87f613659 | |||
| 249cafe897 | |||
| 0f17a98793 | |||
| 04e2351246 | |||
| bd148abbc4 | |||
| c76f481ddc | |||
| ce08f5290b | |||
| bc2b0d8272 | |||
| 965f47efe3 | |||
| 5bbcc32b5d | |||
| 517b9a2d5f | |||
| 5063c2055f | |||
| 9f3448f662 | |||
| 609a5c3cfa | |||
| d937401511 | |||
| 8499de6afe | |||
| 3452e878a7 | |||
| 804d9016ae | |||
| ad522f8444 | |||
| 9f59a4a5ca | |||
| 417efb3c05 | |||
| 4df40d2c19 | |||
| 069b912056 | |||
| a8772eb0af | |||
| a81617d8ee | |||
| 5408c86b7b | |||
| 4cd93f3eee | |||
| dfc3c98b22 | |||
| 4585e93066 | |||
| 5af72796f2 | |||
| ccac1e28de | |||
| bdca897248 | |||
| b93d166ff8 | |||
| d9553eeec7 | |||
| 9d74412fec | |||
| 95f562c298 | |||
| d489dd8909 | |||
| 1f227bbe20 | |||
| 9844075bb2 | |||
| a3cc9c7ac3 | |||
| aff9f9ffae | |||
| 38faa7c2cb | |||
| 52e182611d | |||
| 82338fd8c5 | |||
| 12aaacdffc | |||
| 6941a913a3 | |||
| 27e37f9d95 | |||
| 43d61f043c | |||
| 77017a913a | |||
| 24ff455bc0 | |||
| 2920503f94 | |||
| 46e3c907f6 | |||
| 2ed88a1dff | |||
| 107a6f4c00 | |||
| 059d0b6c4c | |||
| 65405bafa6 | |||
| d4a83deb7d | |||
| dd58eb68f0 | |||
| 4cfd774855 | |||
| e9cf5d67cf | |||
| 74554a523f | |||
| 2d4ac33ed7 | |||
| c9d77fb3fb | |||
| a432afd173 | |||
| c51ffe3808 | |||
| ef94b134c3 | |||
| f24ad7e27a | |||
| b88adeb4ad | |||
| a15aed1a79 | |||
| aa26dded8b | |||
| a06f31b472 | |||
| b3ed39525d | |||
| 57c44831da | |||
| 8ebc51a8aa | |||
| 4ecbdb0d7a | |||
| 4b945a1b79 | |||
| e8a03f7f32 | |||
| 69d3066d82 | |||
| 9574eee0e3 | |||
| 492ed73127 | |||
| af92603d17 | |||
| ecb661fe85 | |||
| dff6a80faf | |||
| 3a764c0ae3 | |||
| 11c14a138f | |||
| bdee8731b7 | |||
| 4b81dda1b5 | |||
| edc3ce89fa | |||
| 02f66e6e84 | |||
| 15267e4082 | |||
| 628e230b63 | |||
| 98512fc62b | |||
| 38ffb324f8 | |||
| 78007e82e0 | |||
| 534fb19714 | |||
| 294cb687f6 | |||
| 2a86d0cea5 | |||
| bbe5b38643 | |||
| 2691aa8e39 | |||
| da62722d07 | |||
| f6e2dd280d | |||
| 8583826166 | |||
| 93ed08ba20 | |||
| 6b6b7f0f33 | |||
| bea893820e | |||
| e624da2eed | |||
| 656de3f17b | |||
| 63508d0481 | |||
| b1a6223b14 | |||
| e771dfa007 | |||
| d7c562e130 | |||
| f87bc52405 | |||
| 1268227ce5 | |||
| 76f1f189db | |||
| 9fdcbae8de | |||
| f18aa113a5 | |||
| a3d3d0fea6 | |||
| 5745909e9b | |||
| fd37cd1d03 | |||
| ab1a962803 | |||
| 32671d1c3f | |||
| 01e7606b70 | |||
| bd1c7f39ec | |||
| c28eb95874 | |||
| a544cd7d39 | |||
| b7725c5cbb | |||
| 7ed960f713 | |||
| 6420e8d92a | |||
| 695a2d783f | |||
| 2596de8543 | |||
| 7a6dc19104 | |||
| 7e2b8430c5 | |||
| 521fa09b0d | |||
| 5adcff1221 | |||
| b9aa1962ca | |||
| 6b1b6aca05 | |||
| 41a8bc3fc4 | |||
| 540f4f5933 | |||
| 0e58ac33ad | |||
| 53e5ae0578 | |||
| dd0690da6f | |||
| 57d0a58855 | |||
| f64f3944a6 | |||
| 65b2bfe5d8 | |||
| 1caae26cfc | |||
| 94cf600bfe | |||
| 4a1b721636 | |||
| 55f033ced0 | |||
| 2182be05ea | |||
| 3e44c90c68 | |||
| 2d35bd895f | |||
| 855d5022ad | |||
| 6a363365ab | |||
| d238a1ccc4 | |||
| 1eeba86ec1 | |||
| 96d55a3283 | |||
| 5752095bc2 | |||
| 8560f2732a | |||
| b8bcf32457 | |||
| 1a93104bfd | |||
| ab43fd1369 | |||
| 605dfaa1a9 | |||
| b279aa6015 | |||
| 0f542bef38 | |||
| f364110a36 | |||
| 635a3bc7ab | |||
| 56b3b4d245 | |||
| 168b9831b2 | |||
| d20794f900 | |||
| 7b79305d99 | |||
| dd7da3153a | |||
| 39849def72 | |||
| 4db23ed4c6 | |||
| a4e016c142 | |||
| 61f7c7ea03 | |||
| 82a959ef8e | |||
| b3f369612d | |||
| ae0962cd0c | |||
| f00ff77c55 | |||
| dab51a864f | |||
| 360fd1555f | |||
| 813d794f05 | |||
| ddb9039493 | |||
| 0b7df7df10 | |||
| dd3feac854 | |||
| f7644c913e | |||
| 13ea74bcb4 | |||
| dc6e644359 | |||
| 85f00ff80a | |||
| 3af3c7e748 | |||
| 545ad018e0 | |||
| e86d4e86a6 | |||
| 7002d24213 | |||
| 10a33a4bf1 | |||
| d1e069210f | |||
| 8714203d2c | |||
| ee54e82090 | |||
| 79cd8420eb | |||
| 8c533b14c0 | |||
| 494eba5961 | |||
| ad875632ac | |||
| 63068481d7 | |||
| 275206c14d | |||
| c3b0f0d11a | |||
| 1c69770c53 | |||
| 551e2f77bf | |||
| ad04c6a038 | |||
| bb4b96e05d | |||
| 7d71354fd0 | |||
| 49685fc2bc | |||
| 0eacf34e15 | |||
| 0be0d7fa94 | |||
| 736cf6d9df | |||
| df6d34e52b | |||
| 39d1eec575 | |||
| 2266a9dd9c | |||
| f8372ccc4d | |||
| f8c45d307c | |||
| ca04b70d0a | |||
| 571a547671 | |||
| b29d0a17af | |||
| 859bd215bf | |||
| 4988a62b31 | |||
| e202bbe4aa | |||
| 4286a64083 | |||
| 341786acb5 | |||
| 04b23ff849 | |||
| 6996e87f8d | |||
| 18406e77ee | |||
| b6432e705d | |||
| fdd43f49e0 | |||
| 5d7155fdda | |||
| b9986cae06 | |||
| 2c0903e45e | |||
| f93481d0d4 | |||
| 389b639ef2 | |||
| 5f6e05410d | |||
| 5624a4ccd6 | |||
| d81d66193f | |||
| d1d6fae613 | |||
| 35aeeee657 | |||
| a6fdef77df | |||
| df66604a45 | |||
| c001f3c9b4 | |||
| 752fe03118 | |||
| 84c276bb6c | |||
| 9042cfa1ad | |||
| 83e6e7da93 | |||
| 31403f4a5c | |||
| 117d5cee4f | |||
| fa18e6395c | |||
| 75e352e5d0 | |||
| 63ab2fb1b3 | |||
| 97f1bac71d | |||
| 00b7c8e8ad | |||
| 1276452cfc | |||
| 8b2eac4d1f | |||
| e78e6261ca | |||
| 61915eb914 | |||
| d5f1d8c33a | |||
| e16d422cf4 | |||
| 3509fccec7 | |||
| 613d13bbfb | |||
| f70a156c7e | |||
| d204d626bd | |||
| fd590b206e | |||
| 6102aedf05 | |||
| c7efc009a4 | |||
| c23f2dce2c | |||
| 4a15bdcdae | |||
| 30a858c23d | |||
| d95bc0dcfe | |||
| 2406b32d55 | |||
| 6979849305 | |||
| bf2294dee2 | |||
| fcb0a496ed | |||
| c91a0a83f6 | |||
| 63107e6e6b | |||
| 0584a5f5eb | |||
| f24dfd6ee9 | |||
| 9022b4d322 | |||
| b782958abd | |||
| 3fa6726f88 | |||
| 8c240cc1a4 | |||
| 9541692eb0 | |||
| f83b749ec2 | |||
| b930f5c3f1 | |||
| 0a58d8b761 | |||
| 64e785d00f | |||
| 9db432e8fb | |||
| 6ce156ee16 | |||
| a89ed55b65 | |||
| 9dc4986e21 | |||
| f17a0aac94 | |||
| 934fd5a5a8 | |||
| b5576de97e | |||
| 58090f5f7e | |||
| 09a55a7833 | |||
| 8abfbc56a1 | |||
| 8b53f9158d | |||
| 21538e5a09 | |||
| 19d56f685b | |||
| 508863e5a8 | |||
| f28d6fb6bc | |||
| 54a2d31e97 | |||
| b0b9079437 | |||
| c7382f8258 | |||
| 08401a96c2 | |||
| f37fd3ea34 | |||
| e541489b33 | |||
| e5ac18702c | |||
| 3c93d4cba1 | |||
| dc4dae6794 | |||
| f170440f4a | |||
| fa329eb9ff | |||
| 310ba9d2c0 | |||
| f0053d4619 | |||
| 052692b25d | |||
| 79bf1e1450 | |||
| b5d2026fc7 | |||
| d398f9951e | |||
| 55c3885742 | |||
| cb32793300 | |||
| d8569b07eb | |||
| efd5301f65 | |||
| 5dcaf3bef8 | |||
| bf43c7e8c7 | |||
| 1dec68014f | |||
| 8badc7d813 | |||
| 9be7a48ccd | |||
| 6b94c47c6a | |||
| b706673e1c | |||
| e4813645fa | |||
| 12f1be19cc | |||
| e5ebd45576 | |||
| 0870e26fb6 | |||
| d75b8f4540 | |||
| f4b8384332 | |||
| 5766202763 | |||
| 6871203c45 | |||
| 1d48cbdffa | |||
| 54db569c2c | |||
| 31e4fe55ac | |||
| a8b5c74507 | |||
| 470c3f4a92 | |||
| af09b7a45b | |||
| 7fae59167e | |||
| 08d8bb9975 | |||
| 240e0036d2 | |||
| d5e75dd0af | |||
| e53cc41b47 | |||
| d0382e2d48 | |||
| 78b15773c9 | |||
| f95959afdb | |||
| 1c14375796 | |||
| 1658898498 | |||
| 9a8795f063 | |||
| d5b25e14fd | |||
| 23c774eb19 | |||
| a68ea44af3 | |||
| 5e7f5dd840 | |||
| cc4f786846 | |||
| f4657aa2d5 | |||
| 46bbe6890a | |||
| 380d91c8f7 | |||
| 24121f8abf | |||
| 9d19cca006 | |||
| ee9da82aab | |||
| 06630e8a39 | |||
| 2cc70ef2e4 | |||
| 37ac33fbcc | |||
| 0376660023 | |||
| 5908b7cda0 | |||
| d0375942b8 | |||
| bbed1a2551 | |||
| 2b0aab3a38 | |||
| d8ae8c201a | |||
| 9bcd965f0b | |||
| 6e7587a75c | |||
| c631a22eb6 | |||
| 7dfb7967b6 | |||
| 58d6211bc2 | |||
| 4e239dbc22 | |||
| 3469d9aadb | |||
| 18da21e65b | |||
| 50f0cf25a6 | |||
| bea040095c | |||
| 3584523a93 | |||
| 2e82908c07 | |||
| d3bcc80d28 | |||
| 0ce679f687 | |||
| d55ccba5fe | |||
| f85b3473a2 | |||
| b750229e70 | |||
| 40b61a8212 | |||
| 5927316788 | |||
| dd89bc30fa | |||
| bf4bf0e5b7 | |||
| 9164148d48 | |||
| ac3dcbe62f | |||
| ba19527181 | |||
| 4acf0438c8 | |||
| bd5fbbabda | |||
| 1777d548bf | |||
| 095d96fbe0 | |||
| 2ca6f893df | |||
| a17a8daad5 | |||
| acace97ef8 | |||
| 0208d26845 | |||
| dd8aa4a21e | |||
| d6c85abcd3 | |||
| 56d1961625 | |||
| 1dbae159a8 | |||
| 76458d175f | |||
| ad181ba501 | |||
| 71290f3805 | |||
| e42ee228c2 | |||
| 9510e05dc0 | |||
| 6e87e66bc5 | |||
| 1197ea9ab9 | |||
| 9d7edbf57a | |||
| acec60d19e | |||
| 6a3dcc74e8 | |||
| 6e851ff886 | |||
| 7a5d8a813b | |||
| 4742bf0230 | |||
| 4bf2bfb122 | |||
| 797b769478 | |||
| 024e2af269 | |||
| e35513afc4 | |||
| 6607283cec | |||
| 08162be765 | |||
| 7061c18cee | |||
| c36c30e74b | |||
| 1f9ec135a4 | |||
| b71914e006 | |||
| 0557283e3d | |||
| a9d5c9e23a | |||
| 793f8fee32 | |||
| 5e1a576f3d | |||
| fd98db72ab | |||
| 2f1a58f991 | |||
| c01719bb99 | |||
| 4cc68f57cf | |||
| 5e2a5b5355 | |||
| 44ec08c112 | |||
| 60ec7dc7b6 | |||
| af1fb2644e | |||
| 4651bc6a1f | |||
| ac1dd692af | |||
| 6dd72973ec | |||
| 4e0a26be8d | |||
| 363735f7ce | |||
| 7c3759e147 | |||
| 5303afb0dc | |||
| 118d903e2d | |||
| 93eb8418b7 | |||
| 6922d58762 | |||
| b4b747e5cb | |||
| 2d53f4cf01 | |||
| 4a1101c032 | |||
| 41bba2b55a | |||
| d801cebb2e | |||
| 3a19f85512 | |||
| dcc166343f | |||
| 4f5df6589d | |||
| 3cc9d89d45 | |||
| baaa2704ee | |||
| e59f675715 | |||
| 00afa068a1 | |||
| 5beae930e4 | |||
| 0274b73760 | |||
| 6bea70ac86 | |||
| 055b29b226 | |||
| 6330a9c53a | |||
| 2c4e114b51 | |||
| e264b4269f | |||
| fef89d1039 | |||
| fc372e2ae1 | |||
| cd22ee3327 | |||
| e97a1d1a44 | |||
| 6795b09d0a | |||
| 20d484c7cb | |||
| 7e1a8d41a1 | |||
| 0c452dbafe | |||
| 56ed377197 | |||
| 92f9684fdb | |||
| 91b7752268 | |||
| 2ebf09eb07 | |||
| 90af6be9b8 | |||
| 3504ccb639 | |||
| 443cd795a3 | |||
| 06b2c68e03 | |||
| 3478ac1338 | |||
| ce04d25f7d | |||
| 0c7abf3855 | |||
| 0b9ab8bb91 | |||
| 6b52ee7ef2 | |||
| c3d5c5f016 | |||
| 0374979397 | |||
| a17a38d8c3 | |||
| 8b13186a32 | |||
| 9c5bf2ce0a | |||
| f9b5d1e9e5 | |||
| 041606de4c | |||
| daaec59464 | |||
| 56ef3751d8 | |||
| c244a5d485 | |||
| 308475fcc9 | |||
| a7de971334 | |||
| 61658fbfe3 | |||
| 5ef0040ac6 | |||
| c188c96956 | |||
| 0376600dec | |||
| cfc28176f2 | |||
| 7b104c682b | |||
| 42f43c3231 | |||
| b2201c2a1d | |||
| d1005f3b69 | |||
| 24d3f07a2f | |||
| b10c2ada79 | |||
| d44fde7117 | |||
| d634894300 | |||
| 8856585129 | |||
| e7cc70f3fa | |||
| de0790f912 | |||
| a6b562e0c1 | |||
| 60ae57a3ed | |||
| 5a0c064346 | |||
| ca5234a32f | |||
| fd1937c6d4 | |||
| a27efe5796 | |||
| 870430e19f | |||
| 6cbef7bc13 | |||
| 9cc0d7a1c9 | |||
| e244aabe88 | |||
| b15390d351 | |||
| 2af7b3441e | |||
| 87c495b761 | |||
| d016071df3 | |||
| 940c5b3b3f | |||
| 256ee6cf6f | |||
| b5855bcade | |||
| 8f328f17fc | |||
| b6f3692b56 | |||
| 6266feeed2 | |||
| 876ac69047 | |||
| 16047e3c3d | |||
| 47ca2c9381 | |||
| 29a3b3315f | |||
| 10f3f56801 | |||
| 7eb65e878b | |||
| 2e42bf9fa4 | |||
| 3beee1b80e | |||
| 3a958b882a | |||
| 1b17bf40cd | |||
| 6e8f325024 | |||
| cc21fd3ac3 | |||
| 010a32bb9b | |||
| 6f6dfa6bba | |||
| a37d3569bd | |||
| d3e26cf695 | |||
| 05e331736d | |||
| ab9a58c64a | |||
| ddf05d7126 | |||
| 59a16b9cdc | |||
| 276713ddf9 | |||
| e1a4189c1f | |||
| a1f4ba55bf | |||
| d899834b63 | |||
| c5372e9041 | |||
| 1bf0fb3851 | |||
| fe39ffa55a | |||
| 0437998bce | |||
| de8f7c4584 | |||
| 286c4f8403 | |||
| 0977a91d65 | |||
| 245d5bba9c | |||
| 2ef29967e8 | |||
| 6d559c4219 | |||
| 3cc4683eb7 | |||
| ac08c79139 | |||
| 04dcdf46bc | |||
| 7f1def00b2 | |||
| 94ee6b0f43 | |||
| 91696ba6c8 | |||
| 608a1c2baa | |||
| 93a96695ea | |||
| 146c64b0f1 | |||
| 4cd5c1b3c2 | |||
| 811363cab9 | |||
| b2e94548b9 | |||
| cf5ae3cbca | |||
| 561c490b2a | |||
| 496ae85f67 | |||
| 5c630b20a9 | |||
| c2a7437972 | |||
| 1550520b63 | |||
| bcb4a6a3e3 | |||
| 7835b9aa17 | |||
| f2c4749420 | |||
| 238fca2334 | |||
| 72ecc330e2 | |||
| d9b5a1e30b | |||
| f43dc93bd9 | |||
| 06a5a380df | |||
| a4166563e1 | |||
| 1792a60053 | |||
| 538e1e8a9a | |||
| 7a43e2cb67 | |||
| 571937da84 | |||
| 6442752486 | |||
| ed34c4cfd6 | |||
| 8810948eca | |||
| 0b6da2077f | |||
| 159d3a30e3 | |||
| 6db6d79211 | |||
| a064de7ceb | |||
| c787507449 | |||
| 3352e48c51 | |||
| 081bb51e58 | |||
| faa23595af | |||
| cf083711bb | |||
| 9f7002fdf1 | |||
| 761c349490 | |||
| 03a14ff864 | |||
| c48b724de1 | |||
| 542e14306e | |||
| 79bc6c3a52 | |||
| 8952c947d1 | |||
| a1e9cf9df9 | |||
| 8a64cc57a9 | |||
| 2ddf95d47f | |||
| 8bd8066589 | |||
| 44cf6b358e | |||
| ded5e5c8d0 | |||
| 21b8189a45 | |||
| 76a552715f | |||
| bd3b7a1d87 | |||
| 8543afc78a | |||
| 12f923445b | |||
| 0e127cf88b | |||
| c5b65d072d | |||
| ed8d1a65c3 | |||
| 91930c2d0d | |||
| 111e8897be | |||
| 19459d2b2e | |||
| 5af3f32157 | |||
| 16dda06a0c | |||
| 76d084d877 | |||
| 90a9ef277c | |||
| b32227e69f | |||
| 7cc237aa4c | |||
| 0a14e19808 | |||
| c16879f2b8 | |||
| 8d0cb9c8cf | |||
| 2ecdd2810c | |||
| 35e38f5fe4 | |||
| 2a0ac63fa5 | |||
| ca058bcc81 | |||
| f96406b13f | |||
| 0738c05d9f | |||
| 08b76d3de6 | |||
| cef81da1e9 | |||
| f4a36f7f74 | |||
| f911493177 | |||
| fa2050ab1a | |||
| 4bffe422e4 | |||
| f881a9ba68 | |||
| afa9ec1138 | |||
| ddf8abc14a | |||
| 5f722d2c93 | |||
| 31ac5a216d | |||
| 1b262a5a52 | |||
| 517289f3a5 | |||
| 6fcd2187e1 | |||
| 8fa3f60de7 | |||
| a3f40dbac3 | |||
| f99dc2eab2 | |||
| cdcc2f6766 | |||
| 1304f95978 | |||
| c4393277fb | |||
| 7cd9ab27e6 | |||
| ece999c548 | |||
| 082cf39d73 | |||
| f41d77b24f | |||
| f45f239774 | |||
| 02e550e2cb | |||
| 06298b28f1 | |||
| a694d051b3 | |||
| 468a50b6f6 | |||
| 4e8a4f87f4 | |||
| 30350f4207 | |||
| c98ba4ff4c | |||
| c46cf9f536 | |||
| 23e1c4f49e | |||
| d6af0e6eb5 | |||
| 09926bf5b5 | |||
| f9f33c4dc4 | |||
| 5fc6fe68f6 | |||
| 806655b052 | |||
| 5d54743d8b | |||
| b28ff40d4d | |||
| 07163f793b | |||
| 66687746f9 | |||
| b27fa58444 | |||
| 8bca2ca758 | |||
| cefddf4b9b | |||
| f829c90de6 | |||
| 6bd3cab8a8 | |||
| e54c0091bc | |||
| 48568cba0b | |||
| 6ecb1060be | |||
| 93977e2ee2 | |||
| 8650ca837f | |||
| 6853f1db29 | |||
| 140aa95523 | |||
| 69544c57fd | |||
| a3f2452fa7 | |||
| c736d43cce | |||
| a28cc71b8b | |||
| 612c518dd6 | |||
| 5ccabb9d54 | |||
| 0bb2f8c9d4 | |||
| 3c4ddba992 | |||
| 488d84c664 | |||
| b6a0c89dc5 | |||
| a6f4cdb319 | |||
| b80d3e113b | |||
| d80cde6e41 | |||
| c6db0cd4b6 | |||
| 489afc3842 | |||
| b5f86446d4 | |||
| 62b5fd54e6 | |||
| 7aeb7085a3 | |||
| edafe139a4 | |||
| 80f4becabf | |||
| 3a74f8c568 | |||
| 5eed9490c6 | |||
| c8e10139c2 | |||
| 966bb6cc54 | |||
| 57b461a186 | |||
| 887ea25b6d | |||
| 735c2fb48e | |||
| 028f5ca1f4 | |||
| d6238c285a | |||
| 80e23509ba | |||
| c07ddcefb0 | |||
| 4f407dabcd | |||
| fd34659dc3 | |||
| 1f85860f7e | |||
| 14f3f6dd1a | |||
| e527b463a5 | |||
| 7dc56dc064 | |||
| 0a98ee9e4f | |||
| 43d162e8fb | |||
| e8f65bc652 | |||
| 037e6e749a | |||
| d984fb1bae | |||
| 3661a01489 | |||
| 7fd131e01c | |||
| 5d8e54ae3e | |||
| 422885dce6 | |||
| 136574fbcb | |||
| f81e7245fe | |||
| 0cb6b7b807 | |||
| 4a869778a9 | |||
| a120053d12 | |||
| a48988ccb3 | |||
| a5f9c2fc23 | |||
| 6704f63a3d | |||
| 8e13d8abd0 | |||
| 8831b11a24 | |||
| 03a4f7ef9a | |||
| c393973916 | |||
| 27f89e6634 | |||
| 4166c9fccb | |||
| ced5f417b8 | |||
| f67f84109e | |||
| eea07462fa | |||
| 96d1b876bb | |||
| 56d3014298 | |||
| ae6aa0f008 | |||
| ecde604198 | |||
| 4af41ffce6 | |||
| 0650964559 | |||
| 2dac616bef | |||
| 5a9fdde156 | |||
| 9bb6e997aa | |||
| cd03aa19a1 | |||
| 10065c8c28 | |||
| 1b426a3160 | |||
| c91225b52e | |||
| 49a611df59 | |||
| b62014eb12 | |||
| 037e8c18f8 | |||
| 2ba6df2506 | |||
| 9b7bf4a101 | |||
| 4bd60cd3cd | |||
| 3fe33cbe97 | |||
| a61badb564 | |||
| 2e21deeae8 | |||
| b3878fb211 | |||
| 33a26ba373 | |||
| 58af294ffd | |||
| 132f10365a | |||
| bafbfe19b4 | |||
| 98bc70344f | |||
| dae95af1df | |||
| 0fa8e01d1f | |||
| f142f1cd70 | |||
| eb5cd542d9 | |||
| 1257d31a56 | |||
| 2e9b980fc2 | |||
| 2b7f91d151 | |||
| 7665045fc6 | |||
| af1583cdfc | |||
| a46007d84d | |||
| 13b71b4e81 | |||
| b084294dc0 | |||
| 6cf95918c5 | |||
| 86d52ab969 | |||
| 52fb0b8171 | |||
| 0072449b01 | |||
| f03efab907 | |||
| cddc3b9e8f | |||
| d977a5bd62 | |||
| 99c2fcc797 | |||
| 5b98ea04ad | |||
| b9344af9bb | |||
| 1e0f1a8abc | |||
| 8ba36b76a0 | |||
| 3f382d6e69 | |||
| 10edb90ac6 | |||
| 45099e7fcd | |||
| 77f069cbe5 | |||
| 1070dda3ee | |||
| decd7d4c1c | |||
| fcd5897650 | |||
| dc5dfe7f3b | |||
| f9c57ff285 | |||
| f1785c245a | |||
| 6892b62761 | |||
| 3d3a5de409 | |||
| bef93ecf65 | |||
| a18ddf12eb | |||
| 46ae67b607 | |||
| 4d3aeaba6d | |||
| ba67e468ab | |||
| e946e9de0b | |||
| 7d2563880a | |||
| 43edc51cb6 | |||
| 9476a8a7f6 | |||
| 053441fbb3 | |||
| 1179273217 | |||
| e35a1eca99 | |||
| 3d11e8ef36 | |||
| c51b41e96a | |||
| 73f720220b | |||
| a1202eaf2a | |||
| a941e8f78f | |||
| 9aca13cf2d | |||
| 7722d14b89 | |||
| 043eab5620 | |||
| 51d3f0dea2 | |||
| 8be8bbbfdb | |||
| 1f778c8c23 | |||
| 981494a354 | |||
| 254f55ac15 | |||
| 96b58024ab | |||
| a9229e11a0 | |||
| 020f503364 | |||
| c274dba36e | |||
| 35c87a1519 | |||
| ac087d085e | |||
| 46d65095af | |||
| 81bd8aa0e2 | |||
| 667f3bb32f | |||
| c908189e73 | |||
| c65cf18c75 | |||
| 55a31d7657 | |||
| ac17c35cfe | |||
| bcb13a7229 | |||
| 0ce28803ec | |||
| db8cd9f411 | |||
| 51312afd3d | |||
| efc23644c7 | |||
| e531f844f6 | |||
| 46f74753cd | |||
| d5cbb89d84 | |||
| 4ce701150a | |||
| 96fded0399 | |||
| 12597856da | |||
| 593c3a0c8e | |||
| 187d3a079c | |||
| 9755520b87 | |||
| 7099bd18e3 | |||
| cb670c2c3d | |||
| f5b84e74f4 | |||
| 2b8e887e44 | |||
| 64f74dad27 | |||
| 7e959c5a3e | |||
| 28795d3065 | |||
| 8aed5a1a89 | |||
| 4d65c52e6d | |||
| a5c973be89 | |||
| 39dcc88330 | |||
| fc6afd5ab8 | |||
| 177a1a3c8b | |||
| 1979a6d8e8 | |||
| 944c23f369 | |||
| 2230933d4b | |||
| 3ea474dd58 | |||
| 8879d481e5 | |||
| 5e35feb3ab | |||
| 5c12a7cfc3 | |||
| f309be9038 | |||
| 959ebd22d8 | |||
| 5b6436a90c | |||
| ee7601ae9d | |||
| 54cf8d6a5e | |||
| aac90dd11b | |||
| 85b9f8962e | |||
| 8f970bcb99 | |||
| a668bc9eda | |||
| fd50941cff | |||
| 831f2396d9 | |||
| 5fc4c2b25c | |||
| b03e7821d4 | |||
| 35241a5fb8 | |||
| 5da6bf9e03 | |||
| 948d42b3e5 | |||
| 422de59898 | |||
| 7a990b99f7 | |||
| 0a84b00406 | |||
| e76e1e500c | |||
| cd70e23dc3 | |||
| 1dfef69a3c | |||
| c35df583a5 | |||
| db3df61c34 | |||
| 32f0a2cbbc | |||
| 569099eb70 | |||
| df7f426405 | |||
| bddd20c425 | |||
| e89e4407c5 | |||
| d849d6f1d7 | |||
| 0b958f7c9a | |||
| 2fc10e8299 | |||
| bf8cae5e7c | |||
| 93015c1c17 | |||
| 97329e46ae | |||
| d76f756f42 | |||
| 71a418d166 | |||
| fb58e8f1f7 | |||
| 5dea009113 | |||
| de024fd4a7 | |||
| 7c90c0669a | |||
| fc4a0fb944 | |||
| 5c01365125 | |||
| d7770ad55c | |||
| 1bd3255f14 | |||
| 76d50df466 | |||
| 8c36739ebd | |||
| 560ed80123 | |||
| 2e788ae54d | |||
| a0a5c9b9ca | |||
| 12220ec82d | |||
| 3715fe85aa | |||
| ba6e5f125d | |||
| 1459d3519d | |||
| c9cfe2c727 | |||
| 27a8837422 | |||
| bc979ea6aa | |||
| 79472cdf83 | |||
| adf6f28ebf | |||
| a7dfd36c00 | |||
| 53327edb50 | |||
| 6c7f3751e7 | |||
| c179a3ccb7 | |||
| 13efc421c4 | |||
| 10db1edc7f | |||
| 039b85f355 | |||
| 0b41b42f7b | |||
| a46ff01cab | |||
| e7b6e62b82 | |||
| 3662a8e962 | |||
| 49b6ef7f48 | |||
| 1f9efd9311 | |||
| 7f8dbf24e7 | |||
| 5e4b88201e | |||
| 1252188b4b | |||
| a0c10be1ff | |||
| 15d3a166f7 | |||
| a58db66a98 | |||
| f51c2aeced | |||
| 3edb3243f6 | |||
| c693bc1247 | |||
| 5d3ab260e1 | |||
| ea64c4c0ae | |||
| 84bce8ae02 | |||
| 3c5974930a | |||
| be854df32d | |||
| e5e56614c9 | |||
| 1eb82fcc85 | |||
| 987f53e69a | |||
| 9a04a5eaae | |||
| 50b8ae9e09 | |||
| adbf68f771 | |||
| f62177a827 | |||
| bb40d161e8 | |||
| a30fc9bcd2 | |||
| 84b1f363e4 | |||
| 19a7d1d5d7 | |||
| fb8f46cba9 | |||
| 70386c6b00 | |||
| edeede5e82 | |||
| a5348b8679 | |||
| 6df313b974 | |||
| 9442bc9aec | |||
| 63c9a85c6a | |||
| adf9ec5360 | |||
| 883d1232d3 | |||
| b58fddb83e | |||
| ce1491df9c | |||
| ea01a53711 | |||
| 85cdb2ed9a | |||
| 368947c88c | |||
| 763049f068 | |||
| 3f1f7ad89c | |||
| c6c644a3a6 | |||
| c876a83a31 | |||
| a04a5b4284 | |||
| 373894a81f | |||
| 34ce746869 | |||
| e96b0da9d7 | |||
| 6d7910ed74 | |||
| e54ddf30b8 | |||
| 3093bb0b66 | |||
| a8cfa2e2fe | |||
| c8eed43538 | |||
| 29a2f576f5 | |||
| 31ec0096e4 | |||
| 8728c7dde3 | |||
| e9a37d99c3 | |||
| 67742699cc | |||
| de975d5af9 | |||
| c3143f3833 | |||
| 1c2f9e6190 | |||
| 654338f9c7 | |||
| dfd7a8c8d7 | |||
| bb8a5bd476 | |||
| e4359e9acb | |||
| 13b8a67ae2 | |||
| 89d9fdca82 | |||
| a478b64ff3 | |||
| b3c2daf9e5 | |||
| 792a9b715c | |||
| 631d6d9ef4 | |||
| 6249211745 | |||
| 2213f8f8a4 | |||
| 4e85568370 | |||
| 88a4f2baf1 |
@@ -1,18 +0,0 @@
|
|||||||
**/.git
|
|
||||||
.DS_Store
|
|
||||||
*.dylib
|
|
||||||
*.DSYM
|
|
||||||
*.d
|
|
||||||
*.pyc
|
|
||||||
*.pyo
|
|
||||||
.*.swp
|
|
||||||
.*.swo
|
|
||||||
.*.un~
|
|
||||||
*.tmp
|
|
||||||
*.o
|
|
||||||
*.o-*
|
|
||||||
*.os
|
|
||||||
*.os-*
|
|
||||||
|
|
||||||
venv/
|
|
||||||
.venv/
|
|
||||||
+2
-11
@@ -10,14 +10,5 @@
|
|||||||
*.otf filter=lfs diff=lfs merge=lfs -text
|
*.otf filter=lfs diff=lfs merge=lfs -text
|
||||||
*.wav filter=lfs diff=lfs merge=lfs -text
|
*.wav filter=lfs diff=lfs merge=lfs -text
|
||||||
|
|
||||||
selfdrive/car/tests/test_models_segs.txt filter=lfs diff=lfs merge=lfs -text
|
openpilot/selfdrive/car/tests/test_models_segs.txt filter=lfs diff=lfs merge=lfs -text
|
||||||
system/hardware/tici/updater_weston filter=lfs diff=lfs merge=lfs -text
|
openpilot/common/hardware/tici/updater filter=lfs diff=lfs merge=lfs -text
|
||||||
system/hardware/tici/updater_magic filter=lfs diff=lfs merge=lfs -text
|
|
||||||
third_party/**/*.a filter=lfs diff=lfs merge=lfs -text
|
|
||||||
third_party/**/*.so filter=lfs diff=lfs merge=lfs -text
|
|
||||||
third_party/**/*.so.* filter=lfs diff=lfs merge=lfs -text
|
|
||||||
third_party/**/*.dylib filter=lfs diff=lfs merge=lfs -text
|
|
||||||
third_party/acados/*/t_renderer filter=lfs diff=lfs merge=lfs -text
|
|
||||||
third_party/qt5/larch64/bin/lrelease filter=lfs diff=lfs merge=lfs -text
|
|
||||||
third_party/qt5/larch64/bin/lupdate filter=lfs diff=lfs merge=lfs -text
|
|
||||||
third_party/catch2/include/catch2/catch.hpp filter=lfs diff=lfs merge=lfs -text
|
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
---
|
|
||||||
name: Enhancement
|
|
||||||
about: For openpilot enhancement suggestions
|
|
||||||
title: ''
|
|
||||||
labels: 'enhancement'
|
|
||||||
assignees: ''
|
|
||||||
---
|
|
||||||
|
|
||||||
@@ -8,24 +8,24 @@ chore:
|
|||||||
|
|
||||||
car:
|
car:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-all-files: '{selfdrive/car/**,opendbc_repo}'
|
- any-glob-to-all-files: '{openpilot/selfdrive/car/**,opendbc_repo}'
|
||||||
|
|
||||||
simulation:
|
simulation:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-all-files: 'tools/sim/**'
|
- any-glob-to-all-files: 'openpilot/tools/sim/**'
|
||||||
|
|
||||||
ui:
|
ui:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-all-files: '{selfdrive/assets/**,selfdrive/ui/**,system/ui/**}'
|
- any-glob-to-all-files: '{openpilot/selfdrive/assets/**,openpilot/selfdrive/ui/**,openpilot/system/ui/**}'
|
||||||
|
|
||||||
tools:
|
tools:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-all-files: 'tools/**'
|
- any-glob-to-all-files: 'openpilot/tools/**'
|
||||||
|
|
||||||
multilanguage:
|
multilanguage:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-all-files: 'selfdrive/ui/translations/**'
|
- any-glob-to-all-files: 'openpilot/selfdrive/ui/translations/**'
|
||||||
|
|
||||||
autonomy:
|
autonomy:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-all-files: "{selfdrive/modeld/models/**,selfdrive/test/process_replay/model_replay_ref_commit,sunnypilot/modeld*/models/**}"
|
- any-glob-to-all-files: "{openpilot/selfdrive/modeld/models/**,openpilot/selfdrive/test/process_replay/model_replay_ref_commit,openpilot/sunnypilot/modeld*/models/**}"
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ Explain how you tested this bug fix.
|
|||||||
|
|
||||||
**Checklist**
|
**Checklist**
|
||||||
|
|
||||||
- [ ] added entry to CAR in selfdrive/car/*/values.py and ran `selfdrive/car/docs.py` to generate new docs
|
- [ ] added entry to CAR in openpilot/selfdrive/car/*/values.py and ran `openpilot/selfdrive/car/docs.py` to generate new docs
|
||||||
- [ ] test route added to [routes.py](https://github.com/commaai/openpilot/blob/master/selfdrive/car/tests/routes.py)
|
- [ ] test route added to [routes.py](https://github.com/commaai/openpilot/blob/master/openpilot/selfdrive/car/tests/routes.py)
|
||||||
- [ ] route with openpilot:
|
- [ ] route with openpilot:
|
||||||
- [ ] route with stock system:
|
- [ ] route with stock system:
|
||||||
- [ ] car harness used (if comma doesn't sell it, put N/A):
|
- [ ] car harness used (if comma doesn't sell it, put N/A):
|
||||||
|
|||||||
@@ -1,58 +0,0 @@
|
|||||||
name: 'automatically cache based on current runner'
|
|
||||||
|
|
||||||
inputs:
|
|
||||||
path:
|
|
||||||
description: 'path to cache'
|
|
||||||
required: true
|
|
||||||
key:
|
|
||||||
description: 'key'
|
|
||||||
required: true
|
|
||||||
restore-keys:
|
|
||||||
description: 'restore-keys'
|
|
||||||
required: true
|
|
||||||
save:
|
|
||||||
description: 'whether to save the cache'
|
|
||||||
default: 'true'
|
|
||||||
required: false
|
|
||||||
outputs:
|
|
||||||
cache-hit:
|
|
||||||
description: 'cache hit occurred'
|
|
||||||
value: ${{ (contains(runner.name, 'nsc') && steps.ns-cache.outputs.cache-hit) ||
|
|
||||||
(!contains(runner.name, 'nsc') && inputs.save != 'false' && steps.gha-cache.outputs.cache-hit) ||
|
|
||||||
(!contains(runner.name, 'nsc') && inputs.save == 'false' && steps.gha-cache-ro.outputs.cache-hit) }}
|
|
||||||
|
|
||||||
runs:
|
|
||||||
using: "composite"
|
|
||||||
steps:
|
|
||||||
- name: setup namespace cache
|
|
||||||
id: ns-cache
|
|
||||||
if: ${{ contains(runner.name, 'nsc') }}
|
|
||||||
uses: namespacelabs/nscloud-cache-action@v1
|
|
||||||
with:
|
|
||||||
path: ${{ inputs.path }}
|
|
||||||
|
|
||||||
- name: setup github cache
|
|
||||||
id: gha-cache
|
|
||||||
if: ${{ !contains(runner.name, 'nsc') && inputs.save != 'false' }}
|
|
||||||
uses: 'actions/cache@v4'
|
|
||||||
with:
|
|
||||||
path: ${{ inputs.path }}
|
|
||||||
key: ${{ inputs.key }}
|
|
||||||
restore-keys: ${{ inputs.restore-keys }}
|
|
||||||
|
|
||||||
- name: setup github cache
|
|
||||||
id: gha-cache-ro
|
|
||||||
if: ${{ !contains(runner.name, 'nsc') && inputs.save == 'false' }}
|
|
||||||
uses: 'actions/cache/restore@v4'
|
|
||||||
with:
|
|
||||||
path: ${{ inputs.path }}
|
|
||||||
key: ${{ inputs.key }}
|
|
||||||
restore-keys: ${{ inputs.restore-keys }}
|
|
||||||
|
|
||||||
# make the directory manually in case we didn't get a hit, so it doesn't fail on future steps
|
|
||||||
- id: scons-cache-setup
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
mkdir -p ${{ inputs.path }}
|
|
||||||
sudo chmod -R 777 ${{ inputs.path }}
|
|
||||||
sudo chown -R $USER ${{ inputs.path }}
|
|
||||||
@@ -12,19 +12,19 @@ jobs:
|
|||||||
issues: write
|
issues: write
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v7
|
||||||
with:
|
with:
|
||||||
submodules: false
|
submodules: false
|
||||||
|
|
||||||
# Label PRs
|
# Label PRs
|
||||||
- uses: actions/labeler@v5.0.0
|
- uses: actions/labeler@v6
|
||||||
with:
|
with:
|
||||||
dot: true
|
dot: true
|
||||||
configuration-path: .github/labeler.yaml
|
configuration-path: .github/labeler.yaml
|
||||||
|
|
||||||
# Check PR target branch
|
# Check PR target branch
|
||||||
- name: check branch
|
- name: check branch
|
||||||
uses: Vankka/pr-target-branch-action@def32ec9d93514138d6ac0132ee62e120a72aed5
|
uses: Vankka/pr-target-branch-action@5da68a42bcb7b43d39104295a876a6f3f8d7908b
|
||||||
if: github.repository == 'sunnypilot/sunnypilot'
|
if: github.repository == 'sunnypilot/sunnypilot'
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -55,13 +55,13 @@ jobs:
|
|||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
issue_number: prNumber
|
issue_number: prNumber
|
||||||
});
|
});
|
||||||
|
|
||||||
const hasDevC3Label = labels.some(label => label.name === process.env.PR_LABEL);
|
const hasDevC3Label = labels.some(label => label.name === process.env.PR_LABEL);
|
||||||
const hasTrustLabel = labels.some(label => label.name === process.env.TRUST_FORK_PR_LABEL);
|
const hasTrustLabel = labels.some(label => label.name === process.env.TRUST_FORK_PR_LABEL);
|
||||||
|
|
||||||
console.log(`PR #${prNumber} has ${process.env.PR_LABEL} label: ${hasDevC3Label}`);
|
console.log(`PR #${prNumber} has ${process.env.PR_LABEL} label: ${hasDevC3Label}`);
|
||||||
console.log(`PR #${prNumber} has ${process.env.TRUST_FORK_PR_LABEL} label: ${hasTrustLabel}`);
|
console.log(`PR #${prNumber} has ${process.env.TRUST_FORK_PR_LABEL} label: ${hasTrustLabel}`);
|
||||||
|
|
||||||
core.setOutput('has-dev', hasDevC3Label ? 'true' : 'false');
|
core.setOutput('has-dev', hasDevC3Label ? 'true' : 'false');
|
||||||
core.setOutput('has-trust', hasTrustLabel ? 'true' : 'false');
|
core.setOutput('has-trust', hasTrustLabel ? 'true' : 'false');
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ jobs:
|
|||||||
});
|
});
|
||||||
|
|
||||||
console.log(`Removed '${process.env.TRUST_FORK_PR_LABEL}' label from PR #${prNumber} as it received new commits`);
|
console.log(`Removed '${process.env.TRUST_FORK_PR_LABEL}' label from PR #${prNumber} as it received new commits`);
|
||||||
|
|
||||||
// Add a comment to the PR
|
// Add a comment to the PR
|
||||||
await github.rest.issues.createComment({
|
await github.rest.issues.createComment({
|
||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
|
|||||||
@@ -5,9 +5,7 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
BASE_IMAGE: sunnypilot-base
|
PYTHONPATH: ${{ github.workspace }}
|
||||||
DOCKER_REGISTRY: ghcr.io/sunnypilot
|
|
||||||
RUN: docker run --shm-size 2G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v $GITHUB_WORKSPACE/.ci_cache/scons_cache:/tmp/scons_cache -v $GITHUB_WORKSPACE/.ci_cache/comma_download_cache:/tmp/comma_download_cache -v $GITHUB_WORKSPACE/.ci_cache/openpilot_cache:/tmp/openpilot_cache $DOCKER_REGISTRY/$BASE_IMAGE:latest /bin/bash -c
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
badges:
|
badges:
|
||||||
@@ -17,13 +15,13 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- uses: ./.github/workflows/setup-with-retry
|
- run: ./tools/op.sh setup
|
||||||
- name: Push badges
|
- name: Push badges
|
||||||
run: |
|
run: |
|
||||||
${{ env.RUN }} "python3 selfdrive/ui/translations/create_badges.py"
|
python3 selfdrive/ui/translations/create_badges.py
|
||||||
|
|
||||||
rm .gitattributes
|
rm .gitattributes
|
||||||
|
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ jobs:
|
|||||||
echo "tinygrad_ref=$ref" >> $GITHUB_OUTPUT
|
echo "tinygrad_ref=$ref" >> $GITHUB_OUTPUT
|
||||||
echo "tinygrad_ref is $ref"
|
echo "tinygrad_ref is $ref"
|
||||||
|
|
||||||
- name: Checkout docs repo (sunnypilot-docs, gh-pages)
|
- name: Checkout docs repo (sunnypilot-models, gh-pages)
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
repository: sunnypilot/sunnypilot-docs
|
repository: sunnypilot/sunnypilot-models
|
||||||
ref: gh-pages
|
ref: gh-pages
|
||||||
path: docs
|
path: docs
|
||||||
ssh-key: ${{ secrets.CI_SUNNYPILOT_DOCS_PRIVATE_KEY }}
|
ssh-key: ${{ secrets.CI_SUNNYPILOT_DOCS_PRIVATE_KEY }}
|
||||||
@@ -120,6 +120,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
upstream_branch: ${{ matrix.model.ref }}
|
upstream_branch: ${{ matrix.model.ref }}
|
||||||
custom_name: ${{ matrix.model.display_name }}
|
custom_name: ${{ matrix.model.display_name }}
|
||||||
|
is_20hz: ${{ matrix.model.is_20hz }}
|
||||||
recompiled_dir: ${{ needs.setup.outputs.recompiled_dir }}
|
recompiled_dir: ${{ needs.setup.outputs.recompiled_dir }}
|
||||||
json_version: ${{ needs.setup.outputs.json_version }}
|
json_version: ${{ needs.setup.outputs.json_version }}
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
@@ -140,7 +141,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
echo '${{ needs.setup.outputs.model_matrix }}' > matrix.json
|
echo '${{ needs.setup.outputs.model_matrix }}' > matrix.json
|
||||||
built=(); while IFS= read -r line; do built+=("$line"); done < <(
|
built=(); while IFS= read -r line; do built+=("$line"); done < <(
|
||||||
ls output | sed -E 's/^model-//' | sed -E 's/-[0-9]+$//' | sed -E 's/ \([^)]*\)//' | awk '{gsub(/^ +| +$/, ""); print}'
|
find output -maxdepth 1 -name 'model-*' -printf "%f\n" | sed -E 's/^model-//' | sed -E 's/-[0-9]+$//' | sed -E 's/ \([^)]*\)//' | awk '{gsub(/^ +| +$/, ""); print}'
|
||||||
)
|
)
|
||||||
jq -c --argjson built "$(printf '%s\n' "${built[@]}" | jq -R . | jq -s .)" \
|
jq -c --argjson built "$(printf '%s\n' "${built[@]}" | jq -R . | jq -s .)" \
|
||||||
'map(select(.display_name as $n | ($built | index($n | gsub("^ +| +$"; "")) | not)))' matrix.json > retry_matrix.json
|
'map(select(.display_name as $n | ($built | index($n | gsub("^ +| +$"; "")) | not)))' matrix.json > retry_matrix.json
|
||||||
@@ -157,6 +158,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
upstream_branch: ${{ matrix.model.ref }}
|
upstream_branch: ${{ matrix.model.ref }}
|
||||||
custom_name: ${{ matrix.model.display_name }}
|
custom_name: ${{ matrix.model.display_name }}
|
||||||
|
is_20hz: ${{ matrix.model.is_20hz }}
|
||||||
recompiled_dir: ${{ needs.setup.outputs.recompiled_dir }}
|
recompiled_dir: ${{ needs.setup.outputs.recompiled_dir }}
|
||||||
json_version: ${{ needs.setup.outputs.json_version }}
|
json_version: ${{ needs.setup.outputs.json_version }}
|
||||||
artifact_suffix: -retry
|
artifact_suffix: -retry
|
||||||
@@ -168,6 +170,7 @@ jobs:
|
|||||||
if: ${{ !cancelled() && (needs.get_and_build.result != 'failure' || needs.retry_get_and_build.result == 'success' || (needs.retry_failed_models.outputs.retry_matrix != '[]' && needs.retry_failed_models.outputs.retry_matrix != '')) }}
|
if: ${{ !cancelled() && (needs.get_and_build.result != 'failure' || needs.retry_get_and_build.result == 'success' || (needs.retry_failed_models.outputs.retry_matrix != '[]' && needs.retry_failed_models.outputs.retry_matrix != '')) }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
max-parallel: 1
|
max-parallel: 1
|
||||||
matrix:
|
matrix:
|
||||||
model: ${{ fromJson(needs.setup.outputs.model_matrix) }}
|
model: ${{ fromJson(needs.setup.outputs.model_matrix) }}
|
||||||
@@ -201,7 +204,7 @@ jobs:
|
|||||||
- name: Checkout docs repo
|
- name: Checkout docs repo
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
repository: sunnypilot/sunnypilot-docs
|
repository: sunnypilot/sunnypilot-models
|
||||||
ref: gh-pages
|
ref: gh-pages
|
||||||
path: docs
|
path: docs
|
||||||
ssh-key: ${{ secrets.CI_SUNNYPILOT_DOCS_PRIVATE_KEY }}
|
ssh-key: ${{ secrets.CI_SUNNYPILOT_DOCS_PRIVATE_KEY }}
|
||||||
|
|||||||
@@ -24,6 +24,11 @@ on:
|
|||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
default: ''
|
default: ''
|
||||||
|
is_20hz:
|
||||||
|
description: 'Is this a 20Hz model'
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
bypass_push:
|
bypass_push:
|
||||||
description: 'Bypass pushing to GitLab for build-all'
|
description: 'Bypass pushing to GitLab for build-all'
|
||||||
required: false
|
required: false
|
||||||
@@ -39,6 +44,11 @@ on:
|
|||||||
description: 'Custom name for the model (no date, only name)'
|
description: 'Custom name for the model (no date, only name)'
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
|
is_20hz:
|
||||||
|
description: 'Is this a 20Hz model'
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
recompiled_dir:
|
recompiled_dir:
|
||||||
description: 'Existing recompiled directory number (e.g. 3 for recompiled3)'
|
description: 'Existing recompiled directory number (e.g. 3 for recompiled3)'
|
||||||
required: true
|
required: true
|
||||||
@@ -82,7 +92,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
upstream_branch: ${{ inputs.upstream_branch }}
|
upstream_branch: ${{ inputs.upstream_branch }}
|
||||||
custom_name: ${{ inputs.custom_name || inputs.upstream_branch }}
|
custom_name: ${{ inputs.custom_name || inputs.upstream_branch }}
|
||||||
is_20hz: true
|
is_20hz: ${{ inputs.is_20hz }}
|
||||||
artifact_suffix: ${{ inputs.artifact_suffix }}
|
artifact_suffix: ${{ inputs.artifact_suffix }}
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
@@ -119,7 +129,7 @@ jobs:
|
|||||||
- name: Checkout docs repo
|
- name: Checkout docs repo
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
repository: sunnypilot/sunnypilot-docs
|
repository: sunnypilot/sunnypilot-models
|
||||||
ref: gh-pages
|
ref: gh-pages
|
||||||
path: docs
|
path: docs
|
||||||
ssh-key: ${{ secrets.CI_SUNNYPILOT_DOCS_PRIVATE_KEY }}
|
ssh-key: ${{ secrets.CI_SUNNYPILOT_DOCS_PRIVATE_KEY }}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ on:
|
|||||||
- master
|
- master
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- 'cereal/**'
|
- 'openpilot/cereal/**'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
inputs:
|
inputs:
|
||||||
@@ -20,57 +20,78 @@ concurrency:
|
|||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
env:
|
env:
|
||||||
PYTHONWARNINGS: error
|
CI: 1
|
||||||
BASE_IMAGE: openpilot-base
|
|
||||||
BUILD: selfdrive/test/docker_build.sh base
|
|
||||||
RUN: docker run --shm-size 2G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e CI=1 -e PYTHONWARNINGS=error -e FILEREADER_CACHE=1 -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v $GITHUB_WORKSPACE/.ci_cache/scons_cache:/tmp/scons_cache -v $GITHUB_WORKSPACE/.ci_cache/comma_download_cache:/tmp/comma_download_cache -v $GITHUB_WORKSPACE/.ci_cache/openpilot_cache:/tmp/openpilot_cache $BASE_IMAGE /bin/bash -c
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
generate_cereal_artifact:
|
|
||||||
name: Generate cereal validation artifacts
|
|
||||||
runs-on: ubuntu-24.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
- uses: ./.github/workflows/setup-with-retry
|
|
||||||
- name: Build openpilot
|
|
||||||
run: ${{ env.RUN }} "scons -j$(nproc) cereal"
|
|
||||||
- name: Generate the log file
|
|
||||||
run: |
|
|
||||||
${{ env.RUN }} "cereal/messaging/tests/validate_sp_cereal_upstream.py -g -f schema_instances.bin" && \
|
|
||||||
ls -la
|
|
||||||
ls -la cereal/messaging/tests
|
|
||||||
- name: 'Prepare artifact'
|
|
||||||
run: |
|
|
||||||
mkdir -p "cereal/messaging/tests/cereal_validations"
|
|
||||||
cp cereal/messaging/tests/validate_sp_cereal_upstream.py "cereal/messaging/tests/cereal_validations/validate_sp_cereal_upstream.py"
|
|
||||||
cp schema_instances.bin "cereal/messaging/tests/cereal_validations/schema_instances.bin"
|
|
||||||
- name: 'Upload Artifact'
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: cereal_validations
|
|
||||||
path: cereal/messaging/tests/cereal_validations
|
|
||||||
|
|
||||||
validate_cereal_with_upstream:
|
validate_cereal_with_upstream:
|
||||||
name: Validate cereal with Upstream
|
name: Validate cereal with Upstream
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
needs: generate_cereal_artifact
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- name: Checkout sunnypilot cereal
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
sparse-checkout: |
|
||||||
|
openpilot/cereal
|
||||||
|
uv.lock
|
||||||
|
submodules: false
|
||||||
|
|
||||||
|
- name: Init sunnypilot opendbc submodule
|
||||||
|
run: git submodule update --init --depth 1 opendbc_repo
|
||||||
|
|
||||||
|
- name: Locate sunnypilot capnp import paths
|
||||||
|
id: locate-sp-capnp
|
||||||
|
run: |
|
||||||
|
SP_IMPORT_ARGS=""
|
||||||
|
SP_CAR_CAPNP=$(find opendbc_repo -maxdepth 4 -name car.capnp -path '*/opendbc/car/car.capnp' -printf '%h\n' -quit)
|
||||||
|
if [ -n "$SP_CAR_CAPNP" ]; then
|
||||||
|
SP_IMPORT_ARGS="-I $SP_CAR_CAPNP"
|
||||||
|
echo "Found sunnypilot car.capnp at: $SP_CAR_CAPNP"
|
||||||
|
fi
|
||||||
|
echo "import_args=$SP_IMPORT_ARGS" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Checkout upstream openpilot
|
||||||
|
uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
repository: 'commaai/openpilot'
|
repository: 'commaai/openpilot'
|
||||||
submodules: true
|
path: upstream_openpilot
|
||||||
ref: "refs/heads/master"
|
ref: "refs/heads/master"
|
||||||
- uses: ./.github/workflows/setup-with-retry
|
|
||||||
- name: Build openpilot
|
- name: Init upstream opendbc submodule
|
||||||
run: ${{ env.RUN }} "scons -j$(nproc) cereal"
|
working-directory: upstream_openpilot
|
||||||
- name: Download build artifacts
|
run: git submodule update --init --depth 1 opendbc_repo
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
- name: Locate upstream capnp paths
|
||||||
name: cereal_validations
|
id: locate-capnp
|
||||||
path: cereal/messaging/tests/cereal_validations
|
|
||||||
- name: 'Run the validation'
|
|
||||||
run: |
|
run: |
|
||||||
chmod +x cereal/messaging/tests/cereal_validations/validate_sp_cereal_upstream.py
|
CEREAL_DIR=$(find upstream_openpilot -maxdepth 4 -name log.capnp -path '*/cereal/log.capnp' -printf '%h\n' -quit)
|
||||||
${{ env.RUN }} "cereal/messaging/tests/cereal_validations/validate_sp_cereal_upstream.py -r -f cereal/messaging/tests/cereal_validations/schema_instances.bin"
|
if [ -z "$CEREAL_DIR" ]; then
|
||||||
|
echo "::error::Could not locate cereal/log.capnp in upstream openpilot"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "cereal_dir=$CEREAL_DIR" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "Found upstream cereal at: $CEREAL_DIR"
|
||||||
|
|
||||||
|
IMPORT_ARGS=""
|
||||||
|
CAR_CAPNP=$(find upstream_openpilot -maxdepth 5 -name car.capnp -path '*/opendbc/car/car.capnp' -printf '%h\n' -quit)
|
||||||
|
if [ -n "$CAR_CAPNP" ]; then
|
||||||
|
IMPORT_ARGS="-I $CAR_CAPNP"
|
||||||
|
echo "Found car.capnp at: $CAR_CAPNP"
|
||||||
|
fi
|
||||||
|
echo "import_args=$IMPORT_ARGS" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Install pycapnp
|
||||||
|
run: |
|
||||||
|
PYCAPNP_VER=$(python3 -c "import re; m=re.search(r'name = \"pycapnp\"\nversion = \"([^\"]+)\"', open('uv.lock').read()); print(m.group(1))")
|
||||||
|
pip install "pycapnp==${PYCAPNP_VER}"
|
||||||
|
|
||||||
|
- name: Generate sunnypilot schema
|
||||||
|
run: |
|
||||||
|
python3 openpilot/cereal/messaging/tests/validate_sp_cereal_upstream.py \
|
||||||
|
-g -f /tmp/sp_schema.json --cereal-dir openpilot/cereal \
|
||||||
|
${{ steps.locate-sp-capnp.outputs.import_args }}
|
||||||
|
|
||||||
|
- name: Validate against upstream
|
||||||
|
run: |
|
||||||
|
python3 openpilot/cereal/messaging/tests/validate_sp_cereal_upstream.py \
|
||||||
|
-r -f /tmp/sp_schema.json --cereal-dir ${{ steps.locate-capnp.outputs.cereal_dir }} \
|
||||||
|
${{ steps.locate-capnp.outputs.import_args }}
|
||||||
|
|||||||
@@ -1,101 +0,0 @@
|
|||||||
name: weekly CI test report
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: '37 9 * * 1' # 9:37AM UTC -> 2:37AM PST every monday
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
ci_runs:
|
|
||||||
description: 'The amount of runs to trigger in CI test report'
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
env:
|
|
||||||
CI_RUNS: ${{ github.event.inputs.ci_runs || '50' }}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
setup:
|
|
||||||
if: github.repository == 'sunnypilot/sunnypilot'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
ci_runs: ${{ steps.ci_runs_setup.outputs.matrix }}
|
|
||||||
steps:
|
|
||||||
- id: ci_runs_setup
|
|
||||||
name: CI_RUNS=${{ env.CI_RUNS }}
|
|
||||||
run: |
|
|
||||||
matrix=$(python3 -c "import json; print(json.dumps({ 'run_number' : list(range(${{ env.CI_RUNS }})) }))")
|
|
||||||
echo "matrix=$matrix" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
ci_matrix_run:
|
|
||||||
needs: [ setup ]
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix: ${{fromJSON(needs.setup.outputs.ci_runs)}}
|
|
||||||
uses: sunnypilot/sunnypilot/.github/workflows/ci_weekly_run.yaml@master
|
|
||||||
with:
|
|
||||||
run_number: ${{ matrix.run_number }}
|
|
||||||
|
|
||||||
report:
|
|
||||||
needs: [ci_matrix_run]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: always() && github.repository == 'commaai/openpilot'
|
|
||||||
steps:
|
|
||||||
- name: Get job results
|
|
||||||
uses: actions/github-script@v7
|
|
||||||
id: get-job-results
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const jobs = await github
|
|
||||||
.paginate("GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt}/jobs", {
|
|
||||||
owner: "commaai",
|
|
||||||
repo: "${{ github.event.repository.name }}",
|
|
||||||
run_id: "${{ github.run_id }}",
|
|
||||||
attempt: "${{ github.run_attempt }}",
|
|
||||||
})
|
|
||||||
var report = {}
|
|
||||||
jobs.slice(1, jobs.length-1).forEach(job => {
|
|
||||||
if (job.conclusion === "skipped") return;
|
|
||||||
const jobName = job.name.split(" / ")[2];
|
|
||||||
const runRegex = /\((.*?)\)/;
|
|
||||||
const run = job.name.match(runRegex)[1];
|
|
||||||
report[jobName] = report[jobName] || { successes: [], failures: [], canceled: [] };
|
|
||||||
switch (job.conclusion) {
|
|
||||||
case "success":
|
|
||||||
report[jobName].successes.push({ "run_number": run, "link": job.html_url}); break;
|
|
||||||
case "failure":
|
|
||||||
report[jobName].failures.push({ "run_number": run, "link": job.html_url }); break;
|
|
||||||
case "canceled":
|
|
||||||
report[jobName].canceled.push({ "run_number": run, "link": job.html_url }); break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return JSON.stringify({"jobs": report});
|
|
||||||
|
|
||||||
- name: Add job results to summary
|
|
||||||
env:
|
|
||||||
JOB_RESULTS: ${{ fromJSON(steps.get-job-results.outputs.result) }}
|
|
||||||
run: |
|
|
||||||
cat <<EOF >> template.html
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th></th>
|
|
||||||
<th>Job</th>
|
|
||||||
<th>✅ Passing</th>
|
|
||||||
<th>❌ Failure Details</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for key in jobs.keys() %}<tr>
|
|
||||||
<td>{% for i in range(5) %}{% if i+1 <= (5 * jobs[key]["successes"]|length // ${{ env.CI_RUNS }}) %}🟩{% else %}🟥{% endif %}{% endfor%}</td>
|
|
||||||
<td>{{ key }}</td>
|
|
||||||
<td>{{ 100 * jobs[key]["successes"]|length // ${{ env.CI_RUNS }} }}%</td>
|
|
||||||
<td>{% if jobs[key]["failures"]|length > 0 %}<details>{% for failure in jobs[key]["failures"] %}<a href="{{ failure['link'] }}">Log for run #{{ failure['run_number'] }}</a><br>{% endfor %}</details>{% else %}{% endif %}</td>
|
|
||||||
</td>
|
|
||||||
</tr>{% endfor %}
|
|
||||||
</table>
|
|
||||||
EOF
|
|
||||||
|
|
||||||
pip install jinja2-cli
|
|
||||||
echo $JOB_RESULTS | jinja2 template.html > report.html
|
|
||||||
echo "# CI Test Report - ${{ env.CI_RUNS }} Runs" >> $GITHUB_STEP_SUMMARY
|
|
||||||
cat report.html >> $GITHUB_STEP_SUMMARY
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
name: weekly CI test run
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
inputs:
|
|
||||||
run_number:
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ci-run-${{ inputs.run_number }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
tests:
|
|
||||||
uses: sunnypilot/sunnypilot/.github/workflows/tests.yaml@master
|
|
||||||
with:
|
|
||||||
run_number: ${{ inputs.run_number }}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
name: 'compile openpilot'
|
|
||||||
|
|
||||||
runs:
|
|
||||||
using: "composite"
|
|
||||||
steps:
|
|
||||||
- shell: bash
|
|
||||||
name: Build openpilot with all flags
|
|
||||||
run: |
|
|
||||||
${{ env.RUN }} "scons -j$(nproc)"
|
|
||||||
${{ env.RUN }} "release/check-dirty.sh"
|
|
||||||
- shell: bash
|
|
||||||
name: Cleanup scons cache and rebuild
|
|
||||||
run: |
|
|
||||||
${{ env.RUN }} "rm -rf /tmp/scons_cache/* && \
|
|
||||||
scons -j$(nproc) --cache-populate"
|
|
||||||
- name: Save scons cache
|
|
||||||
uses: actions/cache/save@v4
|
|
||||||
if: github.ref == 'refs/heads/master'
|
|
||||||
with:
|
|
||||||
path: .ci_cache/scons_cache
|
|
||||||
key: scons-${{ runner.arch }}-${{ env.CACHE_COMMIT_DATE }}-${{ github.sha }}
|
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
name: diff report
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request_target:
|
||||||
|
types: [opened, synchronize, reopened]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
comment:
|
||||||
|
name: comment
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 10
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: write
|
||||||
|
actions: read
|
||||||
|
steps:
|
||||||
|
- name: Wait for process replay
|
||||||
|
id: wait
|
||||||
|
continue-on-error: true
|
||||||
|
uses: lewagon/wait-on-check-action@1d57e2c51a58d812d2765e036a028b6bdb5a6154
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
check-name: process replay
|
||||||
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
allowed-conclusions: success,failure
|
||||||
|
wait-interval: 20
|
||||||
|
- name: Get tests run ID
|
||||||
|
if: steps.wait.outcome == 'success'
|
||||||
|
id: tests-run
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
run_id=$(gh api \
|
||||||
|
"repos/${{ github.repository }}/actions/workflows/tests.yaml/runs?event=pull_request&head_sha=${{ github.event.pull_request.head.sha }}&per_page=1" \
|
||||||
|
--jq '.workflow_runs[0].id // empty')
|
||||||
|
if [ -z "$run_id" ]; then
|
||||||
|
echo "No tests.yaml run found for ${{ github.event.pull_request.head.sha }}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "run-id=$run_id" >> "$GITHUB_OUTPUT"
|
||||||
|
- name: Download diff
|
||||||
|
if: steps.wait.outcome == 'success'
|
||||||
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
|
||||||
|
with:
|
||||||
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
repository: ${{ github.repository }}
|
||||||
|
run-id: ${{ steps.tests-run.outputs.run-id }}
|
||||||
|
name: diff_report_${{ github.event.number }}
|
||||||
|
path: .
|
||||||
|
- name: Comment on PR
|
||||||
|
if: steps.wait.outcome == 'success'
|
||||||
|
uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b
|
||||||
|
with:
|
||||||
|
file-path: diff_report.txt
|
||||||
|
comment-tag: diff_report
|
||||||
|
pr-number: ${{ github.event.number }}
|
||||||
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -22,19 +22,19 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: commaai/timeout@v1
|
- uses: commaai/timeout@v1
|
||||||
|
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v7
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
|
|
||||||
# Build
|
# Build
|
||||||
- name: Build docs
|
- name: Build docs
|
||||||
run: |
|
run: |
|
||||||
# TODO: can we install just the "docs" dependency group without the normal deps?
|
git lfs pull
|
||||||
pip install mkdocs
|
pip install zensical
|
||||||
mkdocs build
|
python scripts/docs.py build
|
||||||
|
|
||||||
# Push to docs.comma.ai
|
# Push to docs.comma.ai
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v7
|
||||||
if: github.ref == 'refs/heads/master' && github.repository == 'sunnypilot/sunnypilot'
|
if: github.ref == 'refs/heads/master' && github.repository == 'sunnypilot/sunnypilot'
|
||||||
with:
|
with:
|
||||||
path: openpilot-docs
|
path: openpilot-docs
|
||||||
@@ -45,7 +45,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
source release/identity.sh
|
source tools/release/identity.sh
|
||||||
|
|
||||||
cd openpilot-docs
|
cd openpilot-docs
|
||||||
git checkout --orphan tmp
|
git checkout --orphan tmp
|
||||||
|
|||||||
@@ -5,7 +5,44 @@ on:
|
|||||||
types: [created, edited]
|
types: [created, edited]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# TODO: gc old branches in a separate job in this workflow
|
cleanup-branches:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
steps:
|
||||||
|
- name: Delete stale Jenkins branches
|
||||||
|
uses: actions/github-script@v9
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const cutoff = Date.now() - 24 * 60 * 60 * 1000;
|
||||||
|
const prefixes = ['tmp-jenkins', '__jenkins'];
|
||||||
|
|
||||||
|
for await (const response of github.paginate.iterator(github.rest.repos.listBranches, {
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
per_page: 100,
|
||||||
|
})) {
|
||||||
|
for (const branch of response.data) {
|
||||||
|
if (!prefixes.some(p => branch.name.startsWith(p))) continue;
|
||||||
|
|
||||||
|
const { data: commit } = await github.rest.repos.getCommit({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
ref: branch.commit.sha,
|
||||||
|
});
|
||||||
|
|
||||||
|
const commitDate = new Date(commit.commit.committer.date).getTime();
|
||||||
|
if (commitDate < cutoff) {
|
||||||
|
console.log(`Deleting branch: ${branch.name} (last commit: ${commit.commit.committer.date})`);
|
||||||
|
await github.rest.git.deleteRef({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
ref: `heads/${branch.name}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
scan-comments:
|
scan-comments:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event.issue.pull_request }}
|
if: ${{ github.event.issue.pull_request }}
|
||||||
@@ -15,7 +52,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Check for trigger phrase
|
- name: Check for trigger phrase
|
||||||
id: check_comment
|
id: check_comment
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v9
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const triggerPhrase = "trigger-jenkins";
|
const triggerPhrase = "trigger-jenkins";
|
||||||
@@ -35,7 +72,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
if: steps.check_comment.outputs.result == 'true'
|
if: steps.check_comment.outputs.result == 'true'
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
with:
|
with:
|
||||||
ref: refs/pull/${{ github.event.issue.number }}/head
|
ref: refs/pull/${{ github.event.issue.number }}/head
|
||||||
|
|
||||||
@@ -49,7 +86,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Delete trigger comment
|
- name: Delete trigger comment
|
||||||
if: steps.check_comment.outputs.result == 'true' && always()
|
if: steps.check_comment.outputs.result == 'true' && always()
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v9
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
await github.rest.issues.deleteComment({
|
await github.rest.issues.deleteComment({
|
||||||
|
|||||||
@@ -1,151 +0,0 @@
|
|||||||
name: "mici raylib ui preview"
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
pull_request_target:
|
|
||||||
types: [assigned, opened, synchronize, reopened, edited]
|
|
||||||
branches:
|
|
||||||
- 'master'
|
|
||||||
paths:
|
|
||||||
- 'selfdrive/assets/**'
|
|
||||||
- 'selfdrive/ui/**'
|
|
||||||
- 'system/ui/**'
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
env:
|
|
||||||
UI_JOB_NAME: "Create mici raylib UI Report"
|
|
||||||
REPORT_NAME: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && 'master' || github.event.number }}
|
|
||||||
SHA: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && github.sha || github.event.pull_request.head.sha }}
|
|
||||||
BRANCH_NAME: "openpilot/pr-${{ github.event.number }}-mici-raylib-ui"
|
|
||||||
MASTER_BRANCH_NAME: "openpilot_master_ui_mici_raylib"
|
|
||||||
# All report files are pushed here
|
|
||||||
REPORT_FILES_BRANCH_NAME: "mici-raylib-ui-reports"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
preview:
|
|
||||||
if: github.repository == 'sunnypilot/sunnypilot'
|
|
||||||
name: preview
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 20
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pull-requests: write
|
|
||||||
actions: read
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
|
|
||||||
- name: Waiting for ui generation to end
|
|
||||||
uses: lewagon/wait-on-check-action@v1.3.4
|
|
||||||
with:
|
|
||||||
ref: ${{ env.SHA }}
|
|
||||||
check-name: ${{ env.UI_JOB_NAME }}
|
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
allowed-conclusions: success
|
|
||||||
wait-interval: 20
|
|
||||||
|
|
||||||
- name: Getting workflow run ID
|
|
||||||
id: get_run_id
|
|
||||||
run: |
|
|
||||||
echo "run_id=$(curl https://api.github.com/repos/${{ github.repository }}/commits/${{ env.SHA }}/check-runs | jq -r '.check_runs[] | select(.name == "${{ env.UI_JOB_NAME }}") | .html_url | capture("(?<number>[0-9]+)") | .number')" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Getting proposed ui # filename: pr_ui/mici_ui_replay.mp4
|
|
||||||
id: download-artifact
|
|
||||||
uses: dawidd6/action-download-artifact@v6
|
|
||||||
with:
|
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
run_id: ${{ steps.get_run_id.outputs.run_id }}
|
|
||||||
search_artifacts: true
|
|
||||||
name: mici-raylib-report-1-${{ env.REPORT_NAME }}
|
|
||||||
path: ${{ github.workspace }}/pr_ui
|
|
||||||
|
|
||||||
- name: Getting master ui # filename: master_ui_raylib/mici_ui_replay.mp4
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
repository: sunnypilot/ci-artifacts
|
|
||||||
ssh-key: ${{ secrets.CI_ARTIFACTS_DEPLOY_KEY }}
|
|
||||||
path: ${{ github.workspace }}/master_ui_raylib
|
|
||||||
ref: ${{ env.MASTER_BRANCH_NAME }}
|
|
||||||
|
|
||||||
- name: Saving new master ui
|
|
||||||
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
|
|
||||||
working-directory: ${{ github.workspace }}/master_ui_raylib
|
|
||||||
run: |
|
|
||||||
git checkout --orphan=new_master_ui_mici_raylib
|
|
||||||
git rm -rf *
|
|
||||||
git branch -D ${{ env.MASTER_BRANCH_NAME }}
|
|
||||||
git branch -m ${{ env.MASTER_BRANCH_NAME }}
|
|
||||||
git config user.name "GitHub Actions Bot"
|
|
||||||
git config user.email "<>"
|
|
||||||
mv ${{ github.workspace }}/pr_ui/* .
|
|
||||||
git add .
|
|
||||||
git commit -m "mici raylib video for commit ${{ env.SHA }}"
|
|
||||||
git push origin ${{ env.MASTER_BRANCH_NAME }} --force
|
|
||||||
|
|
||||||
- name: Setup FFmpeg
|
|
||||||
uses: AnimMouse/setup-ffmpeg@ae28d57dabbb148eff63170b6bf7f2b60062cbae
|
|
||||||
|
|
||||||
- name: Finding diff
|
|
||||||
if: github.event_name == 'pull_request_target'
|
|
||||||
id: find_diff
|
|
||||||
run: |
|
|
||||||
# Find the video file from PR
|
|
||||||
pr_video="${{ github.workspace }}/pr_ui/mici_ui_replay_proposed.mp4"
|
|
||||||
mv "${{ github.workspace }}/pr_ui/mici_ui_replay.mp4" "$pr_video"
|
|
||||||
|
|
||||||
master_video="${{ github.workspace }}/pr_ui/mici_ui_replay_master.mp4"
|
|
||||||
mv "${{ github.workspace }}/master_ui_raylib/mici_ui_replay.mp4" "$master_video"
|
|
||||||
|
|
||||||
# Run report
|
|
||||||
export PYTHONPATH=${{ github.workspace }}
|
|
||||||
baseurl="https://github.com/sunnypilot/ci-artifacts/raw/refs/heads/${{ env.BRANCH_NAME }}"
|
|
||||||
diff_exit_code=0
|
|
||||||
python3 ${{ github.workspace }}/selfdrive/ui/tests/diff/diff.py "${{ github.workspace }}/pr_ui/mici_ui_replay_master.mp4" "${{ github.workspace }}/pr_ui/mici_ui_replay_proposed.mp4" "diff.html" --basedir "$baseurl" --no-open || diff_exit_code=$?
|
|
||||||
|
|
||||||
# Copy diff report files
|
|
||||||
cp ${{ github.workspace }}/selfdrive/ui/tests/diff/report/diff.html ${{ github.workspace }}/pr_ui/
|
|
||||||
cp ${{ github.workspace }}/selfdrive/ui/tests/diff/report/diff.mp4 ${{ github.workspace }}/pr_ui/
|
|
||||||
|
|
||||||
REPORT_URL="https://sunnypilot.github.io/ci-artifacts/diff_pr_${{ github.event.number }}.html"
|
|
||||||
if [ $diff_exit_code -eq 0 ]; then
|
|
||||||
DIFF="✅ Videos are identical! [View Diff Report]($REPORT_URL)"
|
|
||||||
else
|
|
||||||
DIFF="❌ <strong>Videos differ!</strong> [View Diff Report]($REPORT_URL)"
|
|
||||||
fi
|
|
||||||
echo "DIFF=$DIFF" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- name: Saving proposed ui
|
|
||||||
if: github.event_name == 'pull_request_target'
|
|
||||||
working-directory: ${{ github.workspace }}/master_ui_raylib
|
|
||||||
run: |
|
|
||||||
# Overwrite PR branch w/ proposed ui, and master ui at this point in time for future reference
|
|
||||||
git config user.name "GitHub Actions Bot"
|
|
||||||
git config user.email "<>"
|
|
||||||
git checkout --orphan=${{ env.BRANCH_NAME }}
|
|
||||||
git rm -rf *
|
|
||||||
mv ${{ github.workspace }}/pr_ui/* .
|
|
||||||
git add .
|
|
||||||
git commit -m "mici raylib video for PR #${{ github.event.number }}"
|
|
||||||
git push origin ${{ env.BRANCH_NAME }} --force
|
|
||||||
|
|
||||||
# Append diff report to report files branch
|
|
||||||
git fetch origin ${{ env.REPORT_FILES_BRANCH_NAME }}
|
|
||||||
git checkout ${{ env.REPORT_FILES_BRANCH_NAME }}
|
|
||||||
cp ${{ github.workspace }}/selfdrive/ui/tests/diff/report/diff.html diff_pr_${{ github.event.number }}.html
|
|
||||||
git add diff_pr_${{ github.event.number }}.html
|
|
||||||
git commit -m "mici raylib ui diff report for PR #${{ github.event.number }}" || echo "No changes to commit"
|
|
||||||
git push origin ${{ env.REPORT_FILES_BRANCH_NAME }}
|
|
||||||
|
|
||||||
- name: Comment Video on PR
|
|
||||||
if: github.event_name == 'pull_request_target'
|
|
||||||
uses: thollander/actions-comment-pull-request@v2
|
|
||||||
with:
|
|
||||||
message: |
|
|
||||||
<!-- _(run_id_video_mici_raylib **${{ github.run_id }}**)_ -->
|
|
||||||
## mici raylib UI Preview
|
|
||||||
${{ steps.find_diff.outputs.DIFF }}
|
|
||||||
comment_tag: run_id_video_mici_raylib
|
|
||||||
pr_number: ${{ github.event.number }}
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
@@ -4,7 +4,7 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
types: [opened, reopened, synchronize]
|
types: [opened, reopened, synchronize]
|
||||||
paths:
|
paths:
|
||||||
- 'selfdrive/modeld/models/*.onnx'
|
- 'openpilot/selfdrive/modeld/models/*.onnx'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -16,27 +16,27 @@ jobs:
|
|||||||
if: github.repository == 'commaai/openpilot'
|
if: github.repository == 'commaai/openpilot'
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
- name: Checkout master
|
- name: Checkout master
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
with:
|
with:
|
||||||
ref: master
|
ref: master
|
||||||
path: base
|
path: base
|
||||||
- run: git lfs pull
|
- run: git lfs pull
|
||||||
- run: cd base && git lfs pull
|
- run: cd base && git lfs pull
|
||||||
|
|
||||||
- run: pip install onnx
|
|
||||||
|
|
||||||
- name: scripts/reporter.py
|
- name: scripts/reporter.py
|
||||||
id: report
|
id: report
|
||||||
run: |
|
run: |
|
||||||
echo "content<<EOF" >> $GITHUB_OUTPUT
|
echo "content<<EOF" >> $GITHUB_OUTPUT
|
||||||
echo "## Model Review" >> $GITHUB_OUTPUT
|
echo "## Model Review" >> $GITHUB_OUTPUT
|
||||||
MASTER_PATH=${{ github.workspace }}/base python scripts/reporter.py >> $GITHUB_OUTPUT
|
PYTHONPATH=${{ github.workspace }} MASTER_PATH=${{ github.workspace }}/base python scripts/reporter.py >> $GITHUB_OUTPUT
|
||||||
echo "EOF" >> $GITHUB_OUTPUT
|
echo "EOF" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Post model report comment
|
- name: Post model report comment
|
||||||
uses: marocchino/sticky-pull-request-comment@baa7203ed60924babbe5dcd0ac8eae3b66ec5e16
|
uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0
|
||||||
with:
|
with:
|
||||||
header: model-review
|
header: model-review
|
||||||
message: ${{ steps.report.outputs.content }}
|
message: ${{ steps.report.outputs.content }}
|
||||||
@@ -6,7 +6,7 @@ on:
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
DOCKER_LOGIN: docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }}
|
DOCKER_LOGIN: docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }}
|
||||||
BUILD: release/ci/docker_build_sp.sh prebuilt
|
BUILD: release/ci/docker_build_sp.sh
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build_prebuilt:
|
build_prebuilt:
|
||||||
@@ -28,8 +28,8 @@ jobs:
|
|||||||
wait-interval: 30
|
wait-interval: 30
|
||||||
running-workflow-name: 'build prebuilt'
|
running-workflow-name: 'build prebuilt'
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
check-regexp: ^((?!.*(build master-ci).*).)*$
|
check-regexp: ^((?!.*(build master-ci|create badges).*).)*$
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- run: git lfs pull
|
- run: git lfs pull
|
||||||
|
|||||||
@@ -1,175 +0,0 @@
|
|||||||
name: "raylib ui preview"
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
pull_request_target:
|
|
||||||
types: [assigned, opened, synchronize, reopened, edited]
|
|
||||||
branches:
|
|
||||||
- 'master'
|
|
||||||
paths:
|
|
||||||
- 'selfdrive/assets/**'
|
|
||||||
- 'selfdrive/ui/**'
|
|
||||||
- 'system/ui/**'
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
env:
|
|
||||||
UI_JOB_NAME: "Create raylib UI Report"
|
|
||||||
REPORT_NAME: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && 'master' || github.event.number }}
|
|
||||||
SHA: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && github.sha || github.event.pull_request.head.sha }}
|
|
||||||
BRANCH_NAME: "openpilot/pr-${{ github.event.number }}-raylib-ui"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
preview:
|
|
||||||
if: github.repository == 'sunnypilot/sunnypilot'
|
|
||||||
name: preview
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 20
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pull-requests: write
|
|
||||||
actions: read
|
|
||||||
steps:
|
|
||||||
- name: Waiting for ui generation to start
|
|
||||||
run: sleep 30
|
|
||||||
|
|
||||||
- name: Waiting for ui generation to end
|
|
||||||
uses: lewagon/wait-on-check-action@v1.3.4
|
|
||||||
with:
|
|
||||||
ref: ${{ env.SHA }}
|
|
||||||
check-name: ${{ env.UI_JOB_NAME }}
|
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
allowed-conclusions: success
|
|
||||||
wait-interval: 20
|
|
||||||
|
|
||||||
- name: Getting workflow run ID
|
|
||||||
id: get_run_id
|
|
||||||
run: |
|
|
||||||
echo "run_id=$(curl https://api.github.com/repos/${{ github.repository }}/commits/${{ env.SHA }}/check-runs | jq -r '.check_runs[] | select(.name == "${{ env.UI_JOB_NAME }}") | .html_url | capture("(?<number>[0-9]+)") | .number')" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Getting proposed ui
|
|
||||||
id: download-artifact
|
|
||||||
uses: dawidd6/action-download-artifact@v6
|
|
||||||
with:
|
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
run_id: ${{ steps.get_run_id.outputs.run_id }}
|
|
||||||
search_artifacts: true
|
|
||||||
name: raylib-report-1-${{ env.REPORT_NAME }}
|
|
||||||
path: ${{ github.workspace }}/pr_ui
|
|
||||||
|
|
||||||
- name: Getting master ui
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
repository: sunnypilot/ci-artifacts
|
|
||||||
ssh-key: ${{ secrets.CI_ARTIFACTS_DEPLOY_KEY }}
|
|
||||||
path: ${{ github.workspace }}/master_ui_raylib
|
|
||||||
ref: openpilot_master_ui_raylib
|
|
||||||
|
|
||||||
- name: Saving new master ui
|
|
||||||
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
|
|
||||||
working-directory: ${{ github.workspace }}/master_ui_raylib
|
|
||||||
run: |
|
|
||||||
git checkout --orphan=new_master_ui_raylib
|
|
||||||
git rm -rf *
|
|
||||||
git branch -D openpilot_master_ui_raylib
|
|
||||||
git branch -m openpilot_master_ui_raylib
|
|
||||||
git config user.name "GitHub Actions Bot"
|
|
||||||
git config user.email "<>"
|
|
||||||
mv ${{ github.workspace }}/pr_ui/*.png .
|
|
||||||
git add .
|
|
||||||
git commit -m "raylib screenshots for commit ${{ env.SHA }}"
|
|
||||||
git push origin openpilot_master_ui_raylib --force
|
|
||||||
|
|
||||||
- name: Finding diff
|
|
||||||
if: github.event_name == 'pull_request_target'
|
|
||||||
id: find_diff
|
|
||||||
run: >-
|
|
||||||
sudo apt-get update && sudo apt-get install -y imagemagick
|
|
||||||
|
|
||||||
scenes=$(find ${{ github.workspace }}/pr_ui/*.png -type f -printf "%f\n" | cut -d '.' -f 1 | grep -v 'pair_device')
|
|
||||||
A=($scenes)
|
|
||||||
|
|
||||||
DIFF=""
|
|
||||||
TABLE="<details><summary>All Screenshots</summary>"
|
|
||||||
TABLE="${TABLE}<table>"
|
|
||||||
|
|
||||||
for ((i=0; i<${#A[*]}; i=i+1));
|
|
||||||
do
|
|
||||||
# Check if the master file exists
|
|
||||||
if [ ! -f "${{ github.workspace }}/master_ui_raylib/${A[$i]}.png" ]; then
|
|
||||||
# This is a new file in PR UI that doesn't exist in master
|
|
||||||
DIFF="${DIFF}<details open>"
|
|
||||||
DIFF="${DIFF}<summary>${A[$i]} : \$\${\\color{cyan}\\text{NEW}}\$\$</summary>"
|
|
||||||
DIFF="${DIFF}<table>"
|
|
||||||
|
|
||||||
DIFF="${DIFF}<tr>"
|
|
||||||
DIFF="${DIFF} <td> <img src=\"https://raw.githubusercontent.com/sunnypilot/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}.png\"> </td>"
|
|
||||||
DIFF="${DIFF}</tr>"
|
|
||||||
|
|
||||||
DIFF="${DIFF}</table>"
|
|
||||||
DIFF="${DIFF}</details>"
|
|
||||||
elif ! compare -fuzz 2% -highlight-color DeepSkyBlue1 -lowlight-color Black -compose Src ${{ github.workspace }}/master_ui_raylib/${A[$i]}.png ${{ github.workspace }}/pr_ui/${A[$i]}.png ${{ github.workspace }}/pr_ui/${A[$i]}_diff.png; then
|
|
||||||
convert ${{ github.workspace }}/pr_ui/${A[$i]}_diff.png -transparent black mask.png
|
|
||||||
composite mask.png ${{ github.workspace }}/master_ui_raylib/${A[$i]}.png composite_diff.png
|
|
||||||
convert -delay 100 ${{ github.workspace }}/master_ui_raylib/${A[$i]}.png composite_diff.png -loop 0 ${{ github.workspace }}/pr_ui/${A[$i]}_diff.gif
|
|
||||||
|
|
||||||
mv ${{ github.workspace }}/master_ui_raylib/${A[$i]}.png ${{ github.workspace }}/pr_ui/${A[$i]}_master_ref.png
|
|
||||||
|
|
||||||
DIFF="${DIFF}<details open>"
|
|
||||||
DIFF="${DIFF}<summary>${A[$i]} : \$\${\\color{red}\\text{DIFFERENT}}\$\$</summary>"
|
|
||||||
DIFF="${DIFF}<table>"
|
|
||||||
|
|
||||||
DIFF="${DIFF}<tr>"
|
|
||||||
DIFF="${DIFF} <td> master <img src=\"https://raw.githubusercontent.com/sunnypilot/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}_master_ref.png\"> </td>"
|
|
||||||
DIFF="${DIFF} <td> proposed <img src=\"https://raw.githubusercontent.com/sunnypilot/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}.png\"> </td>"
|
|
||||||
DIFF="${DIFF}</tr>"
|
|
||||||
|
|
||||||
DIFF="${DIFF}<tr>"
|
|
||||||
DIFF="${DIFF} <td> diff <img src=\"https://raw.githubusercontent.com/sunnypilot/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}_diff.png\"> </td>"
|
|
||||||
DIFF="${DIFF} <td> composite diff <img src=\"https://raw.githubusercontent.com/sunnypilot/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}_diff.gif\"> </td>"
|
|
||||||
DIFF="${DIFF}</tr>"
|
|
||||||
|
|
||||||
DIFF="${DIFF}</table>"
|
|
||||||
DIFF="${DIFF}</details>"
|
|
||||||
else
|
|
||||||
rm -f ${{ github.workspace }}/pr_ui/${A[$i]}_diff.png
|
|
||||||
fi
|
|
||||||
|
|
||||||
INDEX=$(($i % 2))
|
|
||||||
if [[ $INDEX -eq 0 ]]; then
|
|
||||||
TABLE="${TABLE}<tr>"
|
|
||||||
fi
|
|
||||||
TABLE="${TABLE} <td> <img src=\"https://raw.githubusercontent.com/sunnypilot/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}.png\"> </td>"
|
|
||||||
if [[ $INDEX -eq 1 || $(($i + 1)) -eq ${#A[*]} ]]; then
|
|
||||||
TABLE="${TABLE}</tr>"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
TABLE="${TABLE}</table></details>"
|
|
||||||
|
|
||||||
echo "DIFF=$DIFF$TABLE" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- name: Saving proposed ui
|
|
||||||
if: github.event_name == 'pull_request_target'
|
|
||||||
working-directory: ${{ github.workspace }}/master_ui_raylib
|
|
||||||
run: |
|
|
||||||
git config user.name "GitHub Actions Bot"
|
|
||||||
git config user.email "<>"
|
|
||||||
git checkout --orphan=${{ env.BRANCH_NAME }}
|
|
||||||
git rm -rf *
|
|
||||||
mv ${{ github.workspace }}/pr_ui/* .
|
|
||||||
git add .
|
|
||||||
git commit -m "raylib screenshots for PR #${{ github.event.number }}"
|
|
||||||
git push origin ${{ env.BRANCH_NAME }} --force
|
|
||||||
|
|
||||||
- name: Comment Screenshots on PR
|
|
||||||
if: github.event_name == 'pull_request_target'
|
|
||||||
uses: thollander/actions-comment-pull-request@v2
|
|
||||||
with:
|
|
||||||
message: |
|
|
||||||
<!-- _(run_id_screenshots_raylib **${{ github.run_id }}**)_ -->
|
|
||||||
## raylib UI Preview
|
|
||||||
${{ steps.find_diff.outputs.DIFF }}
|
|
||||||
comment_tag: run_id_screenshots_raylib
|
|
||||||
pr_number: ${{ github.event.number }}
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
@@ -7,36 +7,25 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build___nightly:
|
build___nightly:
|
||||||
name: build __nightly
|
name: build __nightly
|
||||||
env:
|
|
||||||
ImageOS: ubuntu24
|
|
||||||
container:
|
|
||||||
image: ghcr.io/sunnypilot/sunnypilot-base:latest
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: github.repository == 'sunnypilot/sunnypilot'
|
if: github.repository == 'sunnypilot/sunnypilot'
|
||||||
permissions:
|
permissions:
|
||||||
checks: read
|
checks: read
|
||||||
contents: write
|
contents: write
|
||||||
steps:
|
steps:
|
||||||
- name: Install wait-on-check-action dependencies
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y libyaml-dev
|
|
||||||
- name: Wait for green check mark
|
- name: Wait for green check mark
|
||||||
if: ${{ github.event_name == 'schedule' }}
|
if: ${{ github.event_name == 'schedule' }}
|
||||||
uses: lewagon/wait-on-check-action@ccfb013c15c8afb7bf2b7c028fb74dc5a068cccc
|
uses: lewagon/wait-on-check-action@1d57e2c51a58d812d2765e036a028b6bdb5a6154
|
||||||
with:
|
with:
|
||||||
ref: master
|
ref: master
|
||||||
wait-interval: 30
|
wait-interval: 30
|
||||||
running-workflow-name: 'build __nightly'
|
running-workflow-name: 'build __nightly'
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
check-regexp: ^((?!.*(build prebuilt).*).)*$
|
check-regexp: ^((?!.*(build prebuilt|create badges).*).)*$
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4 # checkout version > v4 breaks nightly release script
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Pull LFS
|
- run: ./tools/op.sh setup
|
||||||
run: |
|
|
||||||
git config --global --add safe.directory '*'
|
|
||||||
git lfs pull
|
|
||||||
- name: Push __nightly
|
- name: Push __nightly
|
||||||
run: BRANCH=__nightly release/build_stripped.sh
|
run: BRANCH=__nightly tools/release/build_stripped.sh
|
||||||
|
|||||||
@@ -3,65 +3,61 @@ name: repo maintenance
|
|||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 14 * * 1" # every Monday at 2am UTC (6am PST)
|
- cron: "0 14 * * 1" # every Monday at 2am UTC (6am PST)
|
||||||
|
pull_request:
|
||||||
|
types: [closed]
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
BASE_IMAGE: sunnypilot-base
|
PYTHONPATH: ${{ github.workspace }}
|
||||||
BUILD: release/ci/docker_build_sp.sh base
|
|
||||||
RUN: docker run --shm-size 2G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e CI=1 -e PYTHONWARNINGS=error -e FILEREADER_CACHE=1 -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v $GITHUB_WORKSPACE/.ci_cache/scons_cache:/tmp/scons_cache -v $GITHUB_WORKSPACE/.ci_cache/comma_download_cache:/tmp/comma_download_cache -v $GITHUB_WORKSPACE/.ci_cache/openpilot_cache:/tmp/openpilot_cache $BASE_IMAGE /bin/bash -c
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update_translations:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.repository == 'sunnypilot/sunnypilot'
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: ./.github/workflows/setup-with-retry
|
|
||||||
- name: Update translations
|
|
||||||
run: |
|
|
||||||
${{ env.RUN }} "python3 selfdrive/ui/update_translations.py --vanish"
|
|
||||||
- name: Create Pull Request
|
|
||||||
uses: peter-evans/create-pull-request@9153d834b60caba6d51c9b9510b087acf9f33f83
|
|
||||||
with:
|
|
||||||
author: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
|
|
||||||
commit-message: "Update translations"
|
|
||||||
title: "[bot] Update translations"
|
|
||||||
body: "Automatic PR from repo-maintenance -> update_translations"
|
|
||||||
branch: "update-translations"
|
|
||||||
base: "master"
|
|
||||||
delete-branch: true
|
|
||||||
labels: bot
|
|
||||||
|
|
||||||
package_updates:
|
package_updates:
|
||||||
name: package_updates
|
name: package_updates
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
if: >-
|
||||||
image: ghcr.io/sunnypilot/sunnypilot-base:latest
|
github.repository == 'sunnypilot/sunnypilot' &&
|
||||||
if: github.repository == 'sunnypilot/sunnypilot'
|
(github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v7
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
|
- run: ./tools/op.sh setup
|
||||||
- name: uv lock
|
- name: uv lock
|
||||||
if: github.repository == 'commaai/openpilot'
|
run: uv lock --upgrade
|
||||||
|
- name: uv pip tree
|
||||||
|
id: pip_tree
|
||||||
run: |
|
run: |
|
||||||
python3 -m ensurepip --upgrade
|
echo 'PIP_TREE<<EOF' >> $GITHUB_OUTPUT
|
||||||
pip3 install uv
|
uv pip tree >> $GITHUB_OUTPUT
|
||||||
uv lock --upgrade
|
echo 'EOF' >> $GITHUB_OUTPUT
|
||||||
|
- name: venv size
|
||||||
|
id: venv_size
|
||||||
|
run: |
|
||||||
|
echo 'VENV_SIZE<<EOF' >> $GITHUB_OUTPUT
|
||||||
|
echo "Total: $(du -sh .venv | cut -f1)" >> $GITHUB_OUTPUT
|
||||||
|
echo "" >> $GITHUB_OUTPUT
|
||||||
|
echo "Top 10 by size:" >> $GITHUB_OUTPUT
|
||||||
|
du -sh .venv/lib/python*/site-packages/* 2>/dev/null \
|
||||||
|
| grep -v '\.dist-info' \
|
||||||
|
| grep -v '__pycache__' \
|
||||||
|
| sort -rh \
|
||||||
|
| head -10 \
|
||||||
|
| while IFS=$'\t' read size path; do echo "$size ${path##*/}"; done >> $GITHUB_OUTPUT
|
||||||
|
echo 'EOF' >> $GITHUB_OUTPUT
|
||||||
- name: bump submodules
|
- name: bump submodules
|
||||||
run: |
|
run: |
|
||||||
git config --global --add safe.directory '*'
|
git config submodule.msgq.update none
|
||||||
|
git config submodule.rednose_repo.update none
|
||||||
|
git config submodule.teleoprtc_repo.update none
|
||||||
git config submodule.tinygrad.update none
|
git config submodule.tinygrad.update none
|
||||||
git submodule update --remote
|
git submodule update --remote
|
||||||
git add .
|
git add .
|
||||||
- name: update car docs
|
- name: update car docs
|
||||||
run: |
|
run: |
|
||||||
export PYTHONPATH="$PWD"
|
python openpilot/selfdrive/car/docs.py
|
||||||
scons -j$(nproc) --minimal opendbc_repo
|
|
||||||
python selfdrive/car/docs.py
|
|
||||||
git add docs/CARS.md
|
git add docs/CARS.md
|
||||||
- name: Create Pull Request
|
- name: Create Pull Request
|
||||||
uses: peter-evans/create-pull-request@9153d834b60caba6d51c9b9510b087acf9f33f83
|
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1
|
||||||
with:
|
with:
|
||||||
author: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
|
author: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
|
||||||
token: ${{ github.repository == 'commaai/openpilot' && secrets.ACTIONS_CREATE_PR_PAT || secrets.GITHUB_TOKEN }}
|
token: ${{ github.repository == 'commaai/openpilot' && secrets.ACTIONS_CREATE_PR_PAT || secrets.GITHUB_TOKEN }}
|
||||||
@@ -70,5 +66,56 @@ jobs:
|
|||||||
branch: auto-package-updates
|
branch: auto-package-updates
|
||||||
base: master
|
base: master
|
||||||
delete-branch: true
|
delete-branch: true
|
||||||
body: 'Automatic PR from repo-maintenance -> package_updates'
|
body: |
|
||||||
|
Automatic PR from repo-maintenance -> package_updates
|
||||||
|
|
||||||
|
```
|
||||||
|
$ du -sh .venv && du -sh .venv/lib/python*/site-packages/* | sort -rh | head -10
|
||||||
|
${{ steps.venv_size.outputs.VENV_SIZE }}
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
$ uv pip tree
|
||||||
|
${{ steps.pip_tree.outputs.PIP_TREE }}
|
||||||
|
```
|
||||||
labels: bot
|
labels: bot
|
||||||
|
|
||||||
|
cleanup_closed_branches:
|
||||||
|
if: github.repository == 'commaai/openpilot'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: read
|
||||||
|
steps:
|
||||||
|
- uses: actions/github-script@v9
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const { owner, repo } = context.repo;
|
||||||
|
const upstream = `${owner}/${repo}`;
|
||||||
|
|
||||||
|
for await (const response of github.paginate.iterator(github.rest.pulls.list, {
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
state: 'closed',
|
||||||
|
per_page: 100,
|
||||||
|
})) {
|
||||||
|
for (const pr of response.data) {
|
||||||
|
if (pr.head.repo?.full_name !== upstream) continue;
|
||||||
|
|
||||||
|
const branch = pr.head.ref;
|
||||||
|
try {
|
||||||
|
await github.rest.git.deleteRef({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
ref: `heads/${branch}`,
|
||||||
|
});
|
||||||
|
console.log(`Deleted branch ${branch} (PR #${pr.number})`);
|
||||||
|
} catch (error) {
|
||||||
|
if (error.status === 422 || error.status === 403) {
|
||||||
|
console.log(`Skipping branch ${branch} (PR #${pr.number}): ${error.message}`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
name: 'openpilot env setup, with retry on failure'
|
|
||||||
|
|
||||||
inputs:
|
|
||||||
docker_hub_pat:
|
|
||||||
description: 'Auth token for Docker Hub, required for BuildJet jobs'
|
|
||||||
required: false
|
|
||||||
default: ''
|
|
||||||
sleep_time:
|
|
||||||
description: 'Time to sleep between retries'
|
|
||||||
required: false
|
|
||||||
default: 30
|
|
||||||
|
|
||||||
outputs:
|
|
||||||
duration:
|
|
||||||
description: 'Duration of the setup process in seconds'
|
|
||||||
value: ${{ steps.get_duration.outputs.duration }}
|
|
||||||
|
|
||||||
runs:
|
|
||||||
using: "composite"
|
|
||||||
steps:
|
|
||||||
- id: start_time
|
|
||||||
shell: bash
|
|
||||||
run: echo "START_TIME=$(date +%s)" >> $GITHUB_ENV
|
|
||||||
- id: setup1
|
|
||||||
uses: ./.github/workflows/setup
|
|
||||||
continue-on-error: true
|
|
||||||
with:
|
|
||||||
is_retried: true
|
|
||||||
- if: steps.setup1.outcome == 'failure'
|
|
||||||
shell: bash
|
|
||||||
run: sleep ${{ inputs.sleep_time }}
|
|
||||||
- id: setup2
|
|
||||||
if: steps.setup1.outcome == 'failure'
|
|
||||||
uses: ./.github/workflows/setup
|
|
||||||
continue-on-error: true
|
|
||||||
with:
|
|
||||||
is_retried: true
|
|
||||||
- if: steps.setup2.outcome == 'failure'
|
|
||||||
shell: bash
|
|
||||||
run: sleep ${{ inputs.sleep_time }}
|
|
||||||
- id: setup3
|
|
||||||
if: steps.setup2.outcome == 'failure'
|
|
||||||
uses: ./.github/workflows/setup
|
|
||||||
with:
|
|
||||||
is_retried: true
|
|
||||||
- id: get_duration
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
END_TIME=$(date +%s)
|
|
||||||
DURATION=$((END_TIME - START_TIME))
|
|
||||||
echo "Total duration: $DURATION seconds"
|
|
||||||
echo "duration=$DURATION" >> $GITHUB_OUTPUT
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
name: 'openpilot env setup'
|
|
||||||
|
|
||||||
inputs:
|
|
||||||
is_retried:
|
|
||||||
description: 'A mock param that asserts that we use the setup-with-retry instead of this action directly'
|
|
||||||
required: false
|
|
||||||
default: 'false'
|
|
||||||
|
|
||||||
runs:
|
|
||||||
using: "composite"
|
|
||||||
steps:
|
|
||||||
# assert that this action is retried using the setup-with-retry
|
|
||||||
- shell: bash
|
|
||||||
if: ${{ inputs.is_retried == 'false' }}
|
|
||||||
run: |
|
|
||||||
echo "You should not run this action directly. Use setup-with-retry instead"
|
|
||||||
exit 1
|
|
||||||
|
|
||||||
- shell: bash
|
|
||||||
name: No retries!
|
|
||||||
run: |
|
|
||||||
if [ "${{ github.run_attempt }}" -gt ${{ github.event.pull_request.head.repo.fork && github.event.pull_request.author_association == 'NONE' && 2 || 1}} ]; then
|
|
||||||
echo -e "\033[0;31m##################################################"
|
|
||||||
echo -e "\033[0;31m Retries not allowed! Fix the flaky test! "
|
|
||||||
echo -e "\033[0;31m##################################################\033[0m"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# do this after checkout to ensure our custom LFS config is used to pull from GitLab
|
|
||||||
- shell: bash
|
|
||||||
run: git lfs pull
|
|
||||||
|
|
||||||
# build cache
|
|
||||||
- id: date
|
|
||||||
shell: bash
|
|
||||||
run: echo "CACHE_COMMIT_DATE=$(git log -1 --pretty='format:%cd' --date=format:'%Y-%m-%d-%H:%M')" >> $GITHUB_ENV
|
|
||||||
- shell: bash
|
|
||||||
run: echo "$CACHE_COMMIT_DATE"
|
|
||||||
- id: scons-cache
|
|
||||||
uses: ./.github/workflows/auto-cache
|
|
||||||
with:
|
|
||||||
path: .ci_cache/scons_cache
|
|
||||||
key: scons-${{ runner.arch }}-${{ env.CACHE_COMMIT_DATE }}-${{ github.sha }}
|
|
||||||
restore-keys: |
|
|
||||||
scons-${{ runner.arch }}-${{ env.CACHE_COMMIT_DATE }}
|
|
||||||
scons-${{ runner.arch }}
|
|
||||||
# as suggested here: https://github.com/moby/moby/issues/32816#issuecomment-910030001
|
|
||||||
- id: normalize-file-permissions
|
|
||||||
shell: bash
|
|
||||||
name: Normalize file permissions to ensure a consistent docker build cache
|
|
||||||
run: |
|
|
||||||
find . -type f -executable -not -perm 755 -exec chmod 755 {} \;
|
|
||||||
find . -type f -not -executable -not -perm 644 -exec chmod 644 {} \;
|
|
||||||
# build our docker image
|
|
||||||
- shell: bash
|
|
||||||
run: eval ${{ env.BUILD }}
|
|
||||||
@@ -13,7 +13,7 @@ jobs:
|
|||||||
stale:
|
stale:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v9
|
- uses: actions/stale@v10
|
||||||
with:
|
with:
|
||||||
exempt-all-milestones: true
|
exempt-all-milestones: true
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ jobs:
|
|||||||
stale_drafts:
|
stale_drafts:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v9
|
- uses: actions/stale@v10
|
||||||
with:
|
with:
|
||||||
exempt-all-milestones: true
|
exempt-all-milestones: true
|
||||||
|
|
||||||
|
|||||||
@@ -164,18 +164,63 @@ jobs:
|
|||||||
source /etc/profile
|
source /etc/profile
|
||||||
export UV_PROJECT_ENVIRONMENT=${HOME}/venv
|
export UV_PROJECT_ENVIRONMENT=${HOME}/venv
|
||||||
export VIRTUAL_ENV=$UV_PROJECT_ENVIRONMENT
|
export VIRTUAL_ENV=$UV_PROJECT_ENVIRONMENT
|
||||||
export PYTHONPATH="${PYTHONPATH}:${{ env.TINYGRAD_PATH }}"
|
export PYTHONPATH="${PYTHONPATH}:${{ env.TINYGRAD_PATH }}:${{ github.workspace }}"
|
||||||
|
|
||||||
# Loop through all .onnx files
|
COMPILE_MODELD="${{ github.workspace }}/sunnypilot/modeld_v2/compile_modeld.py"
|
||||||
|
MODEL_SIZE=$(python3 -c "from openpilot.common.transformations.model import MEDMODEL_INPUT_SIZE as s; print(f'{s[0]}x{s[1]}')")
|
||||||
|
CAMERA_RES=$(python3 -c "from openpilot.common.transformations.camera import _ar_ox_fisheye as a, _os_fisheye as o; print(f'{a.width}x{a.height} {o.width}x{o.height}')")
|
||||||
|
TG_FLAGS="DEV=QCOM IMAGE=1 FLOAT16=1 NOLOCALS=1 JIT_BATCH_SIZE=0 OPENPILOT_HACKS=1"
|
||||||
|
|
||||||
|
# Generate metadata for all ONNX files
|
||||||
find "${{ env.MODELS_DIR }}" -maxdepth 1 -name '*.onnx' | while IFS= read -r onnx_file; do
|
find "${{ env.MODELS_DIR }}" -maxdepth 1 -name '*.onnx' | while IFS= read -r onnx_file; do
|
||||||
base_name=$(basename "$onnx_file" .onnx)
|
echo "Generating metadata: $onnx_file"
|
||||||
output_file="${{ env.MODELS_DIR }}/${base_name}_tinygrad.pkl"
|
env ${TG_FLAGS} python3 "${{ env.MODELS_DIR }}/../get_model_metadata.py" "$onnx_file" || true
|
||||||
|
|
||||||
echo "Compiling: $onnx_file -> $output_file"
|
|
||||||
QCOM=1 python3 "${{ env.TINYGRAD_PATH }}/examples/openpilot/compile3.py" "$onnx_file" "$output_file"
|
|
||||||
QCOM=1 python3 "${{ env.MODELS_DIR }}/../get_model_metadata.py" "$onnx_file" || true
|
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Detect model type and build compile args
|
||||||
|
VISION_ONNX="${{ env.MODELS_DIR }}/driving_vision.onnx"
|
||||||
|
POLICY_ONNX="${{ env.MODELS_DIR }}/driving_policy.onnx"
|
||||||
|
OFF_POLICY_ONNX="${{ env.MODELS_DIR }}/driving_off_policy.onnx"
|
||||||
|
ON_POLICY_ONNX="${{ env.MODELS_DIR }}/driving_on_policy.onnx"
|
||||||
|
SUPERCOMBO_ONNX="${{ env.MODELS_DIR }}/supercombo.onnx"
|
||||||
|
|
||||||
|
MODEL_TYPE="" ONNX_ARGS="" OUTPUT_NAME=""
|
||||||
|
if [ -f "$VISION_ONNX" ]; then
|
||||||
|
ONNX_ARGS="--vision-onnx $VISION_ONNX"
|
||||||
|
if [ -f "$ON_POLICY_ONNX" ] && [ -f "$OFF_POLICY_ONNX" ]; then
|
||||||
|
MODEL_TYPE=vision_multi_policy
|
||||||
|
ONNX_ARGS="$ONNX_ARGS --off-policy-onnx $OFF_POLICY_ONNX --on-policy-onnx $ON_POLICY_ONNX"
|
||||||
|
elif [ -f "$OFF_POLICY_ONNX" ] && [ -f "$POLICY_ONNX" ]; then
|
||||||
|
MODEL_TYPE=vision_multi_policy
|
||||||
|
ONNX_ARGS="$ONNX_ARGS --policy-onnx $POLICY_ONNX --off-policy-onnx $OFF_POLICY_ONNX"
|
||||||
|
elif [ -f "$POLICY_ONNX" ]; then
|
||||||
|
MODEL_TYPE=vision_policy
|
||||||
|
ONNX_ARGS="$ONNX_ARGS --policy-onnx $POLICY_ONNX"
|
||||||
|
fi
|
||||||
|
elif [ -f "$SUPERCOMBO_ONNX" ]; then
|
||||||
|
MODEL_TYPE=supercombo
|
||||||
|
ONNX_ARGS="--supercombo-onnx $SUPERCOMBO_ONNX"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$MODEL_TYPE" ]; then
|
||||||
|
echo "Detected: $MODEL_TYPE -> driving_tinygrad.pkl"
|
||||||
|
env ${TG_FLAGS} python3 "$COMPILE_MODELD" \
|
||||||
|
--model-type $MODEL_TYPE \
|
||||||
|
--model-size $MODEL_SIZE \
|
||||||
|
--camera-resolutions $CAMERA_RES \
|
||||||
|
$ONNX_ARGS \
|
||||||
|
--output "${{ env.MODELS_DIR }}/driving_tinygrad.pkl"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Validate Model Outputs
|
||||||
|
run: |
|
||||||
|
source /etc/profile
|
||||||
|
export UV_PROJECT_ENVIRONMENT=${HOME}/venv
|
||||||
|
export VIRTUAL_ENV=$UV_PROJECT_ENVIRONMENT
|
||||||
|
python3 "${{ github.workspace }}/release/ci/model_generator.py" \
|
||||||
|
--validate-only \
|
||||||
|
--model-dir "${{ env.MODELS_DIR }}"
|
||||||
|
|
||||||
- name: Prepare Output
|
- name: Prepare Output
|
||||||
run: |
|
run: |
|
||||||
sudo rm -rf ${{ env.OUTPUT_DIR }}
|
sudo rm -rf ${{ env.OUTPUT_DIR }}
|
||||||
@@ -184,8 +229,9 @@ jobs:
|
|||||||
# Copy the model files
|
# Copy the model files
|
||||||
rsync -avm \
|
rsync -avm \
|
||||||
--include='*.dlc' \
|
--include='*.dlc' \
|
||||||
--include='*.thneed' \
|
|
||||||
--include='*.pkl' \
|
--include='*.pkl' \
|
||||||
|
--include='*.chunk*' \
|
||||||
|
--include='*.chunkmanifest' \
|
||||||
--include='*.onnx' \
|
--include='*.onnx' \
|
||||||
--exclude='*' \
|
--exclude='*' \
|
||||||
--delete-excluded \
|
--delete-excluded \
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ jobs:
|
|||||||
is_stable_branch="$(echo "$CONFIG" | jq -r '.stable_branch // false')";
|
is_stable_branch="$(echo "$CONFIG" | jq -r '.stable_branch // false')";
|
||||||
echo "is_stable_branch=$is_stable_branch" >> $GITHUB_OUTPUT
|
echo "is_stable_branch=$is_stable_branch" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
stable_version=$(cat sunnypilot/common/version.h | grep SUNNYPILOT_VERSION | sed -e 's/[^0-9|.]//g');
|
stable_version=$(cat openpilot/sunnypilot/common/version.h | grep SUNNYPILOT_VERSION | sed -e 's/[^0-9|.]//g');
|
||||||
echo "version=$([ "$is_stable_branch" = "true" ] && echo "$stable_version" || echo "$BUILD")" >> $GITHUB_OUTPUT
|
echo "version=$([ "$is_stable_branch" = "true" ] && echo "$stable_version" || echo "$BUILD")" >> $GITHUB_OUTPUT
|
||||||
echo "extra_version_identifier=${environment}" >> $GITHUB_OUTPUT
|
echo "extra_version_identifier=${environment}" >> $GITHUB_OUTPUT
|
||||||
fi
|
fi
|
||||||
@@ -177,17 +177,15 @@ jobs:
|
|||||||
- name: Build Main Project
|
- name: Build Main Project
|
||||||
run: |
|
run: |
|
||||||
export PYTHONPATH="$BUILD_DIR"
|
export PYTHONPATH="$BUILD_DIR"
|
||||||
./release/release_files.py | sort | uniq | rsync -rRl${RUNNER_DEBUG:+v} --files-from=- . $BUILD_DIR/
|
./tools/release/release_files.py | sort | uniq | rsync -rRl${RUNNER_DEBUG:+v} --files-from=- . $BUILD_DIR/
|
||||||
cd $BUILD_DIR
|
cd $BUILD_DIR
|
||||||
sed -i '/from .board.jungle import PandaJungle, PandaJungleDFU/s/^/#/' panda/__init__.py
|
sed -i '/from .board.jungle import PandaJungle, PandaJungleDFU/s/^/#/' panda/__init__.py
|
||||||
echo "Building sunnypilot's modeld..."
|
|
||||||
scons -j$(nproc) cache_dir=${{env.SCONS_CACHE_DIR}} --minimal sunnypilot/modeld
|
|
||||||
echo "Building sunnypilot's modeld_v2..."
|
echo "Building sunnypilot's modeld_v2..."
|
||||||
scons -j$(nproc) cache_dir=${{env.SCONS_CACHE_DIR}} --minimal sunnypilot/modeld_v2
|
scons -j$(nproc) cache_dir=${{env.SCONS_CACHE_DIR}} --minimal sunnypilot/modeld_v2
|
||||||
echo "Building sunnypilot's locationd..."
|
echo "Building sunnypilot's locationd..."
|
||||||
scons -j2 cache_dir=${{env.SCONS_CACHE_DIR}} --minimal sunnypilot/selfdrive/locationd
|
scons -j2 cache_dir=${{env.SCONS_CACHE_DIR}} --minimal sunnypilot/selfdrive/locationd
|
||||||
echo "Building openpilot's locationd..."
|
echo "Building openpilot's locationd..."
|
||||||
scons -j$(nproc) cache_dir=${{env.SCONS_CACHE_DIR}} --minimal selfdrive/locationd
|
scons -j1 cache_dir=${{env.SCONS_CACHE_DIR}} --minimal selfdrive/locationd
|
||||||
echo "Building rest of sunnypilot"
|
echo "Building rest of sunnypilot"
|
||||||
scons -j$(nproc) cache_dir=${{env.SCONS_CACHE_DIR}} --minimal
|
scons -j$(nproc) cache_dir=${{env.SCONS_CACHE_DIR}} --minimal
|
||||||
touch ${BUILD_DIR}/prebuilt
|
touch ${BUILD_DIR}/prebuilt
|
||||||
@@ -210,18 +208,17 @@ jobs:
|
|||||||
--exclude='Jenkinsfile' \
|
--exclude='Jenkinsfile' \
|
||||||
--exclude='**/release/' \
|
--exclude='**/release/' \
|
||||||
--exclude='**/.github/' \
|
--exclude='**/.github/' \
|
||||||
--exclude='**/selfdrive/ui/replay/' \
|
--exclude='**/openpilot/selfdrive/ui/replay/' \
|
||||||
--exclude='**/__pycache__/' \
|
--exclude='**/__pycache__/' \
|
||||||
--exclude='${{env.SCONS_CACHE_DIR}}' \
|
--exclude='${{env.SCONS_CACHE_DIR}}' \
|
||||||
--exclude='**/.git/' \
|
--exclude='**/.git/' \
|
||||||
--exclude='**/SConstruct' \
|
--exclude='**/SConstruct' \
|
||||||
--exclude='**/SConscript' \
|
--exclude='**/SConscript' \
|
||||||
--exclude='**/.venv/' \
|
--exclude='**/.venv/' \
|
||||||
--exclude='selfdrive/modeld/models/driving_vision.onnx' \
|
--exclude='openpilot/selfdrive/modeld/models/*.onnx*' \
|
||||||
--exclude='selfdrive/modeld/models/driving_policy.onnx' \
|
--exclude='openpilot/sunnypilot/modeld*/models/*.onnx*' \
|
||||||
--exclude='sunnypilot/modeld*/models/supercombo.onnx' \
|
--exclude='openpilot/third_party/*x86*' \
|
||||||
--exclude='third_party/*x86*' \
|
--exclude='openpilot/third_party/*Darwin*' \
|
||||||
--exclude='third_party/*Darwin*' \
|
|
||||||
--delete-excluded \
|
--delete-excluded \
|
||||||
--chown=comma:comma \
|
--chown=comma:comma \
|
||||||
${BUILD_DIR}/ ${OUTPUT_DIR}/
|
${BUILD_DIR}/ ${OUTPUT_DIR}/
|
||||||
|
|||||||
@@ -174,6 +174,24 @@ jobs:
|
|||||||
echo ' pushurl = ${{ env.LFS_PUSH_URL }}' >> .lfsconfig
|
echo ' pushurl = ${{ env.LFS_PUSH_URL }}' >> .lfsconfig
|
||||||
echo ' locksverify = false' >> .lfsconfig
|
echo ' locksverify = false' >> .lfsconfig
|
||||||
|
|
||||||
|
- name: Restore workflows from source
|
||||||
|
run: |
|
||||||
|
TARGET_BRANCH="${{ inputs.target_branch || env.DEFAULT_TARGET_BRANCH }}"
|
||||||
|
SOURCE_BRANCH="${{ inputs.source_branch || env.DEFAULT_SOURCE_BRANCH }}"
|
||||||
|
|
||||||
|
# Ensure we are on the target branch
|
||||||
|
git checkout $TARGET_BRANCH
|
||||||
|
|
||||||
|
echo "Restoring .github/workflows from $SOURCE_BRANCH"
|
||||||
|
git checkout origin/$SOURCE_BRANCH -- .github/workflows
|
||||||
|
|
||||||
|
if ! git diff --cached --quiet; then
|
||||||
|
echo "Workflows differ. Committing restoration."
|
||||||
|
git commit -m "chore: restore .github/workflows from $SOURCE_BRANCH"
|
||||||
|
else
|
||||||
|
echo "Workflows match $SOURCE_BRANCH."
|
||||||
|
fi
|
||||||
|
|
||||||
- uses: actions/create-github-app-token@v2
|
- uses: actions/create-github-app-token@v2
|
||||||
id: ci-token
|
id: ci-token
|
||||||
with:
|
with:
|
||||||
@@ -223,10 +241,3 @@ jobs:
|
|||||||
gh run watch "$RUN_ID"
|
gh run watch "$RUN_ID"
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Trigger prebuilt workflow
|
|
||||||
if: success() && steps.push-changes.outputs.has_changes == 'true'
|
|
||||||
run: |
|
|
||||||
gh workflow run sunnypilot-build-prebuilt.yaml --ref "${{ inputs.target_branch || env.DEFAULT_TARGET_BRANCH }}"
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|||||||
+115
-189
@@ -18,15 +18,8 @@ concurrency:
|
|||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
env:
|
env:
|
||||||
PYTHONWARNINGS: error
|
CI: 1
|
||||||
BASE_IMAGE: sunnypilot-base
|
PYTHONPATH: ${{ github.workspace }}
|
||||||
AZURE_TOKEN: ${{ secrets.AZURE_COMMADATACI_OPENPILOTCI_TOKEN }}
|
|
||||||
|
|
||||||
DOCKER_LOGIN: docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
BUILD: release/ci/docker_build_sp.sh base
|
|
||||||
|
|
||||||
RUN: docker run --shm-size 2G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e CI=1 -e PYTHONWARNINGS=error -e FILEREADER_CACHE=1 -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v $GITHUB_WORKSPACE/.ci_cache/scons_cache:/tmp/scons_cache -v $GITHUB_WORKSPACE/.ci_cache/comma_download_cache:/tmp/comma_download_cache -v $GITHUB_WORKSPACE/.ci_cache/openpilot_cache:/tmp/openpilot_cache $BASE_IMAGE /bin/bash -c
|
|
||||||
|
|
||||||
PYTEST: pytest --continue-on-collection-errors --durations=0 -n logical
|
PYTEST: pytest --continue-on-collection-errors --durations=0 -n logical
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -36,34 +29,33 @@ jobs:
|
|||||||
(github.repository == 'commaai/openpilot') &&
|
(github.repository == 'commaai/openpilot') &&
|
||||||
((github.event_name != 'pull_request') ||
|
((github.event_name != 'pull_request') ||
|
||||||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))
|
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))
|
||||||
&& fromJSON('["namespace-profile-amd64-8x16", "namespace-experiments:docker.builds.local-cache=separate"]')
|
&& fromJSON('["namespace-profile-amd64-8x16"]')
|
||||||
|| fromJSON('["ubuntu-24.04"]') }}
|
|| fromJSON('["ubuntu-24.04"]') }}
|
||||||
env:
|
env:
|
||||||
STRIPPED_DIR: /tmp/releasepilot
|
STRIPPED_DIR: /tmp/releasepilot
|
||||||
|
PYTHONPATH: /tmp/releasepilot
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v7
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Getting LFS files
|
- name: Getting LFS files
|
||||||
uses: nick-fields/retry@7152eba30c6575329ac0576536151aca5a72780e
|
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60
|
||||||
with:
|
with:
|
||||||
timeout_minutes: 2
|
timeout_minutes: 2
|
||||||
max_attempts: 3
|
max_attempts: 3
|
||||||
command: git lfs pull
|
command: git lfs pull
|
||||||
- name: Build devel
|
- name: Build devel
|
||||||
timeout-minutes: 1
|
timeout-minutes: 3
|
||||||
run: TARGET_DIR=$STRIPPED_DIR release/build_stripped.sh
|
run: TARGET_DIR=$STRIPPED_DIR tools/release/build_stripped.sh
|
||||||
- uses: ./.github/workflows/setup-with-retry
|
- run: ./tools/op.sh setup
|
||||||
- name: Build openpilot and run checks
|
- name: Build openpilot and run checks
|
||||||
timeout-minutes: ${{ ((steps.restore-scons-cache.outputs.cache-hit == 'true') && 10 || 30) }} # allow more time when we missed the scons cache
|
timeout-minutes: 30
|
||||||
run: |
|
working-directory: ${{ env.STRIPPED_DIR }}
|
||||||
cd $STRIPPED_DIR
|
run: python3 openpilot/system/manager/build.py
|
||||||
${{ env.RUN }} "python3 system/manager/build.py"
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
timeout-minutes: 1
|
timeout-minutes: 1
|
||||||
run: |
|
working-directory: ${{ env.STRIPPED_DIR }}
|
||||||
cd $STRIPPED_DIR
|
run: tools/release/check-dirty.sh
|
||||||
${{ env.RUN }} "release/check-dirty.sh"
|
|
||||||
- name: Check submodules
|
- name: Check submodules
|
||||||
if: github.repository == 'sunnypilot/sunnypilot'
|
if: github.repository == 'sunnypilot/sunnypilot'
|
||||||
timeout-minutes: 3
|
timeout-minutes: 3
|
||||||
@@ -83,75 +75,20 @@ jobs:
|
|||||||
export CHECK_PR_REFS=true
|
export CHECK_PR_REFS=true
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
release/check-submodules.sh
|
tools/release/check-submodules.sh
|
||||||
|
|
||||||
build:
|
|
||||||
runs-on: ${{
|
|
||||||
(github.repository == 'commaai/openpilot') &&
|
|
||||||
((github.event_name != 'pull_request') ||
|
|
||||||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))
|
|
||||||
&& fromJSON('["namespace-profile-amd64-8x16", "namespace-experiments:docker.builds.local-cache=separate"]')
|
|
||||||
|| fromJSON('["ubuntu-24.04"]') }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
- name: Setup docker push
|
|
||||||
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'sunnypilot/sunnypilot'
|
|
||||||
run: |
|
|
||||||
echo "PUSH_IMAGE=true" >> "$GITHUB_ENV"
|
|
||||||
$DOCKER_LOGIN
|
|
||||||
- uses: ./.github/workflows/setup-with-retry
|
|
||||||
- uses: ./.github/workflows/compile-openpilot
|
|
||||||
timeout-minutes: 30
|
|
||||||
|
|
||||||
build_mac:
|
build_mac:
|
||||||
name: build macOS
|
name: build macOS
|
||||||
runs-on: ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-macos-8x14' || 'macos-latest' }}
|
runs-on: ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-macos-8x14' || 'macos-latest' }}
|
||||||
if: false # There'll be one day that this works. That day is not today.
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v7
|
||||||
with:
|
- name: Remove Homebrew from environment
|
||||||
submodules: true
|
run: |
|
||||||
- run: echo "CACHE_COMMIT_DATE=$(git log -1 --pretty='format:%cd' --date=format:'%Y-%m-%d-%H:%M')" >> $GITHUB_ENV
|
FILTERED=$(echo "$PATH" | tr ':' '\n' | grep -v '/opt/homebrew' | tr '\n' ':')
|
||||||
- name: Homebrew cache
|
echo "PATH=${FILTERED}/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" >> $GITHUB_ENV
|
||||||
uses: ./.github/workflows/auto-cache
|
- run: ./tools/op.sh setup
|
||||||
with:
|
|
||||||
save: false # No need save here if we manually save it later conditionally
|
|
||||||
path: ~/Library/Caches/Homebrew
|
|
||||||
key: brew-macos-${{ hashFiles('tools/Brewfile') }}-${{ github.sha }}
|
|
||||||
restore-keys: |
|
|
||||||
brew-macos-${{ hashFiles('tools/Brewfile') }}
|
|
||||||
brew-macos-
|
|
||||||
- name: Install dependencies
|
|
||||||
run: ./tools/mac_setup.sh
|
|
||||||
env:
|
|
||||||
PYTHONWARNINGS: default # package install has DeprecationWarnings
|
|
||||||
HOMEBREW_DISPLAY_INSTALL_TIMES: 1
|
|
||||||
- name: Save Homebrew cache
|
|
||||||
uses: actions/cache/save@v4
|
|
||||||
if: github.ref == 'refs/heads/master'
|
|
||||||
with:
|
|
||||||
path: ~/Library/Caches/Homebrew
|
|
||||||
key: brew-macos-${{ hashFiles('tools/Brewfile') }}-${{ github.sha }}
|
|
||||||
- run: git lfs pull
|
|
||||||
- name: Getting scons cache
|
|
||||||
uses: ./.github/workflows/auto-cache
|
|
||||||
with:
|
|
||||||
save: false # No need save here if we manually save it later conditionally
|
|
||||||
path: /tmp/scons_cache
|
|
||||||
key: scons-${{ runner.arch }}-macos-${{ env.CACHE_COMMIT_DATE }}-${{ github.sha }}
|
|
||||||
restore-keys: |
|
|
||||||
scons-${{ runner.arch }}-macos-${{ env.CACHE_COMMIT_DATE }}
|
|
||||||
scons-${{ runner.arch }}-macos
|
|
||||||
- name: Building openpilot
|
- name: Building openpilot
|
||||||
run: . .venv/bin/activate && scons -j$(nproc)
|
run: scons
|
||||||
- name: Save scons cache
|
|
||||||
uses: actions/cache/save@v4
|
|
||||||
if: github.ref == 'refs/heads/master'
|
|
||||||
with:
|
|
||||||
path: /tmp/scons_cache
|
|
||||||
key: scons-${{ runner.arch }}-macos-${{ env.CACHE_COMMIT_DATE }}-${{ github.sha }}
|
|
||||||
|
|
||||||
static_analysis:
|
static_analysis:
|
||||||
name: static analysis
|
name: static analysis
|
||||||
@@ -159,18 +96,14 @@ jobs:
|
|||||||
(github.repository == 'commaai/openpilot') &&
|
(github.repository == 'commaai/openpilot') &&
|
||||||
((github.event_name != 'pull_request') ||
|
((github.event_name != 'pull_request') ||
|
||||||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))
|
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))
|
||||||
&& fromJSON('["namespace-profile-amd64-8x16", "namespace-experiments:docker.builds.local-cache=separate"]')
|
&& fromJSON('["namespace-profile-amd64-8x16"]')
|
||||||
|| fromJSON('["ubuntu-24.04"]') }}
|
|| fromJSON('["ubuntu-24.04"]') }}
|
||||||
env:
|
|
||||||
PYTHONWARNINGS: default
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v7
|
||||||
with:
|
- run: ./tools/op.sh setup
|
||||||
submodules: true
|
|
||||||
- uses: ./.github/workflows/setup-with-retry
|
|
||||||
- name: Static analysis
|
- name: Static analysis
|
||||||
timeout-minutes: 1
|
timeout-minutes: 1
|
||||||
run: ${{ env.RUN }} "scripts/lint/lint.sh"
|
run: scripts/lint/lint.sh
|
||||||
|
|
||||||
unit_tests:
|
unit_tests:
|
||||||
name: unit tests
|
name: unit tests
|
||||||
@@ -178,24 +111,24 @@ jobs:
|
|||||||
(github.repository == 'commaai/openpilot') &&
|
(github.repository == 'commaai/openpilot') &&
|
||||||
((github.event_name != 'pull_request') ||
|
((github.event_name != 'pull_request') ||
|
||||||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))
|
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))
|
||||||
&& fromJSON('["namespace-profile-amd64-8x16", "namespace-experiments:docker.builds.local-cache=separate"]')
|
&& fromJSON('["namespace-profile-amd64-8x16"]')
|
||||||
|| fromJSON('["ubuntu-24.04"]') }}
|
|| fromJSON('["ubuntu-24.04"]') }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v7
|
||||||
with:
|
- run: ./tools/op.sh setup
|
||||||
submodules: true
|
- name: Install raylib headless dependencies
|
||||||
- uses: ./.github/workflows/setup-with-retry
|
if: ${{ !contains(runner.name, 'nsc') }}
|
||||||
id: setup-step
|
run: sudo apt-get install -y --no-install-recommends libgles2 libegl1
|
||||||
- name: Build openpilot
|
- name: Build openpilot
|
||||||
run: ${{ env.RUN }} "scons -j$(nproc)"
|
run: scons
|
||||||
- name: Run unit tests
|
- name: Run unit tests
|
||||||
timeout-minutes: ${{ contains(runner.name, 'nsc') && ((steps.setup-step.outputs.duration < 18) && 1 || 2) || 999 }}
|
timeout-minutes: ${{ contains(runner.name, 'nsc') && 2 || 999 }}
|
||||||
|
env:
|
||||||
|
RAYLIB_BACKEND: headless
|
||||||
run: |
|
run: |
|
||||||
${{ env.RUN }} "source selfdrive/test/setup_xvfb.sh && \
|
# Pre-compile Python bytecode so each pytest worker doesn't need to
|
||||||
# Pre-compile Python bytecode so each pytest worker doesn't need to
|
$PYTEST --collect-only -m 'not slow' -qq
|
||||||
$PYTEST --collect-only -m 'not slow' -qq && \
|
MAX_EXAMPLES=1 $PYTEST -m 'not slow'
|
||||||
MAX_EXAMPLES=1 $PYTEST -m 'not slow' && \
|
|
||||||
chmod -R 777 /tmp/comma_download_cache"
|
|
||||||
|
|
||||||
process_replay:
|
process_replay:
|
||||||
name: process replay
|
name: process replay
|
||||||
@@ -204,48 +137,69 @@ jobs:
|
|||||||
(github.repository == 'commaai/openpilot') &&
|
(github.repository == 'commaai/openpilot') &&
|
||||||
((github.event_name != 'pull_request') ||
|
((github.event_name != 'pull_request') ||
|
||||||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))
|
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))
|
||||||
&& fromJSON('["namespace-profile-amd64-8x16", "namespace-experiments:docker.builds.local-cache=separate"]')
|
&& fromJSON('["namespace-profile-amd64-8x16"]')
|
||||||
|| fromJSON('["ubuntu-24.04"]') }}
|
|| fromJSON('["ubuntu-24.04"]') }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v7
|
||||||
with:
|
- run: ./tools/op.sh setup
|
||||||
submodules: true
|
|
||||||
- uses: ./.github/workflows/setup-with-retry
|
|
||||||
id: setup-step
|
|
||||||
- name: Cache test routes
|
|
||||||
id: dependency-cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: .ci_cache/comma_download_cache
|
|
||||||
key: proc-replay-${{ hashFiles('selfdrive/test/process_replay/ref_commit', 'selfdrive/test/process_replay/test_processes.py') }}
|
|
||||||
- name: Build openpilot
|
- name: Build openpilot
|
||||||
run: |
|
run: scons
|
||||||
${{ env.RUN }} "scons -j$(nproc)"
|
|
||||||
- name: Run replay
|
- name: Run replay
|
||||||
timeout-minutes: ${{ contains(runner.name, 'nsc') && (steps.dependency-cache.outputs.cache-hit == 'true') && ((steps.setup-step.outputs.duration < 18) && 1 || 2) || 20 }}
|
timeout-minutes: ${{ contains(runner.name, 'nsc') && 2 || 20 }}
|
||||||
run: |
|
continue-on-error: ${{ github.ref == 'refs/heads/master' }}
|
||||||
${{ env.RUN }} "selfdrive/test/process_replay/test_processes.py -j$(nproc) && \
|
run: openpilot/selfdrive/test/process_replay/test_processes.py -j$(nproc)
|
||||||
chmod -R 777 /tmp/comma_download_cache"
|
|
||||||
- name: Print diff
|
- name: Print diff
|
||||||
id: print-diff
|
id: print-diff
|
||||||
if: always()
|
if: always()
|
||||||
run: cat selfdrive/test/process_replay/diff.txt
|
run: cat openpilot/selfdrive/test/process_replay/diff.txt
|
||||||
- uses: actions/upload-artifact@v4
|
- name: Print diff report
|
||||||
|
if: always()
|
||||||
|
run: cat openpilot/selfdrive/test/process_replay/diff_report.txt
|
||||||
|
- uses: actions/upload-artifact@v7
|
||||||
if: always()
|
if: always()
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
with:
|
with:
|
||||||
name: process_replay_diff.txt
|
name: process_replay_diff.txt
|
||||||
path: selfdrive/test/process_replay/diff.txt
|
path: openpilot/selfdrive/test/process_replay/diff.txt
|
||||||
- name: Upload reference logs
|
- name: Upload diff report
|
||||||
if: false # TODO: move this to github instead of azure
|
uses: actions/upload-artifact@v7
|
||||||
|
if: always() && github.event_name == 'pull_request'
|
||||||
|
continue-on-error: true
|
||||||
|
with:
|
||||||
|
name: diff_report_${{ github.event.number }}
|
||||||
|
path: openpilot/selfdrive/test/process_replay/diff_report.txt
|
||||||
|
- name: Checkout ci-artifacts
|
||||||
|
if: github.repository == 'commaai/openpilot' && github.ref == 'refs/heads/master'
|
||||||
|
uses: actions/checkout@v7
|
||||||
|
with:
|
||||||
|
repository: commaai/ci-artifacts
|
||||||
|
ssh-key: ${{ secrets.CI_ARTIFACTS_DEPLOY_KEY }}
|
||||||
|
path: ${{ github.workspace }}/ci-artifacts
|
||||||
|
- name: Prepare refs
|
||||||
|
if: github.repository == 'commaai/openpilot' && github.ref == 'refs/heads/master'
|
||||||
|
working-directory: ${{ github.workspace }}/ci-artifacts
|
||||||
run: |
|
run: |
|
||||||
${{ env.RUN }} "unset PYTHONWARNINGS && AZURE_TOKEN='$AZURE_TOKEN' python3 selfdrive/test/process_replay/test_processes.py -j$(nproc) --upload-only"
|
git config user.name "GitHub Actions Bot"
|
||||||
|
git config user.email "<>"
|
||||||
|
git fetch origin process-replay || true
|
||||||
|
git checkout process-replay 2>/dev/null || git checkout --orphan process-replay
|
||||||
|
cp ${{ github.workspace }}/openpilot/selfdrive/test/process_replay/fakedata/*.zst .
|
||||||
|
echo "${{ github.sha }}" > ref_commit
|
||||||
|
git add .
|
||||||
|
git commit -m "process-replay refs for ${{ github.repository }}@${{ github.sha }}" || echo "No changes to commit"
|
||||||
|
- name: Push refs
|
||||||
|
if: github.repository == 'commaai/openpilot' && github.ref == 'refs/heads/master'
|
||||||
|
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60
|
||||||
|
with:
|
||||||
|
timeout_minutes: 2
|
||||||
|
max_attempts: 3
|
||||||
|
command: cd ${{ github.workspace }}/ci-artifacts && git push origin process-replay --force
|
||||||
- name: Run regen
|
- name: Run regen
|
||||||
if: false
|
if: false
|
||||||
timeout-minutes: 4
|
timeout-minutes: 4
|
||||||
run: |
|
env:
|
||||||
${{ env.RUN }} "ONNXCPU=1 $PYTEST selfdrive/test/process_replay/test_regen.py && \
|
ONNXCPU: 1
|
||||||
chmod -R 777 /tmp/comma_download_cache"
|
run: $PYTEST openpilot/selfdrive/test/process_replay/test_regen.py
|
||||||
|
|
||||||
simulator_driving:
|
simulator_driving:
|
||||||
name: simulator driving
|
name: simulator driving
|
||||||
@@ -253,73 +207,45 @@ jobs:
|
|||||||
(github.repository == 'commaai/openpilot') &&
|
(github.repository == 'commaai/openpilot') &&
|
||||||
((github.event_name != 'pull_request') ||
|
((github.event_name != 'pull_request') ||
|
||||||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))
|
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))
|
||||||
&& fromJSON('["namespace-profile-amd64-8x16", "namespace-experiments:docker.builds.local-cache=separate"]')
|
&& fromJSON('["namespace-profile-amd64-8x16"]')
|
||||||
|| fromJSON('["ubuntu-24.04"]') }}
|
|| fromJSON('["ubuntu-24.04"]') }}
|
||||||
if: false # FIXME: Started to timeout recently
|
if: false # FIXME: Started to timeout recently
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v7
|
||||||
with:
|
- run: ./tools/op.sh setup
|
||||||
submodules: true
|
|
||||||
- uses: ./.github/workflows/setup-with-retry
|
|
||||||
id: setup-step
|
|
||||||
- name: Build openpilot
|
- name: Build openpilot
|
||||||
run: |
|
run: scons
|
||||||
${{ env.RUN }} "scons -j$(nproc)"
|
|
||||||
- name: Driving test
|
- name: Driving test
|
||||||
timeout-minutes: ${{ (steps.setup-step.outputs.duration < 18) && 1 || 2 }}
|
timeout-minutes: 2
|
||||||
run: |
|
env:
|
||||||
${{ env.RUN }} "source selfdrive/test/setup_xvfb.sh && \
|
# MetaDrive renders offscreen through panda3d's EGL pipe on llvmpipe
|
||||||
source selfdrive/test/setup_vsound.sh && \
|
EGL_PLATFORM: surfaceless
|
||||||
CI=1 pytest -s tools/sim/tests/test_metadrive_bridge.py"
|
run: pytest -s openpilot/tools/sim/tests/test_metadrive_bridge.py
|
||||||
|
|
||||||
create_raylib_ui_report:
|
create_ui_report:
|
||||||
name: Create raylib UI Report
|
name: Create UI Report
|
||||||
runs-on: ${{
|
runs-on: ${{
|
||||||
(github.repository == 'commaai/openpilot') &&
|
(github.repository == 'commaai/openpilot') &&
|
||||||
((github.event_name != 'pull_request') ||
|
((github.event_name != 'pull_request') ||
|
||||||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))
|
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))
|
||||||
&& fromJSON('["namespace-profile-amd64-8x16", "namespace-experiments:docker.builds.local-cache=separate"]')
|
&& fromJSON('["namespace-profile-amd64-8x16"]')
|
||||||
|| fromJSON('["ubuntu-24.04"]') }}
|
|| fromJSON('["ubuntu-24.04"]') }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v7
|
||||||
with:
|
- run: ./tools/op.sh setup
|
||||||
submodules: true
|
- name: Install raylib headless dependencies
|
||||||
- uses: ./.github/workflows/setup-with-retry
|
if: ${{ !contains(runner.name, 'nsc') }}
|
||||||
|
run: sudo apt-get install -y --no-install-recommends libgles2 libegl1
|
||||||
- name: Build openpilot
|
- name: Build openpilot
|
||||||
run: ${{ env.RUN }} "scons -j$(nproc)"
|
run: scons
|
||||||
- name: Create raylib UI Report
|
- name: Create UI Report
|
||||||
run: >
|
env:
|
||||||
${{ env.RUN }} "PYTHONWARNINGS=ignore &&
|
RAYLIB_BACKEND: headless
|
||||||
source selfdrive/test/setup_xvfb.sh &&
|
run: |
|
||||||
python3 selfdrive/ui/tests/test_ui/raylib_screenshots.py"
|
python3 openpilot/selfdrive/ui/tests/diff/replay.py
|
||||||
- name: Upload Raylib UI Report
|
python3 openpilot/selfdrive/ui/tests/diff/replay.py --big
|
||||||
uses: actions/upload-artifact@v4
|
- name: Upload UI Report
|
||||||
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: raylib-report-${{ inputs.run_number || '1' }}-${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && 'master' || github.event.number }}
|
name: ui-report-${{ inputs.run_number || '1' }}-${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && 'master' || github.event.number }}
|
||||||
path: selfdrive/ui/tests/test_ui/raylib_report/screenshots
|
path: openpilot/selfdrive/ui/tests/diff/report
|
||||||
|
|
||||||
create_mici_raylib_ui_report:
|
|
||||||
name: Create mici raylib UI Report
|
|
||||||
runs-on: ${{
|
|
||||||
(github.repository == 'commaai/openpilot') &&
|
|
||||||
((github.event_name != 'pull_request') ||
|
|
||||||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))
|
|
||||||
&& fromJSON('["namespace-profile-amd64-8x16", "namespace-experiments:docker.builds.local-cache=separate"]')
|
|
||||||
|| fromJSON('["ubuntu-24.04"]') }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
- uses: ./.github/workflows/setup-with-retry
|
|
||||||
- name: Build openpilot
|
|
||||||
run: ${{ env.RUN }} "scons -j$(nproc)"
|
|
||||||
- name: Create mici raylib UI Report
|
|
||||||
run: >
|
|
||||||
${{ env.RUN }} "PYTHONWARNINGS=ignore &&
|
|
||||||
source selfdrive/test/setup_xvfb.sh &&
|
|
||||||
WINDOWED=1 python3 selfdrive/ui/tests/diff/replay.py"
|
|
||||||
- name: Upload Raylib UI Report
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: mici-raylib-report-${{ inputs.run_number || '1' }}-${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && 'master' || github.event.number }}
|
|
||||||
path: selfdrive/ui/tests/diff/report
|
|
||||||
|
|||||||
@@ -0,0 +1,175 @@
|
|||||||
|
name: "ui preview"
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
pull_request_target:
|
||||||
|
types: [assigned, opened, synchronize, reopened, edited]
|
||||||
|
branches:
|
||||||
|
- 'master'
|
||||||
|
paths:
|
||||||
|
- 'openpilot/selfdrive/assets/**'
|
||||||
|
- 'openpilot/selfdrive/ui/**'
|
||||||
|
- 'openpilot/system/ui/**'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
UI_JOB_NAME: "Create UI Report"
|
||||||
|
REPORT_NAME: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && 'master' || github.event.number }}
|
||||||
|
SHA: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && github.sha || github.event.pull_request.head.sha }}
|
||||||
|
BRANCH_NAME: "openpilot/pr-${{ github.event.number }}-ui-preview"
|
||||||
|
REPORT_FILES_BRANCH_NAME: "mici-raylib-ui-reports"
|
||||||
|
|
||||||
|
# variant:video_prefix:master_branch
|
||||||
|
VARIANTS: "mici:mici_ui_replay:openpilot_master_ui_mici_raylib big:tizi_ui_replay:openpilot_master_ui_big_raylib"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
preview:
|
||||||
|
if: github.repository == 'sunnypilot/sunnypilot'
|
||||||
|
name: preview
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 20
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: write
|
||||||
|
actions: read
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v7
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
|
||||||
|
- name: Waiting for ui generation to end
|
||||||
|
uses: lewagon/wait-on-check-action@1d57e2c51a58d812d2765e036a028b6bdb5a6154
|
||||||
|
with:
|
||||||
|
ref: ${{ env.SHA }}
|
||||||
|
check-name: ${{ env.UI_JOB_NAME }}
|
||||||
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
allowed-conclusions: success
|
||||||
|
wait-interval: 20
|
||||||
|
|
||||||
|
- name: Getting workflow run ID
|
||||||
|
id: get_run_id
|
||||||
|
run: |
|
||||||
|
echo "run_id=$(curl https://api.github.com/repos/${{ github.repository }}/commits/${{ env.SHA }}/check-runs | jq -r '.check_runs[] | select(.name == "${{ env.UI_JOB_NAME }}") | .html_url | capture("(?<number>[0-9]+)") | .number')" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Getting proposed ui
|
||||||
|
uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run_id: ${{ steps.get_run_id.outputs.run_id }}
|
||||||
|
search_artifacts: true
|
||||||
|
name: ui-report-1-${{ env.REPORT_NAME }}
|
||||||
|
path: ${{ github.workspace }}/pr_ui
|
||||||
|
|
||||||
|
- name: Getting mici master ui
|
||||||
|
uses: actions/checkout@v7
|
||||||
|
with:
|
||||||
|
repository: sunnypilot/ci-artifacts
|
||||||
|
ssh-key: ${{ secrets.CI_ARTIFACTS_DEPLOY_KEY }}
|
||||||
|
path: ${{ github.workspace }}/master_mici
|
||||||
|
ref: openpilot_master_ui_mici_raylib
|
||||||
|
|
||||||
|
- name: Getting big master ui
|
||||||
|
uses: actions/checkout@v7
|
||||||
|
with:
|
||||||
|
repository: sunnypilot/ci-artifacts
|
||||||
|
ssh-key: ${{ secrets.CI_ARTIFACTS_DEPLOY_KEY }}
|
||||||
|
path: ${{ github.workspace }}/master_big
|
||||||
|
ref: openpilot_master_ui_big_raylib
|
||||||
|
|
||||||
|
- name: Saving new master ui
|
||||||
|
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
|
||||||
|
run: |
|
||||||
|
for variant in $VARIANTS; do
|
||||||
|
IFS=':' read -r name video branch <<< "$variant"
|
||||||
|
master_dir="${{ github.workspace }}/master_${name}"
|
||||||
|
cd "$master_dir"
|
||||||
|
git checkout --orphan=new_branch
|
||||||
|
git rm -rf *
|
||||||
|
git branch -D "$branch"
|
||||||
|
git branch -m "$branch"
|
||||||
|
git config user.name "GitHub Actions Bot"
|
||||||
|
git config user.email "<>"
|
||||||
|
cp "${{ github.workspace }}/pr_ui/${video}.mp4" .
|
||||||
|
git add .
|
||||||
|
git commit -m "${name} video for commit ${{ env.SHA }}"
|
||||||
|
git push origin "$branch" --force
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Setup FFmpeg
|
||||||
|
uses: AnimMouse/setup-ffmpeg@178e0b4a408f06ce40d896c3cd79f50fa6f8b0c3
|
||||||
|
|
||||||
|
- name: Finding diffs
|
||||||
|
if: github.event_name == 'pull_request_target'
|
||||||
|
id: find_diff
|
||||||
|
run: |
|
||||||
|
export PYTHONPATH=${{ github.workspace }}
|
||||||
|
baseurl="https://github.com/sunnypilot/ci-artifacts/raw/refs/heads/${{ env.BRANCH_NAME }}"
|
||||||
|
|
||||||
|
COMMENT=""
|
||||||
|
for variant in $VARIANTS; do
|
||||||
|
IFS=':' read -r name video _ <<< "$variant"
|
||||||
|
diff_name="${name}_diff"
|
||||||
|
|
||||||
|
mv "${{ github.workspace }}/pr_ui/${video}.mp4" "${{ github.workspace }}/pr_ui/${video}_proposed.mp4"
|
||||||
|
cp "${{ github.workspace }}/master_${name}/${video}.mp4" "${{ github.workspace }}/pr_ui/${video}_master.mp4"
|
||||||
|
|
||||||
|
diff_exit_code=0
|
||||||
|
python3 ${{ github.workspace }}/openpilot/selfdrive/ui/tests/diff/diff.py \
|
||||||
|
"${{ github.workspace }}/pr_ui/${video}_master.mp4" \
|
||||||
|
"${{ github.workspace }}/pr_ui/${video}_proposed.mp4" \
|
||||||
|
"${diff_name}.html" --basedir "$baseurl" --no-open || diff_exit_code=$?
|
||||||
|
|
||||||
|
cp "${{ github.workspace }}/openpilot/selfdrive/ui/tests/diff/report/${diff_name}.html" "${{ github.workspace }}/pr_ui/"
|
||||||
|
cp "${{ github.workspace }}/openpilot/selfdrive/ui/tests/diff/report/${diff_name}.mp4" "${{ github.workspace }}/pr_ui/"
|
||||||
|
|
||||||
|
REPORT_URL="https://sunnypilot.github.io/ci-artifacts/${diff_name}_pr_${{ github.event.number }}.html"
|
||||||
|
if [ $diff_exit_code -eq 0 ]; then
|
||||||
|
COMMENT+="**${name}**: Videos are identical! [View Diff Report]($REPORT_URL)"$'\n'
|
||||||
|
else
|
||||||
|
COMMENT+="**${name}**: ⚠️ <strong>Videos differ!</strong> [View Diff Report]($REPORT_URL)"$'\n'
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "COMMENT<<EOF"
|
||||||
|
echo "$COMMENT"
|
||||||
|
echo "EOF"
|
||||||
|
} >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Saving proposed ui
|
||||||
|
if: github.event_name == 'pull_request_target'
|
||||||
|
working-directory: ${{ github.workspace }}/master_mici
|
||||||
|
run: |
|
||||||
|
git config user.name "GitHub Actions Bot"
|
||||||
|
git config user.email "<>"
|
||||||
|
git checkout --orphan=${{ env.BRANCH_NAME }}
|
||||||
|
git rm -rf *
|
||||||
|
mv ${{ github.workspace }}/pr_ui/* .
|
||||||
|
git add .
|
||||||
|
git commit -m "ui videos for PR #${{ github.event.number }}"
|
||||||
|
git push origin ${{ env.BRANCH_NAME }} --force
|
||||||
|
|
||||||
|
# Append diff reports to report files branch
|
||||||
|
git fetch origin ${{ env.REPORT_FILES_BRANCH_NAME }}
|
||||||
|
git checkout ${{ env.REPORT_FILES_BRANCH_NAME }}
|
||||||
|
for variant in $VARIANTS; do
|
||||||
|
IFS=':' read -r name _ _ <<< "$variant"
|
||||||
|
diff_name="${name}_diff"
|
||||||
|
cp "${{ github.workspace }}/openpilot/selfdrive/ui/tests/diff/report/${diff_name}.html" "${diff_name}_pr_${{ github.event.number }}.html"
|
||||||
|
git add "${diff_name}_pr_${{ github.event.number }}.html"
|
||||||
|
done
|
||||||
|
git commit -m "ui diff reports for PR #${{ github.event.number }}" || echo "No changes to commit"
|
||||||
|
git push origin ${{ env.REPORT_FILES_BRANCH_NAME }}
|
||||||
|
|
||||||
|
- name: Comment on PR
|
||||||
|
if: github.event_name == 'pull_request_target'
|
||||||
|
uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b
|
||||||
|
with:
|
||||||
|
message: |
|
||||||
|
<!-- _(run_id_ui_preview **${{ github.run_id }}**)_ -->
|
||||||
|
## UI Preview
|
||||||
|
${{ steps.find_diff.outputs.COMMENT }}
|
||||||
|
comment-tag: run_id_ui_preview
|
||||||
|
pr-number: ${{ github.event.number }}
|
||||||
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
+33
-34
@@ -13,13 +13,20 @@ venv/
|
|||||||
a.out
|
a.out
|
||||||
.hypothesis
|
.hypothesis
|
||||||
.cache/
|
.cache/
|
||||||
|
bin/
|
||||||
|
|
||||||
/docs_site/
|
# created at launch for TICI PYTHONPATH (PC uses editable installs via pyproject.toml)
|
||||||
|
/msgq
|
||||||
|
/opendbc
|
||||||
|
/rednose
|
||||||
|
/teleoprtc
|
||||||
|
/tinygrad
|
||||||
|
|
||||||
*.mp4
|
*.mp4
|
||||||
*.dylib
|
*.dylib
|
||||||
*.DSYM
|
*.DSYM
|
||||||
*.d
|
*.d
|
||||||
|
*.pem
|
||||||
*.pyc
|
*.pyc
|
||||||
*.pyo
|
*.pyo
|
||||||
.*.swp
|
.*.swp
|
||||||
@@ -39,65 +46,57 @@ a.out
|
|||||||
*.mo
|
*.mo
|
||||||
*_pyx.cpp
|
*_pyx.cpp
|
||||||
*.stats
|
*.stats
|
||||||
|
*.pkl
|
||||||
|
*.pkl*
|
||||||
config.json
|
config.json
|
||||||
clcache
|
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
compare_runtime*.html
|
compare_runtime*.html
|
||||||
|
openpilot/selfdrive/modeld/models/tg_input_devices.json
|
||||||
|
|
||||||
selfdrive/pandad/pandad
|
# build artifacts
|
||||||
cereal/services.h
|
docs_site/
|
||||||
cereal/gen
|
openpilot/selfdrive/pandad/pandad
|
||||||
cereal/messaging/bridge
|
openpilot/cereal/services.h
|
||||||
selfdrive/ui/translations/tmp
|
openpilot/cereal/gen
|
||||||
selfdrive/car/tests/cars_dump
|
openpilot/cereal/messaging/bridge
|
||||||
system/camerad/camerad
|
openpilot/selfdrive/ui/translations/tmp
|
||||||
system/camerad/test/ae_gray_test
|
openpilot/selfdrive/car/tests/cars_dump
|
||||||
|
openpilot/system/camerad/camerad
|
||||||
|
openpilot/system/camerad/test/ae_gray_test
|
||||||
|
|
||||||
.coverage*
|
.coverage*
|
||||||
coverage.xml
|
coverage.xml
|
||||||
htmlcov
|
htmlcov
|
||||||
pandaextra
|
|
||||||
|
|
||||||
.mypy_cache/
|
|
||||||
flycheck_*
|
|
||||||
|
|
||||||
cppcheck_report.txt
|
|
||||||
comma*.sh
|
|
||||||
|
|
||||||
selfdrive/modeld/models/*.pkl
|
|
||||||
sunnypilot/modeld*/thneed/compile
|
|
||||||
sunnypilot/modeld*/models/*.thneed
|
|
||||||
sunnypilot/modeld*/models/*.pkl
|
|
||||||
|
|
||||||
# openpilot log files
|
# openpilot log files
|
||||||
*.bz2
|
*.bz2
|
||||||
*.zst
|
*.zst
|
||||||
|
*.rlog
|
||||||
|
|
||||||
build/
|
build/
|
||||||
|
|
||||||
!**/.gitkeep
|
!**/.gitkeep
|
||||||
|
|
||||||
poetry.toml
|
|
||||||
Pipfile
|
|
||||||
|
|
||||||
### VisualStudioCode ###
|
### VisualStudioCode ###
|
||||||
|
*.vsix
|
||||||
|
.history
|
||||||
|
.ionide
|
||||||
.vscode/*
|
.vscode/*
|
||||||
|
.history/
|
||||||
!.vscode/settings.json
|
!.vscode/settings.json
|
||||||
!.vscode/tasks.json
|
!.vscode/tasks.json
|
||||||
!.vscode/launch.json
|
!.vscode/launch.json
|
||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
!.vscode/*.code-snippets
|
!.vscode/*.code-snippets
|
||||||
|
|
||||||
# Local History for Visual Studio Code
|
# agents
|
||||||
.history/
|
.claude/
|
||||||
|
.context/
|
||||||
# Built Visual Studio Code Extensions
|
PLAN.md
|
||||||
*.vsix
|
TASK.md
|
||||||
|
CLAUDE.md
|
||||||
### VisualStudioCode Patch ###
|
SKILL.md
|
||||||
# Ignore all local history of files
|
|
||||||
.history
|
|
||||||
.ionide
|
|
||||||
|
|
||||||
### JetBrains ###
|
### JetBrains ###
|
||||||
!.idea/customTargets.xml
|
!.idea/customTargets.xml
|
||||||
|
|||||||
+3
-3
@@ -6,7 +6,7 @@
|
|||||||
url = https://github.com/sunnypilot/opendbc.git
|
url = https://github.com/sunnypilot/opendbc.git
|
||||||
[submodule "msgq"]
|
[submodule "msgq"]
|
||||||
path = msgq_repo
|
path = msgq_repo
|
||||||
url = https://github.com/commaai/msgq.git
|
url = https://github.com/sunnypilot/msgq.git
|
||||||
[submodule "rednose_repo"]
|
[submodule "rednose_repo"]
|
||||||
path = rednose_repo
|
path = rednose_repo
|
||||||
url = https://github.com/commaai/rednose.git
|
url = https://github.com/commaai/rednose.git
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
url = https://github.com/commaai/teleoprtc
|
url = https://github.com/commaai/teleoprtc
|
||||||
[submodule "tinygrad"]
|
[submodule "tinygrad"]
|
||||||
path = tinygrad_repo
|
path = tinygrad_repo
|
||||||
url = https://github.com/commaai/tinygrad.git
|
url = https://github.com/sunnypilot/tinygrad.git
|
||||||
[submodule "sunnypilot/neural_network_data"]
|
[submodule "sunnypilot/neural_network_data"]
|
||||||
path = sunnypilot/neural_network_data
|
path = openpilot/sunnypilot/neural_network_data
|
||||||
url = https://github.com/sunnypilot/neural-network-data.git
|
url = https://github.com/sunnypilot/neural-network-data.git
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
3.12.13
|
||||||
Vendored
+7
-4
@@ -6,9 +6,9 @@
|
|||||||
"type": "pickString",
|
"type": "pickString",
|
||||||
"description": "Select the process to debug",
|
"description": "Select the process to debug",
|
||||||
"options": [
|
"options": [
|
||||||
"selfdrive/controls/controlsd.py",
|
"openpilot/selfdrive/controls/controlsd.py",
|
||||||
"system/timed/timed.py",
|
"openpilot/system/timed/timed.py",
|
||||||
"tools/sim/run_bridge.py"
|
"openpilot/tools/sim/run_bridge.py"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
"type": "pickString",
|
"type": "pickString",
|
||||||
"description": "Select the process to debug",
|
"description": "Select the process to debug",
|
||||||
"options": [
|
"options": [
|
||||||
"selfdrive/ui/ui"
|
"openpilot/selfdrive/ui/ui"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -52,6 +52,9 @@
|
|||||||
"type": "lldb",
|
"type": "lldb",
|
||||||
"request": "attach",
|
"request": "attach",
|
||||||
"pid": "${command:pickMyProcess}",
|
"pid": "${command:pickMyProcess}",
|
||||||
|
"sourceMap": {
|
||||||
|
".": "${workspaceFolder}/opendbc/safety"
|
||||||
|
},
|
||||||
"initCommands": [
|
"initCommands": [
|
||||||
"script import time; time.sleep(3)"
|
"script import time; time.sleep(3)"
|
||||||
]
|
]
|
||||||
|
|||||||
Vendored
-6
@@ -17,11 +17,5 @@
|
|||||||
"**/.git",
|
"**/.git",
|
||||||
"**/.venv",
|
"**/.venv",
|
||||||
"**/__pycache__",
|
"**/__pycache__",
|
||||||
// exclude directories that should be using the symlinked version
|
|
||||||
"common/**",
|
|
||||||
"selfdrive/**",
|
|
||||||
"system/**",
|
|
||||||
"third_party/**",
|
|
||||||
"tools/**",
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
+217
-1
@@ -1,5 +1,221 @@
|
|||||||
sunnypilot Version 2025.003.000 (20xx-xx-xx)
|
sunnypilot Version 2026.002.000 (2026-06-28)
|
||||||
========================
|
========================
|
||||||
|
* What's Changed (sunnypilot/sunnypilot)
|
||||||
|
* ui: update gates for certain toggles by @sunnyhaibin in https://github.com/sunnypilot/sunnypilot/pull/1830
|
||||||
|
* release: ignore upstream IsReleaseBranch by @sunnyhaibin in https://github.com/sunnypilot/sunnypilot/pull/1831
|
||||||
|
* manager: disable DEVELOPMENT_ONLY reset by @sunnyhaibin in https://github.com/sunnypilot/sunnypilot/pull/1833
|
||||||
|
* sunnylink: fix max time offroad values by @nayan8teen in https://github.com/sunnypilot/sunnypilot/pull/1835
|
||||||
|
* ui: show default model name by @nayan8teen in https://github.com/sunnypilot/sunnypilot/pull/1837
|
||||||
|
* sunnylink: add CarParams fallback for brand-specific capabilities by @sunnyhaibin in https://github.com/sunnypilot/sunnypilot/pull/1839
|
||||||
|
* sunnylink SDUI: tweak DisableUpdate param for clarity by @sunnyhaibin in https://github.com/sunnypilot/sunnypilot/pull/1842
|
||||||
|
* Revert "DM: Lancia Delta HF Integrale model" by @sunnyhaibin in https://github.com/sunnypilot/sunnypilot/pull/1849
|
||||||
|
* modeld_v2: safe model validation by @Discountchubbs in https://github.com/sunnypilot/sunnypilot/pull/1855
|
||||||
|
* Revert "deprecate `carState.brake`" for Honda Gas Interceptor by @mvl-boston in https://github.com/sunnypilot/sunnypilot/pull/1860
|
||||||
|
* sunnylink: deprecate legacy params metadata by @sunnyhaibin in https://github.com/sunnypilot/sunnypilot/pull/1862
|
||||||
|
* ui: reset Enforce Torque Control and NNLC if both are enabled by @sunnyhaibin in https://github.com/sunnypilot/sunnypilot/pull/1863
|
||||||
|
* What's Changed (sunnypilot/opendbc)
|
||||||
|
* Rivian: suppress ACM hold-the-wheel warning during MADS-only lateral by @lukasloetkolben in https://github.com/sunnypilot/opendbc/pull/465
|
||||||
|
* Sync: `commaai/opendbc:master` → `sunnypilot/opendbc:master` by @sunnyhaibin in https://github.com/sunnypilot/opendbc/pull/479
|
||||||
|
* safety: add option to ignore frequency check for RX checks by @sunnyhaibin in https://github.com/sunnypilot/opendbc/pull/480
|
||||||
|
* Revert "deprecate carState.brake" for Honda Gas Interceptor by @mvl-boston in https://github.com/sunnypilot/opendbc/pull/481
|
||||||
|
* New Contributors (sunnypilot/sunnypilot)
|
||||||
|
* @mvl-boston made their first contribution in https://github.com/sunnypilot/sunnypilot/pull/1860
|
||||||
|
* Full Changelog: https://github.com/sunnypilot/sunnypilot/compare/v2026.001.007...v2026.002.000
|
||||||
|
************************
|
||||||
|
* Synced with commaai's openpilot (v0.11.1)
|
||||||
|
* master commit 69e2c321e49760e52f7983eaa0a5f77cb95de637 (June 02, 2026)
|
||||||
|
* New driver monitoring model
|
||||||
|
* Improved image processing pipeline for driver camera
|
||||||
|
* Improved thermal policy for comma four
|
||||||
|
* Acura MDX 2022-24 support thanks to mvl-boston!
|
||||||
|
* Rivian R1S and R1T 2025 support thanks to lukasloetkolben!
|
||||||
|
|
||||||
|
sunnypilot Version 2026.001.000 (2026-05-06)
|
||||||
|
========================
|
||||||
|
* What's Changed (sunnypilot/sunnypilot)
|
||||||
|
* Complete rewrite of the user interface from Qt C++ to Raylib Python
|
||||||
|
* comma four support
|
||||||
|
* ui: sunnypilot toggle style by @nayan8teen
|
||||||
|
* ui: fix scroll panel mouse wheel behavior by @nayan8teen
|
||||||
|
* ui: sunnypilot panels by @nayan8teen
|
||||||
|
* sunnylink: centralize key pair handling in sunnylink registration by @devtekve
|
||||||
|
* ui: reimplement sunnypilot branding with Raylib by @sunnyhaibin
|
||||||
|
* ui: Platform Selector by @Discountchubbs
|
||||||
|
* ui: vehicle brand settings by @Discountchubbs
|
||||||
|
* ui: sunnylink client-side implementation by @nayan8teen
|
||||||
|
* ui: `NetworkUISP` by @Discountchubbs
|
||||||
|
* ui: add sunnypilot font by @nayan8teen
|
||||||
|
* ui: sunnypilot sponsor tier color mapping by @sunnyhaibin
|
||||||
|
* ui: sunnylink panel by @nayan8teen
|
||||||
|
* ui: Models panel by @Discountchubbs
|
||||||
|
* ui: software panel by @Discountchubbs
|
||||||
|
* modeld_v2: support planplus outputs by @Discountchubbs
|
||||||
|
* ui: OSM panel by @Discountchubbs
|
||||||
|
* ui: Developer panel extension by @Discountchubbs
|
||||||
|
* sunnylink: Vehicle Selector support by @sunnyhaibin
|
||||||
|
* [TIZI/TICI] ui: Developer Metrics by @rav4kumar
|
||||||
|
* [comma 4] ui: sunnylink panel by @nayan8teen
|
||||||
|
* ui: lateral-only and longitudinal-only UI statuses support by @royjr
|
||||||
|
* sunnylink: elliptic curve keys support and improve key path handling by @nayan8teen
|
||||||
|
* sunnylink: block remote modification of SSH key parameters by @zikeji
|
||||||
|
* [TIZI/TICI] ui: rainbow path by @rav4kumar
|
||||||
|
* [TIZI/TICI] ui: chevron metrics by @rav4kumar
|
||||||
|
* ui: include MADS enabled state to `engaged` check by @sunnyhaibin
|
||||||
|
* Toyota: Enforce Factory Longitudinal Control by @sunnyhaibin
|
||||||
|
* ui: fix malformed dongle ID display on the PC if dongleID is not set by @dzid26
|
||||||
|
* SL: Re enable and validate ingestion of swaglogs by @devtekve
|
||||||
|
* modeld_v2: planplus model tuning by @Discountchubbs
|
||||||
|
* ui: fix Always Offroad button visibility by @nayan8teen
|
||||||
|
* Reimplement sunnypilot Terms of Service & sunnylink Consent Screens by @sunnyhaibin
|
||||||
|
* [TIZI/TICI] ui: update dmoji position and Developer UI adjustments by @rav4kumar
|
||||||
|
* modeld: configurable camera offset by @Discountchubbs
|
||||||
|
* [TIZI/TICI] ui: sunnylink status on sidebar by @Copilot
|
||||||
|
* ui: Global Brightness Override by @nayan8teen
|
||||||
|
* ui: Customizable Interactive Timeout by @sunnyhaibin
|
||||||
|
* sunnylink: add units to param metadata by @nayan8teen
|
||||||
|
* ui: Customizable Onroad Brightness by @sunnyhaibin
|
||||||
|
* [TIZI/TICI] ui: Steering panel by @nayan8teen
|
||||||
|
* [TIZI/TICI] ui: Rocket Fuel by @rav4kumar
|
||||||
|
* [TIZI/TICI] ui: MICI style turn signals by @rav4kumar
|
||||||
|
* [TIZI/TICI] ui: MICI style blindspot indicators by @sunnyhaibin
|
||||||
|
* [MICI] ui: display blindspot indicators when available by @rav4kumar
|
||||||
|
* [TIZI/TICI] ui: Road Name by @rav4kumar
|
||||||
|
* [TIZI/TICI] ui: Blue "Exit Always Offroad" button by @dzid26
|
||||||
|
* [TIZI/TICI] ui: Speed Limit by @rav4kumar
|
||||||
|
* Reapply "latcontrol_torque: lower kp and lower friction threshold (commaai/openpilot#36619)" by @sunnyhaibin
|
||||||
|
* [TIZI/TICI] ui: steering arc by @royjr
|
||||||
|
* [TIZI/TICI] ui: Smart Cruise Control elements by @sunnyhaibin
|
||||||
|
* [TIZI/TICI] ui: Green Light and Lead Departure elements by @sunnyhaibin
|
||||||
|
* [TIZI/TICI] ui: standstill timer by @sunnyhaibin
|
||||||
|
* [MICI] ui: driving models selector by @Discountchubbs
|
||||||
|
* [TIZI/TICI] ui: Hide vEgo and True vEgo by @sunnyhaibin
|
||||||
|
* [TIZI/TICI] ui: Visuals panel by @nayan8teen
|
||||||
|
* Device: Retain QuickBoot state after op switch by @nayan8teen
|
||||||
|
* [TIZI/TICI] ui: Trips panel by @sunnyhaibin
|
||||||
|
* [TIZI/TICI] ui: dynamic ICBM status by @sunnyhaibin
|
||||||
|
* [TIZI/TICI] ui: Cruise panel by @sunnyhaibin
|
||||||
|
* ui: better wake mode support by @nayan8teen
|
||||||
|
* Pause Lateral Control with Blinker: Post-Blinker Delay by @CHaucke89
|
||||||
|
* SCC-V: Use p97 for predicted lateral accel by @yasu-oh
|
||||||
|
* Controls: Support for Torque Lateral Control v0 Tune by @sunnyhaibin
|
||||||
|
* [TIZI/TICI] ui: ensure null checks for `CarParams` and `CarParamsSP` by @sunnyhaibin
|
||||||
|
* [TIZI/TICI] ui: use `vCruiseCluster` and `vEgoCluster` for SLA `preActive` by @sunnyhaibin
|
||||||
|
* Fix display of values when using use_float_scaling by @CHaucke89
|
||||||
|
* models: fix default & index "0" by @nayan8teen
|
||||||
|
* [TIZI/TICI] visuals: Improved speed limit by @angaz
|
||||||
|
* ICBM: ensure button timers update on disable to clear stale presses by @jamesmikesell
|
||||||
|
* [TIZI/TICI] ui: simplify Smart Cruise Control text rendering by @sunnyhaibin
|
||||||
|
* controlsd: fix steer_limited_by_safety not updating under MADS by @zephleggett
|
||||||
|
* soundd: trigger timeout warning during MADS lateral-only by @zephleggett
|
||||||
|
* pandad: flasher for Rivian long upgrade module by @lukasloetkolben
|
||||||
|
* modeld_v2: tinygrad transformation warp by @Discountchubbs
|
||||||
|
* tools: block `manage_sunnylinkd` in sim startup script by @sunnyhaibin
|
||||||
|
* [MICI] ui: need superclass `_render` in `HudRendererSP` by @sunnyhaibin
|
||||||
|
* [TIZI/TICI] ui: Speed Limit Assist active status by @sunnyhaibin
|
||||||
|
* ui: reimplement "Screen Off" option to Onroad Brightness by @sunnyhaibin
|
||||||
|
* ui: don't hide steering wheel when blindspot disabled by @royjr
|
||||||
|
* ui: Speed Limit Assist `preActive` improvements by @sunnyhaibin
|
||||||
|
* ui: consolidate Speed Limit Assist `preActive` status rendering by @sunnyhaibin
|
||||||
|
* [MICI] ui: Speed Limit Assist `preActive` status by @sunnyhaibin
|
||||||
|
* sunnypilot modeld: remove thneed modeld by @Discountchubbs
|
||||||
|
* modeld_v2: decouple planplus scaling from accel by @Discountchubbs
|
||||||
|
* sunnylink: Handle exceptions in `getParamsAllKeysV1` to log crashes by @devtekve
|
||||||
|
* [TIZI/TICI] ui: Developer UI cleanup by @sunnyhaibin
|
||||||
|
* [TIZI/TICI] ui: dynamic alert size by @nayan8teen
|
||||||
|
* i18n(fr): Add French translations by @didlawowo
|
||||||
|
* Toyota: Stop and Go Hack (Alpha) by @sunnyhaibin
|
||||||
|
* ui: `AlertFadeAnimator` for longitudinal-related statuses by @sunnyhaibin
|
||||||
|
* pandad: gate unsupported pandas before flashing by @sunnyhaibin
|
||||||
|
* Rivian: Flash xnor's Longitudinal Upgrade Kit prior supported panda check by @lukasloetkolben
|
||||||
|
* [TIZI/TICI] ui: add back gate steering arc behind toggle by @sunnyhaibin
|
||||||
|
* ui: gate Onroad Brightness Delay on readiness by @sunnyhaibin
|
||||||
|
* ui: add new timer options for Onroad Brightness Delay by @sunnyhaibin
|
||||||
|
* [TIZI/TICI] ui: branch switcher is always available by @sunnyhaibin
|
||||||
|
* pandad: always prioritize internal panda by @sunnyhaibin
|
||||||
|
* sunnylinkd: fetch compressed params schema by @sunnyhaibin
|
||||||
|
* sunnypilot locationd: remove unused car_ekf filter by @sunnyhaibin
|
||||||
|
* modeld_v2: update deprecated temporalPose ref by @sunnyhaibin
|
||||||
|
* NNLC: restore pre-v1 PID gains in torque extension by @mmmorks
|
||||||
|
* MADS safety: enable heartbeat and lateral controls mismatch checks by @sunnyhaibin
|
||||||
|
* [MICI] ui: models panel enhancements by @nayan8teen
|
||||||
|
* [TIZI/TICI] ui: fix unintended selection while scrolling in TreeOptionDialog by @TheSecurityDev
|
||||||
|
* tools: script for video concatenation by @Discountchubbs
|
||||||
|
* tools: profile memory usage by @Discountchubbs
|
||||||
|
* [TIZI/TICI] ui: remove per-frame param sync by @sunnyhaibin
|
||||||
|
* [MICI] ui: always offroad by @nayan8teen
|
||||||
|
* controls: always default Torque Lateral Control to v0 Tune by @sunnyhaibin
|
||||||
|
* Revert "controls: always default Torque Lateral Control to v0 Tune" by @sunnyhaibin
|
||||||
|
* Reapply "controls: always default Torque Lateral Control to v0 Tune" (#1806) by @sunnyhaibin
|
||||||
|
* [MICI] ui: add sunnylink info & connectivity check by @nayan8teen
|
||||||
|
* sunnylink: Remove unused API endpoint by @devtekve
|
||||||
|
* DM: wheel touch enforcement in MADS by @sunnyhaibin
|
||||||
|
* torque: show static override values in Dev UI & gate `useParams` on custom torque tune by @sunnyhaibin
|
||||||
|
* MADS: suppress espActive event when long is not engaged by @sunnyhaibin
|
||||||
|
* sunnylink: SDUI by @sunnyhaibin
|
||||||
|
* [MICI] ui: align upstream changes with sunnypilot settings buttons by @nayan8teen
|
||||||
|
* ui: fix cellular toggles by @AmyJeanes
|
||||||
|
* sunnylink: switch athena domain by @devtekve
|
||||||
|
* Platform List: dynamically migrate CarPlatformBundle by @sunnyhaibin
|
||||||
|
* What's Changed (sunnypilot/opendbc)
|
||||||
|
* Honda: DBC for Accord 9th Generation by @mvl-boston
|
||||||
|
* FCA: update tire stiffness values for `RAM_HD` by @dparring
|
||||||
|
* Honda: Nidec hybrid baseline brake support by @mvl-boston
|
||||||
|
* Subaru Global Gen2: bump steering limits and update tuning by @sunnyhaibin
|
||||||
|
* Toyota: Enforce Stock Longitudinal Control by @rav4kumar
|
||||||
|
* Nissan: use MADS enabled status for LKAS HUD logic by @downquark7
|
||||||
|
* Reapply "Lateral: lower friction threshold (#2915)" (#378) by @sunnyhaibin
|
||||||
|
* HKG: add KIA_FORTE_2019_NON_SCC fingerprint by @royjr
|
||||||
|
* Nissan: Parse cruise control buttons by @downquark7
|
||||||
|
* Rivian: Add stalk down ACC behavior to match stock Rivian by @lukasloetkolben
|
||||||
|
* Tesla: remove `TESLA_MODEL_X` from `dashcamOnly` by @ssysm
|
||||||
|
* Hyundai Longitudinal: refactor tuning by @Discountchubbs
|
||||||
|
* Tesla: add fingerprint for Model 3 Performance HW4 by @sunnyhaibin
|
||||||
|
* Toyota: do not disable radar when smartDSU or CAN Filter detected by @sunnyhaibin
|
||||||
|
* Honda: add missing `GasInterceptor` messages to Taiwan Odyssey DBC by @mvl-boston
|
||||||
|
* GM: remove `CHEVROLET_EQUINOX_NON_ACC_3RD_GEN` from `dashcamOnly` by @sunnyhaibin
|
||||||
|
* GM: remove `CHEVROLET_BOLT_NON_ACC_2ND_GEN` from `dashcamOnly` by @sunnyhaibin
|
||||||
|
* Hyundai Longitudinal: deprecate ramp update for dynamic tune by @Discountchubbs
|
||||||
|
* Rivian: long upgrade messages on bus 1 by @lukasloetkolben
|
||||||
|
* Toyota: Stop and Go Hack (Alpha) by @sunnyhaibin
|
||||||
|
* Toyota: gate Smart DSU behind Alpha Longitudinal by @sunnyhaibin
|
||||||
|
* Toyota: Gas Interceptor always set `standstill_req` by @sunnyhaibin
|
||||||
|
* MADS safety: dedicated `controls_allowed_lateral` by @sunnyhaibin
|
||||||
|
* Platform List: include community supported platforms by @sunnyhaibin
|
||||||
|
* New Contributors (sunnypilot/sunnypilot)
|
||||||
|
* @TheSecurityDev made their first contribution in "ui: fix sidebar scroll in UI screenshots"
|
||||||
|
* @zikeji made their first contribution in "sunnylink: block remote modification of SSH key parameters"
|
||||||
|
* @Candy0707 made their first contribution in "[TIZI/TICI] ui: Fix misaligned turn signals and blindspot indicators with sidebar"
|
||||||
|
* @CHaucke89 made their first contribution in "Pause Lateral Control with Blinker: Post-Blinker Delay"
|
||||||
|
* @yasu-oh made their first contribution in "SCC-V: Use p97 for predicted lateral accel"
|
||||||
|
* @angaz made their first contribution in "[TIZI/TICI] visuals: Improved speed limit"
|
||||||
|
* @jamesmikesell made their first contribution in "ICBM: ensure button timers update on disable to clear stale presses"
|
||||||
|
* @zephleggett made their first contribution in "controlsd: fix steer_limited_by_safety not updating under MADS"
|
||||||
|
* @lukasloetkolben made their first contribution in "pandad: flasher for Rivian long upgrade module"
|
||||||
|
* @didlawowo made their first contribution in "i18n(fr): Add French translations"
|
||||||
|
* @mmmorks made their first contribution in "NNLC: restore pre-v1 PID gains in torque extension"
|
||||||
|
* New Contributors (sunnypilot/opendbc)
|
||||||
|
* @AmyJeanes made their first contribution in "Tesla: Fix stock LKAS being blocked when MADS is enabled"
|
||||||
|
* @mvl-boston made their first contribution in "Honda: Update Clarity brake to renamed DBC message name"
|
||||||
|
* @dzid26 made their first contribution in "Tesla: Parse speed limit from CAN"
|
||||||
|
* @firestar5683 made their first contribution in "GM: Non-ACC platforms with steering only support"
|
||||||
|
* @downquark7 made their first contribution in "Nissan: use MADS enabled status for LKAS HUD logic"
|
||||||
|
* @royjr made their first contribution in "HKG: add KIA_FORTE_2019_NON_SCC fingerprint"
|
||||||
|
* @ssysm made their first contribution in "Tesla: remove `TESLA_MODEL_X` from `dashcamOnly`"
|
||||||
|
* Full Changelog: https://github.com/sunnypilot/sunnypilot/compare/v2025.002.000...v2026.001.000
|
||||||
|
************************
|
||||||
|
* Synced with commaai's openpilot (v0.11.1)
|
||||||
|
* master commit c001f3c9b490a80e69539f0af6022f6e07ceb721 (April 16, 2026)
|
||||||
|
* New driver monitoring model
|
||||||
|
* Improved image processing pipeline for driver camera
|
||||||
|
* Rivian R1S and R1T 2025 support thanks to lukasloetkolben!
|
||||||
|
* New driving model #36798
|
||||||
|
* Fully trained using a learned simulator
|
||||||
|
* Improved longitudinal performance in Experimental mode
|
||||||
|
* Reduce comma four standby power usage by 77% to 52 mW
|
||||||
|
* Kia K7 2017 support thanks to royjr!
|
||||||
|
* Lexus LS 2018 support thanks to Hacheoy!
|
||||||
|
* Improved inter-process communication memory efficiency
|
||||||
|
* comma four support
|
||||||
|
|
||||||
sunnypilot Version 2025.002.000 (2025-11-06)
|
sunnypilot Version 2025.002.000 (2025-11-06)
|
||||||
========================
|
========================
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
FROM ghcr.io/commaai/openpilot-base:latest
|
|
||||||
|
|
||||||
ENV PYTHONUNBUFFERED=1
|
|
||||||
|
|
||||||
ENV OPENPILOT_PATH=/home/batman/openpilot
|
|
||||||
|
|
||||||
RUN mkdir -p ${OPENPILOT_PATH}
|
|
||||||
WORKDIR ${OPENPILOT_PATH}
|
|
||||||
|
|
||||||
COPY . ${OPENPILOT_PATH}/
|
|
||||||
|
|
||||||
ENV UV_BIN="/home/batman/.local/bin/"
|
|
||||||
ENV PATH="$UV_BIN:$PATH"
|
|
||||||
RUN UV_PROJECT_ENVIRONMENT=$VIRTUAL_ENV uv run scons --cache-readonly -j$(nproc)
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
FROM ubuntu:24.04
|
|
||||||
|
|
||||||
ENV PYTHONUNBUFFERED=1
|
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND=noninteractive
|
|
||||||
RUN apt-get update && \
|
|
||||||
apt-get install -y --no-install-recommends sudo tzdata locales ssh pulseaudio xvfb x11-xserver-utils gnome-screenshot python3-tk python3-dev && \
|
|
||||||
rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
|
|
||||||
ENV LANG=en_US.UTF-8
|
|
||||||
ENV LANGUAGE=en_US:en
|
|
||||||
ENV LC_ALL=en_US.UTF-8
|
|
||||||
|
|
||||||
COPY tools/install_ubuntu_dependencies.sh /tmp/tools/
|
|
||||||
RUN /tmp/tools/install_ubuntu_dependencies.sh && \
|
|
||||||
rm -rf /var/lib/apt/lists/* /tmp/* && \
|
|
||||||
cd /usr/lib/gcc/arm-none-eabi/* && \
|
|
||||||
rm -rf arm/ thumb/nofp thumb/v6* thumb/v8* thumb/v7+fp thumb/v7-r+fp.sp
|
|
||||||
|
|
||||||
# Add OpenCL
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
||||||
apt-utils \
|
|
||||||
alien \
|
|
||||||
unzip \
|
|
||||||
tar \
|
|
||||||
curl \
|
|
||||||
xz-utils \
|
|
||||||
dbus \
|
|
||||||
gcc-arm-none-eabi \
|
|
||||||
tmux \
|
|
||||||
vim \
|
|
||||||
libx11-6 \
|
|
||||||
wget \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
RUN mkdir -p /tmp/opencl-driver-intel && \
|
|
||||||
cd /tmp/opencl-driver-intel && \
|
|
||||||
wget https://github.com/intel/llvm/releases/download/2024-WW14/oclcpuexp-2024.17.3.0.09_rel.tar.gz && \
|
|
||||||
wget https://github.com/oneapi-src/oneTBB/releases/download/v2021.12.0/oneapi-tbb-2021.12.0-lin.tgz && \
|
|
||||||
mkdir -p /opt/intel/oclcpuexp_2024.17.3.0.09_rel && \
|
|
||||||
cd /opt/intel/oclcpuexp_2024.17.3.0.09_rel && \
|
|
||||||
tar -zxvf /tmp/opencl-driver-intel/oclcpuexp-2024.17.3.0.09_rel.tar.gz && \
|
|
||||||
mkdir -p /etc/OpenCL/vendors && \
|
|
||||||
echo /opt/intel/oclcpuexp_2024.17.3.0.09_rel/x64/libintelocl.so > /etc/OpenCL/vendors/intel_expcpu.icd && \
|
|
||||||
cd /opt/intel && \
|
|
||||||
tar -zxvf /tmp/opencl-driver-intel/oneapi-tbb-2021.12.0-lin.tgz && \
|
|
||||||
ln -s /opt/intel/oneapi-tbb-2021.12.0/lib/intel64/gcc4.8/libtbb.so /opt/intel/oclcpuexp_2024.17.3.0.09_rel/x64 && \
|
|
||||||
ln -s /opt/intel/oneapi-tbb-2021.12.0/lib/intel64/gcc4.8/libtbbmalloc.so /opt/intel/oclcpuexp_2024.17.3.0.09_rel/x64 && \
|
|
||||||
ln -s /opt/intel/oneapi-tbb-2021.12.0/lib/intel64/gcc4.8/libtbb.so.12 /opt/intel/oclcpuexp_2024.17.3.0.09_rel/x64 && \
|
|
||||||
ln -s /opt/intel/oneapi-tbb-2021.12.0/lib/intel64/gcc4.8/libtbbmalloc.so.2 /opt/intel/oclcpuexp_2024.17.3.0.09_rel/x64 && \
|
|
||||||
mkdir -p /etc/ld.so.conf.d && \
|
|
||||||
echo /opt/intel/oclcpuexp_2024.17.3.0.09_rel/x64 > /etc/ld.so.conf.d/libintelopenclexp.conf && \
|
|
||||||
ldconfig -f /etc/ld.so.conf.d/libintelopenclexp.conf && \
|
|
||||||
cd / && \
|
|
||||||
rm -rf /tmp/opencl-driver-intel
|
|
||||||
|
|
||||||
ENV NVIDIA_VISIBLE_DEVICES=all
|
|
||||||
ENV NVIDIA_DRIVER_CAPABILITIES=graphics,utility,compute
|
|
||||||
ENV QTWEBENGINE_DISABLE_SANDBOX=1
|
|
||||||
|
|
||||||
RUN dbus-uuidgen > /etc/machine-id
|
|
||||||
RUN apt-get update && apt-get install -y fonts-noto-cjk fonts-noto-color-emoji
|
|
||||||
|
|
||||||
ARG USER=batman
|
|
||||||
ARG USER_UID=1001
|
|
||||||
RUN useradd -m -s /bin/bash -u $USER_UID $USER
|
|
||||||
RUN usermod -aG sudo $USER
|
|
||||||
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
|
|
||||||
USER $USER
|
|
||||||
|
|
||||||
COPY --chown=$USER pyproject.toml uv.lock /home/$USER
|
|
||||||
COPY --chown=$USER tools/install_python_dependencies.sh /home/$USER/tools/
|
|
||||||
|
|
||||||
ENV VIRTUAL_ENV=/home/$USER/.venv
|
|
||||||
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
|
|
||||||
RUN cd /home/$USER && \
|
|
||||||
tools/install_python_dependencies.sh && \
|
|
||||||
rm -rf tools/ pyproject.toml uv.lock .cache
|
|
||||||
|
|
||||||
USER root
|
|
||||||
RUN sudo git config --global --add safe.directory /tmp/openpilot
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
FROM ghcr.io/sunnypilot/sunnypilot-base:latest
|
|
||||||
|
|
||||||
ENV PYTHONUNBUFFERED=1
|
|
||||||
|
|
||||||
ENV OPENPILOT_PATH=/home/batman/openpilot
|
|
||||||
|
|
||||||
RUN mkdir -p ${OPENPILOT_PATH}
|
|
||||||
WORKDIR ${OPENPILOT_PATH}
|
|
||||||
|
|
||||||
COPY . ${OPENPILOT_PATH}/
|
|
||||||
|
|
||||||
RUN scons --cache-readonly -j$(nproc)
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
FROM ubuntu:24.04
|
|
||||||
|
|
||||||
ENV PYTHONUNBUFFERED=1
|
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND=noninteractive
|
|
||||||
RUN apt-get update && \
|
|
||||||
apt-get install -y --no-install-recommends sudo tzdata locales ssh pulseaudio xvfb x11-xserver-utils gnome-screenshot python3-tk python3-dev && \
|
|
||||||
rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
|
|
||||||
ENV LANG=en_US.UTF-8
|
|
||||||
ENV LANGUAGE=en_US:en
|
|
||||||
ENV LC_ALL=en_US.UTF-8
|
|
||||||
|
|
||||||
COPY tools/install_ubuntu_dependencies.sh /tmp/tools/
|
|
||||||
RUN /tmp/tools/install_ubuntu_dependencies.sh && \
|
|
||||||
rm -rf /var/lib/apt/lists/* /tmp/* && \
|
|
||||||
cd /usr/lib/gcc/arm-none-eabi/* && \
|
|
||||||
rm -rf arm/ thumb/nofp thumb/v6* thumb/v8* thumb/v7+fp thumb/v7-r+fp.sp
|
|
||||||
|
|
||||||
# Add OpenCL
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
||||||
apt-utils \
|
|
||||||
alien \
|
|
||||||
unzip \
|
|
||||||
tar \
|
|
||||||
curl \
|
|
||||||
xz-utils \
|
|
||||||
dbus \
|
|
||||||
gcc-arm-none-eabi \
|
|
||||||
tmux \
|
|
||||||
vim \
|
|
||||||
libx11-6 \
|
|
||||||
wget \
|
|
||||||
rsync \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
RUN mkdir -p /tmp/opencl-driver-intel && \
|
|
||||||
cd /tmp/opencl-driver-intel && \
|
|
||||||
wget https://github.com/intel/llvm/releases/download/2024-WW14/oclcpuexp-2024.17.3.0.09_rel.tar.gz && \
|
|
||||||
wget https://github.com/oneapi-src/oneTBB/releases/download/v2021.12.0/oneapi-tbb-2021.12.0-lin.tgz && \
|
|
||||||
mkdir -p /opt/intel/oclcpuexp_2024.17.3.0.09_rel && \
|
|
||||||
cd /opt/intel/oclcpuexp_2024.17.3.0.09_rel && \
|
|
||||||
tar -zxvf /tmp/opencl-driver-intel/oclcpuexp-2024.17.3.0.09_rel.tar.gz && \
|
|
||||||
mkdir -p /etc/OpenCL/vendors && \
|
|
||||||
echo /opt/intel/oclcpuexp_2024.17.3.0.09_rel/x64/libintelocl.so > /etc/OpenCL/vendors/intel_expcpu.icd && \
|
|
||||||
cd /opt/intel && \
|
|
||||||
tar -zxvf /tmp/opencl-driver-intel/oneapi-tbb-2021.12.0-lin.tgz && \
|
|
||||||
ln -s /opt/intel/oneapi-tbb-2021.12.0/lib/intel64/gcc4.8/libtbb.so /opt/intel/oclcpuexp_2024.17.3.0.09_rel/x64 && \
|
|
||||||
ln -s /opt/intel/oneapi-tbb-2021.12.0/lib/intel64/gcc4.8/libtbbmalloc.so /opt/intel/oclcpuexp_2024.17.3.0.09_rel/x64 && \
|
|
||||||
ln -s /opt/intel/oneapi-tbb-2021.12.0/lib/intel64/gcc4.8/libtbb.so.12 /opt/intel/oclcpuexp_2024.17.3.0.09_rel/x64 && \
|
|
||||||
ln -s /opt/intel/oneapi-tbb-2021.12.0/lib/intel64/gcc4.8/libtbbmalloc.so.2 /opt/intel/oclcpuexp_2024.17.3.0.09_rel/x64 && \
|
|
||||||
mkdir -p /etc/ld.so.conf.d && \
|
|
||||||
echo /opt/intel/oclcpuexp_2024.17.3.0.09_rel/x64 > /etc/ld.so.conf.d/libintelopenclexp.conf && \
|
|
||||||
ldconfig -f /etc/ld.so.conf.d/libintelopenclexp.conf && \
|
|
||||||
cd / && \
|
|
||||||
rm -rf /tmp/opencl-driver-intel
|
|
||||||
|
|
||||||
ENV NVIDIA_VISIBLE_DEVICES=all
|
|
||||||
ENV NVIDIA_DRIVER_CAPABILITIES=graphics,utility,compute
|
|
||||||
ENV QTWEBENGINE_DISABLE_SANDBOX=1
|
|
||||||
|
|
||||||
RUN dbus-uuidgen > /etc/machine-id
|
|
||||||
RUN apt-get update && apt-get install -y fonts-noto-cjk fonts-noto-color-emoji
|
|
||||||
|
|
||||||
ARG USER=batman
|
|
||||||
ARG USER_UID=1001
|
|
||||||
RUN useradd -m -s /bin/bash -u $USER_UID $USER
|
|
||||||
RUN usermod -aG sudo $USER
|
|
||||||
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
|
|
||||||
USER $USER
|
|
||||||
|
|
||||||
COPY --chown=$USER pyproject.toml uv.lock /home/$USER
|
|
||||||
COPY --chown=$USER tools/install_python_dependencies.sh /home/$USER/tools/
|
|
||||||
|
|
||||||
ENV VIRTUAL_ENV=/home/$USER/.venv
|
|
||||||
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
|
|
||||||
RUN cd /home/$USER && \
|
|
||||||
tools/install_python_dependencies.sh && \
|
|
||||||
rm -rf tools/ pyproject.toml uv.lock .cache
|
|
||||||
|
|
||||||
USER root
|
|
||||||
RUN sudo git config --global --add safe.directory /tmp/openpilot
|
|
||||||
Vendored
+31
-39
@@ -12,7 +12,7 @@ def retryWithDelay(int maxRetries, int delay, Closure body) {
|
|||||||
def device(String ip, String step_label, String cmd) {
|
def device(String ip, String step_label, String cmd) {
|
||||||
withCredentials([file(credentialsId: 'id_rsa', variable: 'key_file')]) {
|
withCredentials([file(credentialsId: 'id_rsa', variable: 'key_file')]) {
|
||||||
def ssh_cmd = """
|
def ssh_cmd = """
|
||||||
ssh -o ConnectTimeout=5 -o ServerAliveInterval=5 -o ServerAliveCountMax=2 -o BatchMode=yes -o StrictHostKeyChecking=no -i ${key_file} 'comma@${ip}' exec /usr/bin/bash <<'END'
|
ssh -o ControlMaster=auto -o ControlPath=/tmp/ssh_control_%C -o ControlPersist=yes -o ConnectTimeout=5 -o ServerAliveInterval=5 -o ServerAliveCountMax=2 -o BatchMode=yes -o StrictHostKeyChecking=no -i ${key_file} 'comma@${ip}' exec /usr/bin/bash <<'END'
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ shopt -s huponexit # kill all child processes when the shell exits
|
|||||||
|
|
||||||
export CI=1
|
export CI=1
|
||||||
export PYTHONWARNINGS=error
|
export PYTHONWARNINGS=error
|
||||||
export LOGPRINT=debug
|
#export LOGPRINT=debug # this has gotten too spammy...
|
||||||
export TEST_DIR=${env.TEST_DIR}
|
export TEST_DIR=${env.TEST_DIR}
|
||||||
export SOURCE_DIR=${env.SOURCE_DIR}
|
export SOURCE_DIR=${env.SOURCE_DIR}
|
||||||
export GIT_BRANCH=${env.GIT_BRANCH}
|
export GIT_BRANCH=${env.GIT_BRANCH}
|
||||||
@@ -63,6 +63,8 @@ if [ -f /data/openpilot/launch_env.sh ]; then
|
|||||||
source /data/openpilot/launch_env.sh
|
source /data/openpilot/launch_env.sh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
export LD_LIBRARY_PATH="\$(python -c 'import ffmpeg; print(ffmpeg.LIB_DIR)'):/usr/local/lib:\${LD_LIBRARY_PATH:-}"
|
||||||
|
|
||||||
ln -snf ${env.TEST_DIR} /data/pythonpath
|
ln -snf ${env.TEST_DIR} /data/pythonpath
|
||||||
|
|
||||||
cd ${env.TEST_DIR} || true
|
cd ${env.TEST_DIR} || true
|
||||||
@@ -93,7 +95,7 @@ def deviceStage(String stageName, String deviceType, List extra_env, def steps)
|
|||||||
retry (3) {
|
retry (3) {
|
||||||
def date = sh(script: 'date', returnStdout: true).trim();
|
def date = sh(script: 'date', returnStdout: true).trim();
|
||||||
device(device_ip, "set time", "date -s '" + date + "'")
|
device(device_ip, "set time", "date -s '" + date + "'")
|
||||||
device(device_ip, "git checkout", extra + "\n" + readFile("selfdrive/test/setup_device_ci.sh"))
|
device(device_ip, "git checkout", extra + "\n" + readFile("openpilot/selfdrive/test/setup_device_ci.sh"))
|
||||||
}
|
}
|
||||||
steps.each { item ->
|
steps.each { item ->
|
||||||
def name = item[0]
|
def name = item[0]
|
||||||
@@ -166,8 +168,8 @@ node {
|
|||||||
env.GIT_BRANCH = checkout(scm).GIT_BRANCH
|
env.GIT_BRANCH = checkout(scm).GIT_BRANCH
|
||||||
env.GIT_COMMIT = checkout(scm).GIT_COMMIT
|
env.GIT_COMMIT = checkout(scm).GIT_COMMIT
|
||||||
|
|
||||||
def excludeBranches = ['__nightly', 'devel', 'devel-staging', 'release3', 'release3-staging',
|
def excludeBranches = ['__nightly', 'devel', 'devel-staging',
|
||||||
'release-tici', 'release-tizi', 'release-tizi-staging', 'testing-closet*', 'hotfix-*']
|
'release-tizi', 'release-tizi-staging', 'release-mici', 'release-mici-staging', 'testing-closet*', 'hotfix-*']
|
||||||
def excludeRegex = excludeBranches.join('|').replaceAll('\\*', '.*')
|
def excludeRegex = excludeBranches.join('|').replaceAll('\\*', '.*')
|
||||||
|
|
||||||
if (env.BRANCH_NAME != 'master' && !env.BRANCH_NAME.contains('__jenkins_loop_')) {
|
if (env.BRANCH_NAME != 'master' && !env.BRANCH_NAME.contains('__jenkins_loop_')) {
|
||||||
@@ -179,7 +181,7 @@ node {
|
|||||||
try {
|
try {
|
||||||
if (env.BRANCH_NAME == 'devel-staging') {
|
if (env.BRANCH_NAME == 'devel-staging') {
|
||||||
deviceStage("build release-tizi-staging", "tizi-needs-can", [], [
|
deviceStage("build release-tizi-staging", "tizi-needs-can", [], [
|
||||||
step("build release-tizi-staging", "RELEASE_BRANCH=release-tizi-staging $SOURCE_DIR/release/build_release.sh"),
|
step("build release-tizi-staging", "RELEASE_BRANCH=release-tizi-staging,release-mici-staging $SOURCE_DIR/tools/release/build_release.sh"),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,12 +189,12 @@ node {
|
|||||||
parallel (
|
parallel (
|
||||||
'nightly': {
|
'nightly': {
|
||||||
deviceStage("build nightly", "tizi-needs-can", [], [
|
deviceStage("build nightly", "tizi-needs-can", [], [
|
||||||
step("build nightly", "RELEASE_BRANCH=nightly $SOURCE_DIR/release/build_release.sh"),
|
step("build nightly", "RELEASE_BRANCH=nightly $SOURCE_DIR/tools/release/build_release.sh"),
|
||||||
])
|
])
|
||||||
},
|
},
|
||||||
'nightly-dev': {
|
'nightly-dev': {
|
||||||
deviceStage("build nightly-dev", "tizi-needs-can", [], [
|
deviceStage("build nightly-dev", "tizi-needs-can", [], [
|
||||||
step("build nightly-dev", "PANDA_DEBUG_BUILD=1 RELEASE_BRANCH=nightly-dev $SOURCE_DIR/release/build_release.sh"),
|
step("build nightly-dev", "PANDA_DEBUG_BUILD=1 RELEASE_BRANCH=nightly-dev $SOURCE_DIR/tools/release/build_release.sh"),
|
||||||
])
|
])
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -202,61 +204,51 @@ node {
|
|||||||
parallel (
|
parallel (
|
||||||
'onroad tests': {
|
'onroad tests': {
|
||||||
deviceStage("onroad", "tizi-needs-can", ["UNSAFE=1"], [
|
deviceStage("onroad", "tizi-needs-can", ["UNSAFE=1"], [
|
||||||
step("build openpilot", "cd system/manager && ./build.py"),
|
step("build openpilot", "cd openpilot/system/manager && ./build.py"),
|
||||||
step("check dirty", "release/check-dirty.sh"),
|
step("check dirty", "tools/release/check-dirty.sh"),
|
||||||
step("onroad tests", "pytest selfdrive/test/test_onroad.py -s", [timeout: 60]),
|
step("onroad tests", "pytest openpilot/selfdrive/test/test_onroad.py -s", [timeout: 60]),
|
||||||
])
|
])
|
||||||
},
|
},
|
||||||
'HW + Unit Tests': {
|
'HW + Unit Tests': {
|
||||||
deviceStage("tizi-hardware", "tizi-common", ["UNSAFE=1"], [
|
deviceStage("tizi-hardware", "tizi-common", ["UNSAFE=1"], [
|
||||||
step("build", "cd system/manager && ./build.py"),
|
step("build", "cd openpilot/system/manager && ./build.py"),
|
||||||
step("test pandad", "pytest selfdrive/pandad/tests/test_pandad.py", [diffPaths: ["panda", "selfdrive/pandad/"]]),
|
step("test power draw", "pytest -s openpilot/selfdrive/test//test_power_draw.py"),
|
||||||
step("test power draw", "pytest -s system/hardware/tici/tests/test_power_draw.py"),
|
step("test encoder", "pytest openpilot/system/loggerd/tests/test_encoder.py", [diffPaths: ["openpilot/system/loggerd/"]]),
|
||||||
step("test encoder", "LD_LIBRARY_PATH=/usr/local/lib pytest system/loggerd/tests/test_encoder.py", [diffPaths: ["system/loggerd/"]]),
|
step("test manager", "pytest openpilot/system/manager/test/test_manager.py"),
|
||||||
step("test manager", "pytest system/manager/test/test_manager.py"),
|
|
||||||
])
|
|
||||||
},
|
|
||||||
'loopback': {
|
|
||||||
deviceStage("loopback", "tizi-loopback", ["UNSAFE=1"], [
|
|
||||||
step("build openpilot", "cd system/manager && ./build.py"),
|
|
||||||
step("test pandad loopback", "pytest selfdrive/pandad/tests/test_pandad_loopback.py"),
|
|
||||||
])
|
])
|
||||||
},
|
},
|
||||||
'camerad OX03C10': {
|
'camerad OX03C10': {
|
||||||
deviceStage("OX03C10", "tizi-ox03c10", ["UNSAFE=1"], [
|
deviceStage("OX03C10", "tizi-ox03c10", ["UNSAFE=1"], [
|
||||||
step("build", "cd system/manager && ./build.py"),
|
step("build", "cd openpilot/system/manager && ./build.py"),
|
||||||
step("test camerad", "pytest system/camerad/test/test_camerad.py", [timeout: 60]),
|
step("test pandad", "pytest openpilot/selfdrive/pandad/tests/test_pandad.py"),
|
||||||
step("test exposure", "pytest system/camerad/test/test_exposure.py"),
|
step("test camerad", "pytest openpilot/system/camerad/test/test_camerad.py", [timeout: 90]),
|
||||||
])
|
])
|
||||||
},
|
},
|
||||||
'camerad OS04C10': {
|
'camerad OS04C10': {
|
||||||
deviceStage("OS04C10", "tici-os04c10", ["UNSAFE=1"], [
|
deviceStage("OS04C10", "tici-os04c10", ["UNSAFE=1"], [
|
||||||
step("build", "cd system/manager && ./build.py"),
|
step("build", "cd openpilot/system/manager && ./build.py"),
|
||||||
step("test camerad", "pytest system/camerad/test/test_camerad.py", [timeout: 60]),
|
step("test pandad", "pytest openpilot/selfdrive/pandad/tests/test_pandad.py"),
|
||||||
step("test exposure", "pytest system/camerad/test/test_exposure.py"),
|
step("test camerad", "pytest openpilot/system/camerad/test/test_camerad.py", [timeout: 90]),
|
||||||
])
|
])
|
||||||
},
|
},
|
||||||
'sensord': {
|
'sensord': {
|
||||||
deviceStage("LSM + MMC", "tizi-lsmc", ["UNSAFE=1"], [
|
deviceStage("LSM + MMC", "tizi-lsmc", ["UNSAFE=1"], [
|
||||||
step("build", "cd system/manager && ./build.py"),
|
step("build", "cd openpilot/system/manager && ./build.py"),
|
||||||
step("test sensord", "pytest system/sensord/tests/test_sensord.py"),
|
step("test sensord", "pytest openpilot/system/sensord/tests/test_sensord.py"),
|
||||||
])
|
])
|
||||||
},
|
},
|
||||||
'replay': {
|
'replay': {
|
||||||
deviceStage("model-replay", "tizi-replay", ["UNSAFE=1"], [
|
deviceStage("model-replay", "tizi-replay", ["UNSAFE=1"], [
|
||||||
step("build", "cd system/manager && ./build.py", [diffPaths: ["selfdrive/modeld/", "tinygrad_repo", "selfdrive/test/process_replay/model_replay.py"]]),
|
step("build", "cd openpilot/system/manager && ./build.py", [diffPaths: ["openpilot/selfdrive/modeld/", "tinygrad_repo", "openpilot/selfdrive/test/process_replay/model_replay.py"]]),
|
||||||
step("model replay", "selfdrive/test/process_replay/model_replay.py", [diffPaths: ["selfdrive/modeld/", "tinygrad_repo", "selfdrive/test/process_replay/model_replay.py"]]),
|
step("model replay", "openpilot/selfdrive/test/process_replay/model_replay.py", [diffPaths: ["openpilot/selfdrive/modeld/", "tinygrad_repo", "openpilot/selfdrive/test/process_replay/model_replay.py"]]),
|
||||||
])
|
])
|
||||||
},
|
},
|
||||||
'tizi': {
|
'tizi': {
|
||||||
deviceStage("tizi", "tizi", ["UNSAFE=1"], [
|
deviceStage("tizi", "tizi", ["UNSAFE=1"], [
|
||||||
step("build openpilot", "cd system/manager && ./build.py"),
|
step("build openpilot", "cd openpilot/system/manager && ./build.py"),
|
||||||
step("test pandad loopback", "SINGLE_PANDA=1 pytest selfdrive/pandad/tests/test_pandad_loopback.py"),
|
step("test pandad loopback", "pytest openpilot/selfdrive/pandad/tests/test_pandad_loopback.py"),
|
||||||
step("test pandad spi", "pytest selfdrive/pandad/tests/test_pandad_spi.py"),
|
step("test pandad spi", "pytest openpilot/selfdrive/pandad/tests/test_pandad_spi.py"),
|
||||||
step("test amp", "pytest system/hardware/tici/tests/test_amplifier.py"),
|
step("test amp", "pytest openpilot/common/hardware/tici/tests/test_amplifier.py"),
|
||||||
// TODO: enable once new AGNOS is available
|
|
||||||
// step("test esim", "pytest system/hardware/tici/tests/test_esim.py"),
|
|
||||||
step("test qcomgpsd", "pytest system/qcomgpsd/tests/test_qcomgpsd.py", [diffPaths: ["system/qcomgpsd/"]]),
|
|
||||||
])
|
])
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -11,66 +11,10 @@ Join the official sunnypilot community forum to stay up to date with all the lat
|
|||||||
https://docs.sunnypilot.ai/ is your one stop shop for everything from features to installation to FAQ about the sunnypilot
|
https://docs.sunnypilot.ai/ is your one stop shop for everything from features to installation to FAQ about the sunnypilot
|
||||||
|
|
||||||
## 🚘 Running on a dedicated device in a car
|
## 🚘 Running on a dedicated device in a car
|
||||||
* A supported device to run this software
|
First, check out this list of items you'll need to [get started](https://community.sunnypilot.ai/t/getting-started-using-sunnypilot-in-your-supported-car/251).
|
||||||
* a [comma three](https://comma.ai/shop/products/three) or a [C3X](https://comma.ai/shop/comma-3x)
|
|
||||||
* This software
|
|
||||||
* One of [the 325+ supported cars](https://github.com/sunnypilot/sunnypilot/blob/master/docs/CARS.md). We support Honda, Toyota, Hyundai, Nissan, Kia, Chrysler, Lexus, Acura, Audi, VW, Ford, and more. If your car is not supported but has adaptive cruise control and lane-keeping assist, it's likely able to run sunnypilot.
|
|
||||||
* A [car harness](https://comma.ai/shop/products/car-harness) to connect to your car
|
|
||||||
|
|
||||||
Detailed instructions for [how to mount the device in a car](https://comma.ai/setup).
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
Please refer to [Recommended Branches](#recommended-branches) to find your preferred/supported branch. This guide will assume you want to install the latest `staging` branch.
|
Next, refer to the sunnypilot community forum for [installation instructions](https://community.sunnypilot.ai/t/read-before-installing-sunnypilot/254), as well as a complete list of [Recommended Branch Installations](https://community.sunnypilot.ai/t/recommended-branch-installations/235).
|
||||||
|
|
||||||
### If you want to use our newest branches (our rewrite)
|
|
||||||
> [!TIP]
|
|
||||||
>You can see the rewrite state on our [rewrite project board](https://github.com/orgs/sunnypilot/projects/2), and to install the new branches, you can use the following links
|
|
||||||
|
|
||||||
* sunnypilot not installed or you installed a version before 0.8.17?
|
|
||||||
1. [Factory reset/uninstall](https://github.com/commaai/openpilot/wiki/FAQ#how-can-i-reset-the-device) the previous software if you have another software/fork installed.
|
|
||||||
2. After factory reset/uninstall and upon reboot, select `Custom Software` when given the option.
|
|
||||||
3. Input the installation URL per [Recommended Branches](#recommended-branches). Example: ```https://staging.sunnypilot.ai```.
|
|
||||||
4. Complete the rest of the installation following the onscreen instructions.
|
|
||||||
|
|
||||||
* sunnypilot already installed and you installed a version after 0.8.17?
|
|
||||||
1. On the comma three/3X, go to `Settings` ▶️ `Software`.
|
|
||||||
2. At the `Download` option, press `CHECK`. This will fetch the list of latest branches from sunnypilot.
|
|
||||||
3. At the `Target Branch` option, press `SELECT` to open the Target Branch selector.
|
|
||||||
4. Scroll to select the desired branch per Recommended Branches (see below). Example: `staging`
|
|
||||||
|
|
||||||
### Recommended Branches
|
|
||||||
| Branch | Installation URL |
|
|
||||||
|:---------------:|:---------------------------------------------:|
|
|
||||||
| `release` | `https://release.sunnypilot.ai` |
|
|
||||||
| `staging` | `https://staging.sunnypilot.ai` |
|
|
||||||
| `dev` | `https://dev.sunnypilot.ai` |
|
|
||||||
| `custom-branch` | `https://install.sunnypilot.ai/{branch_name}` |
|
|
||||||
|
|
||||||
> [!TIP]
|
|
||||||
> You can use sunnypilot/targetbranch as an install URL. Example: 'sunnypilot/staging'.
|
|
||||||
|
|
||||||
> [!NOTE]
|
|
||||||
> Do you require further assistance with software installation? Join the [sunnypilot community forum](https://community.sunnypilot.ai/new-topic?category=general/qa) and create a topic in the General/Q&A Category channel.
|
|
||||||
|
|
||||||
|
|
||||||
<details>
|
|
||||||
|
|
||||||
<summary>Older legacy branches</summary>
|
|
||||||
|
|
||||||
### If you want to use our older legacy branches (*not recommended*)
|
|
||||||
|
|
||||||
> [**IMPORTANT**]
|
|
||||||
> It is recommended to [re-flash AGNOS](https://flash.comma.ai/) if you intend to downgrade from the new branches.
|
|
||||||
> You can still restore the latest sunnylink backup made on the old branches.
|
|
||||||
|
|
||||||
| Branch | Installation URL |
|
|
||||||
|:------------:|:--------------------------------:|
|
|
||||||
| `release-c3` | https://release-c3.sunnypilot.ai |
|
|
||||||
| `staging-c3` | https://staging-c3.sunnypilot.ai |
|
|
||||||
| `dev-c3` | https://dev-c3.sunnypilot.ai |
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
|
|
||||||
## 🎆 Pull Requests
|
## 🎆 Pull Requests
|
||||||
We welcome both pull requests and issues on GitHub. Bug fixes are encouraged.
|
We welcome both pull requests and issues on GitHub. Bug fixes are encouraged.
|
||||||
|
|||||||
+22
-1
@@ -1,3 +1,24 @@
|
|||||||
|
Version 0.11.2 (2026-06-15)
|
||||||
|
========================
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.11.1 (2026-05-18)
|
||||||
|
========================
|
||||||
|
* New driver monitoring model
|
||||||
|
* Improved image processing pipeline for driver camera
|
||||||
|
* Improved thermal policy for comma four
|
||||||
|
* Acura MDX 2022-24 support thanks to mvl-boston!
|
||||||
|
* Rivian R1S and R1T 2025 support thanks to lukasloetkolben!
|
||||||
|
|
||||||
|
Version 0.11.0 (2026-03-17)
|
||||||
|
========================
|
||||||
|
* New driving model #36798
|
||||||
|
* Fully trained using a learned simulator
|
||||||
|
* Improved longitudinal performance in Experimental mode
|
||||||
|
* Reduce comma four standby power usage by 77% to 52 mW
|
||||||
|
* Kia K7 2017 support thanks to royjr!
|
||||||
|
* Lexus LS 2018 support thanks to Hacheoy!
|
||||||
|
|
||||||
Version 0.10.3 (2025-12-17)
|
Version 0.10.3 (2025-12-17)
|
||||||
========================
|
========================
|
||||||
* New driving model #36249
|
* New driving model #36249
|
||||||
@@ -1083,7 +1104,7 @@ Version 0.2.1 (2016-12-14)
|
|||||||
|
|
||||||
Version 0.2 (2016-12-12)
|
Version 0.2 (2016-12-12)
|
||||||
=========================
|
=========================
|
||||||
* Car/Radar abstraction layers have shipped, see cereal/car.capnp
|
* Car/Radar abstraction layers have shipped, see openpilot/cereal/car.capnp
|
||||||
* controlsd has been refactored
|
* controlsd has been refactored
|
||||||
* Shipped plant model and testing maneuvers
|
* Shipped plant model and testing maneuvers
|
||||||
* visiond exits more gracefully now
|
* visiond exits more gracefully now
|
||||||
|
|||||||
+204
-84
@@ -4,33 +4,49 @@ import sys
|
|||||||
import sysconfig
|
import sysconfig
|
||||||
import platform
|
import platform
|
||||||
import shlex
|
import shlex
|
||||||
|
import importlib
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
import SCons.Errors
|
import SCons.Errors
|
||||||
|
from SCons.Defaults import _stripixes
|
||||||
|
|
||||||
|
TICI = os.path.isfile('/TICI')
|
||||||
|
|
||||||
SCons.Warnings.warningAsException(True)
|
SCons.Warnings.warningAsException(True)
|
||||||
|
|
||||||
Decider('MD5-timestamp')
|
Decider('MD5-timestamp')
|
||||||
|
|
||||||
SetOption('num_jobs', max(1, int(os.cpu_count()/2)))
|
SetOption('num_jobs', max(1, int(os.cpu_count()/(1 if "CI" in os.environ else 2))))
|
||||||
|
|
||||||
AddOption('--kaitai', action='store_true', help='Regenerate kaitai struct parsers')
|
|
||||||
AddOption('--asan', action='store_true', help='turn on ASAN')
|
|
||||||
AddOption('--ubsan', action='store_true', help='turn on UBSan')
|
|
||||||
AddOption('--mutation', action='store_true', help='generate mutation-ready code')
|
|
||||||
AddOption('--ccflags', action='store', type='string', default='', help='pass arbitrary flags over the command line')
|
AddOption('--ccflags', action='store', type='string', default='', help='pass arbitrary flags over the command line')
|
||||||
|
AddOption('--verbose', action='store_true', default=False, help='show full build commands')
|
||||||
|
release = not os.path.exists(File('#.gitattributes').abspath) # file absent on release branch, see release_files.py
|
||||||
AddOption('--minimal',
|
AddOption('--minimal',
|
||||||
action='store_false',
|
action='store_false',
|
||||||
dest='extras',
|
dest='extras',
|
||||||
default=os.path.exists(File('#.gitattributes').abspath), # minimal by default on release branch (where there's no LFS)
|
default=(not TICI and not release),
|
||||||
help='the minimum build to run openpilot. no tests, tools, etc.')
|
help='the minimum build to run openpilot. no tests, tools, etc.')
|
||||||
|
|
||||||
|
submodule_python_paths = [
|
||||||
|
Dir("#").abspath,
|
||||||
|
Dir("#msgq_repo").abspath,
|
||||||
|
Dir("#opendbc_repo").abspath,
|
||||||
|
Dir("#rednose_repo").abspath,
|
||||||
|
Dir("#teleoprtc_repo").abspath,
|
||||||
|
Dir("#tinygrad_repo").abspath,
|
||||||
|
]
|
||||||
|
for p in reversed(submodule_python_paths):
|
||||||
|
if p not in sys.path:
|
||||||
|
sys.path.insert(0, p)
|
||||||
|
|
||||||
|
if external_pythonpath := os.environ.get("PYTHONPATH"):
|
||||||
|
submodule_python_paths += [p for p in external_pythonpath.split(os.pathsep) if p and p not in submodule_python_paths]
|
||||||
|
|
||||||
# Detect platform
|
# Detect platform
|
||||||
arch = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip()
|
arch = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip()
|
||||||
if platform.system() == "Darwin":
|
if platform.system() == "Darwin":
|
||||||
arch = "Darwin"
|
arch = "Darwin"
|
||||||
brew_prefix = subprocess.check_output(['brew', '--prefix'], encoding='utf8').strip()
|
elif arch == "aarch64" and TICI:
|
||||||
elif arch == "aarch64" and os.path.isfile('/TICI'):
|
|
||||||
arch = "larch64"
|
arch = "larch64"
|
||||||
assert arch in [
|
assert arch in [
|
||||||
"larch64", # linux tici arm64
|
"larch64", # linux tici arm64
|
||||||
@@ -39,23 +55,84 @@ assert arch in [
|
|||||||
"Darwin", # macOS arm64 (x86 not supported)
|
"Darwin", # macOS arm64 (x86 not supported)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
pkg_names = ['acados', 'bzip2', 'capnproto', 'catch2', 'eigen', 'ffmpeg', 'json11', 'ncurses', 'zeromq', 'zstd']
|
||||||
|
pkgs = [importlib.import_module(name) for name in pkg_names]
|
||||||
|
acados = pkgs[pkg_names.index('acados')]
|
||||||
|
ffmpeg = pkgs[pkg_names.index('ffmpeg')]
|
||||||
|
# Shared package ships .so/.dylib; older device venvs still have static .a only.
|
||||||
|
# Keep static link deps (x264/z/va/drm) when the installed package is static so
|
||||||
|
# TICI CI works without upgrading the device venv yet.
|
||||||
|
# TODO: drop the static fallback once device venvs have comma-deps-ffmpeg>=7.1.0.post94
|
||||||
|
_ffmpeg_lib_names = os.listdir(ffmpeg.LIB_DIR) if os.path.isdir(ffmpeg.LIB_DIR) else []
|
||||||
|
ffmpeg_shared = any(
|
||||||
|
n.startswith('libavcodec.so') or (n.startswith('libavcodec') and n.endswith('.dylib'))
|
||||||
|
for n in _ffmpeg_lib_names
|
||||||
|
)
|
||||||
|
ffmpeg_libs = ['avformat', 'avcodec', 'swresample', 'avutil']
|
||||||
|
if not ffmpeg_shared:
|
||||||
|
ffmpeg_libs += ['x264', 'z']
|
||||||
|
if arch != "Darwin":
|
||||||
|
ffmpeg_libs += ['va', 'va-drm', 'drm']
|
||||||
|
acados_include_dirs = [
|
||||||
|
acados.INCLUDE_DIR,
|
||||||
|
os.path.join(acados.INCLUDE_DIR, "blasfeo", "include"),
|
||||||
|
os.path.join(acados.INCLUDE_DIR, "hpipm", "include"),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# ***** enforce a whitelist of system libraries *****
|
||||||
|
# this prevents silently relying on a 3rd party package,
|
||||||
|
# e.g. apt-installed libusb. all libraries should either
|
||||||
|
# be distributed with all Linux distros and macOS, or
|
||||||
|
# vendored in commaai/dependencies.
|
||||||
|
allowed_system_libs = {
|
||||||
|
"EGL", "GLESv2", "GL",
|
||||||
|
"Qt5Charts", "Qt5Core", "Qt5Gui", "Qt5Widgets",
|
||||||
|
"dl", "drm", "gbm", "m", "pthread",
|
||||||
|
}
|
||||||
|
|
||||||
|
def _resolve_lib(env, name):
|
||||||
|
for d in env.Flatten(env.get('LIBPATH', [])):
|
||||||
|
p = Dir(str(d)).abspath
|
||||||
|
for ext in ('.a', '.so', '.dylib'):
|
||||||
|
f = File(os.path.join(p, f'lib{name}{ext}'))
|
||||||
|
if f.exists() or f.has_builder():
|
||||||
|
return name
|
||||||
|
if name in allowed_system_libs:
|
||||||
|
return name
|
||||||
|
raise SCons.Errors.UserError(f"Unexpected non-vendored library '{name}'")
|
||||||
|
|
||||||
|
def _libflags(target, source, env, for_signature):
|
||||||
|
libs = []
|
||||||
|
lp = env.subst('$LIBLITERALPREFIX')
|
||||||
|
for lib in env.Flatten(env.get('LIBS', [])):
|
||||||
|
if isinstance(lib, str):
|
||||||
|
if os.sep in lib or lib.startswith('#'):
|
||||||
|
libs.append(File(lib))
|
||||||
|
elif lib.startswith('-') or (lp and lib.startswith(lp)):
|
||||||
|
libs.append(lib)
|
||||||
|
else:
|
||||||
|
libs.append(_resolve_lib(env, lib))
|
||||||
|
else:
|
||||||
|
libs.append(lib)
|
||||||
|
return _stripixes(env['LIBLINKPREFIX'], libs, env['LIBLINKSUFFIX'],
|
||||||
|
env['LIBPREFIXES'], env['LIBSUFFIXES'], env, env['LIBLITERALPREFIX'])
|
||||||
|
|
||||||
env = Environment(
|
env = Environment(
|
||||||
ENV={
|
ENV={
|
||||||
"PATH": os.environ['PATH'],
|
"PATH": os.environ['PATH'],
|
||||||
"PYTHONPATH": Dir("#").abspath + ':' + Dir(f"#third_party/acados").abspath,
|
"PYTHONPATH": os.pathsep.join(submodule_python_paths),
|
||||||
"ACADOS_SOURCE_DIR": Dir("#third_party/acados").abspath,
|
"ACADOS_SOURCE_DIR": acados.DIR,
|
||||||
"ACADOS_PYTHON_INTERFACE_PATH": Dir("#third_party/acados/acados_template").abspath,
|
"ACADOS_PYTHON_INTERFACE_PATH": acados.TEMPLATE_DIR,
|
||||||
"TERA_PATH": Dir("#").abspath + f"/third_party/acados/{arch}/t_renderer"
|
"TERA_PATH": acados.TERA_PATH
|
||||||
},
|
},
|
||||||
CC='clang',
|
|
||||||
CXX='clang++',
|
|
||||||
CCFLAGS=[
|
CCFLAGS=[
|
||||||
"-g",
|
"-g",
|
||||||
"-fPIC",
|
"-fPIC",
|
||||||
"-O2",
|
"-O2",
|
||||||
"-Wunused",
|
"-Wunused",
|
||||||
"-Werror",
|
"-Werror",
|
||||||
"-Wshadow",
|
"-Wshadow" if arch in ("Darwin", "larch64") else "-Wshadow=local",
|
||||||
"-Wno-unknown-warning-option",
|
"-Wno-unknown-warning-option",
|
||||||
"-Wno-inconsistent-missing-override",
|
"-Wno-inconsistent-missing-override",
|
||||||
"-Wno-c99-designator",
|
"-Wno-c99-designator",
|
||||||
@@ -65,40 +142,38 @@ env = Environment(
|
|||||||
CFLAGS=["-std=gnu11"],
|
CFLAGS=["-std=gnu11"],
|
||||||
CXXFLAGS=["-std=c++1z"],
|
CXXFLAGS=["-std=c++1z"],
|
||||||
CPPPATH=[
|
CPPPATH=[
|
||||||
|
"#openpilot",
|
||||||
|
"#msgq_repo", # #include "msgq/..."
|
||||||
|
"#opendbc_repo", # #include "opendbc/..."
|
||||||
|
"#rednose_repo", # #include "rednose/..."
|
||||||
|
"#rednose_repo/rednose", # #include "logger/..." (rednose package root)
|
||||||
|
"#openpilot/cereal/gen/cpp",
|
||||||
|
acados_include_dirs,
|
||||||
|
[x.INCLUDE_DIR for x in pkgs],
|
||||||
"#",
|
"#",
|
||||||
"#msgq",
|
|
||||||
"#third_party",
|
|
||||||
"#third_party/json11",
|
|
||||||
"#third_party/linux/include",
|
|
||||||
"#third_party/acados/include",
|
|
||||||
"#third_party/acados/include/blasfeo/include",
|
|
||||||
"#third_party/acados/include/hpipm/include",
|
|
||||||
"#third_party/catch2/include",
|
|
||||||
"#third_party/libyuv/include",
|
|
||||||
],
|
],
|
||||||
LIBPATH=[
|
LIBPATH=[
|
||||||
"#common",
|
"#openpilot/common",
|
||||||
"#msgq_repo",
|
"#msgq_repo",
|
||||||
"#third_party",
|
"#openpilot/selfdrive/pandad",
|
||||||
"#selfdrive/pandad",
|
"#rednose_repo/rednose/helpers",
|
||||||
"#rednose/helpers",
|
[x.LIB_DIR for x in pkgs],
|
||||||
f"#third_party/libyuv/{arch}/lib",
|
|
||||||
f"#third_party/acados/{arch}/lib",
|
|
||||||
],
|
],
|
||||||
RPATH=[],
|
RPATH=[ffmpeg.LIB_DIR] if ffmpeg_shared else [],
|
||||||
CYTHONCFILESUFFIX=".cpp",
|
CYTHONCFILESUFFIX=".cpp",
|
||||||
COMPILATIONDB_USE_ABSPATH=True,
|
COMPILATIONDB_USE_ABSPATH=True,
|
||||||
REDNOSE_ROOT="#",
|
REDNOSE_ROOT="#rednose_repo",
|
||||||
tools=["default", "cython", "compilation_db", "rednose_filter"],
|
tools=["default", "cython", "compilation_db", "rednose_filter"],
|
||||||
toolpath=["#site_scons/site_tools", "#rednose_repo/site_scons/site_tools"],
|
toolpath=["#site_scons/site_tools", "#rednose_repo/site_scons/site_tools"],
|
||||||
)
|
)
|
||||||
|
if arch != "larch64":
|
||||||
|
env['_LIBFLAGS'] = _libflags
|
||||||
|
|
||||||
# Arch-specific flags and paths
|
# Arch-specific flags and paths
|
||||||
if arch == "larch64":
|
if arch == "larch64":
|
||||||
env.Append(CPPPATH=["#third_party/opencl/include"])
|
env["CC"] = "clang"
|
||||||
|
env["CXX"] = "clang++"
|
||||||
env.Append(LIBPATH=[
|
env.Append(LIBPATH=[
|
||||||
"/usr/local/lib",
|
|
||||||
"/system/vendor/lib64",
|
|
||||||
"/usr/lib/aarch64-linux-gnu",
|
"/usr/lib/aarch64-linux-gnu",
|
||||||
])
|
])
|
||||||
arch_flags = ["-D__TICI__", "-mcpu=cortex-a57", "-DQCOM2"]
|
arch_flags = ["-D__TICI__", "-mcpu=cortex-a57", "-DQCOM2"]
|
||||||
@@ -106,30 +181,10 @@ if arch == "larch64":
|
|||||||
env.Append(CXXFLAGS=arch_flags)
|
env.Append(CXXFLAGS=arch_flags)
|
||||||
elif arch == "Darwin":
|
elif arch == "Darwin":
|
||||||
env.Append(LIBPATH=[
|
env.Append(LIBPATH=[
|
||||||
f"{brew_prefix}/lib",
|
|
||||||
f"{brew_prefix}/opt/openssl@3.0/lib",
|
|
||||||
f"{brew_prefix}/opt/llvm/lib/c++",
|
|
||||||
"/System/Library/Frameworks/OpenGL.framework/Libraries",
|
"/System/Library/Frameworks/OpenGL.framework/Libraries",
|
||||||
])
|
])
|
||||||
env.Append(CCFLAGS=["-DGL_SILENCE_DEPRECATION"])
|
env.Append(CCFLAGS=["-DGL_SILENCE_DEPRECATION"])
|
||||||
env.Append(CXXFLAGS=["-DGL_SILENCE_DEPRECATION"])
|
env.Append(CXXFLAGS=["-DGL_SILENCE_DEPRECATION"])
|
||||||
env.Append(CPPPATH=[
|
|
||||||
f"{brew_prefix}/include",
|
|
||||||
f"{brew_prefix}/opt/openssl@3.0/include",
|
|
||||||
])
|
|
||||||
else:
|
|
||||||
env.Append(LIBPATH=[
|
|
||||||
"/usr/lib",
|
|
||||||
"/usr/local/lib",
|
|
||||||
])
|
|
||||||
|
|
||||||
# Sanitizers and extra CCFLAGS from CLI
|
|
||||||
if GetOption('asan'):
|
|
||||||
env.Append(CCFLAGS=["-fsanitize=address", "-fno-omit-frame-pointer"])
|
|
||||||
env.Append(LINKFLAGS=["-fsanitize=address"])
|
|
||||||
elif GetOption('ubsan'):
|
|
||||||
env.Append(CCFLAGS=["-fsanitize=undefined"])
|
|
||||||
env.Append(LINKFLAGS=["-fsanitize=undefined"])
|
|
||||||
|
|
||||||
_extra_cc = shlex.split(GetOption('ccflags') or '')
|
_extra_cc = shlex.split(GetOption('ccflags') or '')
|
||||||
if _extra_cc:
|
if _extra_cc:
|
||||||
@@ -139,21 +194,26 @@ if _extra_cc:
|
|||||||
if arch != "Darwin":
|
if arch != "Darwin":
|
||||||
env.Append(LINKFLAGS=["-Wl,--as-needed", "-Wl,--no-undefined"])
|
env.Append(LINKFLAGS=["-Wl,--as-needed", "-Wl,--no-undefined"])
|
||||||
|
|
||||||
# progress output
|
# Shorter build output: show brief descriptions instead of full commands.
|
||||||
node_interval = 5
|
# Full command lines are still printed on failure by scons.
|
||||||
node_count = 0
|
if not GetOption('verbose'):
|
||||||
def progress_function(node):
|
for action, short in (
|
||||||
global node_count
|
("CC", "CC"),
|
||||||
node_count += node_interval
|
("CXX", "CXX"),
|
||||||
sys.stderr.write("progress: %d\n" % node_count)
|
("LINK", "LINK"),
|
||||||
if os.environ.get('SCONS_PROGRESS'):
|
("SHCC", "CC"),
|
||||||
Progress(progress_function, interval=node_interval)
|
("SHCXX", "CXX"),
|
||||||
|
("SHLINK", "LINK"),
|
||||||
|
("AR", "AR"),
|
||||||
|
("RANLIB", "RANLIB"),
|
||||||
|
("AS", "AS"),
|
||||||
|
):
|
||||||
|
env[f"{action}COMSTR"] = f" [{short}] $TARGET"
|
||||||
|
|
||||||
# ********** Cython build environment **********
|
# ********** Cython build environment **********
|
||||||
py_include = sysconfig.get_paths()['include']
|
|
||||||
envCython = env.Clone()
|
envCython = env.Clone()
|
||||||
envCython["CPPPATH"] += [py_include, np.get_include()]
|
envCython["CPPPATH"] += [sysconfig.get_paths()['include'], np.get_include()]
|
||||||
envCython["CCFLAGS"] += ["-Wno-#warnings", "-Wno-shadow", "-Wno-deprecated-declarations"]
|
envCython["CCFLAGS"] += ["-Wno-#warnings", "-Wno-cpp", "-Wno-shadow", "-Wno-deprecated-declarations"]
|
||||||
envCython["CCFLAGS"].remove("-Werror")
|
envCython["CCFLAGS"].remove("-Werror")
|
||||||
|
|
||||||
envCython["LIBS"] = []
|
envCython["LIBS"] = []
|
||||||
@@ -165,18 +225,28 @@ else:
|
|||||||
np_version = SCons.Script.Value(np.__version__)
|
np_version = SCons.Script.Value(np.__version__)
|
||||||
Export('envCython', 'np_version')
|
Export('envCython', 'np_version')
|
||||||
|
|
||||||
Export('env', 'arch')
|
Export('env', 'arch', 'acados', 'release', 'ffmpeg_libs')
|
||||||
|
|
||||||
# Setup cache dir
|
# Setup cache dir
|
||||||
default_cache_dir = '/data/scons_cache' if arch == "larch64" else '/tmp/scons_cache'
|
default_cache_dir = '/data/scons_cache' if arch == "larch64" else '/tmp/scons_cache'
|
||||||
cache_dir = ARGUMENTS.get('cache_dir', default_cache_dir)
|
cache_dir = ARGUMENTS.get('cache_dir', default_cache_dir)
|
||||||
|
cache_size_limit = 4e9 if "CI" in os.environ else 2e9
|
||||||
CacheDir(cache_dir)
|
CacheDir(cache_dir)
|
||||||
Clean(["."], cache_dir)
|
Clean(["."], cache_dir)
|
||||||
|
|
||||||
|
def prune_cache_dir(target=None, source=None, env=None):
|
||||||
|
cache_files = sorted((os.path.join(root, f) for root, _, files in os.walk(cache_dir) for f in files), key=os.path.getmtime)
|
||||||
|
cache_size = sum(os.path.getsize(f) for f in cache_files)
|
||||||
|
for f in cache_files:
|
||||||
|
if cache_size < cache_size_limit:
|
||||||
|
break
|
||||||
|
cache_size -= os.path.getsize(f)
|
||||||
|
os.unlink(f)
|
||||||
|
|
||||||
# ********** start building stuff **********
|
# ********** start building stuff **********
|
||||||
|
|
||||||
# Build common module
|
# Build common module
|
||||||
SConscript(['common/SConscript'])
|
SConscript(['openpilot/common/SConscript'])
|
||||||
Import('_common')
|
Import('_common')
|
||||||
common = [_common, 'json11', 'zmq']
|
common = [_common, 'json11', 'zmq']
|
||||||
Export('common')
|
Export('common')
|
||||||
@@ -186,9 +256,8 @@ Export('common')
|
|||||||
env_swaglog = env.Clone()
|
env_swaglog = env.Clone()
|
||||||
env_swaglog['CXXFLAGS'].append('-DSWAGLOG="\\"common/swaglog.h\\""')
|
env_swaglog['CXXFLAGS'].append('-DSWAGLOG="\\"common/swaglog.h\\""')
|
||||||
SConscript(['msgq_repo/SConscript'], exports={'env': env_swaglog})
|
SConscript(['msgq_repo/SConscript'], exports={'env': env_swaglog})
|
||||||
SConscript(['opendbc_repo/SConscript'], exports={'env': env_swaglog})
|
|
||||||
|
|
||||||
SConscript(['cereal/SConscript'])
|
SConscript(['openpilot/cereal/SConscript'])
|
||||||
|
|
||||||
Import('socketmaster', 'msgq')
|
Import('socketmaster', 'msgq')
|
||||||
messaging = [socketmaster, msgq, 'capnp', 'kj',]
|
messaging = [socketmaster, msgq, 'capnp', 'kj',]
|
||||||
@@ -199,28 +268,79 @@ Export('messaging')
|
|||||||
SConscript(['panda/SConscript'])
|
SConscript(['panda/SConscript'])
|
||||||
|
|
||||||
# Build rednose library
|
# Build rednose library
|
||||||
SConscript(['rednose/SConscript'])
|
SConscript(['rednose_repo/rednose/SConscript'])
|
||||||
|
|
||||||
# Build system services
|
# Build system services
|
||||||
SConscript([
|
SConscript([
|
||||||
'system/ubloxd/SConscript',
|
'openpilot/system/loggerd/SConscript',
|
||||||
'system/loggerd/SConscript',
|
|
||||||
])
|
])
|
||||||
|
|
||||||
if arch == "larch64":
|
if arch == "larch64":
|
||||||
SConscript(['system/camerad/SConscript'])
|
SConscript(['openpilot/system/camerad/SConscript'])
|
||||||
|
|
||||||
# Build openpilot
|
# Build selfdrive
|
||||||
SConscript(['third_party/SConscript'])
|
SConscript([
|
||||||
|
'openpilot/selfdrive/pandad/SConscript',
|
||||||
|
'openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/SConscript',
|
||||||
|
'openpilot/selfdrive/locationd/SConscript',
|
||||||
|
'openpilot/selfdrive/modeld/SConscript',
|
||||||
|
'openpilot/selfdrive/ui/SConscript',
|
||||||
|
])
|
||||||
|
|
||||||
SConscript(['selfdrive/SConscript'])
|
SConscript(['openpilot/sunnypilot/SConscript'])
|
||||||
|
|
||||||
SConscript(['sunnypilot/SConscript'])
|
# Build desktop-only tools
|
||||||
|
if GetOption('extras') and arch != "larch64":
|
||||||
if Dir('#tools/cabana/').exists() and GetOption('extras'):
|
SConscript([
|
||||||
SConscript(['tools/replay/SConscript'])
|
'openpilot/tools/replay/SConscript',
|
||||||
if arch != "larch64":
|
'openpilot/tools/cabana/SConscript',
|
||||||
SConscript(['tools/cabana/SConscript'])
|
'openpilot/tools/jotpluggler/SConscript',
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
env.CompilationDatabase('compile_commands.json')
|
env.CompilationDatabase('compile_commands.json')
|
||||||
|
|
||||||
|
# progress output
|
||||||
|
def count_scons_nodes(nodes):
|
||||||
|
seen = set()
|
||||||
|
stack = list(nodes)
|
||||||
|
|
||||||
|
while stack:
|
||||||
|
node = stack.pop().disambiguate()
|
||||||
|
if node in seen:
|
||||||
|
continue
|
||||||
|
seen.add(node)
|
||||||
|
if hasattr(node, 'has_builder') and node.has_builder():
|
||||||
|
build_product_nodes.add(node)
|
||||||
|
executor = node.get_executor()
|
||||||
|
if executor is not None:
|
||||||
|
stack += executor.get_all_prerequisites() + executor.get_all_children()
|
||||||
|
|
||||||
|
return len(seen)
|
||||||
|
|
||||||
|
progress_interval = 5
|
||||||
|
progress_count = 0
|
||||||
|
build_product_nodes = set()
|
||||||
|
progress_total = max(1, count_scons_nodes(env.arg2nodes(BUILD_TARGETS or [Dir('.')], env.fs.Entry)))
|
||||||
|
|
||||||
|
def progress_function(node):
|
||||||
|
global progress_count
|
||||||
|
if progress_count >= progress_total:
|
||||||
|
return
|
||||||
|
progress_count = min(progress_count + progress_interval, progress_total)
|
||||||
|
progress = round(100. * progress_count / progress_total, 1)
|
||||||
|
sys.stderr.write("\rBuilding: %5.1f%%" % progress if sys.stderr.isatty() else "progress: %.1f\n" % progress)
|
||||||
|
if progress == 100. and sys.stderr.isatty():
|
||||||
|
sys.stderr.write("\n")
|
||||||
|
sys.stderr.flush()
|
||||||
|
|
||||||
|
Progress(progress_function, interval=progress_interval)
|
||||||
|
AddPostAction(BUILD_TARGETS or [Dir('.')], prune_cache_dir)
|
||||||
|
|
||||||
|
def check_build_product_size(target, source, env):
|
||||||
|
limit = 50 * 1024 * 1024 # GitHub max size
|
||||||
|
for t in target:
|
||||||
|
if hasattr(t, 'isfile') and t.isfile() and (size := os.path.getsize(t.abspath)) > limit:
|
||||||
|
raise SCons.Errors.UserError(f"{t} is {size / (1024 * 1024):.1f} MiB, exceeding the {limit / (1024 * 1024):.1f} MiB limit")
|
||||||
|
if not GetOption('extras'):
|
||||||
|
AddPostAction(list(build_product_nodes), Action(check_build_product_size, None))
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
Import('env', 'common', 'msgq')
|
|
||||||
|
|
||||||
cereal_dir = Dir('.')
|
|
||||||
gen_dir = Dir('gen')
|
|
||||||
|
|
||||||
# Build cereal
|
|
||||||
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_files,
|
|
||||||
f"capnpc --src-prefix={cereal_dir.path} $SOURCES -o c++:{gen_dir.path}/cpp/")
|
|
||||||
|
|
||||||
cereal = env.Library('cereal', [f'gen/cpp/{s}.c++' for s in schema_files])
|
|
||||||
|
|
||||||
# Build messaging
|
|
||||||
services_h = env.Command(['services.h'], ['services.py'], 'python3 ' + cereal_dir.path + '/services.py > $TARGET')
|
|
||||||
env.Program('messaging/bridge', ['messaging/bridge.cc', 'messaging/msgq_to_zmq.cc'], LIBS=[msgq, common, 'pthread'])
|
|
||||||
|
|
||||||
socketmaster = env.Library('socketmaster', ['messaging/socketmaster.cc'])
|
|
||||||
|
|
||||||
Export('cereal', 'socketmaster')
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import os
|
|
||||||
import capnp
|
|
||||||
from importlib.resources import as_file, files
|
|
||||||
|
|
||||||
capnp.remove_import_hook()
|
|
||||||
|
|
||||||
with as_file(files("cereal")) as fspath:
|
|
||||||
CEREAL_PATH = fspath.as_posix()
|
|
||||||
log = capnp.load(os.path.join(CEREAL_PATH, "log.capnp"))
|
|
||||||
car = capnp.load(os.path.join(CEREAL_PATH, "car.capnp"))
|
|
||||||
custom = capnp.load(os.path.join(CEREAL_PATH, "custom.capnp"))
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../opendbc_repo/opendbc/car/car.capnp
|
|
||||||
@@ -1,222 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
import argparse
|
|
||||||
import sys
|
|
||||||
from typing import Any, List, Tuple
|
|
||||||
|
|
||||||
DEBUG = False
|
|
||||||
|
|
||||||
|
|
||||||
def print_debug(string: str) -> None:
|
|
||||||
if DEBUG:
|
|
||||||
print(string)
|
|
||||||
|
|
||||||
|
|
||||||
def create_schema_instance(struct: Any, prop: Tuple[str, Any]) -> Any:
|
|
||||||
"""
|
|
||||||
Create a new instance of a schema type, handling different field types.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
struct: The Cap'n Proto schema structure
|
|
||||||
prop: A tuple containing the field name and field metadata
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A new initialized schema instance
|
|
||||||
"""
|
|
||||||
struct_instance = struct.new_message()
|
|
||||||
field_name, field_metadata = prop
|
|
||||||
|
|
||||||
try:
|
|
||||||
field_type = field_metadata.proto.slot.type.which()
|
|
||||||
|
|
||||||
# Initialize different types of fields
|
|
||||||
if field_type in ('list', 'text', 'data'):
|
|
||||||
struct_instance.init(field_name, 1)
|
|
||||||
print_debug(f"Initialized list/text/data field: {field_name}")
|
|
||||||
elif field_type in ('struct', 'object'):
|
|
||||||
struct_instance.init(field_name)
|
|
||||||
print_debug(f"Initialized struct/object field: {field_name}")
|
|
||||||
|
|
||||||
return struct_instance
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error creating instance for {field_name}: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def get_schema_fields(schema_struct: Any) -> List[Tuple[str, Any]]:
|
|
||||||
"""
|
|
||||||
Retrieve all fields from a given schema structure.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
schema_struct: The Cap'n Proto schema structure
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A list of field names and their metadata
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
# Get all fields from the schema
|
|
||||||
schema_fields = list(schema_struct.schema.fields.items())
|
|
||||||
|
|
||||||
print_debug("Discovered schema fields:")
|
|
||||||
for field_name, field_metadata in schema_fields:
|
|
||||||
print_debug(f"- {field_name}")
|
|
||||||
|
|
||||||
return schema_fields
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error retrieving schema fields: {e}")
|
|
||||||
return []
|
|
||||||
|
|
||||||
|
|
||||||
def generate_schema_instances(schema_struct: Any) -> List[Any]:
|
|
||||||
"""
|
|
||||||
Generate instances for all fields in a given schema.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
schema_struct: The Cap'n Proto schema structure
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A list of schema instances
|
|
||||||
"""
|
|
||||||
schema_fields = get_schema_fields(schema_struct)
|
|
||||||
instances = []
|
|
||||||
|
|
||||||
for field_prop in schema_fields:
|
|
||||||
try:
|
|
||||||
instance = create_schema_instance(schema_struct, field_prop)
|
|
||||||
if instance is not None:
|
|
||||||
instances.append(instance)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Skipping field due to error: {e}")
|
|
||||||
|
|
||||||
print(f"Generated {len(instances)} schema instances")
|
|
||||||
return instances
|
|
||||||
|
|
||||||
|
|
||||||
def persist_instances(instances: List[Any], filename: str) -> None:
|
|
||||||
"""
|
|
||||||
Write schema instances to a binary file.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
instances: List of schema instances
|
|
||||||
filename: Output file path
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
with open(filename, 'wb') as f:
|
|
||||||
for instance in instances:
|
|
||||||
f.write(instance.to_bytes())
|
|
||||||
|
|
||||||
print(f"Successfully wrote {len(instances)} instances to {filename}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error persisting instances: {e}")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
def read_instances(filename: str, schema_type: Any) -> List[Any]:
|
|
||||||
"""
|
|
||||||
Read schema instances from a binary file.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
filename: Input file path
|
|
||||||
schema_type: The schema type to use for reading
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A list of read schema instances
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
with open(filename, 'rb') as f:
|
|
||||||
data = f.read()
|
|
||||||
|
|
||||||
instances = list(schema_type.read_multiple_bytes(data))
|
|
||||||
|
|
||||||
print(f"Read {len(instances)} instances from {filename}")
|
|
||||||
return instances
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error reading instances: {e}")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
def compare_schemas(original_instances: List[Any], read_instances: List[Any]) -> bool:
|
|
||||||
"""
|
|
||||||
Compare original and read-back instances to detect potential breaking changes.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
original_instances: List of originally generated instances
|
|
||||||
read_instances: List of instances read back from file
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Boolean indicating whether schemas appear compatible
|
|
||||||
"""
|
|
||||||
if len(original_instances) != len(read_instances):
|
|
||||||
print("❌ Schema Compatibility Warning: Instance count mismatch")
|
|
||||||
return False
|
|
||||||
|
|
||||||
compatible = True
|
|
||||||
for struct in read_instances:
|
|
||||||
try:
|
|
||||||
getattr(struct, struct.which()) # Attempting to access the field to validate readability
|
|
||||||
except Exception as e:
|
|
||||||
print(f"❌ Structural change detected: {struct.which()} is not readable.\nFull error: {e}")
|
|
||||||
compatible = False
|
|
||||||
|
|
||||||
return compatible
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
"""
|
|
||||||
CLI entry point for schema compatibility testing.
|
|
||||||
"""
|
|
||||||
# Setup argument parser
|
|
||||||
parser = argparse.ArgumentParser(
|
|
||||||
description='Cap\'n Proto Schema Compatibility Testing Tool',
|
|
||||||
epilog='Test schema compatibility by generating and reading back instances.'
|
|
||||||
)
|
|
||||||
|
|
||||||
# Add mutually exclusive group for generation or reading mode
|
|
||||||
mode_group = parser.add_mutually_exclusive_group(required=True)
|
|
||||||
mode_group.add_argument('-g', '--generate', action='store_true',
|
|
||||||
help='Generate schema instances')
|
|
||||||
mode_group.add_argument('-r', '--read', action='store_true',
|
|
||||||
help='Read and validate schema instances')
|
|
||||||
|
|
||||||
# Common arguments
|
|
||||||
parser.add_argument('-f', '--file',
|
|
||||||
default='schema_instances.bin',
|
|
||||||
help='Output/input binary file (default: schema_instances.bin)')
|
|
||||||
|
|
||||||
# Parse arguments
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
# Import the schema dynamically
|
|
||||||
try:
|
|
||||||
from cereal import log
|
|
||||||
schema_type = log.Event
|
|
||||||
except ImportError:
|
|
||||||
print("Error: Unable to import schema. Ensure 'cereal' is installed.")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Execute based on mode
|
|
||||||
if args.generate:
|
|
||||||
print("🔧 Generating Schema Instances")
|
|
||||||
instances = generate_schema_instances(schema_type)
|
|
||||||
persist_instances(instances, args.file)
|
|
||||||
print("✅ Instance generation complete")
|
|
||||||
|
|
||||||
elif args.read:
|
|
||||||
print("🔍 Reading and Validating Schema Instances")
|
|
||||||
generated_instances = generate_schema_instances(schema_type)
|
|
||||||
read_back_instances = read_instances(args.file, schema_type)
|
|
||||||
|
|
||||||
# Compare schemas
|
|
||||||
if compare_schemas(generated_instances, read_back_instances):
|
|
||||||
print("✅ Schema Compatibility: No breaking changes detected")
|
|
||||||
sys.exit(0)
|
|
||||||
else:
|
|
||||||
print("❌ Potential Schema Breaking Changes Detected")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
*.cpp
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
#include "common/clutil.h"
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <iostream>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "common/util.h"
|
|
||||||
#include "common/swaglog.h"
|
|
||||||
|
|
||||||
namespace { // helper functions
|
|
||||||
|
|
||||||
template <typename Func, typename Id, typename Name>
|
|
||||||
std::string get_info(Func get_info_func, Id id, Name param_name) {
|
|
||||||
size_t size = 0;
|
|
||||||
CL_CHECK(get_info_func(id, param_name, 0, NULL, &size));
|
|
||||||
std::string info(size, '\0');
|
|
||||||
CL_CHECK(get_info_func(id, param_name, size, info.data(), NULL));
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
inline std::string get_platform_info(cl_platform_id id, cl_platform_info name) { return get_info(&clGetPlatformInfo, id, name); }
|
|
||||||
inline std::string get_device_info(cl_device_id id, cl_device_info name) { return get_info(&clGetDeviceInfo, id, name); }
|
|
||||||
|
|
||||||
void cl_print_info(cl_platform_id platform, cl_device_id device) {
|
|
||||||
size_t work_group_size = 0;
|
|
||||||
cl_device_type device_type = 0;
|
|
||||||
clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(work_group_size), &work_group_size, NULL);
|
|
||||||
clGetDeviceInfo(device, CL_DEVICE_TYPE, sizeof(device_type), &device_type, NULL);
|
|
||||||
const char *type_str = "Other...";
|
|
||||||
switch (device_type) {
|
|
||||||
case CL_DEVICE_TYPE_CPU: type_str ="CL_DEVICE_TYPE_CPU"; break;
|
|
||||||
case CL_DEVICE_TYPE_GPU: type_str = "CL_DEVICE_TYPE_GPU"; break;
|
|
||||||
case CL_DEVICE_TYPE_ACCELERATOR: type_str = "CL_DEVICE_TYPE_ACCELERATOR"; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGD("vendor: %s", get_platform_info(platform, CL_PLATFORM_VENDOR).c_str());
|
|
||||||
LOGD("platform version: %s", get_platform_info(platform, CL_PLATFORM_VERSION).c_str());
|
|
||||||
LOGD("profile: %s", get_platform_info(platform, CL_PLATFORM_PROFILE).c_str());
|
|
||||||
LOGD("extensions: %s", get_platform_info(platform, CL_PLATFORM_EXTENSIONS).c_str());
|
|
||||||
LOGD("name: %s", get_device_info(device, CL_DEVICE_NAME).c_str());
|
|
||||||
LOGD("device version: %s", get_device_info(device, CL_DEVICE_VERSION).c_str());
|
|
||||||
LOGD("max work group size: %zu", work_group_size);
|
|
||||||
LOGD("type = %d, %s", (int)device_type, type_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cl_print_build_errors(cl_program program, cl_device_id device) {
|
|
||||||
cl_build_status status;
|
|
||||||
clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_STATUS, sizeof(status), &status, NULL);
|
|
||||||
size_t log_size;
|
|
||||||
clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size);
|
|
||||||
std::string log(log_size, '\0');
|
|
||||||
clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, log_size, &log[0], NULL);
|
|
||||||
|
|
||||||
LOGE("build failed; status=%d, log: %s", status, log.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
cl_device_id cl_get_device_id(cl_device_type device_type) {
|
|
||||||
cl_uint num_platforms = 0;
|
|
||||||
CL_CHECK(clGetPlatformIDs(0, NULL, &num_platforms));
|
|
||||||
std::unique_ptr<cl_platform_id[]> platform_ids = std::make_unique<cl_platform_id[]>(num_platforms);
|
|
||||||
CL_CHECK(clGetPlatformIDs(num_platforms, &platform_ids[0], NULL));
|
|
||||||
|
|
||||||
for (size_t i = 0; i < num_platforms; ++i) {
|
|
||||||
LOGD("platform[%zu] CL_PLATFORM_NAME: %s", i, get_platform_info(platform_ids[i], CL_PLATFORM_NAME).c_str());
|
|
||||||
|
|
||||||
// Get first device
|
|
||||||
if (cl_device_id device_id = NULL; clGetDeviceIDs(platform_ids[i], device_type, 1, &device_id, NULL) == 0 && device_id) {
|
|
||||||
cl_print_info(platform_ids[i], device_id);
|
|
||||||
return device_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LOGE("No valid openCL platform found");
|
|
||||||
assert(0);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
cl_context cl_create_context(cl_device_id device_id) {
|
|
||||||
return CL_CHECK_ERR(clCreateContext(NULL, 1, &device_id, NULL, NULL, &err));
|
|
||||||
}
|
|
||||||
|
|
||||||
void cl_release_context(cl_context context) {
|
|
||||||
clReleaseContext(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
cl_program cl_program_from_file(cl_context ctx, cl_device_id device_id, const char* path, const char* args) {
|
|
||||||
return cl_program_from_source(ctx, device_id, util::read_file(path), args);
|
|
||||||
}
|
|
||||||
|
|
||||||
cl_program cl_program_from_source(cl_context ctx, cl_device_id device_id, const std::string& src, const char* args) {
|
|
||||||
const char *csrc = src.c_str();
|
|
||||||
cl_program prg = CL_CHECK_ERR(clCreateProgramWithSource(ctx, 1, &csrc, NULL, &err));
|
|
||||||
if (int err = clBuildProgram(prg, 1, &device_id, args, NULL, NULL); err != 0) {
|
|
||||||
cl_print_build_errors(prg, device_id);
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
return prg;
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#include <OpenCL/cl.h>
|
|
||||||
#else
|
|
||||||
#include <CL/cl.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#define CL_CHECK(_expr) \
|
|
||||||
do { \
|
|
||||||
assert(CL_SUCCESS == (_expr)); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define CL_CHECK_ERR(_expr) \
|
|
||||||
({ \
|
|
||||||
cl_int err = CL_INVALID_VALUE; \
|
|
||||||
__typeof__(_expr) _ret = _expr; \
|
|
||||||
assert(_ret&& err == CL_SUCCESS); \
|
|
||||||
_ret; \
|
|
||||||
})
|
|
||||||
|
|
||||||
cl_device_id cl_get_device_id(cl_device_type device_type);
|
|
||||||
cl_context cl_create_context(cl_device_id device_id);
|
|
||||||
void cl_release_context(cl_context context);
|
|
||||||
cl_program cl_program_from_source(cl_context ctx, cl_device_id device_id, const std::string& src, const char* args = nullptr);
|
|
||||||
cl_program cl_program_from_file(cl_context ctx, cl_device_id device_id, const char* path, const char* args);
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
typedef struct vec3 {
|
|
||||||
float v[3];
|
|
||||||
} vec3;
|
|
||||||
|
|
||||||
typedef struct vec4 {
|
|
||||||
float v[4];
|
|
||||||
} vec4;
|
|
||||||
|
|
||||||
typedef struct mat3 {
|
|
||||||
float v[3*3];
|
|
||||||
} mat3;
|
|
||||||
|
|
||||||
typedef struct mat4 {
|
|
||||||
float v[4*4];
|
|
||||||
} mat4;
|
|
||||||
|
|
||||||
static inline mat3 matmul3(const mat3 &a, const mat3 &b) {
|
|
||||||
mat3 ret = {{0.0}};
|
|
||||||
for (int r=0; r<3; r++) {
|
|
||||||
for (int c=0; c<3; c++) {
|
|
||||||
float v = 0.0;
|
|
||||||
for (int k=0; k<3; k++) {
|
|
||||||
v += a.v[r*3+k] * b.v[k*3+c];
|
|
||||||
}
|
|
||||||
ret.v[r*3+c] = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline vec3 matvecmul3(const mat3 &a, const vec3 &b) {
|
|
||||||
vec3 ret = {{0.0}};
|
|
||||||
for (int r=0; r<3; r++) {
|
|
||||||
for (int c=0; c<3; c++) {
|
|
||||||
ret.v[r] += a.v[r*3+c] * b.v[c];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline mat4 matmul(const mat4 &a, const mat4 &b) {
|
|
||||||
mat4 ret = {{0.0}};
|
|
||||||
for (int r=0; r<4; r++) {
|
|
||||||
for (int c=0; c<4; c++) {
|
|
||||||
float v = 0.0;
|
|
||||||
for (int k=0; k<4; k++) {
|
|
||||||
v += a.v[r*4+k] * b.v[k*4+c];
|
|
||||||
}
|
|
||||||
ret.v[r*4+c] = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline vec4 matvecmul(const mat4 &a, const vec4 &b) {
|
|
||||||
vec4 ret = {{0.0}};
|
|
||||||
for (int r=0; r<4; r++) {
|
|
||||||
for (int c=0; c<4; c++) {
|
|
||||||
ret.v[r] += a.v[r*4+c] * b.v[c];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// scales the input and output space of a transformation matrix
|
|
||||||
// that assumes pixel-center origin.
|
|
||||||
static inline mat3 transform_scale_buffer(const mat3 &in, float s) {
|
|
||||||
// in_pt = ( transform(out_pt/s + 0.5) - 0.5) * s
|
|
||||||
|
|
||||||
mat3 transform_out = {{
|
|
||||||
1.0f/s, 0.0f, 0.5f,
|
|
||||||
0.0f, 1.0f/s, 0.5f,
|
|
||||||
0.0f, 0.0f, 1.0f,
|
|
||||||
}};
|
|
||||||
|
|
||||||
mat3 transform_in = {{
|
|
||||||
s, 0.0f, -0.5f*s,
|
|
||||||
0.0f, s, -0.5f*s,
|
|
||||||
0.0f, 0.0f, 1.0f,
|
|
||||||
}};
|
|
||||||
|
|
||||||
return matmul3(transform_in, matmul3(in, transform_out));
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
#define DEFAULT_MODEL "Dark Souls 2 (Default)"
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
#include "catch2/catch.hpp"
|
|
||||||
#define private public
|
|
||||||
#include "common/params.h"
|
|
||||||
#include "common/util.h"
|
|
||||||
|
|
||||||
TEST_CASE("params_nonblocking_put") {
|
|
||||||
char tmp_path[] = "/tmp/asyncWriter_XXXXXX";
|
|
||||||
const std::string param_path = mkdtemp(tmp_path);
|
|
||||||
auto param_names = {"CarParams", "IsMetric"};
|
|
||||||
{
|
|
||||||
Params params(param_path);
|
|
||||||
for (const auto &name : param_names) {
|
|
||||||
params.putNonBlocking(name, "1");
|
|
||||||
// param is empty
|
|
||||||
REQUIRE(params.get(name).empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if thread is running
|
|
||||||
REQUIRE(params.future.valid());
|
|
||||||
REQUIRE(params.future.wait_for(std::chrono::milliseconds(0)) == std::future_status::timeout);
|
|
||||||
}
|
|
||||||
// check results
|
|
||||||
Params p(param_path);
|
|
||||||
for (const auto &name : param_names) {
|
|
||||||
REQUIRE(p.get(name) == "1");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
transformations
|
|
||||||
transformations.cpp
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
Import('env', 'envCython')
|
|
||||||
|
|
||||||
transformations = env.Library('transformations', ['orientation.cc', 'coordinates.cc'])
|
|
||||||
transformations_python = envCython.Program('transformations.so', 'transformations.pyx')
|
|
||||||
Export('transformations', 'transformations_python')
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
# cython: language_level=3
|
|
||||||
from libcpp cimport bool
|
|
||||||
|
|
||||||
cdef extern from "orientation.cc":
|
|
||||||
pass
|
|
||||||
|
|
||||||
cdef extern from "orientation.hpp":
|
|
||||||
cdef cppclass Quaternion "Eigen::Quaterniond":
|
|
||||||
Quaternion()
|
|
||||||
Quaternion(double, double, double, double)
|
|
||||||
double w()
|
|
||||||
double x()
|
|
||||||
double y()
|
|
||||||
double z()
|
|
||||||
|
|
||||||
cdef cppclass Vector3 "Eigen::Vector3d":
|
|
||||||
Vector3()
|
|
||||||
Vector3(double, double, double)
|
|
||||||
double operator()(int)
|
|
||||||
|
|
||||||
cdef cppclass Matrix3 "Eigen::Matrix3d":
|
|
||||||
Matrix3()
|
|
||||||
Matrix3(double*)
|
|
||||||
|
|
||||||
double operator()(int, int)
|
|
||||||
|
|
||||||
Quaternion euler2quat(const Vector3 &)
|
|
||||||
Vector3 quat2euler(const Quaternion &)
|
|
||||||
Matrix3 quat2rot(const Quaternion &)
|
|
||||||
Quaternion rot2quat(const Matrix3 &)
|
|
||||||
Vector3 rot2euler(const Matrix3 &)
|
|
||||||
Matrix3 euler2rot(const Vector3 &)
|
|
||||||
Matrix3 rot_matrix(double, double, double)
|
|
||||||
Vector3 ecef_euler_from_ned(const ECEF &, const Vector3 &)
|
|
||||||
Vector3 ned_euler_from_ecef(const ECEF &, const Vector3 &)
|
|
||||||
|
|
||||||
|
|
||||||
cdef extern from "coordinates.cc":
|
|
||||||
cdef struct ECEF:
|
|
||||||
double x
|
|
||||||
double y
|
|
||||||
double z
|
|
||||||
|
|
||||||
cdef struct NED:
|
|
||||||
double n
|
|
||||||
double e
|
|
||||||
double d
|
|
||||||
|
|
||||||
cdef struct Geodetic:
|
|
||||||
double lat
|
|
||||||
double lon
|
|
||||||
double alt
|
|
||||||
bool radians
|
|
||||||
|
|
||||||
ECEF geodetic2ecef(const Geodetic &)
|
|
||||||
Geodetic ecef2geodetic(const ECEF &)
|
|
||||||
|
|
||||||
cdef cppclass LocalCoord_c "LocalCoord":
|
|
||||||
Matrix3 ned2ecef_matrix
|
|
||||||
Matrix3 ecef2ned_matrix
|
|
||||||
|
|
||||||
LocalCoord_c(const Geodetic &, const ECEF &)
|
|
||||||
LocalCoord_c(const Geodetic &)
|
|
||||||
LocalCoord_c(const ECEF &)
|
|
||||||
|
|
||||||
NED ecef2ned(const ECEF &)
|
|
||||||
ECEF ned2ecef(const NED &)
|
|
||||||
NED geodetic2ned(const Geodetic &)
|
|
||||||
Geodetic ned2geodetic(const NED &)
|
|
||||||
|
|
||||||
cdef extern from "coordinates.hpp":
|
|
||||||
pass
|
|
||||||
@@ -1,173 +0,0 @@
|
|||||||
# distutils: language = c++
|
|
||||||
# cython: language_level = 3
|
|
||||||
from openpilot.common.transformations.transformations cimport Matrix3, Vector3, Quaternion
|
|
||||||
from openpilot.common.transformations.transformations cimport ECEF, NED, Geodetic
|
|
||||||
|
|
||||||
from openpilot.common.transformations.transformations cimport euler2quat as euler2quat_c
|
|
||||||
from openpilot.common.transformations.transformations cimport quat2euler as quat2euler_c
|
|
||||||
from openpilot.common.transformations.transformations cimport quat2rot as quat2rot_c
|
|
||||||
from openpilot.common.transformations.transformations cimport rot2quat as rot2quat_c
|
|
||||||
from openpilot.common.transformations.transformations cimport euler2rot as euler2rot_c
|
|
||||||
from openpilot.common.transformations.transformations cimport rot2euler as rot2euler_c
|
|
||||||
from openpilot.common.transformations.transformations cimport rot_matrix as rot_matrix_c
|
|
||||||
from openpilot.common.transformations.transformations cimport ecef_euler_from_ned as ecef_euler_from_ned_c
|
|
||||||
from openpilot.common.transformations.transformations cimport ned_euler_from_ecef as ned_euler_from_ecef_c
|
|
||||||
from openpilot.common.transformations.transformations cimport geodetic2ecef as geodetic2ecef_c
|
|
||||||
from openpilot.common.transformations.transformations cimport ecef2geodetic as ecef2geodetic_c
|
|
||||||
from openpilot.common.transformations.transformations cimport LocalCoord_c
|
|
||||||
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
cimport numpy as np
|
|
||||||
|
|
||||||
cdef np.ndarray[double, ndim=2] matrix2numpy(Matrix3 m):
|
|
||||||
return np.array([
|
|
||||||
[m(0, 0), m(0, 1), m(0, 2)],
|
|
||||||
[m(1, 0), m(1, 1), m(1, 2)],
|
|
||||||
[m(2, 0), m(2, 1), m(2, 2)],
|
|
||||||
])
|
|
||||||
|
|
||||||
cdef Matrix3 numpy2matrix(np.ndarray[double, ndim=2, mode="fortran"] m):
|
|
||||||
assert m.shape[0] == 3
|
|
||||||
assert m.shape[1] == 3
|
|
||||||
return Matrix3(<double*>m.data)
|
|
||||||
|
|
||||||
cdef ECEF list2ecef(ecef):
|
|
||||||
cdef ECEF e
|
|
||||||
e.x = ecef[0]
|
|
||||||
e.y = ecef[1]
|
|
||||||
e.z = ecef[2]
|
|
||||||
return e
|
|
||||||
|
|
||||||
cdef NED list2ned(ned):
|
|
||||||
cdef NED n
|
|
||||||
n.n = ned[0]
|
|
||||||
n.e = ned[1]
|
|
||||||
n.d = ned[2]
|
|
||||||
return n
|
|
||||||
|
|
||||||
cdef Geodetic list2geodetic(geodetic):
|
|
||||||
cdef Geodetic g
|
|
||||||
g.lat = geodetic[0]
|
|
||||||
g.lon = geodetic[1]
|
|
||||||
g.alt = geodetic[2]
|
|
||||||
return g
|
|
||||||
|
|
||||||
def euler2quat_single(euler):
|
|
||||||
cdef Vector3 e = Vector3(euler[0], euler[1], euler[2])
|
|
||||||
cdef Quaternion q = euler2quat_c(e)
|
|
||||||
return [q.w(), q.x(), q.y(), q.z()]
|
|
||||||
|
|
||||||
def quat2euler_single(quat):
|
|
||||||
cdef Quaternion q = Quaternion(quat[0], quat[1], quat[2], quat[3])
|
|
||||||
cdef Vector3 e = quat2euler_c(q)
|
|
||||||
return [e(0), e(1), e(2)]
|
|
||||||
|
|
||||||
def quat2rot_single(quat):
|
|
||||||
cdef Quaternion q = Quaternion(quat[0], quat[1], quat[2], quat[3])
|
|
||||||
cdef Matrix3 r = quat2rot_c(q)
|
|
||||||
return matrix2numpy(r)
|
|
||||||
|
|
||||||
def rot2quat_single(rot):
|
|
||||||
cdef Matrix3 r = numpy2matrix(np.asfortranarray(rot, dtype=np.double))
|
|
||||||
cdef Quaternion q = rot2quat_c(r)
|
|
||||||
return [q.w(), q.x(), q.y(), q.z()]
|
|
||||||
|
|
||||||
def euler2rot_single(euler):
|
|
||||||
cdef Vector3 e = Vector3(euler[0], euler[1], euler[2])
|
|
||||||
cdef Matrix3 r = euler2rot_c(e)
|
|
||||||
return matrix2numpy(r)
|
|
||||||
|
|
||||||
def rot2euler_single(rot):
|
|
||||||
cdef Matrix3 r = numpy2matrix(np.asfortranarray(rot, dtype=np.double))
|
|
||||||
cdef Vector3 e = rot2euler_c(r)
|
|
||||||
return [e(0), e(1), e(2)]
|
|
||||||
|
|
||||||
def rot_matrix(roll, pitch, yaw):
|
|
||||||
return matrix2numpy(rot_matrix_c(roll, pitch, yaw))
|
|
||||||
|
|
||||||
def ecef_euler_from_ned_single(ecef_init, ned_pose):
|
|
||||||
cdef ECEF init = list2ecef(ecef_init)
|
|
||||||
cdef Vector3 pose = Vector3(ned_pose[0], ned_pose[1], ned_pose[2])
|
|
||||||
|
|
||||||
cdef Vector3 e = ecef_euler_from_ned_c(init, pose)
|
|
||||||
return [e(0), e(1), e(2)]
|
|
||||||
|
|
||||||
def ned_euler_from_ecef_single(ecef_init, ecef_pose):
|
|
||||||
cdef ECEF init = list2ecef(ecef_init)
|
|
||||||
cdef Vector3 pose = Vector3(ecef_pose[0], ecef_pose[1], ecef_pose[2])
|
|
||||||
|
|
||||||
cdef Vector3 e = ned_euler_from_ecef_c(init, pose)
|
|
||||||
return [e(0), e(1), e(2)]
|
|
||||||
|
|
||||||
def geodetic2ecef_single(geodetic):
|
|
||||||
cdef Geodetic g = list2geodetic(geodetic)
|
|
||||||
cdef ECEF e = geodetic2ecef_c(g)
|
|
||||||
return [e.x, e.y, e.z]
|
|
||||||
|
|
||||||
def ecef2geodetic_single(ecef):
|
|
||||||
cdef ECEF e = list2ecef(ecef)
|
|
||||||
cdef Geodetic g = ecef2geodetic_c(e)
|
|
||||||
return [g.lat, g.lon, g.alt]
|
|
||||||
|
|
||||||
|
|
||||||
cdef class LocalCoord:
|
|
||||||
cdef LocalCoord_c * lc
|
|
||||||
|
|
||||||
def __init__(self, geodetic=None, ecef=None):
|
|
||||||
assert (geodetic is not None) or (ecef is not None)
|
|
||||||
if geodetic is not None:
|
|
||||||
self.lc = new LocalCoord_c(list2geodetic(geodetic))
|
|
||||||
elif ecef is not None:
|
|
||||||
self.lc = new LocalCoord_c(list2ecef(ecef))
|
|
||||||
|
|
||||||
@property
|
|
||||||
def ned2ecef_matrix(self):
|
|
||||||
return matrix2numpy(self.lc.ned2ecef_matrix)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def ecef2ned_matrix(self):
|
|
||||||
return matrix2numpy(self.lc.ecef2ned_matrix)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def ned_from_ecef_matrix(self):
|
|
||||||
return self.ecef2ned_matrix
|
|
||||||
|
|
||||||
@property
|
|
||||||
def ecef_from_ned_matrix(self):
|
|
||||||
return self.ned2ecef_matrix
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_geodetic(cls, geodetic):
|
|
||||||
return cls(geodetic=geodetic)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_ecef(cls, ecef):
|
|
||||||
return cls(ecef=ecef)
|
|
||||||
|
|
||||||
def ecef2ned_single(self, ecef):
|
|
||||||
assert self.lc
|
|
||||||
cdef ECEF e = list2ecef(ecef)
|
|
||||||
cdef NED n = self.lc.ecef2ned(e)
|
|
||||||
return [n.n, n.e, n.d]
|
|
||||||
|
|
||||||
def ned2ecef_single(self, ned):
|
|
||||||
assert self.lc
|
|
||||||
cdef NED n = list2ned(ned)
|
|
||||||
cdef ECEF e = self.lc.ned2ecef(n)
|
|
||||||
return [e.x, e.y, e.z]
|
|
||||||
|
|
||||||
def geodetic2ned_single(self, geodetic):
|
|
||||||
assert self.lc
|
|
||||||
cdef Geodetic g = list2geodetic(geodetic)
|
|
||||||
cdef NED n = self.lc.geodetic2ned(g)
|
|
||||||
return [n.n, n.e, n.d]
|
|
||||||
|
|
||||||
def ned2geodetic_single(self, ned):
|
|
||||||
assert self.lc
|
|
||||||
cdef NED n = list2ned(ned)
|
|
||||||
cdef Geodetic g = self.lc.ned2geodetic(n)
|
|
||||||
return [g.lat, g.lon, g.alt]
|
|
||||||
|
|
||||||
def __dealloc__(self):
|
|
||||||
del self.lc
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
import os
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
def sudo_write(val: str, path: str) -> None:
|
|
||||||
try:
|
|
||||||
with open(path, 'w') as f:
|
|
||||||
f.write(str(val))
|
|
||||||
except PermissionError:
|
|
||||||
os.system(f"sudo chmod a+w {path}")
|
|
||||||
try:
|
|
||||||
with open(path, 'w') as f:
|
|
||||||
f.write(str(val))
|
|
||||||
except PermissionError:
|
|
||||||
# fallback for debugfs files
|
|
||||||
os.system(f"sudo su -c 'echo {val} > {path}'")
|
|
||||||
|
|
||||||
def sudo_read(path: str) -> str:
|
|
||||||
try:
|
|
||||||
return subprocess.check_output(f"sudo cat {path}", shell=True, encoding='utf8').strip()
|
|
||||||
except Exception:
|
|
||||||
return ""
|
|
||||||
|
|
||||||
class MovingAverage:
|
|
||||||
def __init__(self, window_size: int):
|
|
||||||
self.window_size: int = window_size
|
|
||||||
self.buffer: list[float] = [0.0] * window_size
|
|
||||||
self.index: int = 0
|
|
||||||
self.count: int = 0
|
|
||||||
self.sum: float = 0.0
|
|
||||||
|
|
||||||
def add_value(self, new_value: float):
|
|
||||||
# Update the sum: subtract the value being replaced and add the new value
|
|
||||||
self.sum -= self.buffer[self.index]
|
|
||||||
self.buffer[self.index] = new_value
|
|
||||||
self.sum += new_value
|
|
||||||
|
|
||||||
# Update the index in a circular manner
|
|
||||||
self.index = (self.index + 1) % self.window_size
|
|
||||||
|
|
||||||
# Track the number of added values (for partial windows)
|
|
||||||
self.count = min(self.count + 1, self.window_size)
|
|
||||||
|
|
||||||
def get_average(self) -> float:
|
|
||||||
if self.count == 0:
|
|
||||||
return float('nan')
|
|
||||||
return self.sum / self.count
|
|
||||||
-118
@@ -1,118 +0,0 @@
|
|||||||
import io
|
|
||||||
import os
|
|
||||||
import tempfile
|
|
||||||
import contextlib
|
|
||||||
import subprocess
|
|
||||||
import time
|
|
||||||
import functools
|
|
||||||
from subprocess import Popen, PIPE, TimeoutExpired
|
|
||||||
import zstandard as zstd
|
|
||||||
from openpilot.common.swaglog import cloudlog
|
|
||||||
|
|
||||||
LOG_COMPRESSION_LEVEL = 10 # little benefit up to level 15. level ~17 is a small step change
|
|
||||||
|
|
||||||
|
|
||||||
class CallbackReader:
|
|
||||||
"""Wraps a file, but overrides the read method to also
|
|
||||||
call a callback function with the number of bytes read so far."""
|
|
||||||
def __init__(self, f, callback, *args):
|
|
||||||
self.f = f
|
|
||||||
self.callback = callback
|
|
||||||
self.cb_args = args
|
|
||||||
self.total_read = 0
|
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
|
||||||
return getattr(self.f, attr)
|
|
||||||
|
|
||||||
def read(self, *args, **kwargs):
|
|
||||||
chunk = self.f.read(*args, **kwargs)
|
|
||||||
self.total_read += len(chunk)
|
|
||||||
self.callback(*self.cb_args, self.total_read)
|
|
||||||
return chunk
|
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
|
||||||
def atomic_write(path: str, mode: str = 'w', buffering: int = -1, encoding: str | None = None, newline: str | None = None,
|
|
||||||
overwrite: bool = False):
|
|
||||||
"""Write to a file atomically using a temporary file in the same directory as the destination file."""
|
|
||||||
dir_name = os.path.dirname(path)
|
|
||||||
|
|
||||||
if not overwrite and os.path.exists(path):
|
|
||||||
raise FileExistsError(f"File '{path}' already exists. To overwrite it, set 'overwrite' to True.")
|
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile(mode=mode, buffering=buffering, encoding=encoding, newline=newline, dir=dir_name, delete=False) as tmp_file:
|
|
||||||
yield tmp_file
|
|
||||||
tmp_file_name = tmp_file.name
|
|
||||||
os.replace(tmp_file_name, path)
|
|
||||||
|
|
||||||
|
|
||||||
def get_upload_stream(filepath: str, should_compress: bool) -> tuple[io.BufferedIOBase, int]:
|
|
||||||
if not should_compress:
|
|
||||||
file_size = os.path.getsize(filepath)
|
|
||||||
file_stream = open(filepath, "rb")
|
|
||||||
return file_stream, file_size
|
|
||||||
|
|
||||||
# Compress the file on the fly
|
|
||||||
compressed_stream = io.BytesIO()
|
|
||||||
compressor = zstd.ZstdCompressor(level=LOG_COMPRESSION_LEVEL)
|
|
||||||
|
|
||||||
with open(filepath, "rb") as f:
|
|
||||||
compressor.copy_stream(f, compressed_stream)
|
|
||||||
compressed_size = compressed_stream.tell()
|
|
||||||
compressed_stream.seek(0)
|
|
||||||
return compressed_stream, compressed_size
|
|
||||||
|
|
||||||
|
|
||||||
# remove all keys that end in DEPRECATED
|
|
||||||
def strip_deprecated_keys(d):
|
|
||||||
for k in list(d.keys()):
|
|
||||||
if isinstance(k, str):
|
|
||||||
if k.endswith('DEPRECATED'):
|
|
||||||
d.pop(k)
|
|
||||||
elif isinstance(d[k], dict):
|
|
||||||
strip_deprecated_keys(d[k])
|
|
||||||
return d
|
|
||||||
|
|
||||||
|
|
||||||
def run_cmd(cmd: list[str], cwd=None, env=None) -> str:
|
|
||||||
return subprocess.check_output(cmd, encoding='utf8', cwd=cwd, env=env).strip()
|
|
||||||
|
|
||||||
|
|
||||||
def run_cmd_default(cmd: list[str], default: str = "", cwd=None, env=None) -> str:
|
|
||||||
try:
|
|
||||||
return run_cmd(cmd, cwd=cwd, env=env)
|
|
||||||
except subprocess.CalledProcessError:
|
|
||||||
return default
|
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
|
||||||
def managed_proc(cmd: list[str], env: dict[str, str]):
|
|
||||||
proc = Popen(cmd, env=env, stdout=PIPE, stderr=PIPE)
|
|
||||||
try:
|
|
||||||
yield proc
|
|
||||||
finally:
|
|
||||||
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 decorator(func):
|
|
||||||
@functools.wraps(func)
|
|
||||||
def wrapper(*args, **kwargs):
|
|
||||||
for _ in range(attempts):
|
|
||||||
try:
|
|
||||||
return func(*args, **kwargs)
|
|
||||||
except Exception:
|
|
||||||
cloudlog.exception(f"{func.__name__} failed, trying again")
|
|
||||||
time.sleep(delay)
|
|
||||||
|
|
||||||
if ignore_failure:
|
|
||||||
cloudlog.error(f"{func.__name__} failed after retry")
|
|
||||||
else:
|
|
||||||
raise Exception(f"{func.__name__} failed after retry")
|
|
||||||
return wrapper
|
|
||||||
return decorator
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
#define COMMA_VERSION "0.10.3"
|
|
||||||
+10
-23
@@ -5,19 +5,18 @@ import pytest
|
|||||||
|
|
||||||
from openpilot.common.prefix import OpenpilotPrefix
|
from openpilot.common.prefix import OpenpilotPrefix
|
||||||
from openpilot.system.manager import manager
|
from openpilot.system.manager import manager
|
||||||
from openpilot.system.hardware import TICI, HARDWARE
|
from openpilot.common.hardware import TICI, HARDWARE
|
||||||
|
|
||||||
# TODO: pytest-cpp doesn't support FAIL, and we need to create test translations in sessionstart
|
# these are heavy CI-only tests, invoked explicitly in .github/workflows/tests.yaml
|
||||||
# pending https://github.com/pytest-dev/pytest-cpp/pull/147
|
|
||||||
collect_ignore = [
|
collect_ignore = [
|
||||||
"selfdrive/ui/tests/test_translations",
|
"openpilot/selfdrive/test/process_replay/test_processes.py",
|
||||||
"selfdrive/test/process_replay/test_processes.py",
|
"openpilot/selfdrive/test/process_replay/test_regen.py",
|
||||||
"selfdrive/test/process_replay/test_regen.py",
|
|
||||||
]
|
"openpilot/tools/sim/",
|
||||||
collect_ignore_glob = [
|
|
||||||
"selfdrive/debug/*.py",
|
# tinygrad JIT has process-global state. Other test files import modeld → tinygrad,
|
||||||
"selfdrive/modeld/*.py",
|
# which corrupts JIT captures for test_warp.py in the same process. Run separately in CI.
|
||||||
"sunnypilot/modeld*/*.py",
|
"openpilot/sunnypilot/modeld_v2/tests/test_warp.py",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -98,15 +97,3 @@ def pytest_collection_modifyitems(config, items):
|
|||||||
class_property_name = item.get_closest_marker('xdist_group_class_property').args[0]
|
class_property_name = item.get_closest_marker('xdist_group_class_property').args[0]
|
||||||
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))
|
||||||
|
|
||||||
|
|
||||||
@pytest.hookimpl(trylast=True)
|
|
||||||
def pytest_configure(config):
|
|
||||||
config_line = "xdist_group_class_property: group tests by a property of the class that contains them"
|
|
||||||
config.addinivalue_line("markers", config_line)
|
|
||||||
|
|
||||||
config_line = "nocapture: don't capture test output"
|
|
||||||
config.addinivalue_line("markers", config_line)
|
|
||||||
|
|
||||||
config_line = "shared_download_cache: share download cache between tests"
|
|
||||||
config.addinivalue_line("markers", config_line)
|
|
||||||
|
|||||||
+179
-177
@@ -10,22 +10,21 @@ A supported vehicle is one that just works when you install a comma device. All
|
|||||||
|---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
|---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||||
|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|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-26|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-26">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|TLX 2021-22|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-22">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 2025|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=Acura TLX 2025">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>|||
|
|Audi[<sup>12</sup>](#footnotes)|A3 2014-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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|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>|||
|
|Audi[<sup>12</sup>](#footnotes)|A3 Sportback e-tron 2017-18|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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>|||
|
||||||
|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>|||
|
|Audi[<sup>12</sup>](#footnotes)|Q2 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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>|||
|
||||||
|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[<sup>12</sup>](#footnotes)|Q3 2019-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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|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[<sup>12</sup>](#footnotes)|RS3 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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>|||
|
||||||
|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[<sup>12</sup>](#footnotes)|S3 2015-17|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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>|||
|
||||||
|
|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" /></a>||
|
||||||
|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>|||
|
|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>|||
|
||||||
|Chevrolet|Bolt EV Non-ACC 2017|Adaptive Cruise Control (ACC)|Stock|24 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 Bolt EV Non-ACC 2017">Buy Here</a></sub></details>|||
|
|
||||||
|Chevrolet|Bolt EV Non-ACC 2018-21|Adaptive Cruise Control (ACC)|Stock|24 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 Bolt EV Non-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|Malibu Non-ACC 2016-23|Adaptive Cruise Control (ACC)|Stock|24 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 Non-ACC 2016-23">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|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|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>|||
|
||||||
|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>|||
|
||||||
@@ -33,34 +32,34 @@ A supported vehicle is one that just works when you install a comma device. All
|
|||||||
|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" /></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[<sup>12</sup>](#footnotes)|Ateca 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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>|||
|
||||||
|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|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|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|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 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" /></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|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 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" /></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|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 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" /></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 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" /></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|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|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 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" /></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 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" /></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|Focus 2018-22[<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-22">Buy Here</a></sub></details>|||
|
||||||
|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 Hybrid 2018-22[<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-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|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|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 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 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 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" /></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|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 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" /></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|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|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|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|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|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 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" /></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 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" /></a>|
|
||||||
|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>|||
|
||||||
@@ -75,37 +74,38 @@ A supported vehicle is one that just works when you install a comma device. All
|
|||||||
|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>||
|
|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" /></a>||
|
||||||
|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>||
|
|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" /></a>||
|
||||||
|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>|||
|
|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>|||
|
||||||
|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>|||
|
|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|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>|||
|
|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>|||
|
||||||
|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>|||
|
|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" /></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" /></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" /></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" /></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|Honda Sensing|openpilot|0 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector + Honda Clarity Proxy Board<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://shop.retropilot.org/product/honda-clarity-proxy-board-kit">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|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 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-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 Hybrid 2023-26">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|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|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|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>|||
|
||||||
@@ -117,16 +117,16 @@ A supported vehicle is one that just works when you install a comma device. All
|
|||||||
|Hyundai|Custin 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 Custin 2023">Buy Here</a></sub></details>|||
|
|Hyundai|Custin 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 Custin 2023">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 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" /></a>||
|
||||||
|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" /></a>||
|
||||||
|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|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|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 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 6 (without HDA II) 2023-24|Highway Driving Assist|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=Hyundai Ioniq 6 (without HDA II) 2023-24">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>|||
|
||||||
@@ -137,19 +137,17 @@ A supported vehicle is one that just works when you install a comma device. All
|
|||||||
|Hyundai|Kona 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 2022-23">Buy Here</a></sub></details>|||
|
|Hyundai|Kona 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 2022-23">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)|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" /></a>||
|
||||||
|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 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 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>|||
|
|
||||||
|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" /></a>||
|
||||||
|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 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" /></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" /></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 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" /></a>||
|
||||||
|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|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>|||
|
||||||
@@ -159,31 +157,30 @@ A supported vehicle is one that just works when you install a comma device. All
|
|||||||
|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 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|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" /></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" /></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 (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|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|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|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 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|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|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|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 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|K7 2017|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 K7 2017">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" /></a>||
|
||||||
|Kia|Niro EV 2020|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=Kia Niro EV 2020">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 2020|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=Kia Niro EV 2020">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=lT7zcG6ZpGo" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||||
|Kia|Niro EV 2021|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=Kia Niro EV 2021">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 2021|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=Kia Niro EV 2021">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=lT7zcG6ZpGo" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||||
|Kia|Niro EV 2022|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 2022">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 2022|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 2022">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=lT7zcG6ZpGo" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||||
|Kia|Niro EV (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 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 Niro EV (with HDA II) 2025">Buy Here</a></sub></details>|||
|
|Kia|Niro EV (with HDA II) 2024-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=Kia Niro EV (with HDA II) 2024-25">Buy Here</a></sub></details>|||
|
||||||
|Kia|Niro EV (without HDA II) 2023-25|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 Niro EV (without HDA II) 2023-25">Buy Here</a></sub></details>|||
|
|Kia|Niro EV (without HDA II) 2023-25|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 Niro EV (without HDA II) 2023-25">Buy Here</a></sub></details>|||
|
||||||
|Kia|Niro Hybrid 2018|Smart Cruise Control (SCC)|Stock|10 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=Kia Niro Hybrid 2018">Buy Here</a></sub></details>|||
|
|Kia|Niro Hybrid 2018|Smart Cruise Control (SCC)|Stock|10 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=Kia Niro Hybrid 2018">Buy Here</a></sub></details>|||
|
||||||
|Kia|Niro Hybrid 2021|Smart Cruise Control (SCC)|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=Kia Niro Hybrid 2021">Buy Here</a></sub></details>|||
|
|Kia|Niro Hybrid 2021|Smart Cruise Control (SCC)|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=Kia Niro Hybrid 2021">Buy Here</a></sub></details>|||
|
||||||
|Kia|Niro Hybrid 2022|Smart Cruise Control (SCC)|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=Kia Niro Hybrid 2022">Buy Here</a></sub></details>|||
|
|Kia|Niro Hybrid 2022|Smart Cruise Control (SCC)|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=Kia Niro Hybrid 2022">Buy Here</a></sub></details>|||
|
||||||
|Kia|Niro Hybrid 2023|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 Niro Hybrid 2023">Buy Here</a></sub></details>|||
|
|Kia|Niro Hybrid 2023-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 Niro Hybrid 2023-24">Buy Here</a></sub></details>|||
|
||||||
|Kia|Niro Plug-in Hybrid 2018-19|All|Stock|10 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=Kia Niro Plug-in Hybrid 2018-19">Buy Here</a></sub></details>|||
|
|Kia|Niro Plug-in Hybrid 2018-19|All|Stock|10 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=Kia Niro Plug-in Hybrid 2018-19">Buy Here</a></sub></details>|||
|
||||||
|Kia|Niro Plug-in Hybrid 2020|Smart Cruise Control (SCC)|Stock|0 mph|32 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=Kia Niro Plug-in Hybrid 2020">Buy Here</a></sub></details>|||
|
|Kia|Niro Plug-in Hybrid 2020|Smart Cruise Control (SCC)|Stock|0 mph|32 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=Kia Niro Plug-in Hybrid 2020">Buy Here</a></sub></details>|||
|
||||||
|Kia|Niro 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 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=Kia Niro Plug-in Hybrid 2021">Buy Here</a></sub></details>|||
|
|Kia|Niro 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 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=Kia Niro Plug-in Hybrid 2021">Buy Here</a></sub></details>|||
|
||||||
@@ -192,25 +189,26 @@ A supported vehicle is one that just works when you install a comma device. All
|
|||||||
|Kia|Optima 2019-20|Smart Cruise Control (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 Optima 2019-20">Buy Here</a></sub></details>|||
|
|Kia|Optima 2019-20|Smart Cruise Control (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 Optima 2019-20">Buy Here</a></sub></details>|||
|
||||||
|Kia|Optima Hybrid 2019|Smart Cruise Control (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 Optima Hybrid 2019">Buy Here</a></sub></details>|||
|
|Kia|Optima Hybrid 2019|Smart Cruise Control (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 Optima Hybrid 2019">Buy Here</a></sub></details>|||
|
||||||
|Kia|Seltos 2021|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 Seltos 2021">Buy Here</a></sub></details>|||
|
|Kia|Seltos 2021|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 Seltos 2021">Buy Here</a></sub></details>|||
|
||||||
|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" /></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" /></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 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 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 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|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" /></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>|||
|
||||||
|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>|||
|
||||||
|Lexus|ES Hybrid 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 Hybrid 2017-18">Buy Here</a></sub></details>|||
|
|Lexus|ES Hybrid 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 Hybrid 2017-18">Buy Here</a></sub></details>|||
|
||||||
|Lexus|ES Hybrid 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 Hybrid 2019-25">Buy Here</a></sub></details>|<a href="https://youtu.be/BZ29osRVJeg?t=12" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Lexus|ES Hybrid 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 Hybrid 2019-25">Buy Here</a></sub></details>|<a href="https://youtu.be/BZ29osRVJeg?t=12" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||||
|Lexus|GS F 2016|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 GS F 2016">Buy Here</a></sub></details>|||
|
|Lexus|GS F 2016|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 GS F 2016">Buy Here</a></sub></details>|||
|
||||||
|Lexus|IS 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=Lexus IS 2017-19">Buy Here</a></sub></details>|||
|
|Lexus|IS 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=Lexus IS 2017-19">Buy Here</a></sub></details>|||
|
||||||
|Lexus|IS 2022-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 IS 2022-24">Buy Here</a></sub></details>|||
|
|Lexus|IS 2022-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 IS 2022-24">Buy Here</a></sub></details>|||
|
||||||
|Lexus|LC 2024-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 LC 2024-25">Buy Here</a></sub></details>|||
|
|Lexus|LC 2024-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 LC 2024-25">Buy Here</a></sub></details>|||
|
||||||
|
|Lexus|LS 2018|All except Lexus Safety System+ A|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 LS 2018">Buy Here</a></sub></details>|||
|
||||||
|Lexus|NX 2018-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 NX 2018-19">Buy Here</a></sub></details>|||
|
|Lexus|NX 2018-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 NX 2018-19">Buy Here</a></sub></details>|||
|
||||||
|Lexus|NX 2020-21|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 NX 2020-21">Buy Here</a></sub></details>|||
|
|Lexus|NX 2020-21|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 NX 2020-21">Buy Here</a></sub></details>|||
|
||||||
|Lexus|NX Hybrid 2018-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 NX Hybrid 2018-19">Buy Here</a></sub></details>|||
|
|Lexus|NX Hybrid 2018-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 NX Hybrid 2018-19">Buy Here</a></sub></details>|||
|
||||||
@@ -226,48 +224,50 @@ A supported vehicle is one that just works when you install a comma device. All
|
|||||||
|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|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|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[<sup>12</sup>](#footnotes)|eTGE 2020-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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" /></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[<sup>12</sup>](#footnotes)|TGE 2017-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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" /></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" /></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-24|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 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-24">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-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 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" /></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)|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 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>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)|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 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>|||
|
||||||
|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>|||
|
|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>|||
|
||||||
|Ram|2500 2020-24|Adaptive Cruise Control (ACC)|Stock|0 mph|36 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 2500 2020-24">Buy Here</a></sub></details>|||
|
|Ram|2500 2020-24|Adaptive Cruise Control (ACC)|Stock|0 mph|36 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 2500 2020-24">Buy Here</a></sub></details>|||
|
||||||
|Ram|3500 2019-22|Adaptive Cruise Control (ACC)|Stock|0 mph|36 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 3500 2019-22">Buy Here</a></sub></details>|||
|
|Ram|3500 2019-22|Adaptive Cruise Control (ACC)|Stock|0 mph|36 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 3500 2019-22">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>|
|
|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 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" /></a>|
|
||||||
|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 2025|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Rivian B connector<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|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|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 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" /></a>|
|
||||||
|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 2025|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Rivian B connector<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|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>|||
|
|SEAT[<sup>12</sup>](#footnotes)|Ateca 2016-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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 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[<sup>12</sup>](#footnotes)|Leon 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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|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>|||
|
|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|Forester 2017-18|EyeSight Driver Assistance[<sup>6</sup>](#footnotes)|Stock|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 2017-18">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" /></a>||
|
||||||
|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|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|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|Forester 2017-18|EyeSight Driver Assistance[<sup>7</sup>](#footnotes)|Stock|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 2017-18">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|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|Legacy 2015-18|EyeSight Driver Assistance[<sup>6</sup>](#footnotes)|Stock|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 Legacy 2015-18">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>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>|||
|
||||||
|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|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>|||
|
||||||
|Subaru|Outback 2015-17|EyeSight Driver Assistance[<sup>6</sup>](#footnotes)|Stock|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 Outback 2015-17">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|Legacy 2015-18|EyeSight Driver Assistance[<sup>7</sup>](#footnotes)|Stock|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 Legacy 2015-18">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 2018-19|EyeSight Driver Assistance[<sup>6</sup>](#footnotes)|Stock|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 Outback 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>|||
|
|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>|||
|
||||||
|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|Outback 2015-17|EyeSight Driver Assistance[<sup>7</sup>](#footnotes)|Stock|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 Outback 2015-17">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|Outback 2018-19|EyeSight Driver Assistance[<sup>7</sup>](#footnotes)|Stock|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 Outback 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>|||
|
||||||
|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|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|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|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" /></a>||
|
||||||
|Š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|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|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>|||
|
|Škoda|Fabia 2022-23[<sup>15</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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>17</sup>](#footnotes)|||
|
||||||
|Š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>|||
|
|Škoda|Kamiq 2021-23[<sup>13,15</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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>17</sup>](#footnotes)|||
|
||||||
|Š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>|||
|
|Škoda[<sup>12</sup>](#footnotes)|Karoq 2019-23[<sup>15</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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|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>|||
|
|Škoda[<sup>12</sup>](#footnotes)|Kodiaq 2017-23[<sup>15</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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 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>|||
|
|Škoda[<sup>12</sup>](#footnotes)|Octavia 2015-19[<sup>15</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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|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)|||
|
|Škoda[<sup>12</sup>](#footnotes)|Octavia RS 2016[<sup>15</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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|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[<sup>12</sup>](#footnotes)|Octavia Scout 2017-19[<sup>15</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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>|||
|
||||||
|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|Scala 2020-23[<sup>15</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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>17</sup>](#footnotes)|||
|
||||||
|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[<sup>12</sup>](#footnotes)|Superb 2015-22[<sup>15</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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>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>|||
|
|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 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>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>|||
|
|Tesla[<sup>10</sup>](#footnotes)|Model 3 (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 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>|||
|
||||||
|
|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 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 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>|||
|
||||||
@@ -280,92 +280,94 @@ 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" /></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" /></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>|||
|
||||||
|Toyota|Corolla 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=Toyota Corolla 2020-22">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=_66pXk0CBYA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Toyota|Corolla 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=Toyota Corolla 2020-22">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=_66pXk0CBYA" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||||
|Toyota|Corolla Cross (Non-US only) 2020-23|All|openpilot|17 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 Cross (Non-US only) 2020-23">Buy Here</a></sub></details>|||
|
|Toyota|Corolla Cross (Non-US only) 2020-23|All|openpilot|17 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 Cross (Non-US only) 2020-23">Buy Here</a></sub></details>|||
|
||||||
|Toyota|Corolla Cross Hybrid (Non-US only) 2020-22|All|openpilot|17 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 Cross Hybrid (Non-US only) 2020-22">Buy Here</a></sub></details>|||
|
|Toyota|Corolla Cross Hybrid (Non-US only) 2020-22|All|openpilot|17 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 Cross Hybrid (Non-US only) 2020-22">Buy Here</a></sub></details>|||
|
||||||
|Toyota|Corolla Hatchback 2019-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=Toyota Corolla Hatchback 2019-22">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=_66pXk0CBYA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Toyota|Corolla Hatchback 2019-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=Toyota Corolla Hatchback 2019-22">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=_66pXk0CBYA" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||||
|Toyota|Corolla 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=Toyota Corolla Hybrid 2020-22">Buy Here</a></sub></details>|||
|
|Toyota|Corolla 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=Toyota Corolla Hybrid 2020-22">Buy Here</a></sub></details>|||
|
||||||
|Toyota|Corolla Hybrid (South America only) 2020-23|All|openpilot|17 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 Hybrid (South America only) 2020-23">Buy Here</a></sub></details>|||
|
|Toyota|Corolla Hybrid (South America only) 2020-23|All|openpilot|17 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 Hybrid (South America only) 2020-23">Buy Here</a></sub></details>|||
|
||||||
|Toyota|Highlander 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 Highlander 2017-19">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=0wS0wXSLzoo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Toyota|Highlander 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 Highlander 2017-19">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=0wS0wXSLzoo" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||||
|Toyota|Highlander 2020-23|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 Highlander 2020-23">Buy Here</a></sub></details>|||
|
|Toyota|Highlander 2020-23|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 Highlander 2020-23">Buy Here</a></sub></details>|||
|
||||||
|Toyota|Highlander Hybrid 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 Highlander Hybrid 2017-19">Buy Here</a></sub></details>|||
|
|Toyota|Highlander Hybrid 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 Highlander Hybrid 2017-19">Buy Here</a></sub></details>|||
|
||||||
|Toyota|Highlander Hybrid 2020-23|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 Highlander Hybrid 2020-23">Buy Here</a></sub></details>|||
|
|Toyota|Highlander Hybrid 2020-23|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 Highlander Hybrid 2020-23">Buy Here</a></sub></details>|||
|
||||||
|Toyota|Mirai 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 Mirai 2021">Buy Here</a></sub></details>|||
|
|Toyota|Mirai 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 Mirai 2021">Buy Here</a></sub></details>|||
|
||||||
|Toyota|Prius 2016|Toyota Safety Sense P|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">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=8zopPJI8XQ0" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Toyota|Prius 2016|Toyota Safety Sense P|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">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=8zopPJI8XQ0" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||||
|Toyota|Prius 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 Prius 2017-20">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=8zopPJI8XQ0" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Toyota|Prius 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 Prius 2017-20">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=8zopPJI8XQ0" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||||
|Toyota|Prius 2021-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=Toyota Prius 2021-22">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=J58TvCpUd4U" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Toyota|Prius 2021-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=Toyota Prius 2021-22">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=J58TvCpUd4U" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||||
|Toyota|Prius Prime 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 Prius Prime 2017-20">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=8zopPJI8XQ0" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Toyota|Prius Prime 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 Prius Prime 2017-20">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=8zopPJI8XQ0" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||||
|Toyota|Prius Prime 2021-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=Toyota Prius Prime 2021-22">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=J58TvCpUd4U" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Toyota|Prius Prime 2021-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=Toyota Prius Prime 2021-22">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=J58TvCpUd4U" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||||
|Toyota|Prius v 2017|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 Prius v 2017">Buy Here</a></sub></details>|||
|
|Toyota|Prius v 2017|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 Prius v 2017">Buy Here</a></sub></details>|||
|
||||||
|Toyota|RAV4 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 RAV4 2016">Buy Here</a></sub></details>|||
|
|Toyota|RAV4 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 RAV4 2016">Buy Here</a></sub></details>|||
|
||||||
|Toyota|RAV4 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=Toyota RAV4 2017-18">Buy Here</a></sub></details>|||
|
|Toyota|RAV4 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=Toyota RAV4 2017-18">Buy Here</a></sub></details>|||
|
||||||
|Toyota|RAV4 2019-21|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 RAV4 2019-21">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=wJxjDd42gGA" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Toyota|RAV4 2019-21|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 RAV4 2019-21">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=wJxjDd42gGA" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||||
|Toyota|RAV4 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 2022">Buy Here</a></sub></details>|||
|
|Toyota|RAV4 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 2022">Buy Here</a></sub></details>|||
|
||||||
|Toyota|RAV4 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 2023-25">Buy Here</a></sub></details>|||
|
|Toyota|RAV4 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 2023-25">Buy Here</a></sub></details>|||
|
||||||
|Toyota|RAV4 Hybrid 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 RAV4 Hybrid 2016">Buy Here</a></sub></details>|<a href="https://youtu.be/LhT5VzJVfNI?t=26" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Toyota|RAV4 Hybrid 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 RAV4 Hybrid 2016">Buy Here</a></sub></details>|<a href="https://youtu.be/LhT5VzJVfNI?t=26" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||||
|Toyota|RAV4 Hybrid 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=Toyota RAV4 Hybrid 2017-18">Buy Here</a></sub></details>|<a href="https://youtu.be/LhT5VzJVfNI?t=26" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Toyota|RAV4 Hybrid 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=Toyota RAV4 Hybrid 2017-18">Buy Here</a></sub></details>|<a href="https://youtu.be/LhT5VzJVfNI?t=26" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||||
|Toyota|RAV4 Hybrid 2019-21|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 RAV4 Hybrid 2019-21">Buy Here</a></sub></details>|||
|
|Toyota|RAV4 Hybrid 2019-21|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 RAV4 Hybrid 2019-21">Buy Here</a></sub></details>|||
|
||||||
|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" /></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" /></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" /></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[<sup>12</sup>](#footnotes)|Arteon 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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" /></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[<sup>12</sup>](#footnotes)|Arteon eHybrid 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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" /></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[<sup>12</sup>](#footnotes)|Arteon R 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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" /></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[<sup>12</sup>](#footnotes)|Arteon Shooting Brake 2020-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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" /></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[<sup>12</sup>](#footnotes)|Atlas 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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[<sup>12</sup>](#footnotes)|Atlas Cross Sport 2020-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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[<sup>12</sup>](#footnotes)|California 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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[<sup>12</sup>](#footnotes)|Caravelle 2020|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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[<sup>12</sup>](#footnotes)|CC 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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" /></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[<sup>12</sup>](#footnotes)|Crafter 2017-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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" /></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[<sup>12</sup>](#footnotes)|e-Crafter 2018-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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" /></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[<sup>12</sup>](#footnotes)|e-Golf 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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[<sup>12</sup>](#footnotes)|Golf 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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[<sup>12</sup>](#footnotes)|Golf Alltrack 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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[<sup>12</sup>](#footnotes)|Golf GTD 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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[<sup>12</sup>](#footnotes)|Golf GTE 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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[<sup>12</sup>](#footnotes)|Golf GTI 2015-21|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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[<sup>12</sup>](#footnotes)|Golf R 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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[<sup>12</sup>](#footnotes)|Golf SportsVan 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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[<sup>12</sup>](#footnotes)|Grand California 2019-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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" /></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[<sup>12</sup>](#footnotes)|Jetta 2019-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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 2019-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[<sup>12</sup>](#footnotes)|Jetta GLI 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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|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|Passat 2015-22[<sup>14</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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|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[<sup>12</sup>](#footnotes)|Passat Alltrack 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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|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[<sup>12</sup>](#footnotes)|Passat GTE 2015-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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|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|Polo 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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>17</sup>](#footnotes)|||
|
||||||
|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|Polo GTI 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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>17</sup>](#footnotes)|||
|
||||||
|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|T-Cross 2021|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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>17</sup>](#footnotes)|||
|
||||||
|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[<sup>12</sup>](#footnotes)|T-Roc 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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|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[<sup>12</sup>](#footnotes)|Taos 2022-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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|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[<sup>12</sup>](#footnotes)|Teramont 2018-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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,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[<sup>12</sup>](#footnotes)|Teramont Cross Sport 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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,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[<sup>12</sup>](#footnotes)|Teramont X 2021-22|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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,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[<sup>12</sup>](#footnotes)|Tiguan 2018-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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,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[<sup>12</sup>](#footnotes)|Tiguan eHybrid 2021-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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,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[<sup>12</sup>](#footnotes)|Touran 2016-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<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>|||
|
||||||
|
|
||||||
### 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 `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>The J533 harness plugs in at the CAN gateway under the dashboard, just above the steering column. More information can be found at <a href="https://docs.howtocomma.com/docs/j533-harness-install" target="_blank">this guide</a>. <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>Not including the China market Kamiq, which is based on the (currently) unsupported PQ34 platform. <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>Refers only to the MQB-based European B8 Passat, not the NMS Passat in the USA/China/Mideast markets. <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>Some Škoda vehicles are equipped with heated windshields, which are known to block GPS signal needed for some comma four functionality. <br />
|
||||||
|
<sup>16</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>17</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
|
## 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/).
|
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/).
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ Development is coordinated through [Discord](https://discord.comma.ai) and GitHu
|
|||||||
## What contributions are we looking for?
|
## What contributions are we looking for?
|
||||||
|
|
||||||
**openpilot's priorities are [safety](SAFETY.md), stability, quality, and features, in that order.**
|
**openpilot's priorities are [safety](SAFETY.md), stability, quality, and features, in that order.**
|
||||||
openpilot is part of comma's mission to *solve self-driving cars while delivering shippable intermediaries*, and all development is towards that goal.
|
openpilot is part of comma's mission to *solve self-driving cars while delivering shippable intermediaries*, and all development is towards that goal.
|
||||||
|
|
||||||
### What gets merged?
|
### What gets merged?
|
||||||
|
|
||||||
The probability of a pull request being merged is a function of its value to the project and the effort it will take us to get it merged.
|
The probability of a pull request being merged is a function of its value to the project and the effort it will take us to get it merged.
|
||||||
If a PR offers *some* value but will take lots of time to get merged, it will be closed.
|
If a PR offers *some* value but will take lots of time to get merged, it will be closed.
|
||||||
Simple, well-tested bug fixes are the easiest to merge, and new features are the hardest to get merged.
|
Simple, well-tested bug fixes are the easiest to merge, and new features are the hardest to get merged.
|
||||||
|
|
||||||
All of these are examples of good PRs:
|
All of these are examples of good PRs:
|
||||||
* typo fix: https://github.com/commaai/openpilot/pull/30678
|
* typo fix: https://github.com/commaai/openpilot/pull/30678
|
||||||
@@ -29,17 +29,17 @@ All of these are examples of good PRs:
|
|||||||
|
|
||||||
### What doesn't get merged?
|
### What doesn't get merged?
|
||||||
|
|
||||||
* **style changes**: code is art, and it's up to the author to make it beautiful
|
* **style changes**: code is art, and it's up to the author to make it beautiful
|
||||||
* **500+ line PRs**: clean it up, break it up into smaller PRs, or both
|
* **500+ line PRs**: clean it up, break it up into smaller PRs, or both
|
||||||
* **PRs without a clear goal**: every PR must have a singular and clear goal
|
* **PRs without a clear goal**: every PR must have a singular and clear goal
|
||||||
* **UI design**: we do not have a good review process for this yet
|
* **UI design**: we do not have a good review process for this yet
|
||||||
* **New features**: We believe openpilot is mostly feature-complete, and the rest is a matter of refinement and fixing bugs. As a result of this, most feature PRs will be immediately closed, however the beauty of open source is that forks can and do offer features that upstream openpilot doesn't.
|
* **New features**: We believe openpilot is mostly feature-complete, and the rest is a matter of refinement and fixing bugs. As a result of this, most feature PRs will be immediately closed, however the beauty of open source is that forks can and do offer features that upstream openpilot doesn't.
|
||||||
* **Negative expected value**: This a class of PRs that makes an improvement, but the risk or validation costs more than the improvement. The risk can be mitigated by first getting a failing test merged.
|
* **Negative expected value**: This is a class of PRs that makes an improvement, but the risk or validation costs more than the improvement. The risk can be mitigated by first getting a failing test merged.
|
||||||
|
|
||||||
### First contribution
|
### First contribution
|
||||||
|
|
||||||
[Projects / openpilot bounties](https://github.com/orgs/commaai/projects/26/views/1?pane=info) is the best place to get started and goes in-depth on what's expected when working on a bounty.
|
[Projects / openpilot bounties](https://github.com/orgs/commaai/projects/26/views/1?pane=info) is the best place to get started and goes in-depth on what's expected when working on a bounty.
|
||||||
There's lot of bounties that don't require a comma 3X or a car.
|
There are a lot of bounties that don't require a comma four or a car.
|
||||||
|
|
||||||
## Pull Requests
|
## Pull Requests
|
||||||
|
|
||||||
@@ -68,6 +68,6 @@ A good pull request has all of the following:
|
|||||||
### A guide for forks
|
### A guide for forks
|
||||||
|
|
||||||
In order for your fork's data to be eligible for the training set:
|
In order for your fork's data to be eligible for the training set:
|
||||||
* **Your cereal messaging structs must be [compatible](../cereal#custom-forks)**
|
* **Your cereal messaging structs must be [compatible](../openpilot/cereal#custom-forks)**
|
||||||
* **The definitions of all the stock messaging structs must not change**: Do not change how any of the fields are set, including everything from `selfdriveState.enabled` to `carState.steeringAngleDeg`. Instead, create your own structs and set them however you'd like.
|
* **The definitions of all the stock messaging structs must not change**: Do not change how any of the fields are set, including everything from `selfdriveState.enabled` to `carState.steeringAngleDeg`. Instead, create your own structs and set them however you'd like.
|
||||||
* **Do not include cars that are not supported in upstream platforms**: Instead, create new opendbc platforms for cars that you'd like to support outside of upstream, even if it's just a trim-level difference.
|
* **Do not include cars that are not supported in upstream platforms**: Instead, create new opendbc platforms for cars that you'd like to support outside of upstream, even if it's just a trim-level difference.
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Docs development
|
||||||
|
|
||||||
|
The `docs/` tree is the source for [docs.comma.ai](https://docs.comma.ai).
|
||||||
|
The site is updated on pushes to master by this [workflow](../.github/workflows/docs.yaml).
|
||||||
|
|
||||||
|
Those commands must be run in the root directory of openpilot, **not /docs**
|
||||||
|
|
||||||
|
**1. Install the docs dependencies**
|
||||||
|
``` bash
|
||||||
|
uv pip install .[docs]
|
||||||
|
```
|
||||||
|
|
||||||
|
**2. Build the new site**
|
||||||
|
``` bash
|
||||||
|
docs build
|
||||||
|
```
|
||||||
|
|
||||||
|
**3. Run the new site locally**
|
||||||
|
``` bash
|
||||||
|
docs serve
|
||||||
|
```
|
||||||
|
|
||||||
|
References:
|
||||||
|
* https://zensical.org/docs/
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
# openpilot docs
|
|
||||||
|
|
||||||
This is the source for [docs.comma.ai](https://docs.comma.ai).
|
|
||||||
The site is updated on pushes to master by this [workflow](../.github/workflows/docs.yaml).
|
|
||||||
|
|
||||||
## Development
|
|
||||||
NOTE: Those commands must be run in the root directory of openpilot, **not /docs**
|
|
||||||
|
|
||||||
**1. Install the docs dependencies**
|
|
||||||
``` bash
|
|
||||||
pip install .[docs]
|
|
||||||
```
|
|
||||||
|
|
||||||
**2. Build the new site**
|
|
||||||
``` bash
|
|
||||||
mkdocs build
|
|
||||||
```
|
|
||||||
|
|
||||||
**3. Run the new site locally**
|
|
||||||
``` bash
|
|
||||||
mkdocs serve
|
|
||||||
```
|
|
||||||
|
|
||||||
References:
|
|
||||||
* https://www.mkdocs.org/getting-started/
|
|
||||||
* https://github.com/ntno/mkdocs-terminal
|
|
||||||
+4
-4
@@ -4,8 +4,8 @@ openpilot is an Adaptive Cruise Control (ACC) and Automated Lane Centering (ALC)
|
|||||||
Like other ACC and ALC systems, openpilot is a failsafe passive system and it requires the
|
Like other ACC and ALC systems, openpilot is a failsafe passive system and it requires the
|
||||||
driver to be alert and to pay attention at all times.
|
driver to be alert and to pay attention at all times.
|
||||||
|
|
||||||
In order to enforce driver alertness, openpilot includes a driver monitoring feature
|
To assist the driver in maintaining alertness, openpilot includes a driver monitoring feature
|
||||||
that alerts the driver when distracted.
|
that alerts when it detects driver distraction.
|
||||||
|
|
||||||
However, even with an attentive driver, we must make further efforts for the system to be
|
However, even with an attentive driver, we must make further efforts for the system to be
|
||||||
safe. We repeat, **driver alertness is necessary, but not sufficient, for openpilot to be
|
safe. We repeat, **driver alertness is necessary, but not sufficient, for openpilot to be
|
||||||
@@ -35,8 +35,8 @@ For additional safety implementation details, refer to [panda safety model](http
|
|||||||
|
|
||||||
### Forks of openpilot
|
### Forks of openpilot
|
||||||
|
|
||||||
* Do not disable or nerf [driver monitoring](https://github.com/commaai/openpilot/tree/master/selfdrive/monitoring)
|
* Do not disable or nerf [driver monitoring](https://github.com/commaai/openpilot/tree/master/openpilot/selfdrive/monitoring)
|
||||||
* Do not disable or nerf [excessive actuation checks](https://github.com/commaai/openpilot/tree/master/selfdrive/selfdrived/helpers.py)
|
* Do not disable or nerf [excessive actuation checks](https://github.com/commaai/openpilot/tree/master/openpilot/selfdrive/selfdrived/helpers.py)
|
||||||
* If your fork modifies any of the code in `opendbc/safety/`:
|
* If your fork modifies any of the code in `opendbc/safety/`:
|
||||||
* your fork cannot use the openpilot trademark
|
* your fork cannot use the openpilot trademark
|
||||||
* your fork must preserve the full [safety test suite](https://github.com/commaai/opendbc/tree/master/opendbc/safety/tests) and all tests must pass, including any new coverage required by the fork's changes
|
* your fork must preserve the full [safety test suite](https://github.com/commaai/opendbc/tree/master/opendbc/safety/tests) and all tests must pass, including any new coverage required by the fork's changes
|
||||||
|
|||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../../selfdrive/assets/icons_mici/settings/comma_icon.png
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
# Developing a car brand port
|
|
||||||
|
|
||||||
A brand port is a port of openpilot to a substantially new car brand or platform within a brand.
|
|
||||||
|
|
||||||
Here's an example of one: https://github.com/commaai/openpilot/pull/23331.
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
# CarState signals
|
|
||||||
|
|
||||||
## Required for basic lateral control
|
|
||||||
|
|
||||||
* `brakePressed`
|
|
||||||
* `cruiseState`
|
|
||||||
* `doorOpen`
|
|
||||||
* `espDisabled`
|
|
||||||
* `gasPressed`
|
|
||||||
* `gearShifter`
|
|
||||||
* `leftBlinker` / `rightBlinker`
|
|
||||||
* `seatbeltUnlatched`
|
|
||||||
* `standstill`
|
|
||||||
* `steeringAngleDeg`
|
|
||||||
* `steeringPressed`
|
|
||||||
* `steeringTorque`
|
|
||||||
* `steerFaultPermanent`
|
|
||||||
* `steerFaultTemporary`
|
|
||||||
* `vCruise`
|
|
||||||
* `wheelSpeeds.[fl|fr|rl|rr]`: Speed of each of the car's four wheels, in m/s. The car's CAN bus often broadcasts the
|
|
||||||
speed in kph, so the helper function `parse_wheel_speeds` performs this conversion by default.
|
|
||||||
|
|
||||||
## Recommended / Required for openpilot longitudinal control
|
|
||||||
|
|
||||||
* `accFaulted`
|
|
||||||
* `espActive`
|
|
||||||
* `parkingBrake`
|
|
||||||
|
|
||||||
## Application Dependent
|
|
||||||
|
|
||||||
* `blockPcmEnable`
|
|
||||||
* `buttonEnable`
|
|
||||||
* `brakeHoldActive`
|
|
||||||
* `carFaultedNonCritical`
|
|
||||||
* `invalidLkasSetting`
|
|
||||||
* `lowSpeedAlert`
|
|
||||||
* `regenBraking`
|
|
||||||
* `steeringAngleOffsetDeg`
|
|
||||||
* `steeringDisengage`
|
|
||||||
* `steeringTorqueEps`
|
|
||||||
* `stockLkas`
|
|
||||||
* `vCruiseCluster`
|
|
||||||
* `vEgoCluster`
|
|
||||||
* `vehicleSensorsInvalid`
|
|
||||||
|
|
||||||
## Automatically populated
|
|
||||||
|
|
||||||
* `buttonEvents`
|
|
||||||
|
|
||||||
These values are populated automatically by `parse_wheel_speeds`:
|
|
||||||
|
|
||||||
* `aEgo`: Acceleration of the ego vehicle, Kalman filtered derivative of `vEgo`.
|
|
||||||
* `vEgo`: Speed of the ego vehicle, Kalman filtered from `vEgoRaw`.
|
|
||||||
* `vEgoRaw`: Speed of the ego vehicle, based on the average of all four wheel speeds, unfiltered.
|
|
||||||
|
|
||||||
## Optional
|
|
||||||
|
|
||||||
* `brake`
|
|
||||||
* `charging`
|
|
||||||
* `fuelGauge`
|
|
||||||
* `leftBlindspot` / `rightBlindspot`
|
|
||||||
* `steeringRateDeg`
|
|
||||||
* `stockAeb`
|
|
||||||
* `stockFcw`
|
|
||||||
* `yawRate`
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
# Developing a car model port
|
|
||||||
|
|
||||||
A model port is a port of openpilot to a new car model within an already supported brand. Model ports are easier than brand ports because the car's existing APIs are already known.
|
|
||||||
|
|
||||||
Here's an example of one: https://github.com/commaai/openpilot/pull/30672/.
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
# Stimulus-Response Tests
|
|
||||||
|
|
||||||
These are example test drives that can help identify the CAN bus messaging necessary for ADAS control. Each scripted
|
|
||||||
test should be done in a separate route (ignition cycle). These tests are a guide, not necessarily exhaustive.
|
|
||||||
|
|
||||||
While testing, constant power to the comma device is highly recommended, using [comma power](https://comma.ai/shop/comma-power) if
|
|
||||||
necessary to make sure all test activity is fully captured and for ease of uploading. If constant power isn't
|
|
||||||
available, keep the ignition on for at least one minute after your test to make sure power loss doesn't result
|
|
||||||
in loss of the last minute of testing data.
|
|
||||||
|
|
||||||
## Stationary ignition-only tests, part 1
|
|
||||||
|
|
||||||
1. Ignition on, but don't start engine, remain in Park
|
|
||||||
2. Open and close each door in a defined order: driver, passenger, rear left, rear right
|
|
||||||
3. Re-enter the vehicle, close the driver's door, and fasten the driver's seatbelt
|
|
||||||
4. Slowly press and release the accelerator pedal 3 times
|
|
||||||
5. Slowly press and release the brake pedal 3 times
|
|
||||||
6. Hold the brake and move the gearshift to reverse, then neutral, then drive, then sport/eco/etc if applicable
|
|
||||||
7. Return to Park, ignition off
|
|
||||||
|
|
||||||
Brake-pressed information may show up in several messages and signals, both as on/off states and as a percentage or
|
|
||||||
pressure. It may reflect a switch on the driver's brake pedal, or a pressure-threshold state, or signals to turn on
|
|
||||||
the rear brake lights. Start by identifying all the potential signals, and confirm while driving with ACC later.
|
|
||||||
|
|
||||||
Locate signals for all four door states if possible, but some cars only expose the driver's door state on the ADAS bus.
|
|
||||||
Driver/passenger door signals may or may not change positions for LHD vs RHD cars. For cars where only the driver's
|
|
||||||
door signal is available, the same signal may follow the driver.
|
|
||||||
|
|
||||||
## Stationary ignition-only tests, part 2
|
|
||||||
|
|
||||||
1. Ignition on, but don't start engine, remain in Park
|
|
||||||
2. Press each ACC button in a defined order: main switch on/off, set, resume, cancel, accel, decel, gap adjust
|
|
||||||
3. Set the left turn signal for about five seconds
|
|
||||||
4. Operate the left turn signal one time in its touch-to-pass mode
|
|
||||||
5. Set the right turn signal for about five seconds
|
|
||||||
6. Operate the right turn signal one time in its touch-to-pass mode
|
|
||||||
7. Set the hazard / emergency indicator switch for about five seconds
|
|
||||||
8. Ignition off
|
|
||||||
|
|
||||||
Your vehicle may have a momentary-press main ACC switch or a physical toggle that remains set. Actual ACC engagement
|
|
||||||
isn't necessary for purposes of detecting the ACC button presses.
|
|
||||||
|
|
||||||
## Steering angle and steering torque tests
|
|
||||||
|
|
||||||
Power steering should be available. On ICE cars, engine RPM may be present.
|
|
||||||
|
|
||||||
1. Ignition on, start engine if applicable, remain in Park
|
|
||||||
2. Rotate the steering wheel as follows, with a few seconds pause between each step
|
|
||||||
* Start as close to exact center as possible
|
|
||||||
* Turn to 45 degrees right and hold
|
|
||||||
* Turn to 90 degrees right and hold
|
|
||||||
* Turn to 180 degrees right and hold
|
|
||||||
* Turn to full lock right and hold, with firm pressure against lock
|
|
||||||
* Release the wheel and allow it to bounce back slightly from lock
|
|
||||||
* Turn to 180 degrees left and hold
|
|
||||||
* Return to center and release
|
|
||||||
3. Ignition off
|
|
||||||
|
|
||||||
Performing the full test to the right, followed by an abbreviated test to the left, helps give additional confirmation
|
|
||||||
of signal scale, and sign/direction for both the steering wheel angle and driver input torque signals.
|
|
||||||
|
|
||||||
## Low speed / parking lot driving tests
|
|
||||||
|
|
||||||
Before this test, drive to a place like an empty parking lot where you are free to drive in a series of curves.
|
|
||||||
|
|
||||||
1. Ignition on, start engine if applicable, prepare to drive
|
|
||||||
2. Slowly (10-20mph at most) drive a figure-8 if possible, or at least one sharp left and one sharp right.
|
|
||||||
3. Come to a complete stop
|
|
||||||
4. When and where safe, drive in reverse for a short distance (10-15 feet)
|
|
||||||
5. Park the car in a safe place, ignition off
|
|
||||||
|
|
||||||
## High speed / highway driving tests
|
|
||||||
|
|
||||||
Select a place and time where you can safely set cruise control at normal travel speeds with little interference from
|
|
||||||
traffic ahead, and safely test the response of your factory lane guidance system.
|
|
||||||
|
|
||||||
1. Ignition on, start engine if applicable, prepare to drive
|
|
||||||
2. When safely able, engage adaptive cruise control below 50 mph
|
|
||||||
3. When safely able, use the ACC buttons to accelerate to 50mph, then 55mph, then 60mph
|
|
||||||
4. Disengage adaptive cruise
|
|
||||||
5. When safely able, allow your factory lane guidance to prevent lane departures, 2-3 times on both the left and right
|
|
||||||
|
|
||||||
The series of setpoints can be adjusted to local traffic regulations, and of course metric units. The specific cruise
|
|
||||||
setpoints are useful for locating the ACC HUD signals later, and confirming their precise scaling. When the car reaches
|
|
||||||
and holds the setpoint, that can also provide additional confirmation of wheel speed scaling.
|
|
||||||
@@ -1,9 +1,3 @@
|
|||||||
# openpilot glossary
|
# openpilot glossary
|
||||||
|
|
||||||
* **onroad**: openpilot's system state while ignition is on
|
{{GLOSSARY_DEFINITIONS}}
|
||||||
* **offroad**: openpilot's system state while ignition is off
|
|
||||||
* **route**: a route is a recording of an onroad session
|
|
||||||
* **segment**: routes are split into one minute chunks called segments.
|
|
||||||
* **comma connect**: the web viewer for all your routes; check it out at [connect.comma.ai](https://connect.comma.ai).
|
|
||||||
* **panda**: this is the secondary processor on the device that implements the functional safety and directly talks to the car over CAN. See the [panda repo](https://github.com/commaai/panda).
|
|
||||||
* **comma 3X**: the latest hardware by comma.ai for running openpilot. more info at [comma.ai/shop](https://comma.ai/shop).
|
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
openpilot records routes in one minute chunks called segments. A route starts on the rising edge of ignition and ends on the falling edge.
|
openpilot records routes in one minute chunks called segments. A route starts on the rising edge of ignition and ends on the falling edge.
|
||||||
|
|
||||||
Check out our [Python library](https://github.com/commaai/openpilot/blob/master/tools/lib/logreader.py) for reading openpilot logs. Also checkout our [tools](https://github.com/commaai/openpilot/tree/master/tools) to replay and view your data. These are the same tools we use to debug and develop openpilot.
|
Check out our [Python library](https://github.com/commaai/openpilot/blob/master/openpilot/tools/lib/logreader.py) for reading openpilot logs. Also checkout our [tools](https://github.com/commaai/openpilot/tree/master/openpilot/tools) to replay and view your data. These are the same tools we use to debug and develop openpilot.
|
||||||
|
|
||||||
For each segment, openpilot records the following log types:
|
For each segment, openpilot records the following log types:
|
||||||
|
|
||||||
## rlog.bz2
|
## rlog.zst
|
||||||
|
|
||||||
rlogs contain all the messages passed amongst openpilot's processes. See [cereal/services.py](https://github.com/commaai/cereal/blob/master/services.py) for a list of all the logged services. They're a bzip2 archive of the serialized capnproto messages.
|
rlogs contain all the messages passed amongst openpilot's processes. See [openpilot/cereal/services.py](https://github.com/commaai/openpilot/blob/master/openpilot/cereal/services.py) for a list of all the logged services. They're a zstd archive of the serialized [Cap’n Proto](https://capnproto.org/) messages.
|
||||||
|
|
||||||
## {f,e,d}camera.hevc
|
## {f,e,d}camera.hevc
|
||||||
|
|
||||||
@@ -18,12 +18,10 @@ Each camera stream is H.265 encoded and written to its respective file.
|
|||||||
* `ecamera.hevc` is the wide road camera
|
* `ecamera.hevc` is the wide road camera
|
||||||
* `dcamera.hevc` is the driver camera
|
* `dcamera.hevc` is the driver camera
|
||||||
|
|
||||||
## qlog.bz2 & qcamera.ts
|
## qlog.zst & qcamera.ts
|
||||||
|
|
||||||
qlogs are a decimated subset of the rlogs. Check out [cereal/services.py](https://github.com/commaai/cereal/blob/master/services.py) for the decimation.
|
|
||||||
|
|
||||||
|
qlogs are a decimated subset of the rlogs. Check out [openpilot/cereal/services.py](https://github.com/commaai/openpilot/blob/master/openpilot/cereal/services.py) for the decimation.
|
||||||
|
|
||||||
qcameras are H.264 encoded, lower res versions of the fcamera.hevc. The video shown in [comma connect](https://connect.comma.ai/) is from the qcameras.
|
qcameras are H.264 encoded, lower res versions of the fcamera.hevc. The video shown in [comma connect](https://connect.comma.ai/) is from the qcameras.
|
||||||
|
|
||||||
|
qlogs and qcameras are designed to be small enough to upload instantly on slow internet, yet useful enough for most analysis and debugging.
|
||||||
qlogs and qcameras are designed to be small enough to upload instantly on slow internet and store forever, yet useful enough for most analysis and debugging.
|
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# How to Give Feedback
|
||||||
|
|
||||||
|
Feedback is one of the highest leverage ways to contribute to openpilot as a user.
|
||||||
|
|
||||||
|
## Driving
|
||||||
|
|
||||||
|
Got feedback about how your car drives?
|
||||||
|
Join the community Discord, then use the form in `#submit-feedback`.
|
||||||
|
|
||||||
|
Before posting feedback, please ensure:
|
||||||
|
|
||||||
|
- **openpilot is up to date** you should be on the latest openpilot release or nightly
|
||||||
|
- **both road-facing cameras have a clear view** your windshield is clean, lenses are clean, etc.
|
||||||
|
- **your device is mounted properly** your device must be mounted horizontally center and relatively high on the windshield
|
||||||
|
|
||||||
|
## Driver Monitoring
|
||||||
|
|
||||||
|
If you find DM annoying while being perfectly attentive, these are likely false positives and we want to fix them!
|
||||||
|
In general, driver monitoring feedback is very actionable, and we can fix your complaint within a release cycle.
|
||||||
|
|
||||||
|
To post your feedback:
|
||||||
|
|
||||||
|
1. Join the [community Discord](https://discord.comma.ai).
|
||||||
|
2. If driver camera recording is toggled off, temporarily enable driver camera recording in the settings until you reproduce the issue.
|
||||||
|
3. Using comma connect, identify the relevant segment and upload the segment's logs and driver camera.
|
||||||
|
4. Post the segment in the `#openpilot-experience` channel on Discord with a good description.
|
||||||
|
|
||||||
|
Before posting feedback, please ensure:
|
||||||
|
|
||||||
|
- **openpilot is up to date** you should be on the latest openpilot release or nightly
|
||||||
|
- **the driver camera has a clear view of the driver** ensure nothing blocks view of the driver (e.g. a cable), the lens is clean, etc.
|
||||||
|
- **your device is mounted properly** your device must be mounted horizontally center and relatively high on the windshield
|
||||||
|
|
||||||
|
## Other bugs
|
||||||
|
|
||||||
|
Got an issue with something else? Open an issue on our [GitHub issue tracker](https://github.com/commaai/openpilot/issues/new/choose).
|
||||||
@@ -7,25 +7,11 @@ This is the roadmap for the next major openpilot releases. Also check out
|
|||||||
* [Bounties](https://comma.ai/bounties) for paid individual issues
|
* [Bounties](https://comma.ai/bounties) for paid individual issues
|
||||||
* [#current-projects](https://discord.com/channels/469524606043160576/1249579909739708446) in Discord for discussion on work-in-progress projects
|
* [#current-projects](https://discord.com/channels/469524606043160576/1249579909739708446) in Discord for discussion on work-in-progress projects
|
||||||
|
|
||||||
## openpilot 0.10
|
|
||||||
|
|
||||||
openpilot 0.10 will be the first release with a driving policy trained in
|
|
||||||
a [learned simulator](https://youtu.be/EqQNZXqzFSI).
|
|
||||||
|
|
||||||
* Driving model trained in a learned simulator
|
|
||||||
* Always-on driver monitoring (behind a toggle)
|
|
||||||
* GPS removed from the driving stack
|
|
||||||
* 100KB qlogs
|
|
||||||
* `nightly` pushed after 1000 hours of hardware-in-the-loop testing
|
|
||||||
* Car interface code moved into [opendbc](https://github.com/commaai/opendbc)
|
|
||||||
* openpilot on PC for Linux x86, Linux arm64, and Mac (Apple Silicon)
|
|
||||||
|
|
||||||
## openpilot 1.0
|
## openpilot 1.0
|
||||||
|
|
||||||
openpilot 1.0 will feature a fully end-to-end driving policy.
|
openpilot 1.0 will feature a fully end-to-end driving policy.
|
||||||
|
|
||||||
* End-to-end longitudinal control in Chill mode
|
* End-to-end longitudinal control in Chill mode
|
||||||
* Automatic Emergency Braking (AEB)
|
|
||||||
* Driver monitoring with sleep detection
|
* Driver monitoring with sleep detection
|
||||||
* Rolling updates/releases pushed out by CI
|
* Rolling updates/releases pushed out by CI
|
||||||
* [panda safety 1.0](https://github.com/orgs/commaai/projects/27)
|
* [panda safety 1.0](https://github.com/orgs/commaai/projects/27)
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
[data-tooltip] {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
border-bottom: 1px dotted black;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-tooltip] .tooltip-content {
|
|
||||||
width: max-content;
|
|
||||||
max-width: 25em;
|
|
||||||
position: absolute;
|
|
||||||
top: 100%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
background-color: white;
|
|
||||||
color: #404040;
|
|
||||||
box-shadow: 0 4px 14px 0 rgba(0,0,0,.2), 0 0 0 1px rgba(0,0,0,.05);
|
|
||||||
padding: 10px;
|
|
||||||
font: 14px/1.5 Lato, proxima-nova, Helvetica Neue, Arial, sans-serif;
|
|
||||||
text-decoration: none;
|
|
||||||
opacity: 0;
|
|
||||||
visibility: hidden;
|
|
||||||
transition: opacity 0.1s, visibility 0s;
|
|
||||||
z-index: 1000;
|
|
||||||
pointer-events: none; /* Prevent accidental interaction */
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-tooltip]:hover .tooltip-content {
|
|
||||||
opacity: 1;
|
|
||||||
visibility: visible;
|
|
||||||
pointer-events: auto; /* Allow interaction when visible */
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip-content .tooltip-glossary-link {
|
|
||||||
display: inline-block;
|
|
||||||
margin-top: 8px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #007bff;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip-content .tooltip-glossary-link:hover {
|
|
||||||
color: #0056b3;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,216 @@
|
|||||||
|
import posixpath
|
||||||
|
import re
|
||||||
|
import tomllib
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from markdown.extensions import Extension
|
||||||
|
from markdown.preprocessors import Preprocessor
|
||||||
|
from markdown.treeprocessors import Treeprocessor
|
||||||
|
|
||||||
|
from zensical.extensions.links import LinksTreeprocessor
|
||||||
|
|
||||||
|
GlossaryTerm = tuple[str, re.Pattern[str], str]
|
||||||
|
|
||||||
|
GLOSSARY_FILE = Path(__file__).with_name("glossary.toml")
|
||||||
|
GLOSSARY_PAGE = "concepts/glossary.md"
|
||||||
|
GLOSSARY_PLACEHOLDER = "{{GLOSSARY_DEFINITIONS}}"
|
||||||
|
|
||||||
|
SKIP_TAGS = {
|
||||||
|
"a",
|
||||||
|
"code",
|
||||||
|
"h1",
|
||||||
|
"h2",
|
||||||
|
"h3",
|
||||||
|
"h4",
|
||||||
|
"h5",
|
||||||
|
"h6",
|
||||||
|
"kbd",
|
||||||
|
"pre",
|
||||||
|
"script",
|
||||||
|
"style",
|
||||||
|
}
|
||||||
|
|
||||||
|
def clean_tooltip(description: str) -> str:
|
||||||
|
text = re.sub(r"\[([^\]]+)]\([^)]+\)", r"\1", description)
|
||||||
|
text = re.sub(r"`([^`]+)`", r"\1", text)
|
||||||
|
text = re.sub(r"[*_~]", "", text)
|
||||||
|
return re.sub(r"\s+", " ", text).strip()
|
||||||
|
|
||||||
|
|
||||||
|
def load_glossary() -> tuple[list[GlossaryTerm], str]:
|
||||||
|
with GLOSSARY_FILE.open("rb") as f:
|
||||||
|
glossary_data = tomllib.load(f).get("glossary", {})
|
||||||
|
|
||||||
|
glossary: list[GlossaryTerm] = []
|
||||||
|
rendered = []
|
||||||
|
for key, value in glossary_data.items():
|
||||||
|
label = str(key).strip().replace("_", " ")
|
||||||
|
description = str(value).strip()
|
||||||
|
if not description:
|
||||||
|
continue
|
||||||
|
|
||||||
|
slug = label.replace(" ", "-").replace("_", "-").lower()
|
||||||
|
glossary.append((slug, re.compile(rf"(?<!\w){re.escape(label)}(?!\w)", re.IGNORECASE), clean_tooltip(description)))
|
||||||
|
rendered.append(f'* <span id="{slug}"></span>**{label}**: {description}')
|
||||||
|
|
||||||
|
return glossary, "\n".join(rendered)
|
||||||
|
|
||||||
|
|
||||||
|
class GlossaryPreprocessor(Preprocessor):
|
||||||
|
def __init__(self, md, glossary: str):
|
||||||
|
super().__init__(md)
|
||||||
|
self.glossary = glossary
|
||||||
|
|
||||||
|
def run(self, lines: list[str]) -> list[str]:
|
||||||
|
markdown = "\n".join(lines)
|
||||||
|
if GLOSSARY_PLACEHOLDER not in markdown:
|
||||||
|
return lines
|
||||||
|
return markdown.replace(GLOSSARY_PLACEHOLDER, self.glossary).splitlines()
|
||||||
|
|
||||||
|
|
||||||
|
class GlossaryTreeprocessor(Treeprocessor):
|
||||||
|
def __init__(self, md, glossary: list[GlossaryTerm]):
|
||||||
|
super().__init__(md)
|
||||||
|
self.glossary = glossary
|
||||||
|
self.seen: set[str] = set()
|
||||||
|
|
||||||
|
def run(self, root: ET.Element) -> None:
|
||||||
|
at = self.md.treeprocessors.get_index_for_name("zrelpath")
|
||||||
|
processor = self.md.treeprocessors[at]
|
||||||
|
if not isinstance(processor, LinksTreeprocessor):
|
||||||
|
raise TypeError("Links processor not registered")
|
||||||
|
if processor.path == GLOSSARY_PAGE:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.seen.clear()
|
||||||
|
glossary_href = f"{posixpath.relpath(GLOSSARY_PAGE, posixpath.dirname(processor.path) or '.')}#"
|
||||||
|
self._walk(root, glossary_href)
|
||||||
|
|
||||||
|
def _walk(self, element: ET.Element, glossary_href: str) -> None:
|
||||||
|
if element.tag in SKIP_TAGS or element.attrib.get("data-glossary-skip") is not None:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._replace(element, glossary_href)
|
||||||
|
|
||||||
|
idx = 0
|
||||||
|
while idx < len(element):
|
||||||
|
child = element[idx]
|
||||||
|
self._walk(child, glossary_href)
|
||||||
|
idx = self._replace(element, glossary_href, idx) + 1
|
||||||
|
|
||||||
|
def _replace(self, parent: ET.Element, glossary_href: str, index: int | None = None) -> int:
|
||||||
|
child = None if index is None else parent[index]
|
||||||
|
text = parent.text if child is None else child.tail
|
||||||
|
pieces = self._pieces(text or "", glossary_href)
|
||||||
|
if not pieces:
|
||||||
|
return -1 if index is None else index
|
||||||
|
|
||||||
|
if child is None:
|
||||||
|
parent.text = pieces[0] if isinstance(pieces[0], str) else ""
|
||||||
|
# Insert replacements for parent.text before the first existing child.
|
||||||
|
insert_at = -1
|
||||||
|
else:
|
||||||
|
assert index is not None
|
||||||
|
child.tail = pieces[0] if isinstance(pieces[0], str) else ""
|
||||||
|
insert_at = index
|
||||||
|
|
||||||
|
start = 1 if isinstance(pieces[0], str) else 0
|
||||||
|
previous = child
|
||||||
|
|
||||||
|
for piece in pieces[start:]:
|
||||||
|
if isinstance(piece, str):
|
||||||
|
previous.tail = (previous.tail or "") + piece
|
||||||
|
continue
|
||||||
|
|
||||||
|
insert_at += 1
|
||||||
|
parent.insert(insert_at, piece)
|
||||||
|
previous = piece
|
||||||
|
|
||||||
|
return insert_at
|
||||||
|
|
||||||
|
def _pieces(self, text: str, glossary_href: str) -> list[str | ET.Element]:
|
||||||
|
if not text.strip():
|
||||||
|
return []
|
||||||
|
|
||||||
|
pieces: list[str | ET.Element] = []
|
||||||
|
cursor = 0
|
||||||
|
|
||||||
|
while True:
|
||||||
|
best = None
|
||||||
|
for slug, pattern, tooltip in self.glossary:
|
||||||
|
if slug in self.seen:
|
||||||
|
continue
|
||||||
|
|
||||||
|
found = pattern.search(text, cursor)
|
||||||
|
if found is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
candidate = (slug, tooltip, found.start(), found.end())
|
||||||
|
if best is None:
|
||||||
|
best = candidate
|
||||||
|
continue
|
||||||
|
|
||||||
|
_, _, best_start, best_end = best
|
||||||
|
_, _, current_start, current_end = candidate
|
||||||
|
if current_start < best_start:
|
||||||
|
best = candidate
|
||||||
|
continue
|
||||||
|
|
||||||
|
if current_start == best_start and current_end - current_start > best_end - best_start:
|
||||||
|
best = candidate
|
||||||
|
|
||||||
|
if best is None:
|
||||||
|
break
|
||||||
|
|
||||||
|
slug, tooltip, start, end = best
|
||||||
|
if start > cursor:
|
||||||
|
pieces.append(text[cursor:start])
|
||||||
|
|
||||||
|
link = ET.Element(
|
||||||
|
"a",
|
||||||
|
{
|
||||||
|
"class": "glossary-term",
|
||||||
|
"data-glossary-term": "",
|
||||||
|
"href": f"{glossary_href}{slug}",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
ET.SubElement(link, "span", {"class": "glossary-term__label"}).text = text[start:end]
|
||||||
|
ET.SubElement(
|
||||||
|
link,
|
||||||
|
"span",
|
||||||
|
{
|
||||||
|
"class": "glossary-term__tooltip",
|
||||||
|
"data-search-exclude": "",
|
||||||
|
},
|
||||||
|
).text = tooltip
|
||||||
|
pieces.append(link)
|
||||||
|
self.seen.add(slug)
|
||||||
|
cursor = end
|
||||||
|
|
||||||
|
if not pieces:
|
||||||
|
return []
|
||||||
|
if cursor < len(text):
|
||||||
|
pieces.append(text[cursor:])
|
||||||
|
return pieces
|
||||||
|
|
||||||
|
|
||||||
|
class GlossaryExtension(Extension):
|
||||||
|
def extendMarkdown(self, md) -> None:
|
||||||
|
md.registerExtension(self)
|
||||||
|
glossary, rendered = load_glossary()
|
||||||
|
|
||||||
|
md.preprocessors.register(
|
||||||
|
GlossaryPreprocessor(md, rendered),
|
||||||
|
"docs-ext-glossary-preprocessor",
|
||||||
|
27,
|
||||||
|
)
|
||||||
|
md.treeprocessors.register(
|
||||||
|
GlossaryTreeprocessor(md, glossary),
|
||||||
|
"docs-ext-glossary-treeprocessor",
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def makeExtension(**kwargs) -> GlossaryExtension:
|
||||||
|
return GlossaryExtension(**kwargs)
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
[glossary]
|
||||||
|
onroad = "openpilot's system state while ignition is on."
|
||||||
|
offroad = "openpilot's system state while ignition is off."
|
||||||
|
route = "A route is a recording of an onroad session."
|
||||||
|
segment = "Routes are split into one minute chunks called segments."
|
||||||
|
"comma connect" = "The web viewer for all your routes; check it out at [connect.comma.ai](https://connect.comma.ai)."
|
||||||
|
panda = "The secondary processor on the device that implements the functional safety and directly talks to the car over CAN. See the [panda repo](https://github.com/commaai/panda)."
|
||||||
|
"comma four" = "The latest hardware by comma.ai for running openpilot. More info at [comma.ai/shop/comma-four](https://www.comma.ai/shop/comma-four)."
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
# What is openpilot?
|
|
||||||
|
|
||||||
[openpilot](http://github.com/commaai/openpilot) is an open source driver assistance system. Currently, openpilot performs the functions of Adaptive Cruise Control (ACC), Automated Lane Centering (ALC), Forward Collision Warning (FCW), and Lane Departure Warning (LDW) for a growing variety of [supported car makes, models, and model years](https://github.com/commaai/openpilot/blob/master/docs/CARS.md). In addition, while openpilot is engaged, a camera-based Driver Monitoring (DM) feature alerts distracted and asleep drivers. See more about [the vehicle integration](https://github.com/commaai/openpilot/blob/master/docs/INTEGRATION.md) and [limitations](https://github.com/commaai/openpilot/blob/master/docs/LIMITATIONS.md).
|
|
||||||
|
|
||||||
|
|
||||||
## How do I use it?
|
|
||||||
|
|
||||||
openpilot is designed to be used on the comma 3X.
|
|
||||||
|
|
||||||
## How does it work?
|
|
||||||
|
|
||||||
In short, openpilot uses the car's existing APIs for the built-in [ADAS](https://en.wikipedia.org/wiki/Advanced_driver-assistance_system) system and simply provides better acceleration, braking, and steering inputs than the stock system.
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
import re
|
|
||||||
import tomllib
|
|
||||||
|
|
||||||
def load_glossary(file_path="docs/glossary.toml"):
|
|
||||||
with open(file_path, "rb") as f:
|
|
||||||
glossary_data = tomllib.load(f)
|
|
||||||
return glossary_data.get("glossary", {})
|
|
||||||
|
|
||||||
def generate_anchor_id(name):
|
|
||||||
return name.replace(" ", "-").replace("_", "-").lower()
|
|
||||||
|
|
||||||
def format_markdown_term(name, definition):
|
|
||||||
anchor_id = generate_anchor_id(name)
|
|
||||||
markdown = f"* [**{name.replace('_', ' ').title()}**](#{anchor_id})"
|
|
||||||
if definition.get("abbreviation"):
|
|
||||||
markdown += f" *({definition['abbreviation']})*"
|
|
||||||
if definition.get("description"):
|
|
||||||
markdown += f": {definition['description']}\n"
|
|
||||||
return markdown
|
|
||||||
|
|
||||||
def glossary_markdown(vocabulary):
|
|
||||||
markdown = ""
|
|
||||||
for category, terms in vocabulary.items():
|
|
||||||
markdown += f"## {category.replace('_', ' ').title()}\n\n"
|
|
||||||
for name, definition in terms.items():
|
|
||||||
markdown += format_markdown_term(name, definition)
|
|
||||||
return markdown
|
|
||||||
|
|
||||||
def format_tooltip_html(term_key, definition, html):
|
|
||||||
display_term = term_key.replace("_", " ").title()
|
|
||||||
clean_description = re.sub(r"\[(.+)]\(.+\)", r"\1", definition["description"])
|
|
||||||
glossary_link = (
|
|
||||||
f"<a href='/concepts/glossary#{term_key}' class='tooltip-glossary-link' title='View in glossary'>Glossary🔗</a>"
|
|
||||||
)
|
|
||||||
return re.sub(
|
|
||||||
re.escape(display_term),
|
|
||||||
lambda
|
|
||||||
match: f"<span data-tooltip>{match.group(0)}<span class='tooltip-content'>{clean_description} {glossary_link}</span></span>",
|
|
||||||
html,
|
|
||||||
flags=re.IGNORECASE,
|
|
||||||
)
|
|
||||||
|
|
||||||
def apply_tooltip(_term_key, _definition, pattern, html):
|
|
||||||
return re.sub(
|
|
||||||
pattern,
|
|
||||||
lambda match: format_tooltip_html(_term_key, _definition, match.group(0)),
|
|
||||||
html,
|
|
||||||
flags=re.IGNORECASE,
|
|
||||||
)
|
|
||||||
|
|
||||||
def tooltip_html(vocabulary, html):
|
|
||||||
for _category, terms in vocabulary.items():
|
|
||||||
for term_key, definition in terms.items():
|
|
||||||
if definition.get("description"):
|
|
||||||
pattern = rf"(?<!\w){re.escape(term_key.replace('_', ' ').title())}(?![^<]*<\/a>)(?!\([^)]*\))"
|
|
||||||
html = apply_tooltip(term_key, definition, pattern, html)
|
|
||||||
return html
|
|
||||||
|
|
||||||
# Page Hooks
|
|
||||||
def on_page_markdown(markdown, **kwargs):
|
|
||||||
glossary = load_glossary()
|
|
||||||
return markdown.replace("{{GLOSSARY_DEFINITIONS}}", glossary_markdown(glossary))
|
|
||||||
|
|
||||||
def on_page_content(html, **kwargs):
|
|
||||||
if kwargs.get("page").title == "Glossary":
|
|
||||||
return html
|
|
||||||
glossary = load_glossary()
|
|
||||||
return tooltip_html(glossary, html)
|
|
||||||
@@ -8,7 +8,7 @@ A car port enables openpilot support on a particular car. Each car model openpil
|
|||||||
|
|
||||||
# Structure of a car port
|
# Structure of a car port
|
||||||
|
|
||||||
Virtually all car-specific code is contained in two other repositories: [opendbc](https://github.com/commaai/opendbc) and [panda](https://github.com/commaai/panda).
|
All car-specific code is contained in the [opendbc](https://github.com/commaai/opendbc) project.
|
||||||
|
|
||||||
## opendbc
|
## opendbc
|
||||||
|
|
||||||
@@ -21,19 +21,31 @@ Each car brand is supported by a standard interface structure in `opendbc/car/[b
|
|||||||
* `values.py`: Limits for actuation, general constants for cars, and supported car documentation
|
* `values.py`: Limits for actuation, general constants for cars, and supported car documentation
|
||||||
* `radar_interface.py`: Interface for parsing radar points from the car, if applicable
|
* `radar_interface.py`: Interface for parsing radar points from the car, if applicable
|
||||||
|
|
||||||
## panda
|
## safety
|
||||||
|
|
||||||
* `board/safety/safety_[brand].h`: Brand-specific safety logic
|
* `opendbc/safety/modes/[brand].h`: Brand-specific safety logic
|
||||||
* `tests/safety/test_[brand].py`: Brand-specific safety CI tests
|
* `opendbc/safety/tests/test_[brand].py`: Brand-specific safety CI tests
|
||||||
|
|
||||||
## openpilot
|
## openpilot
|
||||||
|
|
||||||
For historical reasons, openpilot still contains a small amount of car-specific logic. This will eventually be migrated to opendbc or otherwise removed.
|
For historical reasons, openpilot still contains a small amount of car-specific logic. This will eventually be migrated to opendbc or otherwise removed.
|
||||||
|
|
||||||
* `selfdrive/car/car_specific.py`: Brand-specific event logic
|
* `openpilot/selfdrive/car/car_specific.py`: Brand-specific event logic
|
||||||
|
|
||||||
# Overview
|
# How do I port car?
|
||||||
|
|
||||||
[Jason Young](https://github.com/jyoung8607) gave a talk at COMMA_CON with an overview of the car porting process. The talk is available on YouTube:
|
[Jason Young](https://github.com/jyoung8607) gave a talk at COMMA_CON with an overview of the car porting process. The talk is available on YouTube:
|
||||||
|
|
||||||
https://www.youtube.com/watch?v=XxPS5TpTUnI
|
https://www.youtube.com/watch?v=XxPS5TpTUnI
|
||||||
|
|
||||||
|
## Brand Port
|
||||||
|
|
||||||
|
A brand port is a port of openpilot to a substantially new car brand or platform within a brand.
|
||||||
|
|
||||||
|
Here's an example of one: https://github.com/commaai/openpilot/pull/23331.
|
||||||
|
|
||||||
|
## Model Port
|
||||||
|
|
||||||
|
A model port is a port of openpilot to a new car model within an already supported brand. Model ports are easier than brand ports because the car's existing APIs are already known.
|
||||||
|
|
||||||
|
Here's an example of one: https://github.com/commaai/openpilot/pull/30672/.
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
# connect to a comma 3X
|
# connect to a comma 3X or comma four
|
||||||
|
|
||||||
A comma 3X is a normal [Linux](https://github.com/commaai/agnos-builder) computer that exposes [SSH](https://wiki.archlinux.org/title/Secure_Shell) and a [serial console](https://wiki.archlinux.org/title/Working_with_the_serial_console).
|
A comma device is a normal [Linux](https://github.com/commaai/agnos-builder) computer that exposes [SSH](https://wiki.archlinux.org/title/Secure_Shell) and a [serial console](https://wiki.archlinux.org/title/Working_with_the_serial_console).
|
||||||
|
|
||||||
## Serial Console
|
## Serial Console
|
||||||
|
|
||||||
On both the comma three and 3X, the serial console is accessible from the main OBD-C port.
|
On the comma 3X, the serial console is accessible from the main OBD-C port, forwarded through the panda.
|
||||||
Connect the comma 3X to your computer with a normal USB C cable, or use a [comma serial](https://comma.ai/shop/comma-serial) for steady 12V power.
|
Access it using `panda/scripts/som_debug.sh`.
|
||||||
|
|
||||||
On the comma three, the serial console is exposed through a UART-to-USB chip, and `tools/scripts/serial.sh` can be used to connect.
|
comma four also exposes a serial console, albeit through an internal debug connector. Dedicated debug hardware coming soon to the comma shop.
|
||||||
|
|
||||||
On the comma 3X, the serial console is accessible through the [panda](https://github.com/commaai/panda) using the `panda/tests/som_debug.sh` script.
|
Login to the default user with:
|
||||||
|
|
||||||
* Username: `comma`
|
* Username: `comma`
|
||||||
* Password: `comma`
|
* Password: `comma`
|
||||||
@@ -25,7 +25,7 @@ In order to SSH into your device, you'll need a GitHub account with SSH keys. Se
|
|||||||
* Port: `22`
|
* Port: `22`
|
||||||
|
|
||||||
Here's an example command for connecting to your device using its tethered connection:<br />
|
Here's an example command for connecting to your device using its tethered connection:<br />
|
||||||
`ssh comma@192.168.43.1`
|
`ssh comma@192.168.43.1 -i ~/.ssh/my_github_key`
|
||||||
|
|
||||||
For doing development work on device, it's recommended to use [SSH agent forwarding](https://docs.github.com/en/developers/overview/using-ssh-agent-forwarding).
|
For doing development work on device, it's recommended to use [SSH agent forwarding](https://docs.github.com/en/developers/overview/using-ssh-agent-forwarding).
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ In order to use ADB on your device, you'll need to perform the following steps u
|
|||||||
* Here's an example command for connecting to your device using its tethered connection: `adb connect 192.168.43.1:5555`
|
* Here's an example command for connecting to your device using its tethered connection: `adb connect 192.168.43.1:5555`
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> The default port for ADB is 5555 on the comma 3X.
|
> The default port for ADB is 5555.
|
||||||
|
|
||||||
For more info on ADB, see the [Android Debug Bridge (ADB) documentation](https://developer.android.com/tools/adb).
|
For more info on ADB, see the [Android Debug Bridge (ADB) documentation](https://developer.android.com/tools/adb).
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ The public keys are only fetched from your GitHub account once. In order to upda
|
|||||||
|
|
||||||
The `id_rsa` key in this directory only works while your device is in the setup state with no software installed. After installation, that default key will be removed.
|
The `id_rsa` key in this directory only works while your device is in the setup state with no software installed. After installation, that default key will be removed.
|
||||||
|
|
||||||
#### ssh.comma.ai proxy
|
## ssh.comma.ai proxy
|
||||||
|
|
||||||
With a [comma prime subscription](https://comma.ai/connect), you can SSH into your comma device from anywhere.
|
With a [comma prime subscription](https://comma.ai/connect), you can SSH into your comma device from anywhere.
|
||||||
|
|
||||||
@@ -79,6 +79,7 @@ Host ssh.comma.ai
|
|||||||
```
|
```
|
||||||
ssh -i ~/.ssh/my_github_key -o ProxyCommand="ssh -i ~/.ssh/my_github_key -W %h:%p -p %p %h@ssh.comma.ai" comma@ffffffffffffffff
|
ssh -i ~/.ssh/my_github_key -o ProxyCommand="ssh -i ~/.ssh/my_github_key -W %h:%p -p %p %h@ssh.comma.ai" comma@ffffffffffffffff
|
||||||
```
|
```
|
||||||
|
|
||||||
(Replace `ffffffffffffffff` with your dongle_id)
|
(Replace `ffffffffffffffff` with your dongle_id)
|
||||||
|
|
||||||
### ssh.comma.ai host key fingerprint
|
### ssh.comma.ai host key fingerprint
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ Replaying is a critical tool for openpilot development and debugging.
|
|||||||
## Replaying a route
|
## Replaying a route
|
||||||
*Hardware required: none*
|
*Hardware required: none*
|
||||||
|
|
||||||
Just run `tools/replay/replay --demo`.
|
Just run `openpilot/tools/replay/replay --demo`.
|
||||||
|
|
||||||
## Replaying CAN data
|
## Replaying CAN data
|
||||||
*Hardware required: jungle and comma 3X*
|
*Hardware required: jungle and comma four*
|
||||||
|
|
||||||
1. Connect your PC to a jungle.
|
1. Connect your PC to a jungle.
|
||||||
2.
|
2.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
In 30 minutes, we'll get an openpilot development environment set up on your computer and make some changes to openpilot's UI.
|
In 30 minutes, we'll get an openpilot development environment set up on your computer and make some changes to openpilot's UI.
|
||||||
|
|
||||||
And if you have a comma 3X, we'll deploy the change to your device for testing.
|
And if you have a comma four, we'll deploy the change to your device for testing.
|
||||||
|
|
||||||
## 1. Set up your development environment
|
## 1. Set up your development environment
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ source .venv/bin/activate
|
|||||||
|
|
||||||
Then, compile openpilot:
|
Then, compile openpilot:
|
||||||
```bash
|
```bash
|
||||||
scons -j$(nproc)
|
scons
|
||||||
```
|
```
|
||||||
|
|
||||||
## 2. Run replay
|
## 2. Run replay
|
||||||
@@ -28,10 +28,10 @@ scons -j$(nproc)
|
|||||||
We'll run the `replay` tool with the demo route to get data streaming for testing our UI changes.
|
We'll run the `replay` tool with the demo route to get data streaming for testing our UI changes.
|
||||||
```bash
|
```bash
|
||||||
# in terminal 1
|
# in terminal 1
|
||||||
tools/replay/replay --demo
|
openpilot/tools/replay/replay --demo
|
||||||
|
|
||||||
# in terminal 2
|
# in terminal 2
|
||||||
./selfdrive/ui/ui.py
|
./openpilot/selfdrive/ui/ui.py
|
||||||
```
|
```
|
||||||
|
|
||||||
The openpilot UI should launch and show a replay of the demo route.
|
The openpilot UI should launch and show a replay of the demo route.
|
||||||
@@ -45,10 +45,10 @@ Now let’s update the speed display color in the UI.
|
|||||||
|
|
||||||
Search for the function responsible for rendering the current speed:
|
Search for the function responsible for rendering the current speed:
|
||||||
```bash
|
```bash
|
||||||
git grep "_draw_current_speed" selfdrive/ui/onroad/hud_renderer.py
|
git grep "_draw_current_speed" openpilot/selfdrive/ui/onroad/hud_renderer.py
|
||||||
```
|
```
|
||||||
|
|
||||||
You'll find the relevant code inside `selfdrive/ui/onroad/hud_renderer.py`, in this function:
|
You'll find the relevant code inside `openpilot/selfdrive/ui/onroad/hud_renderer.py`, in this function:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def _draw_current_speed(self, rect: rl.Rectangle) -> None:
|
def _draw_current_speed(self, rect: rl.Rectangle) -> None:
|
||||||
@@ -72,7 +72,7 @@ Change `COLORS.white` to make it **blue** instead of white. A nice soft blue is
|
|||||||
|
|
||||||
After making changes, re-run the UI to see your new UI:
|
After making changes, re-run the UI to see your new UI:
|
||||||
```bash
|
```bash
|
||||||
./selfdrive/ui/ui.py
|
./openpilot/selfdrive/ui/ui.py
|
||||||
```
|
```
|
||||||

|

|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
getting-started/what-is-openpilot.md
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# What is openpilot?
|
||||||
|
|
||||||
|
[openpilot](http://github.com/commaai/openpilot) is an open source driver assistance system. Currently, openpilot performs the functions of Adaptive Cruise Control (ACC), Automated Lane Centering (ALC), Forward Collision Warning (FCW), and Lane Departure Warning (LDW) for a growing variety of [supported car makes, models, and model years](https://github.com/commaai/openpilot/blob/master/docs/CARS.md). In addition, while openpilot is engaged, a camera-based Driver Monitoring (DM) feature alerts distracted and asleep drivers. See more about [the vehicle integration](https://github.com/commaai/openpilot/blob/master/docs/INTEGRATION.md) and [limitations](https://github.com/commaai/openpilot/blob/master/docs/LIMITATIONS.md).
|
||||||
|
|
||||||
|
|
||||||
|
## How do I use it?
|
||||||
|
|
||||||
|
openpilot is designed to be used on the comma four.
|
||||||
|
|
||||||
|
## How does it work?
|
||||||
|
|
||||||
|
In short, openpilot uses the car's existing APIs for the built-in [ADAS](https://en.wikipedia.org/wiki/Advanced_driver-assistance_system) system and simply provides better acceleration, braking, and steering inputs than the stock system.
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
.md-logo img {
|
||||||
|
filter: invert(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.glossary-term {
|
||||||
|
position: relative;
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.glossary-term__label {
|
||||||
|
border-bottom: 1px dotted currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.glossary-term__tooltip {
|
||||||
|
position: absolute;
|
||||||
|
top: calc(100% + 0.4rem);
|
||||||
|
left: 50%;
|
||||||
|
width: max-content;
|
||||||
|
max-width: min(30rem, 80vw);
|
||||||
|
padding: 0.65rem 0.8rem;
|
||||||
|
border-radius: 0.6rem;
|
||||||
|
background: rgb(26 26 26 / 96%);
|
||||||
|
color: white;
|
||||||
|
box-shadow: 0 0.6rem 1.8rem rgb(0 0 0 / 22%);
|
||||||
|
font-size: 0.85rem;
|
||||||
|
line-height: 1.45;
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
transform: translateX(-50%) translateY(-0.15rem);
|
||||||
|
transition: opacity 120ms ease, transform 120ms ease;
|
||||||
|
visibility: hidden;
|
||||||
|
z-index: 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
.glossary-term:hover .glossary-term__tooltip,
|
||||||
|
.glossary-term:focus-visible .glossary-term__tooltip,
|
||||||
|
.glossary-term:focus-within .glossary-term__tooltip {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(-50%) translateY(0);
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
+13
-4
@@ -7,6 +7,7 @@ source "$DIR/launch_env.sh"
|
|||||||
function agnos_init {
|
function agnos_init {
|
||||||
# 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
|
||||||
|
rm -f /data/scons_cache/config.lock
|
||||||
|
|
||||||
# set success flag for current boot slot
|
# set success flag for current boot slot
|
||||||
sudo abctl --set_success
|
sudo abctl --set_success
|
||||||
@@ -18,12 +19,12 @@ function agnos_init {
|
|||||||
|
|
||||||
# Check if AGNOS update is required
|
# Check if AGNOS update is required
|
||||||
if [ $(< /VERSION) != "$AGNOS_VERSION" ]; then
|
if [ $(< /VERSION) != "$AGNOS_VERSION" ]; then
|
||||||
AGNOS_PY="$DIR/system/hardware/tici/agnos.py"
|
AGNOS_PY="$DIR/openpilot/common/hardware/tici/agnos.py"
|
||||||
MANIFEST="$DIR/system/hardware/tici/agnos.json"
|
MANIFEST="$DIR/openpilot/system/hardware/tici/agnos.json"
|
||||||
if $AGNOS_PY --verify $MANIFEST; then
|
if $AGNOS_PY --verify $MANIFEST; then
|
||||||
sudo reboot
|
sudo reboot
|
||||||
fi
|
fi
|
||||||
$DIR/system/hardware/tici/updater $AGNOS_PY $MANIFEST
|
$DIR/openpilot/common/hardware/tici/updater $AGNOS_PY $MANIFEST
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,6 +70,14 @@ function launch {
|
|||||||
ln -sfn $(pwd) /data/pythonpath
|
ln -sfn $(pwd) /data/pythonpath
|
||||||
export PYTHONPATH="$PWD"
|
export PYTHONPATH="$PWD"
|
||||||
|
|
||||||
|
# submodule package symlinks for PYTHONPATH imports on device.
|
||||||
|
# on PC these come from editable installs via pyproject.toml / uv.
|
||||||
|
ln -sfn msgq_repo/msgq msgq
|
||||||
|
ln -sfn opendbc_repo/opendbc opendbc
|
||||||
|
ln -sfn rednose_repo/rednose rednose
|
||||||
|
ln -sfn teleoprtc_repo/teleoprtc teleoprtc
|
||||||
|
ln -sfn tinygrad_repo/tinygrad tinygrad
|
||||||
|
|
||||||
# hardware specific init
|
# hardware specific init
|
||||||
if [ -f /AGNOS ]; then
|
if [ -f /AGNOS ]; then
|
||||||
agnos_init
|
agnos_init
|
||||||
@@ -78,7 +87,7 @@ function launch {
|
|||||||
tmux capture-pane -pq -S-1000 > /tmp/launch_log
|
tmux capture-pane -pq -S-1000 > /tmp/launch_log
|
||||||
|
|
||||||
# start manager
|
# start manager
|
||||||
cd system/manager
|
cd openpilot/system/manager
|
||||||
if [ ! -f $DIR/prebuilt ]; then
|
if [ ! -f $DIR/prebuilt ]; then
|
||||||
./build.py
|
./build.py
|
||||||
fi
|
fi
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ export VECLIB_MAXIMUM_THREADS=1
|
|||||||
export QCOM_PRIORITY=12
|
export QCOM_PRIORITY=12
|
||||||
|
|
||||||
if [ -z "$AGNOS_VERSION" ]; then
|
if [ -z "$AGNOS_VERSION" ]; then
|
||||||
export AGNOS_VERSION="15.1"
|
export AGNOS_VERSION="18.4"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export STAGING_ROOT="/data/safe_staging"
|
export STAGING_ROOT="/data/safe_staging"
|
||||||
|
|||||||
-44
@@ -1,44 +0,0 @@
|
|||||||
site_name: openpilot docs
|
|
||||||
repo_url: https://github.com/commaai/openpilot/
|
|
||||||
site_url: https://docs.comma.ai
|
|
||||||
|
|
||||||
exclude_docs: README.md
|
|
||||||
|
|
||||||
strict: true
|
|
||||||
docs_dir: docs
|
|
||||||
site_dir: docs_site/
|
|
||||||
|
|
||||||
hooks:
|
|
||||||
- docs/hooks/glossary.py
|
|
||||||
extra_css:
|
|
||||||
- css/tooltip.css
|
|
||||||
theme:
|
|
||||||
name: readthedocs
|
|
||||||
navigation_depth: 3
|
|
||||||
|
|
||||||
nav:
|
|
||||||
- Getting Started:
|
|
||||||
- What is openpilot?: getting-started/what-is-openpilot.md
|
|
||||||
- How-to:
|
|
||||||
- Turn the speed blue: how-to/turn-the-speed-blue.md
|
|
||||||
- Connect to a comma 3X: how-to/connect-to-comma.md
|
|
||||||
# - Make your first pull request: how-to/make-first-pr.md
|
|
||||||
#- Replay a drive: how-to/replay-a-drive.md
|
|
||||||
- Concepts:
|
|
||||||
- Logs: concepts/logs.md
|
|
||||||
- Safety: concepts/safety.md
|
|
||||||
- Glossary: concepts/glossary.md
|
|
||||||
- Car Porting:
|
|
||||||
- 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 model: car-porting/model-port.md
|
|
||||||
- Contributing:
|
|
||||||
- Roadmap: contributing/roadmap.md
|
|
||||||
#- Architecture: contributing/architecture.md
|
|
||||||
- Contributing Guide →: https://github.com/commaai/openpilot/blob/master/docs/CONTRIBUTING.md
|
|
||||||
- Links:
|
|
||||||
- Blog →: https://blog.comma.ai
|
|
||||||
- Bounties →: https://comma.ai/bounties
|
|
||||||
- GitHub →: https://github.com/commaai
|
|
||||||
- Discord →: https://discord.comma.ai
|
|
||||||
- X →: https://x.com/comma_ai
|
|
||||||
+1
-1
Submodule msgq_repo updated: 6abe47bc98...bb6cc57ef4
+1
-1
Submodule opendbc_repo updated: 74ac678501...3c0fd77813
@@ -24,17 +24,17 @@ things are not. Read more details [here](https://capnproto.org/language.html).
|
|||||||
### Custom forks
|
### Custom forks
|
||||||
|
|
||||||
Forks of [openpilot](https://github.com/commaai/openpilot) might want to add things to the messaging
|
Forks of [openpilot](https://github.com/commaai/openpilot) might want to add things to the messaging
|
||||||
spec, however this could conflict with future changes made in mainline cereal/openpilot. Rebasing against mainline openpilot
|
spec, however this could conflict with future changes made in mainline openpilot's cereal spec. Rebasing against mainline openpilot
|
||||||
then means breaking backwards-compatibility with all old logs of your fork. So we added reserved events in
|
then means breaking backwards-compatibility with all old logs of your fork. So we added reserved events in
|
||||||
[custom.capnp](custom.capnp) that we will leave empty in mainline cereal/openpilot. **If you only modify those, you can ensure your
|
[custom.capnp](custom.capnp) that we will leave empty in mainline openpilot's cereal spec. **If you only modify those, you can ensure your
|
||||||
fork will remain backwards-compatible with all versions of mainline openpilot and your fork.**
|
fork will remain backwards-compatible with all versions of mainline openpilot and your fork.**
|
||||||
|
|
||||||
An example of compatible changes:
|
An example of compatible changes:
|
||||||
```diff
|
```diff
|
||||||
diff --git a/cereal/custom.capnp b/cereal/custom.capnp
|
diff --git a/openpilot/cereal/custom.capnp b/openpilot/cereal/custom.capnp
|
||||||
index 3348e859e..3365c7b98 100644
|
index 3348e859e..3365c7b98 100644
|
||||||
--- a/cereal/custom.capnp
|
--- a/openpilot/cereal/custom.capnp
|
||||||
+++ b/cereal/custom.capnp
|
+++ b/openpilot/cereal/custom.capnp
|
||||||
@@ -10,7 +10,11 @@ $Cxx.namespace("cereal");
|
@@ -10,7 +10,11 @@ $Cxx.namespace("cereal");
|
||||||
# DO rename the structs
|
# DO rename the structs
|
||||||
# DON'T change the identifier (e.g. @0x81c2f05a394cf4af)
|
# DON'T change the identifier (e.g. @0x81c2f05a394cf4af)
|
||||||
@@ -48,10 +48,10 @@ index 3348e859e..3365c7b98 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct CustomReserved1 @0xaedffd8f31e7b55d {
|
struct CustomReserved1 @0xaedffd8f31e7b55d {
|
||||||
diff --git a/cereal/log.capnp b/cereal/log.capnp
|
diff --git a/openpilot/cereal/log.capnp b/openpilot/cereal/log.capnp
|
||||||
index 1209f3fd9..b189f58b6 100644
|
index 1209f3fd9..b189f58b6 100644
|
||||||
--- a/cereal/log.capnp
|
--- a/openpilot/cereal/log.capnp
|
||||||
+++ b/cereal/log.capnp
|
+++ b/openpilot/cereal/log.capnp
|
||||||
@@ -2558,14 +2558,14 @@ struct Event {
|
@@ -2558,14 +2558,14 @@ struct Event {
|
||||||
|
|
||||||
# DO change the name of the field
|
# DO change the name of the field
|
||||||
@@ -76,7 +76,7 @@ index 1209f3fd9..b189f58b6 100644
|
|||||||
Example
|
Example
|
||||||
---
|
---
|
||||||
```python
|
```python
|
||||||
import cereal.messaging as messaging
|
import openpilot.cereal.messaging as messaging
|
||||||
|
|
||||||
# in subscriber
|
# in subscriber
|
||||||
sm = messaging.SubMaster(['sensorEvents'])
|
sm = messaging.SubMaster(['sensorEvents'])
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
Import('env', 'common', 'msgq')
|
||||||
|
|
||||||
|
cereal_dir = Dir('.')
|
||||||
|
gen_dir = Dir('gen')
|
||||||
|
|
||||||
|
# Build cereal
|
||||||
|
schema_files = ['log.capnp', 'deprecated.capnp', 'custom.capnp']
|
||||||
|
car_capnp = '#opendbc_repo/opendbc/car/car.capnp'
|
||||||
|
all_output = schema_files + ['car.capnp']
|
||||||
|
env.Command([f'gen/cpp/{s}.c++' for s in all_output] + [f'gen/cpp/{s}.h' for s in all_output],
|
||||||
|
schema_files + [car_capnp],
|
||||||
|
f"capnpc --src-prefix={cereal_dir.path} --src-prefix=opendbc_repo/opendbc/car --import-path=opendbc_repo/opendbc/car $SOURCES -o c++:{gen_dir.path}/cpp/")
|
||||||
|
|
||||||
|
cereal = env.Library('cereal', [f'gen/cpp/{s}.c++' for s in all_output])
|
||||||
|
|
||||||
|
# Build messaging
|
||||||
|
services_h = env.Command(['services.h'], ['services.py'], 'python3 ' + cereal_dir.path + '/services.py > $TARGET')
|
||||||
|
env.Program('messaging/bridge', ['messaging/bridge.cc', 'messaging/msgq_to_zmq.cc', 'messaging/bridge_zmq.cc'], LIBS=[msgq, common, 'pthread'])
|
||||||
|
|
||||||
|
socketmaster = env.Library('socketmaster', ['messaging/socketmaster.cc'])
|
||||||
|
|
||||||
|
Export('cereal', 'socketmaster')
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import os
|
||||||
|
import capnp
|
||||||
|
from importlib.resources import as_file, files
|
||||||
|
|
||||||
|
capnp.remove_import_hook()
|
||||||
|
|
||||||
|
with as_file(files("openpilot.cereal")) as fspath, as_file(files("opendbc")) as opendbc_path:
|
||||||
|
CEREAL_PATH = fspath.as_posix()
|
||||||
|
opendbc_import_path = os.path.join(os.path.realpath(opendbc_path.as_posix()), 'car')
|
||||||
|
log = capnp.load(os.path.join(CEREAL_PATH, "log.capnp"), imports=[opendbc_import_path])
|
||||||
|
custom = capnp.load(os.path.join(CEREAL_PATH, "custom.capnp"), imports=[opendbc_import_path])
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user