@@ -77,6 +77,7 @@ public Tuning() {
7777 p .add ("Line" , Line ::new );
7878 p .add ("Triangle" , Triangle ::new );
7979 p .add ("Circle" , Circle ::new );
80+ p .add ("Line90DegreeTurn" , Line90DegreeTurn ::new );
8081 });
8182 });
8283 }
@@ -725,7 +726,7 @@ public void loop() {
725726/**
726727 * This is the Predictive Braking Tuner. It runs the robot forward and backward at various power
727728 * levels, recording the robot’s velocity and position immediately before braking. The motors are
728- * then set to zero-power brake mode , which represents the fastest theoretical braking the robot
729+ * then set to a reverse power , which represents the fastest theoretical braking the robot
729730 * can achieve. Once the robot comes to a complete stop, the tuner measures the stopping distance.
730731 * Using the collected data, it generates a velocity-vs-stopping-distance graph and fits a
731732 * quadratic curve to model the braking behavior.
@@ -736,10 +737,10 @@ public void loop() {
736737 */
737738class PredictiveBrakingTuner extends OpMode {
738739 private static final double [] TEST_POWERS =
739- {1 , 1 , 1 , 0.9 , 0.9 , 0.8 , 0.7 , 0.6 , 0.5 , 0.4 , 0.3 , 0.2 };
740-
741- private static final int DRIVE_TIME_MS = 2000 ;
742- private static final int BRAKE_WAIT_MS = 1000 ;
740+ {1 , 1 , 1 , 0.9 , 0.9 , 0.8 , 0.7 , 0.6 , 0.5 , 0.4 , 0.3 , 0.2 };
741+ private static final double BRAKING_POWER = - 0.2 ;
742+
743+ private static final int DRIVE_TIME_MS = 1000 ;
743744
744745 private enum State {
745746 START_MOVE ,
@@ -749,37 +750,34 @@ private enum State {
749750 RECORD ,
750751 DONE
751752 }
752-
753+
753754 private static class BrakeRecord {
754755 double timeMs ;
755756 Pose pose ;
756757 double velocity ;
757-
758+
758759 BrakeRecord (double timeMs , Pose pose , double velocity ) {
759760 this .timeMs = timeMs ;
760761 this .pose = pose ;
761762 this .velocity = velocity ;
762763 }
763764 }
764-
765- private double lastDriveSign = 1.0 ;
766- private static final int BRAKE_PULSE_MS = 150 ;
767-
765+
768766 private State state = State .START_MOVE ;
769-
767+
770768 private final ElapsedTime timer = new ElapsedTime ();
771-
769+
772770 private int iteration = 0 ;
773-
771+
774772 private Vector startPosition ;
775773 private double measuredVelocity ;
776-
774+
777775 private final List <double []> velocityToBrakingDistance = new ArrayList <>();
778776 private final List <BrakeRecord > brakeData = new ArrayList <>();
779-
777+
780778 @ Override
781779 public void init () {}
782-
780+
783781 @ Override
784782 public void init_loop () {
785783 telemetryM .debug ("The robot will move forwards and backwards starting at max speed and slowing down." );
@@ -791,47 +789,43 @@ public void init_loop() {
791789 follower .update ();
792790 drawCurrent ();
793791 }
794-
792+
795793 @ Override
796794 public void start () {
797795 timer .reset ();
798796 follower .update ();
799797 follower .startTeleOpDrive (true );
800798 }
801-
799+
802800 @ SuppressLint ("DefaultLocale" )
803801 @ Override
804802 public void loop () {
805803 follower .update ();
806-
804+
807805 if (gamepad1 .b ) {
808806 stopRobot ();
809807 requestOpModeStop ();
810808 return ;
811809 }
812-
810+
811+ double direction = (iteration % 2 == 0 ) ? 1 : -1 ;
812+
813813 switch (state ) {
814814 case START_MOVE : {
815815 if (iteration >= TEST_POWERS .length ) {
816816 state = State .DONE ;
817817 break ;
818818 }
819-
819+
820820 double currentPower = TEST_POWERS [iteration ];
821821 follower .setMaxPower (currentPower );
822- if (iteration % 2 != 0 ) {
823- lastDriveSign = -1.0 ;
824- follower .setTeleOpDrive (-1 , 0 , 0 , true );
825- } else {
826- lastDriveSign = 1.0 ;
827- follower .setTeleOpDrive (1 , 0 , 0 , true );
828- }
829-
822+ follower .setTeleOpDrive (direction , 0 , 0 , true );
823+
830824 timer .reset ();
831825 state = State .WAIT_DRIVE_TIME ;
832826 break ;
833827 }
834-
828+
835829 case WAIT_DRIVE_TIME : {
836830 if (timer .milliseconds () >= DRIVE_TIME_MS ) {
837831 measuredVelocity = follower .getVelocity ().getMagnitude ();
@@ -840,57 +834,55 @@ public void loop() {
840834 }
841835 break ;
842836 }
843-
837+
844838 case APPLY_BRAKE : {
845- double reversePower = -lastDriveSign * follower .constants .predictiveBrakingCoefficients .maximumBrakingPower ;
846- follower .setTeleOpDrive (reversePower , 0 , 0 , true );
839+ follower .setTeleOpDrive (BRAKING_POWER * direction , 0 , 0 , true );
847840
848841 timer .reset ();
849842 state = State .WAIT_BRAKE_TIME ;
850843 break ;
851844 }
852-
845+
853846 case WAIT_BRAKE_TIME : {
854847 double t = timer .milliseconds ();
855848 Pose currentPose = follower .getPose ();
856849 double currentVelocity = follower .getVelocity ().getMagnitude ();
857-
850+
858851 brakeData .add (new BrakeRecord (t , currentPose , currentVelocity ));
859-
860- if (t >= BRAKE_PULSE_MS ) {
861- stopRobot ();
862- }
863-
864- if (timer .milliseconds () >= BRAKE_WAIT_MS || follower .getVelocity ().getMagnitude () <= .05 ) {
852+
853+ if (follower .getVelocity ().dot (new Vector (direction ,
854+ follower .getHeading ())) <= 0 ) {
865855 state = State .RECORD ;
866856 }
867857 break ;
868858 }
869-
859+
870860 case RECORD : {
871861 Vector endPosition = follower .getPose ().getAsVector ();
872862 double brakingDistance = endPosition .minus (startPosition ).getMagnitude ();
873-
863+
874864 velocityToBrakingDistance .add (new double []{measuredVelocity , brakingDistance });
875-
865+
876866 telemetryM .debug ("Test " + iteration ,
877- String .format ("v=%.3f d=%.3f" , measuredVelocity ,
878- brakingDistance ));
867+ String .format ("v=%.3f d=%.3f" , measuredVelocity ,
868+ brakingDistance ));
879869 telemetryM .update (telemetry );
880-
870+
881871 iteration ++;
882872 state = State .START_MOVE ;
883-
873+
884874 break ;
885875 }
886-
876+
887877 case DONE : {
878+ stopRobot ();
879+
888880 double [] coefficients = quadraticFit (velocityToBrakingDistance );
889-
881+
890882 telemetryM .debug ("Tuning Complete" );
891883 telemetryM .debug ("Braking Profile:" );
892- telemetryM .debug ("kQuadraticFriction " , coefficients [1 ]);
893- telemetryM .debug ("kLinearBraking " , coefficients [0 ]);
884+ telemetryM .debug ("kQuadratic " , coefficients [1 ]);
885+ telemetryM .debug ("kLinear " , coefficients [0 ]);
894886 telemetryM .update (telemetry );
895887 telemetryM .debug ("Tuning Complete" );
896888 telemetryM .debug ("Braking Profile:" );
@@ -899,9 +891,9 @@ public void loop() {
899891 for (BrakeRecord record : brakeData ) {
900892 Pose p = record .pose ;
901893 telemetryM .debug (String .format ("t=%.0f ms, x=%.2f, y=%.2f, θ=%.2f, v=%.2f" ,
902- record .timeMs , p .getX (), p .getY (),
903- p .getHeading (),
904- record .velocity ));
894+ record .timeMs , p .getX (), p .getY (),
895+ p .getHeading (),
896+ record .velocity ));
905897 }
906898 telemetryM .update ();
907899 break ;
@@ -1182,6 +1174,48 @@ public void loop() {
11821174 }
11831175}
11841176
1177+ /**
1178+ * @author Jacob Ophoven - 18535 Frozen Code
1179+ */
1180+ class Line90DegreeTurn extends OpMode {
1181+ @ Override
1182+ public void init () {}
1183+
1184+ /** This initializes the Follower and creates the forward and backward Paths. */
1185+ @ Override
1186+ public void init_loop () {
1187+ telemetryM .debug ("The robot will go forward 48 inches and then sideways to " +
1188+ "the left 24 inches." );
1189+ telemetryM .update (telemetry );
1190+ follower .update ();
1191+ drawCurrent ();
1192+ }
1193+
1194+ @ Override
1195+ public void start () {
1196+ follower .activateAllPIDFs ();
1197+ Path forwards = new Path (new BezierLine (new Pose (0 , 0 ), new Pose (48 , 0 )));
1198+ forwards .setConstantHeadingInterpolation (0 );
1199+ Path sideways = new Path (new BezierLine (new Pose (48 , 0 ), new Pose (48 ,
1200+ 24 )));
1201+ sideways .setConstantHeadingInterpolation (0 );
1202+ follower .followPath (new PathChain (forwards , sideways ));
1203+ }
1204+
1205+ /** This runs the OpMode, updating the Follower as well as printing out the debug statements to the Telemetry */
1206+ @ Override
1207+ public void loop () {
1208+ follower .update ();
1209+ drawCurrentAndHistory ();
1210+
1211+ if (!follower .isBusy ()) {
1212+ stopRobot ();
1213+ }
1214+
1215+ telemetryM .update (telemetry );
1216+ }
1217+ }
1218+
11851219/**
11861220 * This is the Centripetal Tuner OpMode. It runs the robot in a specified distance
11871221 * forward and to the left. On reaching the end of the forward Path, the robot runs the backward
0 commit comments