Compare commits

...

206 Commits

Author SHA1 Message Date
Jason Wen
9930cbb0b8 always check 2024-11-24 17:34:55 -05:00
Jason Wen
9e4ec43153 should be 8 bytes 2024-11-24 16:17:38 -05:00
Jason Wen
1772dd8eb0 this is now HD 2024-11-24 14:51:33 -05:00
Jason Wen
fb1d21400f allow for hd 2024-11-24 14:47:19 -05:00
Jason Wen
2cb9b316a1 wrong dbc 2024-11-24 14:31:11 -05:00
Jason Wen
09e38e16cd eps messages 2024-11-24 13:07:57 -05:00
Jason Wen
537146e1d6 missing dbc 2024-11-24 12:36:35 -05:00
Jason Wen
ca19344eb8 Merge branch 'fca-s20' into mads-new-fca-s20
# Conflicts:
#	opendbc_repo
#	panda
2024-11-24 12:05:17 -05:00
Jason Wen
06c4fba102 Merge branch 'master-new' into mads-new
# Conflicts:
#	opendbc_repo
#	panda
2024-11-23 12:33:31 -05:00
Jason Wen
6c5afa789f bump submodules 2024-11-22 17:59:33 -05:00
Jason Wen
6a82baac9c fix 2024-11-22 10:25:56 -05:00
Jason Wen
ccea6de343 Merge branch 'master-new' into mads-new
# Conflicts:
#	opendbc_repo
#	panda
2024-11-22 10:17:49 -05:00
Jason Wen
86a4cc6329 bump submodules 2024-11-21 23:48:28 -05:00
Jason Wen
b24e762592 more 2024-11-21 10:40:58 -05:00
Jason Wen
ed8812e730 FCA: S20 init 2024-11-21 10:18:40 -05:00
Jason Wen
7883de0b30 do this for dlob 2024-11-20 20:28:18 -05:00
Jason Wen
a89e79e4bb unify silent enable 2024-11-20 12:08:26 -05:00
Jason Wen
d7629c55df only mads in enabled state and long in disabled state 2024-11-20 11:55:22 -05:00
Jason Wen
bcc4117217 fix 2024-11-20 11:52:35 -05:00
Jason Wen
9fa0d53b82 same thing 2024-11-20 11:51:38 -05:00
Jason Wen
f403c5a93f unused 2024-11-20 11:28:57 -05:00
Jason Wen
0ba2286bf9 simpler 2024-11-20 11:28:51 -05:00
Jason Wen
8ee0f91642 update unit test 2024-11-20 11:23:04 -05:00
Jason Wen
4fb2c5c16c in lists 2024-11-20 11:22:58 -05:00
Jason Wen
692055df39 brake hold should apply to all 2024-11-20 10:43:16 -05:00
Jason Wen
aced3ec768 allow entering paused state if no entry from disabled 2024-11-20 04:06:10 -05:00
Jason Wen
b39d998d82 cleanup 2024-11-20 02:38:33 -05:00
Jason Wen
89ba9a7bf3 need this check 2024-11-20 02:31:04 -05:00
Jason Wen
95697afdf8 bump opendbc 2024-11-19 17:44:06 -05:00
Jason Wen
0744b1a0b9 fixme 2024-11-19 17:26:56 -05:00
Jason Wen
7ef9091d17 fix no entry 2024-11-19 17:25:11 -05:00
Jason Wen
5b7d5017f5 MUST REMOVE test process replay 2024-11-19 12:51:44 -05:00
Jason Wen
220b0a4eb8 just warning 2024-11-19 10:47:36 -05:00
Jason Wen
315312c30a user disable tests 2024-11-19 01:54:12 -05:00
Jason Wen
e5a988bc2f no need 2024-11-19 01:10:32 -05:00
Jason Wen
347914d9bf silent lkas disable 2024-11-19 01:09:54 -05:00
Jason Wen
4c23b2728a revert 2024-11-18 22:42:04 -05:00
Jason Wen
6f5a44ecaa should be enabled 2024-11-18 22:39:24 -05:00
DevTekVE
5c7baa07d1 back to stock
removing allow_cancel
2024-11-17 20:22:59 +01:00
DevTekVE
d541011bdc adjusting creation delays 2024-11-17 19:56:11 +01:00
DevTekVE
ce5eea4a4d ignoring reserved events 2024-11-17 19:45:46 +01:00
DevTekVE
aa32c33687 Revert "show MADS updates"
This reverts commit daf0ad62

Revert "fix changed events"

