@@ -97,7 +97,6 @@ static void cmd_flywheel_toggle(Data *d, unsigned char *cfg, int len);
9797
9898const VESC_PIN beeper_pin = VESC_PIN_PPM ;
9999
100- #define REVSTOP_ERPM_INCR 0.00008
101100#define EXT_BEEPER_ON () VESC_IF->io_write(beeper_pin, 1)
102101#define EXT_BEEPER_OFF () VESC_IF->io_write(beeper_pin, 0)
103102
@@ -161,6 +160,8 @@ static void main_freq_update_reconfigure(float frequency) {
161160 booster_configure (& d -> booster , frequency );
162161
163162 ema_configure (& d -> balance_current , 25.0f , frequency );
163+
164+ reverse_stop_configure (& d -> reverse_stop , frequency );
164165}
165166
166167// Reconfigures all components dependent on the IMU loop frequency.
@@ -208,9 +209,6 @@ static void configure(Data *d) {
208209 VESC_IF -> set_cfg_float (CFG_PARAM_IMU_accel_confidence_decay , 0.1 );
209210 }
210211
211- // Feature: Reverse Stop
212- d -> reverse_tolerance = 20000 ;
213-
214212 // Speed above which to warn users about an impending full switch fault
215213 d -> switch_warn_beep_erpm = d -> float_conf .is_footbeep_enabled ? 2000 : 100000 ;
216214
@@ -242,6 +240,7 @@ static void reset_runtime_vars(Data *d) {
242240 turn_tilt_reset (& d -> turn_tilt );
243241 remote_reset (& d -> remote );
244242 booster_reset (& d -> booster );
243+ reverse_stop_reset (& d -> reverse_stop , d -> motor .distance );
245244
246245 ema_reset (& d -> balance_current , 0.0f );
247246
@@ -424,34 +423,17 @@ static bool check_faults(Data *d) {
424423 timer_refresh (& d -> time , & d -> fault_switch_timer );
425424 }
426425
427- // Feature: Reverse-Stop
428426 if (d -> state .sat == SAT_REVERSESTOP ) {
429- // Taking your foot off entirely while reversing? Ignore delays
427+ // ignore delays if sensor is completely disengaged while reversing
430428 if (d -> footpad .state == FS_NONE ) {
431429 state_stop (& d -> state , STOP_SWITCH_FULL );
432430 return true;
433431 }
434- if (fabsf (d -> imu .pitch ) > 18 ) {
435- state_stop (& d -> state , STOP_REVERSE_STOP );
436- return true;
437- }
438- // Above 10 degrees for a full second? Switch it off
439- if (fabsf (d -> imu .pitch ) > 10 && timer_older (& d -> time , d -> reverse_timer , 1 )) {
440- state_stop (& d -> state , STOP_REVERSE_STOP );
441- return true;
442- }
443- // Above 5 degrees for 2 seconds? Switch it off
444- if (fabsf (d -> imu .pitch ) > 5 && timer_older (& d -> time , d -> reverse_timer , 2 )) {
445- state_stop (& d -> state , STOP_REVERSE_STOP );
446- return true;
447- }
448- if (fabsf (d -> reverse_total_erpm ) > d -> reverse_tolerance * 10 ) {
432+
433+ if (reverse_stop_stop (& d -> reverse_stop , & d -> time )) {
449434 state_stop (& d -> state , STOP_REVERSE_STOP );
450435 return true;
451436 }
452- if (fabsf (d -> imu .pitch ) < 5 ) {
453- timer_refresh (& d -> time , & d -> reverse_timer );
454- }
455437 }
456438
457439 // Switch partially open and stopped
@@ -518,34 +500,15 @@ static void calculate_setpoint_target(Data *d) {
518500 d -> state .sat = SAT_NONE ;
519501 }
520502 } else if (d -> state .sat == SAT_REVERSESTOP ) {
521- // accumalete erpms:
522- d -> reverse_total_erpm += d -> motor .erpm ;
523- if (fabsf (d -> reverse_total_erpm ) > d -> reverse_tolerance ) {
524- // tilt down by 10 degrees after exceeding aggregate erpm
525- d -> setpoint_target =
526- (fabsf (d -> reverse_total_erpm ) - d -> reverse_tolerance ) * REVSTOP_ERPM_INCR ;
503+ if (reverse_stop_active (& d -> reverse_stop )) {
504+ d -> setpoint_target = reverse_stop_setpoint (& d -> reverse_stop );
527505 } else {
528- if (fabsf (d -> reverse_total_erpm ) <= d -> reverse_tolerance * 0.5 ) {
529- if (d -> motor .erpm >= 0 ) {
530- d -> state .sat = SAT_NONE ;
531- d -> reverse_total_erpm = 0 ;
532- d -> setpoint_target = 0 ;
533- }
534- }
506+ d -> state .sat = SAT_NONE ;
535507 }
536- } else if (d -> float_conf .fault_reversestop_enabled && d -> motor . erpm < -200 &&
508+ } else if (d -> float_conf .fault_reversestop_enabled && reverse_stop_active ( & d -> reverse_stop ) &&
537509 !d -> state .darkride ) {
538- // Detecting reverse stop takes priority over any error condition SAT
539- if (d -> state .sat >= SAT_PB_HIGH_VOLTAGE ) {
540- // If this happens while in Error-Tiltback (LV/HV/TEMP) then we need to
541- // take the already existing setpoint into account
542- d -> reverse_total_erpm =
543- - (d -> reverse_tolerance + d -> setpoint_target_interpolated / REVSTOP_ERPM_INCR );
544- } else {
545- d -> reverse_total_erpm = 0 ;
546- }
510+ d -> setpoint_target = reverse_stop_setpoint (& d -> reverse_stop );
547511 d -> state .sat = SAT_REVERSESTOP ;
548- timer_refresh (& d -> time , & d -> reverse_timer );
549512 } else if (d -> state .mode != MODE_FLYWHEEL &&
550513 // not normal, either wheelslip or wheel getting stuck
551514 fabsf (d -> motor .acceleration .value ) > 10000 &&
@@ -906,6 +869,20 @@ static void refloat_thd(void *arg) {
906869 break ;
907870
908871 case (STATE_RUNNING ):
872+ // Only update reverse stop after centering, as the centering angle
873+ // change registers as negative distance, which progresses Reverse
874+ // Stop and causes a jolt right after centering is finished.
875+ if (d -> state .sat != SAT_CENTERING ) {
876+ reverse_stop_update (
877+ & d -> reverse_stop ,
878+ d -> motor .distance ,
879+ d -> motor .erpm ,
880+ d -> setpoint_target_interpolated ,
881+ & d -> time ,
882+ d -> float_conf .fault_reversestop_enabled
883+ );
884+ }
885+
909886 // Check for faults
910887 if (check_faults (d )) {
911888 if (d -> state .stop_condition == STOP_SWITCH_FULL && !d -> state .darkride ) {
@@ -1255,6 +1232,7 @@ static void data_init(Data *d) {
12551232 footpad_sensor_init (& d -> footpad );
12561233 haptic_feedback_init (& d -> haptic_feedback );
12571234 alert_tracker_init (& d -> alert_tracker );
1235+ reverse_stop_init (& d -> reverse_stop );
12581236
12591237 leds_init (& d -> leds );
12601238 lcm_init (& d -> lcm , & d -> float_conf .hardware .leds );
0 commit comments