This reverts commit 31d8c97f
2024-11-17 19:41:08 +01:00
Jason Wen
f3b448d7ff Show our overriding 2024-11-17 07:55:23 -05:00
DevTekVE
7f96037589 Rename test as collector was dying 2024-11-17 11:26:15 +01:00
Jason Wen
a55c8f8e70 static analysis 2024-11-17 05:14:29 -05:00
DevTekVE
c14f09f538 Merge remote-tracking branch 'origin/master-new' into mads-new 2024-11-17 09:52:05 +01:00
Jason Wen
0a9ca2b2a9 static analysis 2024-11-17 00:04:30 -05:00
Jason Wen
2550185feb bump opendbc 2024-11-16 23:58:27 -05:00
Jason Wen
4fb170b195 better format 2024-11-16 23:58:15 -05:00
Jason Wen
99c82a8eb9 enabled <-> active 2024-11-16 23:33:59 -05:00
Jason Wen
bfa88cec5f should use enabled 2024-11-16 23:20:58 -05:00
Jason Wen
d3c69aa0ba don't add pre enable if not long 2024-11-16 23:10:05 -05:00
Jason Wen
8e578bf0b0 fix cluster enabled 2024-11-16 23:00:08 -05:00
Jason Wen
31d8c97f6a fix changed events 2024-11-16 22:58:35 -05:00
Jason Wen
3ac6fa5c5c Merge branch 'master-new' into mads-new 2024-11-16 22:34:15 -05:00
Jason Wen
fb5f8a74ac no longer needed 2024-11-16 19:28:13 -05:00
Jason Wen
6106fe3d2e Add TODO 2024-11-16 19:19:51 -05:00
Jason Wen
daf0ad629b show MADS updates 2024-11-16 19:11:49 -05:00
Jason Wen
e1904c5a3f UI border update 2024-11-16 18:54:18 -05:00
Jason Wen
3ee950d117 no need available 2024-11-16 18:10:56 -05:00
Jason Wen
059ae47c5c no unittest 2024-11-16 18:10:19 -05:00
Jason Wen
71fff2ea24 static analysis 2024-11-16 17:54:00 -05:00
Jason Wen
410e365f9c bump opendbc 2024-11-16 17:48:31 -05:00
Jason Wen
abe4a61870 Merge branch 'master-new' into mads-new 2024-11-16 17:48:25 -05:00
Jason Wen
188fe9a1fd Merge branch 'master-new' into mads-new
# Conflicts:
#	opendbc_repo
2024-11-16 17:33:12 -05:00
Jason Wen
4f78e31cf4 use new cereal 2024-11-16 17:23:31 -05:00
Jason Wen
ca4183808d bump opendbc 2024-11-16 16:56:49 -05:00
Jason Wen
8865ab708c add sunnypilot to unit tests 2024-11-16 16:56:39 -05:00
Jason Wen
7d8a64d781 move unit test 2024-11-16 16:50:17 -05:00
Jason Wen
e1ce8e9f0f no longer needed 2024-11-16 16:45:50 -05:00
Jason Wen
69d55cbf72 always emit user disable 2024-11-16 16:21:42 -05:00
Jason Wen
bb4ddcc483 Merge branch 'master-new' into mads-new 2024-11-16 10:25:52 -05:00
Jason Wen
e5ac29640e final? 2024-11-16 10:07:40 -05:00
Jason Wen
dc7ff7630c more! 2024-11-16 10:03:57 -05:00
Jason Wen
b1be910d5d no more available 2024-11-16 10:03:20 -05:00
Jason Wen
e648ff7341 more fixes 2024-11-16 10:01:52 -05:00
Jason Wen
a7fa22a730 bump opendbc 2024-11-16 09:58:07 -05:00
Jason Wen
053ff2ad14 no need 2024-11-16 09:55:42 -05:00
Jason Wen
89073d6b88 Move car-specific changes to opendbc 2024-11-16 03:33:23 -05:00
Jason Wen
e96db89f40 make sure it's car only 2024-11-16 02:37:01 -05:00
Jason Wen
8a01ed7de8 sunnyParams 2024-11-16 02:17:58 -05:00
Jason Wen
410535c47d hyundai: only allow for cars with lfa button 2024-11-16 01:41:47 -05:00
Jason Wen
f446129afa cleaner 2024-11-16 01:35:04 -05:00
Jason Wen
cdcd25f284 reserve events 2024-11-16 01:29:04 -05:00
Jason Wen
c800614f44 add todo 2024-11-16 01:01:13 -05:00
Jason Wen
fc73b567af group 2024-11-16 00:55:29 -05:00
Jason Wen
8ffd2ea8ee fix 2024-11-15 23:11:44 -05:00
Jason Wen
d5b26f7f18 remoev already checks if it exists 2024-11-15 23:11:19 -05:00
Jason Wen
11c46cdc48 use replace 2024-11-15 23:10:06 -05:00
Jason Wen
9512a09dc7 add replace method 2024-11-15 23:07:48 -05:00
Jason Wen
bfef1ff20e combine 2024-11-15 22:59:03 -05:00
Jason Wen
5018c11d35 fix settings 2024-11-15 18:37:39 -05:00
Jason Wen
436d771105 fix non drive gear re-engage 2024-11-15 17:38:54 -05:00
Jason Wen
cf932da526 no fake lfa button for @devtekve ;) 2024-11-15 16:13:32 -05:00
Jason Wen
64a4d38d32 fix 2024-11-15 16:09:50 -05:00
Jason Wen
60d6e7efce fix panda safety 2024-11-15 12:19:16 -05:00
Jason Wen
ba11b97c59 Rename 2024-11-15 12:03:28 -05:00
Jason Wen
aaf35b391e check if engagement is from openpilot's state machine 2024-11-15 11:45:11 -05:00
Jason Wen
a3c9d72a1e not needed 2024-11-15 11:40:18 -05:00
Jason Wen
6fa78b1db4 more fix 2024-11-15 11:39:13 -05:00
Jason Wen
8f0639ca6c combine 2024-11-15 11:34:01 -05:00
Jason Wen
6a0bc76e63 fix 2024-11-15 11:32:15 -05:00
Jason Wen
23e27bea92 make sure to disengage for allow always cars 2024-11-15 11:29:38 -05:00
Jason Wen
3be1fde36b Fix? 2024-11-15 09:01:12 -05:00
Jason Wen
473349e7b7 rename 2024-11-15 07:32:33 -05:00
Jason Wen
71ffd05027 fix 2024-11-15 07:31:41 -05:00
Jason Wen
ab8547d04b bump opendbc 2024-11-15 07:17:21 -05:00
Jason Wen
74eacd2d44 apply pause/resume fix for hyundai (should do this in a separate PR) 2024-11-15 07:17:11 -05:00
Jason Wen
6a059c6877 bump panda 2024-11-15 07:10:14 -05:00
DevTekVE
eb9b9a13ff Merge remote-tracking branch 'origin/master-new' into mads-new
# Conflicts:
#	panda
#	selfdrive/ui/qt/offroad/developer_panel.cc
2024-11-15 09:32:22 +01:00
DevTekVE
1d4da71784 bump opendbc 2024-11-15 09:30:50 +01:00
Jason Wen
82510dc48c allow re-regage 2024-11-14 23:41:19 -05:00
Jason Wen
5c6750b2ad bump opendbc 2024-11-14 23:34:07 -05:00
Jason Wen
a13e5816bb enforce main 2024-11-14 23:34:02 -05:00
Jason Wen
e1b2b10638 add logging for controls allowed lateral 2024-11-14 23:09:11 -05:00
Jason Wen
58fb1b44b6 hyundai: main button heartbeat 2024-11-14 22:29:38 -05:00
Jason Wen
d78e66deef hyundai: main button handling 2024-11-14 21:46:47 -05:00
Jason Wen
4b1920ecce handle non drive gear events 2024-11-14 20:24:36 -05:00
Jason Wen
dc45bda8b8 no longer needed 2024-11-14 20:00:20 -05:00
Jason Wen
b824810be2 bump panda 2024-11-14 20:00:06 -05:00
Jason Wen
08962ad619 hkg always allow 2024-11-14 19:59:52 -05:00
Jason Wen
652a24f13e only allow lateral when cruise main or state is on 2024-11-14 17:19:23 -05:00
Jason Wen
ca92ffcb57 rename 2024-11-14 17:05:35 -05:00
Jason Wen
80ebb43365 simply checks 2024-11-14 16:59:56 -05:00
Jason Wen
23f417f450 properly 2024-11-13 23:40:44 -05:00
Jason Wen
e63ad5a011 handle available better 2024-11-13 22:44:22 -05:00
Jason Wen
b8a82755e6 support toyota and ford 2024-11-13 20:57:38 -05:00
Jason Wen
70e7747f74 cruise main engage 2024-11-13 20:55:14 -05:00
Jason Wen
de1b084902 enforce cruise main disengage 2024-11-13 20:39:47 -05:00
Jason Wen
097c976a49 Make sure to disengage with long engaged 2024-11-13 20:21:41 -05:00
Jason Wen
5efd1d63bb Unified Engagement Mode: more 2024-11-13 20:15:02 -05:00
Jason Wen
fa3ce0e2a3 add TODO 2024-11-13 20:06:00 -05:00
Jason Wen
835cb71e3b refactor mads params read 2024-11-13 20:04:40 -05:00
Jason Wen
4603fd0f03 Unified Engagement Mode: init 2024-11-13 19:59:19 -05:00
Jason Wen
7f2660d0ad only when mads toggle is enabled 2024-11-13 19:47:51 -05:00
Jason Wen
aa0f588248 change events 2024-11-13 19:42:05 -05:00
Jason Wen
e3e65de225 add lkas enable and disable events 2024-11-13 19:26:22 -05:00
Jason Wen
37b461a591 unused 2024-11-13 16:57:26 -05:00
Jason Wen
2f09489746 enable should carry over from selfdrived 2024-11-13 13:33:00 -05:00
Jason Wen
a9c1e7e277 Expose in settings 2024-11-13 13:25:55 -05:00
Jason Wen
ca0020e613 should be the whole class 2024-11-13 13:12:24 -05:00
Jason Wen
5326b18130 set alt experience in helpers 2024-11-13 13:12:18 -05:00
Jason Wen
c99299af1f no longer needed 2024-11-13 12:56:42 -05:00
Jason Wen
9422a3cf47 implement params 2024-11-13 12:54:02 -05:00
Jason Wen
872abdda17 this is checked after selfdrived states 2024-11-13 11:16:42 -05:00
Jason Wen
1c2e9bd5b1 inherit in carcontroller properly 2024-11-13 03:07:29 -05:00
Jason Wen
70cf693d15 bump panda 2024-11-13 02:38:25 -05:00
Jason Wen
06dc945b09 consolidate 2024-11-13 02:18:29 -05:00
Jason Wen
8fc21127bd use old copy as checks 2024-11-13 02:15:44 -05:00
Jason Wen
eecffb9c8a should be here 2024-11-13 02:08:17 -05:00
Jason Wen
71eb28e1d8 Revert "update in method"
This reverts commit 0403a48e88.
2024-11-13 01:21:12 -05:00
Jason Wen
e605398f55 Revert "reorder"
This reverts commit 1a988c716d.
2024-11-13 01:21:12 -05:00
Jason Wen
1a988c716d reorder 2024-11-13 01:18:51 -05:00
Jason Wen
0403a48e88 update in method 2024-11-13 01:15:22 -05:00
Jason Wen
d9fb57e5f8 Revert "do it prior"
This reverts commit b38798c1a5.
2024-11-13 00:58:37 -05:00
Jason Wen
b38798c1a5 do it prior 2024-11-13 00:00:08 -05:00
Jason Wen
555a753f4c brake check was not handled 2024-11-12 22:52:05 -05:00
Jason Wen
8485cd2013 make sure it's either or 2024-11-12 22:00:44 -05:00
Jason Wen
0fa1ff07f5 try this out 2024-11-12 19:58:22 -05:00
Jason Wen
d2cbdeb683 take them out for all modes 2024-11-12 19:14:37 -05:00
Jason Wen
7c633afe7e skip pedal pressed for MADS 2024-11-12 17:53:50 -05:00
Jason Wen
e5a34e9023 add always available for hyundai 2024-11-12 17:53:25 -05:00
Jason Wen
81708364b8 new logic 2024-11-12 16:15:27 -05:00
Jason Wen
e0e940dd55 do this 2024-11-12 09:17:21 -05:00
Jason Wen
c0b92dee04 more fixes 2024-11-11 22:17:11 -05:00
Jason Wen
249e7c2fa2 fixes 2024-11-11 20:46:56 -05:00
Jason Wen
fae91beaae better 2024-11-11 20:38:10 -05:00
Jason Wen
376cbbdf83 missed 2024-11-11 20:28:00 -05:00
Jason Wen
b497bc607f reset as it should 2024-11-11 09:46:47 -05:00
Jason Wen
90a1ff46b4 Merge branch 'master-new' into mads-new
# Conflicts:
#	cereal/car.capnp
#	cereal/car.capnp~HEAD
#	opendbc_repo
#	panda
2024-11-11 08:23:13 -05:00
DevTekVE
c05191949a Updating submodules 2024-11-02 19:15:58 +01:00
Jason Wen
9d5ea83f5a Add Custom MIT License (#438) 2024-11-02 18:53:31 +01:00
Jason Wen
6a74dc253b typo! 2024-09-30 22:47:24 -04:00
Jason Wen
434a89d83e move to card 2024-09-30 18:51:36 -04:00
Jason Wen
20e6dc4246 hkg dbc 2024-09-30 17:03:50 -04:00
Jason Wen
96b5b7caeb more fix 2024-09-30 16:58:25 -04:00
Jason Wen
85cdce477e fix typo 2024-09-30 16:42:59 -04:00
Jason Wen
cc06b0271c fix typo 2024-09-30 16:40:13 -04:00
Jason Wen
e67833ae7d add events 2024-09-30 16:37:11 -04:00
Jason Wen
42e3061748 Merge branch 'master' into mads-new 2024-09-30 16:31:52 -04:00
Jason Wen
738484e628 some cleanup 2024-09-30 16:28:18 -04:00
Jason Wen
519ab8ec3e traditional state machine with tests 2024-09-30 16:18:59 -04:00
Jason Wen
00bc34b125 test 2024-09-30 15:33:44 -04:00
Jason Wen
ff87abb45b comments 2024-09-30 11:04:56 -04:00
Jason Wen
000bb1b5b3 explicit 2024-09-30 10:56:30 -04:00
Jason Wen
7c95b43e1a should append 2024-09-30 10:45:00 -04:00
Jason Wen
9570a9240f fix type hint 2024-09-30 10:42:57 -04:00
Jason Wen
676702ae3c fixes 2024-09-29 22:43:18 -04:00
Jason Wen
c27b112bbc misra 2024-09-29 12:27:50 -04:00
Jason Wen
0a1a878897 Merge branch 'master' into mads-new
# Conflicts:
#	opendbc_repo
#	panda
2024-09-29 12:11:54 -04:00
Jason Wen
3a593f85dc more 2024-09-29 12:00:46 -04:00
Jason Wen
6db0d94b83 cleanup 2024-09-29 11:58:38 -04:00
Jason Wen
66b900aea6 clearer 2024-09-29 11:55:36 -04:00
Jason Wen
9c57f6bad0 not really 2024-09-29 11:45:47 -04:00
Jason Wen
1b64a7debd move around 2024-09-29 11:30:39 -04:00
Jason Wen
bd19439a4c move around 2024-09-29 11:28:27 -04:00
Jason Wen
18a237c0c0 more update 2024-09-29 11:25:19 -04:00
Jason Wen
dd5ff7e1d3 fix 2024-09-29 11:20:30 -04:00
Jason Wen
515c00c379 fix 2024-09-20 00:01:41 -04:00
Jason Wen
7dc4073c9b safety init 2024-09-19 00:46:26 -04:00
Jason Wen
a9c775bffe no need 2024-09-18 09:01:13 -04:00
Jason Wen
c06d8db015 alternative experience 2024-09-18 08:57:58 -04:00
Jason Wen
8bb6c8fc17 some more infra 2024-09-18 08:22:13 -04:00
Jason Wen
d58be609ac more infra 2024-09-18 07:33:23 -04:00
Jason Wen
434fab00f3 more 2024-09-18 07:15:51 -04:00
Jason Wen
8e62914e69 Modified Assist Driving System: init 2024-09-18 07:15:51 -04:00
33 changed files with 845 additions and 16 deletions

View File

@@ -8,7 +8,23 @@ $Cxx.namespace("cereal");
# cereal, so use these if you want custom events in your fork.
# you can rename the struct, but don't change the identifier
struct CustomReserved0 @0x81c2f05a394cf4af {
struct SelfdriveStateSP @0x81c2f05a394cf4af {
mads @0 :ModularAssistiveDrivingSystem;
struct ModularAssistiveDrivingSystem {
state @0 :ModularAssistiveDrivingSystemState;
enabled @1 :Bool;
active @2 :Bool;
available @3 :Bool;
enum ModularAssistiveDrivingSystemState {
disabled @0;
paused @1;
enabled @2;
softDisabling @3;
overriding @4;
}
}
}
struct CustomReserved1 @0xaedffd8f31e7b55d {

View File

@@ -125,6 +125,76 @@ struct OnroadEvent @0xc4fa6047f024e718 {
espActive @90;
personalityChanged @91;
aeb @92;
eventReserved93 @93;
eventReserved94 @94;
eventReserved95 @95;
eventReserved96 @96;
eventReserved97 @97;
eventReserved98 @98;
eventReserved99 @99;
eventReserved100 @100;
eventReserved101 @101;
eventReserved102 @102;
eventReserved103 @103;
eventReserved104 @104;
eventReserved105 @105;
eventReserved106 @106;
eventReserved107 @107;
eventReserved108 @108;
eventReserved109 @109;
eventReserved110 @110;
eventReserved111 @111;
eventReserved112 @112;
eventReserved113 @113;
eventReserved114 @114;
eventReserved115 @115;
eventReserved116 @116;
eventReserved117 @117;
eventReserved118 @118;
eventReserved119 @119;
eventReserved120 @120;
eventReserved121 @121;
eventReserved122 @122;
eventReserved123 @123;
eventReserved124 @124;
eventReserved125 @125;
eventReserved126 @126;
eventReserved127 @127;
eventReserved128 @128;
eventReserved129 @129;
eventReserved130 @130;
eventReserved131 @131;
eventReserved132 @132;
eventReserved133 @133;
eventReserved134 @134;
eventReserved135 @135;
eventReserved136 @136;
eventReserved137 @137;
eventReserved138 @138;
eventReserved139 @139;
eventReserved140 @140;
eventReserved141 @141;
eventReserved142 @142;
eventReserved143 @143;
eventReserved144 @144;
eventReserved145 @145;
eventReserved146 @146;
eventReserved147 @147;
eventReserved148 @148;
eventReserved149 @149;
eventReserved150 @150;
# sunnypilot
lkasEnable @151;
lkasDisable @152;
manualSteeringRequired @153;
manualLongitudinalRequired @154;
silentPedalPressed @155;
silentLkasEnable @156;
silentLkasDisable @157;
silentBrakeHold @158;
silentWrongGear @159;
silentReverseGear @160;
soundsUnavailableDEPRECATED @47;
}
@@ -586,6 +656,7 @@ struct PandaState @0xa7649e2575e4591e {
# safety stuff
controlsAllowed @3 :Bool;
controlsAllowedLat @5 :Bool;
safetyRxInvalid @19 :UInt32;
safetyTxBlocked @24 :UInt32;
safetyModel @14 :Car.CarParams.SafetyModel;
@@ -693,7 +764,6 @@ struct PandaState @0xa7649e2575e4591e {
}
gasInterceptorDetectedDEPRECATED @4 :Bool;
startedSignalDetectedDEPRECATED @5 :Bool;
hasGpsDEPRECATED @6 :Bool;
gmlanSendErrsDEPRECATED @9 :UInt32;
fanSpeedRpmDEPRECATED @11 :UInt16;
@@ -2544,7 +2614,7 @@ struct Event {
customReservedRawData2 @126 :Data;
# *********** Custom: reserved for forks ***********
customReserved0 @107 :Custom.CustomReserved0;
selfdriveStateSP @107 :Custom.SelfdriveStateSP;
customReserved1 @108 :Custom.CustomReserved1;
customReserved2 @109 :Custom.CustomReserved2;
customReserved3 @110 :Custom.CustomReserved3;

View File

@@ -73,6 +73,9 @@ _services: dict[str, tuple] = {
"userFlag": (True, 0., 1),
"microphone": (True, 10., 10),
# sunnypilot
"selfdriveStateSP": (True, 100., 10),
# debug
"uiDebug": (True, 0., 1),
"testJoystick": (True, 0.),

View File

@@ -201,6 +201,12 @@ std::unordered_map<std::string, uint32_t> keys = {
{"UpdaterTargetBranch", CLEAR_ON_MANAGER_START},
{"UpdaterLastFetchTime", PERSISTENT},
{"Version", PERSISTENT},
// sunnypilot params
{"Mads", PERSISTENT},
{"MadsCruiseMain", PERSISTENT},
{"MadsDisengageLateralOnBrake", PERSISTENT},
{"MadsUnifiedEngagementMode", PERSISTENT},
};
} // namespace

1
openpilot/sunnypilot Symbolic link
View File

@@ -0,0 +1 @@
../sunnypilot

2
panda

Submodule panda updated: dc94921af8...b410bad02a

View File

@@ -162,6 +162,7 @@ testpaths = [
"tools/replay",
"tools/cabana",
"cereal/messaging/tests",
"sunnypilot",
]
[tool.codespell]

View File

@@ -22,6 +22,8 @@ from openpilot.selfdrive.pandad import can_capnp_to_list, can_list_to_can_capnp
from openpilot.selfdrive.car.cruise import VCruiseHelper
from openpilot.selfdrive.car.car_specific import MockCarState
from openpilot.sunnypilot.mads.mads import MadsParams
REPLAY = "REPLAY" in os.environ
EventName = log.OnroadEvent.EventName
@@ -113,6 +115,11 @@ class Car:
if not disengage_on_accelerator:
self.CP.alternativeExperience |= ALTERNATIVE_EXPERIENCE.DISABLE_DISENGAGE_ON_GAS
# mads
data_services = list(self.sm.data.keys()) + ['selfdriveStateSP']
self.sm = messaging.SubMaster(data_services, poll='selfdriveStateSP')
MadsParams().set_alternative_experience(self.CP)
openpilot_enabled_toggle = self.params.get_bool("OpenpilotEnabledToggle")
controller_available = self.CI.CC is not None and openpilot_enabled_toggle and not self.CP.dashcamOnly

View File

@@ -1,6 +1,8 @@
#!/usr/bin/env python3
import math
from typing import SupportsFloat
import time
import threading
from cereal import car, log
import cereal.messaging as messaging
@@ -19,6 +21,7 @@ from openpilot.selfdrive.controls.lib.longcontrol import LongControl
from openpilot.selfdrive.controls.lib.vehicle_model import VehicleModel
from openpilot.selfdrive.locationd.helpers import PoseCalibrator, Pose
from opendbc.sunnypilot import SunnypilotParamFlags
State = log.SelfdriveState.OpenpilotState
LaneChangeState = log.LaneChangeState
@@ -56,6 +59,11 @@ class Controls:
elif self.CP.lateralTuning.which() == 'torque':
self.LaC = LatControlTorque(self.CP, self.CI)
data_services = list(self.sm.data.keys()) + ['selfdriveStateSP']
self.sm = messaging.SubMaster(data_services, poll='selfdriveState')
self.enable_mads = self.params.get_bool("Mads")
def update(self):
self.sm.update(15)
if self.sm.updated["liveCalibration"]:
@@ -88,7 +96,12 @@ class Controls:
# Check which actuators can be enabled
standstill = abs(CS.vEgo) <= max(self.CP.minSteerSpeed, MIN_LATERAL_CONTROL_SPEED) or CS.standstill
CC.latActive = self.sm['selfdriveState'].active and not CS.steerFaultTemporary and not CS.steerFaultPermanent and not standstill
ss_sp = self.sm['selfdriveStateSP']
CC.madsEnabled = ss_sp.mads.enabled
_lat_active = ss_sp.mads.active if ss_sp.mads.available else self.sm['selfdriveState'].active
CC.latActive = _lat_active and not CS.steerFaultTemporary and not CS.steerFaultPermanent and not standstill
CC.longActive = CC.enabled and not any(e.overrideLongitudinal for e in self.sm['onroadEvents']) and self.CP.openpilotLongitudinalControl
actuators = CC.actuators
@@ -157,6 +170,9 @@ class Controls:
hudControl.leftLaneDepart = self.sm['driverAssistance'].leftLaneDeparture
hudControl.rightLaneDepart = self.sm['driverAssistance'].rightLaneDeparture
if self.enable_mads:
CC.sunnypilotParams |= SunnypilotParamFlags.ENABLE_MADS.value
if self.sm['selfdriveState'].active:
CO = self.sm['carOutput']
if self.CP.steerControlType == car.CarParams.SteerControlType.angle:
@@ -203,13 +219,25 @@ class Controls:
cc_send.carControl = CC
self.pm.send('carControl', cc_send)
def params_thread(self, evt):
while not evt.is_set():
self.enable_mads = self.params.get_bool("Mads")
time.sleep(0.1)
def run(self):
e = threading.Event()
t = threading.Thread(target=self.params_thread, args=(e, ))
rk = Ratekeeper(100, print_delay_threshold=None)
while True:
self.update()
CC, lac_log = self.state_control()
self.publish(CC, lac_log)
rk.monitor_time()
try:
t.start()
while True:
self.update()
CC, lac_log = self.state_control()
self.publish(CC, lac_log)
rk.monitor_time()
finally:
e.set()
t.join()
def main():
config_realtime_process(4, Priority.CTRL_HIGH)

View File

@@ -144,6 +144,7 @@ void fill_panda_state(cereal::PandaState::Builder &ps, cereal::PandaState::Panda
ps.setIgnitionLine(health.ignition_line_pkt);
ps.setIgnitionCan(health.ignition_can_pkt);
ps.setControlsAllowed(health.controls_allowed_pkt);
ps.setControlsAllowedLat(health.controls_allowed_lat_pkt);
ps.setTxBufferOverflow(health.tx_buffer_overflow_pkt);
ps.setRxBufferOverflow(health.rx_buffer_overflow_pkt);
ps.setPandaType(hw_type);

View File

@@ -105,6 +105,24 @@ class Events:
ret.append(event)
return ret
def has(self, event_name: int) -> bool:
return event_name in self.events
def has_list(self, events_list: list[int]) -> bool:
return all(event_name in self.events for event_name in events_list)
def remove(self, event_name: int, static: bool = False) -> None:
if static and event_name in self.static_events:
self.static_events.remove(event_name)
if event_name in self.events:
self.event_counters[event_name] = self.event_counters[event_name] + 1
self.events.remove(event_name)
def replace(self, prev_event_name: int, cur_event_name: int, static: bool = False) -> None:
self.remove(prev_event_name, static)
self.add(cur_event_name, static)
class Alert:
def __init__(self,
@@ -951,6 +969,73 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
ET.WARNING: personality_changed_alert,
},
# sunnypilot
EventName.lkasEnable: {
ET.ENABLE: EngagementAlert(AudibleAlert.engage),
},
EventName.lkasDisable: {
ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage),
},
EventName.manualSteeringRequired: {
ET.USER_DISABLE: Alert(
"Automatic Lane Centering is OFF",
"Manual Steering Required",
AlertStatus.normal, AlertSize.mid,
Priority.LOW, VisualAlert.none, AudibleAlert.disengage, 1.),
},
EventName.manualLongitudinalRequired: {
ET.WARNING: Alert(
"Smart/Adaptive Cruise Control: OFF",
"Manual Speed Control Required",
AlertStatus.normal, AlertSize.mid,
Priority.LOW, VisualAlert.none, AudibleAlert.none, 1.),
},
# TODO-SP: remove prior merging
EventName.silentPedalPressed: {
ET.USER_DISABLE: EngagementAlert(AudibleAlert.none),
ET.NO_ENTRY: NoEntryAlert("Pedal Pressed During Attempt",
visual_alert=VisualAlert.brakePressed),
},
EventName.silentLkasEnable: {
ET.ENABLE: EngagementAlert(AudibleAlert.none),
},
EventName.silentLkasDisable: {
ET.USER_DISABLE: EngagementAlert(AudibleAlert.none),
},
EventName.silentBrakeHold: {
ET.USER_DISABLE: EngagementAlert(AudibleAlert.none),
ET.NO_ENTRY: NoEntryAlert("Brake Hold Active"),
},
EventName.silentWrongGear: {
ET.WARNING: Alert(
"Gear not D",
"openpilot Unavailable",
AlertStatus.normal, AlertSize.mid,
Priority.LOW, VisualAlert.none, AudibleAlert.none, 0.),
ET.NO_ENTRY: Alert(
"Gear not D",
"openpilot Unavailable",
AlertStatus.normal, AlertSize.mid,
Priority.LOW, VisualAlert.none, AudibleAlert.none, 0.),
},
EventName.silentReverseGear: {
ET.PERMANENT: Alert(
"Reverse\nGear",
"",
AlertStatus.normal, AlertSize.full,
Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .2, creation_delay=0.5),
ET.NO_ENTRY: NoEntryAlert("Reverse Gear"),
},
}

View File

@@ -23,6 +23,8 @@ from openpilot.selfdrive.controls.lib.latcontrol import MIN_LATERAL_CONTROL_SPEE
from openpilot.system.version import get_build_metadata
from openpilot.sunnypilot.mads.mads import ModularAssistiveDrivingSystem
REPLAY = "REPLAY" in os.environ
SIMULATION = "SIMULATION" in os.environ
TESTING_CLOSET = "TESTING_CLOSET" in os.environ
@@ -131,6 +133,10 @@ class SelfdriveD:
elif self.CP.passive:
self.events.add(EventName.dashcamMode, static=True)
self.mads = ModularAssistiveDrivingSystem(self)
sock_services = list(self.pm.sock.keys()) + ['selfdriveStateSP']
self.pm = messaging.PubMaster(sock_services)
def update_events(self, CS):
"""Compute onroadEvents from carState"""
@@ -451,11 +457,25 @@ class SelfdriveD:
self.pm.send('onroadEvents', ce_send)
self.events_prev = self.events.names.copy()
# selfdriveStateSP
ss_sp_msg = messaging.new_message('selfdriveStateSP')
ss_sp_msg.valid = True
ss_sp = ss_sp_msg.selfdriveStateSP
mads = ss_sp.mads
mads.state = self.mads.state_machine.state
mads.enabled = self.mads.enabled
mads.active = self.mads.active
mads.available = self.mads.enabled_toggle
self.pm.send('selfdriveStateSP', ss_sp_msg)
def step(self):
CS = self.data_sample()
self.update_events(CS)
if not self.CP.passive and self.initialized:
self.enabled, self.active = self.state_machine.update(self.events)
if not self.CP.notCar:
self.mads.update(CS)
self.update_alerts(CS)
self.publish_selfdriveState(CS)

View File

@@ -41,7 +41,7 @@ class TestAlerts:
events = log.OnroadEvent.EventName.schema.enumerants
for name, e in events.items():
if not name.endswith("DEPRECATED"):
if not name.endswith("DEPRECATED") and not name.startswith("eventReserved"):
fail_msg = "%s @%d not in EVENTS" % (name, e)
assert e in EVENTS.keys(), fail_msg

View File

@@ -24,6 +24,20 @@ DeveloperPanel::DeveloperPanel(SettingsWindow *parent) : ListWidget(parent) {
});
addItem(longManeuverToggle);
// FIXME-SP: Move to sunnypilot panels before merging
auto madsToggle = new ParamControl("Mads", tr("Modular Assistive Driving System (MADS)"), "", "");
addItem(madsToggle);
// TODO-SP: Rename toggle
auto madsCruiseMainToggle = new ParamControl("MadsCruiseMain", tr("MADS: Cruise Main"), "", "");
addItem(madsCruiseMainToggle);
auto madsDisengageLateralOnBrakeToggle = new ParamControl("MadsDisengageLateralOnBrake", tr("MADS: Disengage Lateral on Brake"), "", "");
addItem(madsDisengageLateralOnBrakeToggle);
auto madsUnifiedEngagementModeToggle = new ParamControl("MadsUnifiedEngagementMode", tr("MADS: Unified Engagement Mode"), "", "");
addItem(madsUnifiedEngagementModeToggle);
// Joystick and longitudinal maneuvers should be hidden on release branches
is_release = params.getBool("IsReleaseBranch");

View File

@@ -123,6 +123,22 @@
<source>Longitudinal Maneuver Mode</source>
<translation>وضع المناورة الطولية</translation>
</message>
<message>
<source>MADS: Cruise Main</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Disengage Lateral on Brake</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Modular Assistive Driving System (MADS)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Unified Engagement Mode</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DevicePanel</name>

View File

@@ -123,6 +123,22 @@
<source>Longitudinal Maneuver Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Cruise Main</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Disengage Lateral on Brake</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Modular Assistive Driving System (MADS)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Unified Engagement Mode</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DevicePanel</name>

View File

@@ -123,6 +123,22 @@
<source>Longitudinal Maneuver Mode</source>
<translation>Modo de maniobra longitudinal</translation>
</message>
<message>
<source>MADS: Cruise Main</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Disengage Lateral on Brake</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Modular Assistive Driving System (MADS)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Unified Engagement Mode</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DevicePanel</name>

View File

@@ -123,6 +123,22 @@
<source>Longitudinal Maneuver Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Cruise Main</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Disengage Lateral on Brake</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Modular Assistive Driving System (MADS)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Unified Engagement Mode</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DevicePanel</name>

View File

@@ -123,6 +123,22 @@
<source>Longitudinal Maneuver Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Cruise Main</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Disengage Lateral on Brake</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Modular Assistive Driving System (MADS)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Unified Engagement Mode</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DevicePanel</name>

View File

@@ -123,6 +123,22 @@
<source>Longitudinal Maneuver Mode</source>
<translation> </translation>
</message>
<message>
<source>MADS: Cruise Main</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Disengage Lateral on Brake</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Modular Assistive Driving System (MADS)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Unified Engagement Mode</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DevicePanel</name>

View File

@@ -123,6 +123,22 @@
<source>Longitudinal Maneuver Mode</source>
<translation>Modo Longitudinal Maneuver</translation>
</message>
<message>
<source>MADS: Cruise Main</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Disengage Lateral on Brake</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Modular Assistive Driving System (MADS)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Unified Engagement Mode</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DevicePanel</name>

View File

@@ -123,6 +123,22 @@
<source>Longitudinal Maneuver Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Cruise Main</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Disengage Lateral on Brake</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Modular Assistive Driving System (MADS)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Unified Engagement Mode</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DevicePanel</name>

View File

@@ -123,6 +123,22 @@
<source>Longitudinal Maneuver Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Cruise Main</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Disengage Lateral on Brake</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Modular Assistive Driving System (MADS)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Unified Engagement Mode</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DevicePanel</name>

View File

@@ -123,6 +123,22 @@
<source>Longitudinal Maneuver Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Cruise Main</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Disengage Lateral on Brake</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Modular Assistive Driving System (MADS)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Unified Engagement Mode</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DevicePanel</name>

View File

@@ -123,6 +123,22 @@
<source>Longitudinal Maneuver Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Cruise Main</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Disengage Lateral on Brake</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Modular Assistive Driving System (MADS)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MADS: Unified Engagement Mode</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DevicePanel</name>

View File

@@ -68,13 +68,26 @@ void ui_update_params(UIState *s) {
}
void UIState::updateStatus() {
if (scene.started && sm->updated("selfdriveState")) {
if (scene.started && (sm->updated("selfdriveState") || sm->updated("selfdriveStateSP"))) {
auto ss = (*sm)["selfdriveState"].getSelfdriveState();
auto ss_sp = (*sm)["selfdriveStateSP"].getSelfdriveStateSP();
auto mads = ss_sp.getMads();
auto state = ss.getState();
if (state == cereal::SelfdriveState::OpenpilotState::PRE_ENABLED || state == cereal::SelfdriveState::OpenpilotState::OVERRIDING) {
auto state_mads = mads.getState();
if (state == cereal::SelfdriveState::OpenpilotState::PRE_ENABLED || state == cereal::SelfdriveState::OpenpilotState::OVERRIDING ||
state_mads == cereal::SelfdriveStateSP::ModularAssistiveDrivingSystem::ModularAssistiveDrivingSystemState::PAUSED ||
state_mads == cereal::SelfdriveStateSP::ModularAssistiveDrivingSystem::ModularAssistiveDrivingSystemState::OVERRIDING) {
status = STATUS_OVERRIDE;
} else {
status = ss.getEnabled() ? STATUS_ENGAGED : STATUS_DISENGAGED;
if (mads.getAvailable()) {
if (mads.getEnabled()) {
status = ss.getEnabled() ? STATUS_ENGAGED : STATUS_LAT_ONLY;
} else {
status = STATUS_DISENGAGED;
}
} else {
status = ss.getEnabled() ? STATUS_ENGAGED : STATUS_DISENGAGED;
}
}
}
@@ -94,6 +107,7 @@ UIState::UIState(QObject *parent) : QObject(parent) {
"modelV2", "controlsState", "liveCalibration", "radarState", "deviceState",
"pandaStates", "carParams", "driverMonitoringState", "carState", "driverStateV2",
"wideRoadCameraState", "managerState", "selfdriveState", "longitudinalPlan",
"selfdriveStateSP",
});
prime_state = new PrimeState(this);
language = QString::fromStdString(Params().get("LanguageSetting"));

View File

@@ -42,12 +42,16 @@ typedef enum UIStatus {
STATUS_DISENGAGED,
STATUS_OVERRIDE,
STATUS_ENGAGED,
STATUS_LAT_ONLY,
STATUS_LONG_ONLY,
} UIStatus;
const QColor bg_colors [] = {
[STATUS_DISENGAGED] = QColor(0x17, 0x33, 0x49, 0xc8),
[STATUS_OVERRIDE] = QColor(0x91, 0x9b, 0x95, 0xf1),
[STATUS_ENGAGED] = QColor(0x17, 0x86, 0x44, 0xf1),
[STATUS_LAT_ONLY] = QColor(0x00, 0xc8, 0xc8, 0xf1),
[STATUS_LONG_ONLY] = QColor(0x96, 0x1C, 0xA8, 0xf1),
};
typedef struct UIScene {

View File

@@ -0,0 +1,21 @@
from panda import ALTERNATIVE_EXPERIENCE
from openpilot.common.params import Params
class MadsParams:
def __init__(self):
self.params = Params()
def read_param(self, key: str):
return self.params.get_bool(key)
def set_alternative_experience(self, CP):
enabled = self.read_param("Mads")
disengage_lateral_on_brake = self.read_param("MadsDisengageLateralOnBrake")
if enabled:
CP.alternativeExperience |= ALTERNATIVE_EXPERIENCE.ENABLE_MADS
if not disengage_lateral_on_brake:
CP.alternativeExperience |= ALTERNATIVE_EXPERIENCE.DISABLE_DISENGAGE_LATERAL_ON_BRAKE

108
sunnypilot/mads/mads.py Normal file
View File

@@ -0,0 +1,108 @@
from cereal import car, log, custom
from opendbc.car.hyundai.values import HyundaiFlags
from opendbc.sunnypilot.car.hyundai.values import HyundaiFlagsSP
from openpilot.sunnypilot.mads.helpers import MadsParams
from openpilot.sunnypilot.mads.state import StateMachine, GEARS_ALLOW_PAUSED_SILENT
State = custom.SelfdriveStateSP.ModularAssistiveDrivingSystem.ModularAssistiveDrivingSystemState
ButtonType = car.CarState.ButtonEvent.Type
EventName = log.OnroadEvent.EventName
class ModularAssistiveDrivingSystem:
def __init__(self, selfdrive):
mads_params = MadsParams()
self.enabled = False
self.active = False
self.available = False
self.allow_always = False
self.selfdrive = selfdrive
self.selfdrive.enabled_prev = False
self.state_machine = StateMachine(self)
self.events = self.selfdrive.events
if self.selfdrive.CP.carName == "hyundai":
if (self.selfdrive.CP.sunnypilotFlags & HyundaiFlagsSP.HAS_LFA_BUTTON) or \
(self.selfdrive.CP.flags & HyundaiFlags.CANFD):
self.allow_always = True
self.enabled_toggle = mads_params.read_param("Mads")
self.main_enabled_toggle = mads_params.read_param("MadsCruiseMain")
self.disengage_lateral_on_brake_toggle = mads_params.read_param("MadsDisengageLateralOnBrake")
self.unified_engagement_mode = mads_params.read_param("MadsUnifiedEngagementMode")
def update_events(self, CS: car.CarState):
def update_unified_engagement_mode():
if (self.unified_engagement_mode and self.enabled) or not self.unified_engagement_mode:
self.events.remove(EventName.pcmEnable)
self.events.remove(EventName.buttonEnable)
def transition_paused_state():
if self.state_machine.state != State.paused:
self.events.add(EventName.silentLkasDisable)
if not self.selfdrive.enabled and self.enabled:
if self.events.has(EventName.wrongGear) and not self.events.has(EventName.reverseGear):
self.events.replace(EventName.wrongGear, EventName.silentWrongGear)
transition_paused_state()
if self.events.has(EventName.reverseGear) and CS.vEgo < 5:
self.events.replace(EventName.reverseGear, EventName.silentReverseGear)
transition_paused_state()
if self.events.has(EventName.brakeHold):
self.events.replace(EventName.brakeHold, EventName.silentBrakeHold)
transition_paused_state()
if self.disengage_lateral_on_brake_toggle:
if self.events.has(EventName.pedalPressed):
transition_paused_state()
if not (self.disengage_lateral_on_brake_toggle and self.events.has(EventName.pedalPressed)) and \
not self.events.has_list(GEARS_ALLOW_PAUSED_SILENT):
if self.state_machine.state == State.paused:
self.events.add(EventName.silentLkasEnable)
if self.events.has(EventName.pcmEnable) or self.events.has(EventName.buttonEnable):
update_unified_engagement_mode()
else:
if self.main_enabled_toggle:
if CS.cruiseState.available and not self.selfdrive.CS_prev.cruiseState.available:
self.events.add(EventName.lkasEnable)
for be in CS.buttonEvents:
if be.type == ButtonType.cancel:
if not self.selfdrive.enabled and self.selfdrive.enabled_prev:
self.events.add(EventName.manualLongitudinalRequired)
if be.type == ButtonType.lkas and be.pressed and (CS.cruiseState.available or self.allow_always):
if self.enabled:
if self.selfdrive.enabled:
self.events.add(EventName.manualSteeringRequired)
else:
self.events.add(EventName.lkasDisable)
else:
self.events.add(EventName.lkasEnable)
if not CS.cruiseState.available:
self.events.remove(EventName.buttonEnable)
if self.selfdrive.CS_prev.cruiseState.available:
self.events.add(EventName.lkasDisable)
self.events.remove(EventName.pcmDisable)
self.events.remove(EventName.buttonCancel)
self.events.remove(EventName.pedalPressed)
self.events.remove(EventName.wrongCruiseMode)
self.events.remove(EventName.wrongCarMode)
def update(self, CS: car.CarState):
if not self.enabled_toggle:
return
self.update_events(CS)
if not self.selfdrive.CP.passive and self.selfdrive.initialized:
self.enabled, self.active = self.state_machine.update(self.events)
# Copy of previous SelfdriveD states for MADS events handling
self.selfdrive.enabled_prev = self.selfdrive.enabled

117
sunnypilot/mads/state.py Normal file
View File

@@ -0,0 +1,117 @@
from cereal import log, custom
from openpilot.selfdrive.selfdrived.events import ET, Events
from openpilot.selfdrive.selfdrived.state import SOFT_DISABLE_TIME
from openpilot.common.realtime import DT_CTRL
State = custom.SelfdriveStateSP.ModularAssistiveDrivingSystem.ModularAssistiveDrivingSystemState
EventName = log.OnroadEvent.EventName
ACTIVE_STATES = (State.enabled, State.softDisabling, State.overriding)
ENABLED_STATES = (State.paused, *ACTIVE_STATES)
GEARS_ALLOW_PAUSED_SILENT = [EventName.silentWrongGear, EventName.silentReverseGear, EventName.silentBrakeHold]
GEARS_ALLOW_PAUSED = [EventName.wrongGear, EventName.reverseGear, EventName.brakeHold, *GEARS_ALLOW_PAUSED_SILENT]
class StateMachine:
def __init__(self, mads):
self.selfdrive = mads.selfdrive
self.ss_state_machine = mads.selfdrive.state_machine
self.state = State.disabled
def add_current_alert_types(self, alert_type):
if not self.selfdrive.enabled:
self.ss_state_machine.current_alert_types.append(alert_type)
def update(self, events: Events):
# soft disable timer and current alert types are from the state machine of openpilot
# decrement the soft disable timer at every step, as it's reset on
# entrance in SOFT_DISABLING state
# ENABLED, SOFT DISABLING, PAUSED, OVERRIDING
if self.state != State.disabled:
# user and immediate disable always have priority in a non-disabled state
if events.contains(ET.USER_DISABLE):
if events.has(EventName.silentLkasDisable) or events.has(EventName.silentBrakeHold):
self.state = State.paused
else:
self.state = State.disabled
self.ss_state_machine.current_alert_types.append(ET.USER_DISABLE)
elif events.contains(ET.IMMEDIATE_DISABLE):
self.state = State.disabled
self.add_current_alert_types(ET.IMMEDIATE_DISABLE)
else:
# ENABLED
if self.state == State.enabled:
if events.contains(ET.SOFT_DISABLE):
self.state = State.softDisabling
if not self.selfdrive.enabled:
self.ss_state_machine.soft_disable_timer = int(SOFT_DISABLE_TIME / DT_CTRL)
self.ss_state_machine.current_alert_types.append(ET.SOFT_DISABLE)
elif events.contains(ET.OVERRIDE_LATERAL):
self.state = State.overriding
self.add_current_alert_types(ET.OVERRIDE_LATERAL)
# SOFT DISABLING
elif self.state == State.softDisabling:
if not events.contains(ET.SOFT_DISABLE):
# no more soft disabling condition, so go back to ENABLED
self.state = State.enabled
elif self.ss_state_machine.soft_disable_timer > 0:
self.add_current_alert_types(ET.SOFT_DISABLE)
elif self.ss_state_machine.soft_disable_timer <= 0:
self.state = State.disabled
# PAUSED
elif self.state == State.paused:
if events.contains(ET.ENABLE):
if events.contains(ET.NO_ENTRY):
self.add_current_alert_types(ET.NO_ENTRY)
else:
if events.contains(ET.OVERRIDE_LATERAL):
self.state = State.overriding
else:
self.state = State.enabled
self.add_current_alert_types(ET.ENABLE)
# OVERRIDING
elif self.state == State.overriding:
if events.contains(ET.SOFT_DISABLE):
self.state = State.softDisabling
if not self.selfdrive.enabled:
self.ss_state_machine.soft_disable_timer = int(SOFT_DISABLE_TIME / DT_CTRL)
self.ss_state_machine.current_alert_types.append(ET.SOFT_DISABLE)
elif not events.contains(ET.OVERRIDE_LATERAL):
self.state = State.enabled
else:
self.ss_state_machine.current_alert_types += [ET.OVERRIDE_LATERAL]
# DISABLED
elif self.state == State.disabled:
if events.contains(ET.ENABLE):
if events.contains(ET.NO_ENTRY):
if events.has_list(GEARS_ALLOW_PAUSED):
self.state = State.paused
self.add_current_alert_types(ET.NO_ENTRY)
else:
if events.contains(ET.OVERRIDE_LATERAL):
self.state = State.overriding
else:
self.state = State.enabled
self.add_current_alert_types(ET.ENABLE)
# check if MADS is engaged and actuators are enabled
enabled = self.state in ENABLED_STATES
active = self.state in ACTIVE_STATES
if active:
self.add_current_alert_types(ET.WARNING)
return enabled, active

View File

@@ -0,0 +1,130 @@
import pytest
from pytest_mock import MockerFixture
from cereal import log, custom
from openpilot.common.realtime import DT_CTRL
from openpilot.sunnypilot.mads.state import StateMachine, SOFT_DISABLE_TIME, GEARS_ALLOW_PAUSED
from openpilot.selfdrive.selfdrived.events import Events, ET, EVENTS, NormalPermanentAlert
State = custom.SelfdriveStateSP.ModularAssistiveDrivingSystem.ModularAssistiveDrivingSystemState
EventName = log.OnroadEvent.EventName
# The event types that maintain the current state
MAINTAIN_STATES = {State.enabled: (None,), State.disabled: (None,), State.softDisabling: (ET.SOFT_DISABLE,),
State.paused: (None,), State.overriding: (ET.OVERRIDE_LATERAL,)}
ALL_STATES = (State.schema.enumerants.values())
# The event types checked in DISABLED section of state machine
ENABLE_EVENT_TYPES = (ET.ENABLE, ET.OVERRIDE_LATERAL)
def make_event(event_types):
event = {}
for ev in event_types:
event[ev] = NormalPermanentAlert("alert")
EVENTS[0] = event
return 0
class MockMADS:
def __init__(self, mocker: MockerFixture):
self.selfdrive = mocker.MagicMock()
self.selfdrive.state_machine = mocker.MagicMock()
self.selfdrive.active = False
class TestMADSStateMachine:
@pytest.fixture(autouse=True)
def setup_method(self, mocker: MockerFixture):
self.mads = MockMADS(mocker)
self.events = Events()
self.state_machine = StateMachine(self.mads)
self.mads.selfdrive.state_machine.soft_disable_timer = int(SOFT_DISABLE_TIME / DT_CTRL)
def test_immediate_disable(self):
for state in ALL_STATES:
for et in MAINTAIN_STATES[state]:
self.events.add(make_event([et, ET.IMMEDIATE_DISABLE]))
self.state_machine.state = state
self.state_machine.update(self.events)
assert State.disabled == self.state_machine.state
self.events.clear()
def test_user_disable(self):
for state in ALL_STATES:
for et in MAINTAIN_STATES[state]:
self.events.add(make_event([et, ET.USER_DISABLE]))
self.state_machine.state = state
self.state_machine.update(self.events)
assert State.disabled == self.state_machine.state
self.events.clear()
def test_user_disable_to_paused(self):
paused_events = (EventName.silentLkasDisable, EventName.silentBrakeHold)
for state in ALL_STATES:
for et in MAINTAIN_STATES[state]:
self.events.add(make_event([et, ET.USER_DISABLE]))
for en in paused_events:
self.events.add(en)
self.state_machine.state = state
self.state_machine.update(self.events)
final_state = State.paused if self.events.has(en) and state != State.disabled else State.disabled
assert self.state_machine.state == final_state
self.events.clear()
def test_soft_disable(self):
for state in ALL_STATES:
if state == State.paused: # paused considers USER_DISABLE instead
continue
for et in MAINTAIN_STATES[state]:
self.events.add(make_event([et, ET.SOFT_DISABLE]))
self.state_machine.state = state
self.state_machine.update(self.events)
assert self.state_machine.state == State.disabled if state == State.disabled else State.softDisabling
self.events.clear()
def test_soft_disable_timer(self):
self.state_machine.state = State.enabled
self.events.add(make_event([ET.SOFT_DISABLE]))
self.state_machine.update(self.events)
for _ in range(int(SOFT_DISABLE_TIME / DT_CTRL)):
assert self.state_machine.state == State.softDisabling
self.mads.selfdrive.state_machine.soft_disable_timer -= 1
self.state_machine.update(self.events)
assert self.state_machine.state == State.disabled
def test_no_entry(self):
for et in ENABLE_EVENT_TYPES:
self.events.add(make_event([ET.NO_ENTRY, et]))
if not self.events.has_list(GEARS_ALLOW_PAUSED):
self.state_machine.update(self.events)
assert self.state_machine.state == State.disabled
self.events.clear()
def test_no_entry_paused(self):
self.state_machine.state = State.paused
self.events.add(make_event([ET.NO_ENTRY]))
self.state_machine.update(self.events)
assert self.state_machine.state == State.paused
def test_override_lateral(self):
self.state_machine.state = State.enabled
self.events.add(make_event([ET.OVERRIDE_LATERAL]))
self.state_machine.update(self.events)
assert self.state_machine.state == State.overriding
def test_paused_to_enabled(self):
self.state_machine.state = State.paused
self.events.add(make_event([ET.ENABLE]))
self.state_machine.update(self.events)
assert self.state_machine.state == State.enabled
def test_maintain_states(self):
for state in ALL_STATES:
for et in MAINTAIN_STATES[state]:
self.state_machine.state = state
if et is not None:
self.events.add(make_event([et]))
self.state_machine.update(self.events)
assert self.state_machine.state == state
self.events.clear()

View File

@@ -42,11 +42,18 @@ def manager_init() -> None:
("LongitudinalPersonality", str(log.LongitudinalPersonality.standard)),
]
sunnypilot_default_params: list[tuple[str, str | bytes]] = [
("Mads", "1"),
("MadsCruiseMain", "1"),
("MadsDisengageLateralOnBrake", "0"),
("MadsUnifiedEngagementMode", "1"),
]
if params.get_bool("RecordFrontLock"):
params.put_bool("RecordFront", True)
# set unset params
for k, v in default_params:
for k, v in (default_params + sunnypilot_default_params):
if params.get(k) is None:
params.put(k, v)