@@ -1,12 +1,14 @@
package org.firstinspires.ftc.teamcode.libs. pedroPathing ;
package org.firstinspires.ftc.teamcode.pedroPathing ;
import static org.firstinspires.ftc.teamcode.libs .pedroP athing.Tuning.changes ;
import static com .pedrop athing.math.MathFunctions.quadraticFit ;
import static org.firstinspires.ftc.teamcode.libs. pedroPathing.Tuning.drawCurrent ;
import static org.firstinspires.ftc.teamcode.pedroPathing.Tuning.changes ;
import static org.firstinspires.ftc.teamcode.libs. pedroPathing.Tuning.drawCurrentAndHistory ;
import static org.firstinspires.ftc.teamcode.pedroPathing.Tuning.drawCurrent ;
import static org.firstinspires.ftc.teamcode.libs. pedroPathing.Tuning.follower ;
import static org.firstinspires.ftc.teamcode.pedroPathing.Tuning.drawCurrentAndHistory ;
import static org.firstinspires.ftc.teamcode.libs. pedroPathing.Tuning.stopRobot ;
import static org.firstinspires.ftc.teamcode.pedroPathing.Tuning.follower ;
import static org.firstinspires.ftc.teamcode.libs. pedroPathing.Tuning.telemetryM ;
import static org.firstinspires.ftc.teamcode.pedroPathing.Tuning.stopRobot ;
import static org.firstinspires.ftc.teamcode.pedroPathing.Tuning.telemetryM ;
import android.annotation.SuppressLint ;
import com.bylazar.configurables.PanelsConfigurables ;
import com.bylazar.configurables.PanelsConfigurables ;
import com.bylazar.configurables.annotations.Configurable ;
import com.bylazar.configurables.annotations.Configurable ;
@@ -17,13 +19,20 @@ import com.bylazar.field.Style;
import com.bylazar.telemetry.PanelsTelemetry ;
import com.bylazar.telemetry.PanelsTelemetry ;
import com.bylazar.telemetry.TelemetryManager ;
import com.bylazar.telemetry.TelemetryManager ;
import com.pedropathing.follower.Follower ;
import com.pedropathing.follower.Follower ;
import com.pedropathing.geometry.* ;
import com.pedropathing.geometry.BezierCurve ;
import com.pedropathing.math.* ;
import com.pedropathing.geometry.BezierLine ;
import com.pedropathing.paths.* ;
import com.pedropathing.geometry.Pose ;
import com.pedropathing.math.Vector ;
import com.pedropathing.paths.HeadingInterpolator ;
import com.pedropathing.paths.Path ;
import com.pedropathing.paths.PathChain ;
import com.pedropathing.telemetry.SelectableOpMode ;
import com.pedropathing.telemetry.SelectableOpMode ;
import com.pedropathing.util.* ;
import com.pedropathing.util.PoseHistory ;
import com.qualcomm.hardware.lynx.LynxModule ;
import com.qualcomm.robotcore.eventloop.opmode.OpMode ;
import com.qualcomm.robotcore.eventloop.opmode.OpMode ;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp ;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp ;
import com.qualcomm.robotcore.hardware.AnalogInput ;
import com.qualcomm.robotcore.util.ElapsedTime ;
import java.util.ArrayList ;
import java.util.ArrayList ;
import java.util.List ;
import java.util.List ;
@@ -52,6 +61,7 @@ public class Tuning extends SelectableOpMode {
super ( " Select a Tuning OpMode " , s - > {
super ( " Select a Tuning OpMode " , s - > {
s . folder ( " Localization " , l - > {
s . folder ( " Localization " , l - > {
l . add ( " Localization Test " , LocalizationTest : : new ) ;
l . add ( " Localization Test " , LocalizationTest : : new ) ;
l . add ( " Offsets Tuner " , OffsetsTuner : : new ) ;
l . add ( " Forward Tuner " , ForwardTuner : : new ) ;
l . add ( " Forward Tuner " , ForwardTuner : : new ) ;
l . add ( " Lateral Tuner " , LateralTuner : : new ) ;
l . add ( " Lateral Tuner " , LateralTuner : : new ) ;
l . add ( " Turn Tuner " , TurnTuner : : new ) ;
l . add ( " Turn Tuner " , TurnTuner : : new ) ;
@@ -61,6 +71,7 @@ public class Tuning extends SelectableOpMode {
a . add ( " Lateral Velocity Tuner " , LateralVelocityTuner : : new ) ;
a . add ( " Lateral Velocity Tuner " , LateralVelocityTuner : : new ) ;
a . add ( " Forward Zero Power Acceleration Tuner " , ForwardZeroPowerAccelerationTuner : : new ) ;
a . add ( " Forward Zero Power Acceleration Tuner " , ForwardZeroPowerAccelerationTuner : : new ) ;
a . add ( " Lateral Zero Power Acceleration Tuner " , LateralZeroPowerAccelerationTuner : : new ) ;
a . add ( " Lateral Zero Power Acceleration Tuner " , LateralZeroPowerAccelerationTuner : : new ) ;
a . add ( " Predictive Braking Tuner " , PredictiveBrakingTuner : : new ) ;
} ) ;
} ) ;
s . folder ( " Manual " , p - > {
s . folder ( " Manual " , p - > {
p . add ( " Translational Tuner " , TranslationalTuner : : new ) ;
p . add ( " Translational Tuner " , TranslationalTuner : : new ) ;
@@ -73,6 +84,11 @@ public class Tuning extends SelectableOpMode {
p . add ( " Triangle " , Triangle : : new ) ;
p . add ( " Triangle " , Triangle : : new ) ;
p . add ( " Circle " , Circle : : new ) ;
p . add ( " Circle " , Circle : : new ) ;
} ) ;
} ) ;
s . folder ( " Swerve " , p - > {
p . add ( " Analog Min / Max Tuner " , AnalogMinMaxTuner : : new ) ;
p . add ( " Swerve Offsets Test " , SwerveOffsetsTest : : new ) ;
p . add ( " Swerve Turn Test " , SwerveTurnTest : : new ) ;
} ) ;
} ) ;
} ) ;
}
}
@@ -117,23 +133,35 @@ public class Tuning extends SelectableOpMode {
}
}
/ * *
/ * *
* This is the LocalizationTest OpMode . This is basically just a simple mecanum drive attached to a
* This is the LocalizationTest OpMode . This is basically just a simple drive attached to a
* PoseUpdater . The OpMode will print out the robot ' s pose to telemetry as well as draw the robot .
* PoseUpdater . The OpMode will print out the robot ' s pose to telemetry as well as draw the robot .
* You should use this to check the robot ' s localization .
* You should use this to check the robot ' s localization .
*
*
* @author Anyi Lin - 10158 Scott ' s Bots
* @author Anyi Lin - 10158 Scott ' s Bots
* @author Baron Henderson - 20077 The Indubitables
* @author Baron Henderson - 20077 The Indubitables
* @author Kabir Goyal
* @version 1 . 0 , 5 / 6 / 2024
* @version 1 . 0 , 5 / 6 / 2024
* /
* /
class LocalizationTest extends OpMode {
class LocalizationTest extends OpMode {
@Override
boolean debugStringEnabled = false ;
public void init ( ) { }
/** This initializes the PoseUpdater, the mecanum drive motors, and the Panels telemetry. */
@Override
public void init ( ) {
follower . setStartingPose ( new Pose ( 72 , 72 ) ) ;
}
/** This initializes the PoseUpdater, the drive motors, and the Panels telemetry. */
@Override
@Override
public void init_loop ( ) {
public void init_loop ( ) {
if ( gamepad1 . aWasPressed ( ) | | gamepad2 . aWasPressed ( ) ) {
debugStringEnabled = ! debugStringEnabled ;
}
telemetryM . debug ( " This will print your robot's position to telemetry while "
telemetryM . debug ( " This will print your robot's position to telemetry while "
+ " allowing robot control through a basic mecanum drive on gamepad 1. " ) ;
+ " allowing robot control through a basic drive on gamepad 1. " ) ;
telemetryM . debug ( " Drivetrain debug string " + ( ( ( debugStringEnabled ) ? " enabled " : " disabled " ) ) +
" (press gamepad a to toggle) " ) ;
telemetryM . update ( telemetry ) ;
telemetryM . update ( telemetry ) ;
follower . update ( ) ;
follower . update ( ) ;
drawCurrent ( ) ;
drawCurrent ( ) ;
@@ -146,11 +174,15 @@ class LocalizationTest extends OpMode {
}
}
/ * *
/ * *
* This updates the robot ' s pose estimate , the simple mecanum drive, and updates the
* This updates the robot ' s pose estimate , the simple drive , and updates the
* Panels telemetry with the robot ' s position as well as draws the robot ' s position .
* Panels telemetry with the robot ' s position as well as draws the robot ' s position .
* /
* /
@Override
@Override
public void loop ( ) {
public void loop ( ) {
if ( gamepad1 . aWasPressed ( ) | | gamepad2 . aWasPressed ( ) ) {
debugStringEnabled = ! debugStringEnabled ;
}
follower . setTeleOpDrive ( - gamepad1 . left_stick_y , - gamepad1 . left_stick_x , - gamepad1 . right_stick_x , true ) ;
follower . setTeleOpDrive ( - gamepad1 . left_stick_y , - gamepad1 . left_stick_x , - gamepad1 . right_stick_x , true ) ;
follower . update ( ) ;
follower . update ( ) ;
@@ -158,6 +190,10 @@ class LocalizationTest extends OpMode {
telemetryM . debug ( " y: " + follower . getPose ( ) . getY ( ) ) ;
telemetryM . debug ( " y: " + follower . getPose ( ) . getY ( ) ) ;
telemetryM . debug ( " heading: " + follower . getPose ( ) . getHeading ( ) ) ;
telemetryM . debug ( " heading: " + follower . getPose ( ) . getHeading ( ) ) ;
telemetryM . debug ( " total heading: " + follower . getTotalHeading ( ) ) ;
telemetryM . debug ( " total heading: " + follower . getTotalHeading ( ) ) ;
if ( debugStringEnabled ) {
telemetryM . debug ( " Drivetrain Debug String: \ n " +
follower . getDrivetrain ( ) . debugString ( ) ) ;
}
telemetryM . update ( telemetry ) ;
telemetryM . update ( telemetry ) ;
drawCurrentAndHistory ( ) ;
drawCurrentAndHistory ( ) ;
@@ -182,6 +218,7 @@ class ForwardTuner extends OpMode {
@Override
@Override
public void init ( ) {
public void init ( ) {
follower . setStartingPose ( new Pose ( 72 , 72 ) ) ;
follower . update ( ) ;
follower . update ( ) ;
drawCurrent ( ) ;
drawCurrent ( ) ;
}
}
@@ -229,6 +266,7 @@ class LateralTuner extends OpMode {
@Override
@Override
public void init ( ) {
public void init ( ) {
follower . setStartingPose ( new Pose ( 72 , 72 ) ) ;
follower . update ( ) ;
follower . update ( ) ;
drawCurrent ( ) ;
drawCurrent ( ) ;
}
}
@@ -276,6 +314,7 @@ class TurnTuner extends OpMode {
@Override
@Override
public void init ( ) {
public void init ( ) {
follower . setStartingPose ( new Pose ( 72 , 72 ) ) ;
follower . update ( ) ;
follower . update ( ) ;
drawCurrent ( ) ;
drawCurrent ( ) ;
}
}
@@ -312,7 +351,7 @@ class TurnTuner extends OpMode {
* reaching the end of the distance , it averages them and prints out the velocity obtained . It is
* reaching the end of the distance , it averages them and prints out the velocity obtained . It is
* recommended to run this multiple times on a full battery to get the best results . What this does
* recommended to run this multiple times on a full battery to get the best results . What this does
* is , when paired with StrafeVelocityTuner , allows FollowerConstants to create a Vector that
* is , when paired with StrafeVelocityTuner , allows FollowerConstants to create a Vector that
* empirically represents the direction your mecanum wheels actually prefer to go in , allowing for
* empirically represents the direction your wheels actually prefer to go in , allowing for
* more accurate following .
* more accurate following .
*
*
* @author Anyi Lin - 10158 Scott ' s Bots
* @author Anyi Lin - 10158 Scott ' s Bots
@@ -323,13 +362,15 @@ class TurnTuner extends OpMode {
* /
* /
class ForwardVelocityTuner extends OpMode {
class ForwardVelocityTuner extends OpMode {
private final ArrayList < Double > velocities = new ArrayList < > ( ) ;
private final ArrayList < Double > velocities = new ArrayList < > ( ) ;
public static double DISTANCE = 48 ;
public static double DISTANCE = 120 ;
public static double RECORD_NUMBER = 10 ;
public static double RECORD_NUMBER = 10 ;
private boolean end ;
private boolean end ;
@Override
@Override
public void init ( ) { }
public void init ( ) {
follower . setStartingPose ( new Pose ( 72 , 72 ) ) ;
}
/** This initializes the drive motors as well as the cache of velocities and the Panels telemetry. */
/** This initializes the drive motors as well as the cache of velocities and the Panels telemetry. */
@Override
@Override
@@ -374,7 +415,7 @@ class ForwardVelocityTuner extends OpMode {
if ( ! end ) {
if ( ! end ) {
if ( Math . abs ( follower . getPose ( ) . getX ( ) ) > DISTANCE ) {
if ( Math . abs ( follower . getPose ( ) . getX ( ) ) > ( DISTANCE + 72 ) ) {
end = true ;
end = true ;
stopRobot ( ) ;
stopRobot ( ) ;
} else {
} else {
@@ -417,7 +458,7 @@ class ForwardVelocityTuner extends OpMode {
* reaching the end of the distance , it averages them and prints out the velocity obtained . It is
* reaching the end of the distance , it averages them and prints out the velocity obtained . It is
* recommended to run this multiple times on a full battery to get the best results . What this does
* recommended to run this multiple times on a full battery to get the best results . What this does
* is , when paired with ForwardVelocityTuner , allows FollowerConstants to create a Vector that
* is , when paired with ForwardVelocityTuner , allows FollowerConstants to create a Vector that
* empirically represents the direction your mecanum wheels actually prefer to go in , allowing for
* empirically represents the direction your wheels actually prefer to go in , allowing for
* more accurate following .
* more accurate following .
*
*
* @author Anyi Lin - 10158 Scott ' s Bots
* @author Anyi Lin - 10158 Scott ' s Bots
@@ -429,13 +470,15 @@ class ForwardVelocityTuner extends OpMode {
class LateralVelocityTuner extends OpMode {
class LateralVelocityTuner extends OpMode {
private final ArrayList < Double > velocities = new ArrayList < > ( ) ;
private final ArrayList < Double > velocities = new ArrayList < > ( ) ;
public static double DISTANCE = 48 ;
public static double DISTANCE = 120 ;
public static double RECORD_NUMBER = 10 ;
public static double RECORD_NUMBER = 10 ;
private boolean end ;
private boolean end ;
@Override
@Override
public void init ( ) { }
public void init ( ) {
follower . setStartingPose ( new Pose ( 72 , 72 ) ) ;
}
/ * *
/ * *
* This initializes the drive motors as well as the cache of velocities and the Panels
* This initializes the drive motors as well as the cache of velocities and the Panels
@@ -480,7 +523,7 @@ class LateralVelocityTuner extends OpMode {
drawCurrentAndHistory ( ) ;
drawCurrentAndHistory ( ) ;
if ( ! end ) {
if ( ! end ) {
if ( Math . abs ( follower . getPose ( ) . getY ( ) ) > DISTANCE ) {
if ( Math . abs ( follower . getPose ( ) . getY ( ) ) > ( DISTANCE + 72 ) ) {
end = true ;
end = true ;
stopRobot ( ) ;
stopRobot ( ) ;
} else {
} else {
@@ -537,7 +580,9 @@ class ForwardZeroPowerAccelerationTuner extends OpMode {
private boolean end ;
private boolean end ;
@Override
@Override
public void init ( ) { }
public void init ( ) {
follower . setStartingPose ( new Pose ( 72 , 72 ) ) ;
}
/** This initializes the drive motors as well as the Panels telemetryM. */
/** This initializes the drive motors as well as the Panels telemetryM. */
@Override
@Override
@@ -639,7 +684,9 @@ class LateralZeroPowerAccelerationTuner extends OpMode {
private boolean end ;
private boolean end ;
@Override
@Override
public void init ( ) { }
public void init ( ) {
follower . setStartingPose ( new Pose ( 72 , 72 ) ) ;
}
/** This initializes the drive motors as well as the Panels telemetry. */
/** This initializes the drive motors as well as the Panels telemetry. */
@Override
@Override
@@ -717,6 +764,185 @@ class LateralZeroPowerAccelerationTuner extends OpMode {
}
}
}
}
/ * *
* This is the Predictive Braking Tuner . It runs the robot forward and backward at various power
* levels , recording the robot ’ s velocity and position immediately before braking . The motors are
* then set to a reverse power , which represents the fastest theoretical braking the robot
* can achieve . Once the robot comes to a complete stop , the tuner measures the stopping distance .
* Using the collected data , it generates a velocity - vs - stopping - distance graph and fits a
* quadratic curve to model the braking behavior .
*
* @author Ashay Sarda - 19745 Turtle Walkers
* @author Jacob Ophoven - 18535 Frozen Code
* @version 1 . 0 , 12 / 26 / 2025
* /
class PredictiveBrakingTuner extends OpMode {
private static final double [ ] TEST_POWERS =
{ 1 , 1 , 1 , 0 . 9 , 0 . 9 , 0 . 8 , 0 . 7 , 0 . 6 , 0 . 5 , 0 . 4 , 0 . 3 , 0 . 2 } ;
private static final double BRAKING_POWER = - 0 . 2 ;
private static final int DRIVE_TIME_MS = 1000 ;
private enum State {
START_MOVE ,
WAIT_DRIVE_TIME ,
APPLY_BRAKE ,
WAIT_BRAKE_TIME ,
RECORD ,
DONE
}
private static class BrakeRecord {
double timeMs ;
Pose pose ;
double velocity ;
BrakeRecord ( double timeMs , Pose pose , double velocity ) {
this . timeMs = timeMs ;
this . pose = pose ;
this . velocity = velocity ;
}
}
private State state = State . START_MOVE ;
private final ElapsedTime timer = new ElapsedTime ( ) ;
private int iteration = 0 ;
private Vector startPosition ;
private double measuredVelocity ;
private final List < double [ ] > velocityToBrakingDistance = new ArrayList < > ( ) ;
private final List < BrakeRecord > brakeData = new ArrayList < > ( ) ;
@Override
public void init ( ) { }
@Override
public void init_loop ( ) {
telemetryM . debug ( " The robot will move forwards and backwards starting at max speed and slowing down. " ) ;
telemetryM . debug ( " Make sure you have enough room. Leave at least 4-5 feet. " ) ;
telemetryM . debug ( " After stopping, kFriction and kBraking will be displayed. " ) ;
telemetryM . debug ( " Make sure to turn the timer off. " ) ;
telemetryM . debug ( " Press B on game pad 1 to stop. " ) ;
telemetryM . update ( telemetry ) ;
follower . update ( ) ;
drawCurrent ( ) ;
}
@Override
public void start ( ) {
timer . reset ( ) ;
follower . update ( ) ;
follower . startTeleOpDrive ( true ) ;
}
@SuppressLint ( " DefaultLocale " )
@Override
public void loop ( ) {
follower . update ( ) ;
if ( gamepad1 . b ) {
stopRobot ( ) ;
requestOpModeStop ( ) ;
return ;
}
double direction = ( iteration % 2 = = 0 ) ? 1 : - 1 ;
switch ( state ) {
case START_MOVE : {
if ( iteration > = TEST_POWERS . length ) {
state = State . DONE ;
break ;
}
double currentPower = TEST_POWERS [ iteration ] ;
follower . setMaxPower ( currentPower ) ;
follower . setTeleOpDrive ( direction , 0 , 0 , true ) ;
timer . reset ( ) ;
state = State . WAIT_DRIVE_TIME ;
break ;
}
case WAIT_DRIVE_TIME : {
if ( timer . milliseconds ( ) > = DRIVE_TIME_MS ) {
measuredVelocity = follower . getVelocity ( ) . getMagnitude ( ) ;
startPosition = follower . getPose ( ) . getAsVector ( ) ;
state = State . APPLY_BRAKE ;
}
break ;
}
case APPLY_BRAKE : {
follower . setTeleOpDrive ( BRAKING_POWER * direction , 0 , 0 , true ) ;
timer . reset ( ) ;
state = State . WAIT_BRAKE_TIME ;
break ;
}
case WAIT_BRAKE_TIME : {
double t = timer . milliseconds ( ) ;
Pose currentPose = follower . getPose ( ) ;
double currentVelocity = follower . getVelocity ( ) . getMagnitude ( ) ;
brakeData . add ( new BrakeRecord ( t , currentPose , currentVelocity ) ) ;
if ( follower . getVelocity ( ) . dot ( new Vector ( direction ,
follower . getHeading ( ) ) ) < = 0 ) {
state = State . RECORD ;
}
break ;
}
case RECORD : {
Vector endPosition = follower . getPose ( ) . getAsVector ( ) ;
double brakingDistance = endPosition . minus ( startPosition ) . getMagnitude ( ) ;
velocityToBrakingDistance . add ( new double [ ] { measuredVelocity , brakingDistance } ) ;
telemetryM . debug ( " Test " + iteration ,
String . format ( " v=%.3f d=%.3f " , measuredVelocity ,
brakingDistance ) ) ;
telemetryM . update ( telemetry ) ;
iteration + + ;
state = State . START_MOVE ;
break ;
}
case DONE : {
stopRobot ( ) ;
double [ ] coefficients = quadraticFit ( velocityToBrakingDistance ) ;
telemetryM . debug ( " Tuning Complete " ) ;
telemetryM . debug ( " Braking Profile: " ) ;
telemetryM . debug ( " kQuadratic " , coefficients [ 1 ] ) ;
telemetryM . debug ( " kLinear " , coefficients [ 0 ] ) ;
telemetryM . update ( telemetry ) ;
telemetryM . debug ( " Tuning Complete " ) ;
telemetryM . debug ( " Braking Profile: " ) ;
telemetryM . debug ( " kQuadraticFriction " , coefficients [ 1 ] ) ;
telemetryM . debug ( " kLinearBraking " , coefficients [ 0 ] ) ;
for ( BrakeRecord record : brakeData ) {
Pose p = record . pose ;
telemetryM . debug ( String . format ( " t=%.0f ms, x=%.2f, y=%.2f, θ=%.2f, v=%.2f " ,
record . timeMs , p . getX ( ) , p . getY ( ) ,
p . getHeading ( ) ,
record . velocity ) ) ;
}
telemetryM . update ( ) ;
break ;
}
}
}
}
/ * *
/ * *
* This is the Translational PIDF Tuner OpMode . It will keep the robot in place .
* This is the Translational PIDF Tuner OpMode . It will keep the robot in place .
* The user should push the robot laterally to test the PIDF and adjust the PIDF values accordingly .
* The user should push the robot laterally to test the PIDF and adjust the PIDF values accordingly .
@@ -735,7 +961,9 @@ class TranslationalTuner extends OpMode {
private Path backwards ;
private Path backwards ;
@Override
@Override
public void init ( ) { }
public void init ( ) {
follower . setStartingPose ( new Pose ( 72 , 72 ) ) ;
}
/** This initializes the Follower and creates the forward and backward Paths. */
/** This initializes the Follower and creates the forward and backward Paths. */
@Override
@Override
@@ -752,9 +980,9 @@ class TranslationalTuner extends OpMode {
public void start ( ) {
public void start ( ) {
follower . deactivateAllPIDFs ( ) ;
follower . deactivateAllPIDFs ( ) ;
follower . activateTranslational ( ) ;
follower . activateTranslational ( ) ;
forwards = new Path ( new BezierLine ( new Pose ( 0 , 0 ) , new Pose ( DISTANCE , 0 ) ) ) ;
forwards = new Path ( new BezierLine ( new Pose ( 72 , 72 ) , new Pose ( DISTANCE + 72 , 72 ) ) ) ;
forwards . setConstantHeadingInterpolation ( 0 ) ;
forwards . setConstantHeadingInterpolation ( 0 ) ;
backwards = new Path ( new BezierLine ( new Pose ( DISTANCE , 0 ) , new Pose ( 0 , 0 ) ) ) ;
backwards = new Path ( new BezierLine ( new Pose ( DISTANCE + 72 , 72 ) , new Pose ( 72 , 72 ) ) ) ;
backwards . setConstantHeadingInterpolation ( 0 ) ;
backwards . setConstantHeadingInterpolation ( 0 ) ;
follower . followPath ( forwards ) ;
follower . followPath ( forwards ) ;
}
}
@@ -776,6 +1004,9 @@ class TranslationalTuner extends OpMode {
}
}
telemetryM . debug ( " Push the robot laterally to test the Translational PIDF(s). " ) ;
telemetryM . debug ( " Push the robot laterally to test the Translational PIDF(s). " ) ;
telemetryM . addData ( " Zero Line " , 0 ) ;
telemetryM . addData ( " Error X " , follower . errorCalculator . getTranslationalError ( ) . getXComponent ( ) ) ;
telemetryM . addData ( " Error Y " , follower . errorCalculator . getTranslationalError ( ) . getYComponent ( ) ) ;
telemetryM . update ( telemetry ) ;
telemetryM . update ( telemetry ) ;
}
}
}
}
@@ -799,7 +1030,9 @@ class HeadingTuner extends OpMode {
private Path backwards ;
private Path backwards ;
@Override
@Override
public void init ( ) { }
public void init ( ) {
follower . setStartingPose ( new Pose ( 72 , 72 ) ) ;
}
/ * *
/ * *
* This initializes the Follower and creates the forward and backward Paths . Additionally , this
* This initializes the Follower and creates the forward and backward Paths . Additionally , this
@@ -819,9 +1052,9 @@ class HeadingTuner extends OpMode {
public void start ( ) {
public void start ( ) {
follower . deactivateAllPIDFs ( ) ;
follower . deactivateAllPIDFs ( ) ;
follower . activateHeading ( ) ;
follower . activateHeading ( ) ;
forwards = new Path ( new BezierLine ( new Pose ( 0 , 0 ) , new Pose ( DISTANCE , 0 ) ) ) ;
forwards = new Path ( new BezierLine ( new Pose ( 72 , 72 ) , new Pose ( DISTANCE + 72 , 72 ) ) ) ;
forwards . setConstantHeadingInterpolation ( 0 ) ;
forwards . setConstantHeadingInterpolation ( 0 ) ;
backwards = new Path ( new BezierLine ( new Pose ( DISTANCE , 0 ) , new Pose ( 0 , 0 ) ) ) ;
backwards = new Path ( new BezierLine ( new Pose ( DISTANCE + 72 , 72 ) , new Pose ( 72 , 72 ) ) ) ;
backwards . setConstantHeadingInterpolation ( 0 ) ;
backwards . setConstantHeadingInterpolation ( 0 ) ;
follower . followPath ( forwards ) ;
follower . followPath ( forwards ) ;
}
}
@@ -846,6 +1079,8 @@ class HeadingTuner extends OpMode {
}
}
telemetryM . debug ( " Turn the robot manually to test the Heading PIDF(s). " ) ;
telemetryM . debug ( " Turn the robot manually to test the Heading PIDF(s). " ) ;
telemetryM . addData ( " Zero Line " , 0 ) ;
telemetryM . addData ( " Error " , follower . errorCalculator . getHeadingError ( ) ) ;
telemetryM . update ( telemetry ) ;
telemetryM . update ( telemetry ) ;
}
}
}
}
@@ -867,7 +1102,9 @@ class DriveTuner extends OpMode {
private PathChain backwards ;
private PathChain backwards ;
@Override
@Override
public void init ( ) { }
public void init ( ) {
follower . setStartingPose ( new Pose ( 72 , 72 ) ) ;
}
/ * *
/ * *
* This initializes the Follower and creates the forward and backward Paths . Additionally , this
* This initializes the Follower and creates the forward and backward Paths . Additionally , this
@@ -890,13 +1127,13 @@ class DriveTuner extends OpMode {
forwards = follower . pathBuilder ( )
forwards = follower . pathBuilder ( )
. setGlobalDeceleration ( )
. setGlobalDeceleration ( )
. addPath ( new BezierLine ( new Pose ( 0 , 0 ) , new Pose ( DISTANCE , 0 ) ) )
. addPath ( new BezierLine ( new Pose ( 72 , 72 ) , new Pose ( DISTANCE + 72 , 72 ) ) )
. setConstantHeadingInterpolation ( 0 )
. setConstantHeadingInterpolation ( 0 )
. build ( ) ;
. build ( ) ;
backwards = follower . pathBuilder ( )
backwards = follower . pathBuilder ( )
. setGlobalDeceleration ( )
. setGlobalDeceleration ( )
. addPath ( new BezierLine ( new Pose ( DISTANCE , 0 ) , new Pose ( 0 , 0 ) ) )
. addPath ( new BezierLine ( new Pose ( DISTANCE + 72 , 72 ) , new Pose ( 72 , 72 ) ) )
. setConstantHeadingInterpolation ( 0 )
. setConstantHeadingInterpolation ( 0 )
. build ( ) ;
. build ( ) ;
@@ -923,6 +1160,8 @@ class DriveTuner extends OpMode {
}
}
telemetryM . debug ( " Driving forward?: " + forward ) ;
telemetryM . debug ( " Driving forward?: " + forward ) ;
telemetryM . addData ( " Zero Line " , 0 ) ;
telemetryM . addData ( " Error " , follower . errorCalculator . getDriveErrors ( ) [ 1 ] ) ;
telemetryM . update ( telemetry ) ;
telemetryM . update ( telemetry ) ;
}
}
}
}
@@ -945,7 +1184,9 @@ class Line extends OpMode {
private Path backwards ;
private Path backwards ;
@Override
@Override
public void init ( ) { }
public void init ( ) {
follower . setStartingPose ( new Pose ( 72 , 72 ) ) ;
}
/** This initializes the Follower and creates the forward and backward Paths. */
/** This initializes the Follower and creates the forward and backward Paths. */
@Override
@Override
@@ -961,9 +1202,9 @@ class Line extends OpMode {
@Override
@Override
public void start ( ) {
public void start ( ) {
follower . activateAllPIDFs ( ) ;
follower . activateAllPIDFs ( ) ;
forwards = new Path ( new BezierLine ( new Pose ( 0 , 0 ) , new Pose ( DISTANCE , 0 ) ) ) ;
forwards = new Path ( new BezierLine ( new Pose ( 72 , 72 ) , new Pose ( DISTANCE + 72 , 72 ) ) ) ;
forwards . setConstantHeadingInterpolation ( 0 ) ;
forwards . setConstantHeadingInterpolation ( 0 ) ;
backwards = new Path ( new BezierLine ( new Pose ( DISTANCE , 0 ) , new Pose ( 0 , 0 ) ) ) ;
backwards = new Path ( new BezierLine ( new Pose ( DISTANCE + 72 , 72 ) , new Pose ( 72 , 72 ) ) ) ;
backwards . setConstantHeadingInterpolation ( 0 ) ;
backwards . setConstantHeadingInterpolation ( 0 ) ;
follower . followPath ( forwards ) ;
follower . followPath ( forwards ) ;
}
}
@@ -1010,7 +1251,9 @@ class CentripetalTuner extends OpMode {
private Path backwards ;
private Path backwards ;
@Override
@Override
public void init ( ) { }
public void init ( ) {
follower . setStartingPose ( new Pose ( 72 , 72 ) ) ;
}
/ * *
/ * *
* This initializes the Follower and creates the forward and backward Paths .
* This initializes the Follower and creates the forward and backward Paths .
@@ -1029,8 +1272,8 @@ class CentripetalTuner extends OpMode {
@Override
@Override
public void start ( ) {
public void start ( ) {
follower . activateAllPIDFs ( ) ;
follower . activateAllPIDFs ( ) ;
forwards = new Path ( new BezierCurve ( new Pose ( ) , new Pose ( Math . abs ( DISTANCE ) , 0 ) , new Pose ( Math . abs ( DISTANCE ) , DISTANCE ) ) ) ;
forwards = new Path ( new BezierCurve ( new Pose ( 72 , 72 ) , new Pose ( Math . abs ( DISTANCE ) + 72 , 72 ) , new Pose ( Math . abs ( DISTANCE ) + 72 , DISTANCE + 72 ) ) ) ;
backwards = new Path ( new BezierCurve ( new Pose ( Math . abs ( DISTANCE ) , DISTANCE ) , new Pose ( Math . abs ( DISTANCE ) , 0 ) , new Pose ( 0 , 0 ) ) ) ;
backwards = new Path ( new BezierCurve ( new Pose ( Math . abs ( DISTANCE ) + 72 , DISTANCE + 72 ) , new Pose ( Math . abs ( DISTANCE ) + 72 , 72 ) , new Pose ( 72 , 72 ) ) ) ;
backwards . setTangentHeadingInterpolation ( ) ;
backwards . setTangentHeadingInterpolation ( ) ;
backwards . reverseHeadingInterpolation ( ) ;
backwards . reverseHeadingInterpolation ( ) ;
@@ -1071,9 +1314,9 @@ class CentripetalTuner extends OpMode {
* /
* /
class Triangle extends OpMode {
class Triangle extends OpMode {
private final Pose startPose = new Pose ( 0 , 0 , Math . toRadians ( 0 ) ) ;
private final Pose startPose = new Pose ( 72 , 72 , Math . toRadians ( 0 ) ) ;
private final Pose interPose = new Pose ( 24 , - 24 , Math . toRadians ( 90 ) ) ;
private final Pose interPose = new Pose ( 24 + 72 , - 24 + 72 , Math . toRadians ( 90 ) ) ;
private final Pose endPose = new Pose ( 24 , 24 , Math . toRadians ( 45 ) ) ;
private final Pose endPose = new Pose ( 24 + 72 , 24 + 72 , Math . toRadians ( 45 ) ) ;
private PathChain triangle ;
private PathChain triangle ;
@@ -1092,7 +1335,9 @@ class Triangle extends OpMode {
}
}
@Override
@Override
public void init ( ) { }
public void init ( ) {
follower . setStartingPose ( new Pose ( 72 , 72 ) ) ;
}
@Override
@Override
public void init_loop ( ) {
public void init_loop ( ) {
@@ -1138,14 +1383,14 @@ class Circle extends OpMode {
public void start ( ) {
public void start ( ) {
circle = follower . pathBuilder ( )
circle = follower . pathBuilder ( )
. addPath ( new BezierCurve ( new Pose ( 0 , 0 ) , new Pose ( RADIUS , 0 ) , new Pose ( RADIUS , RADIUS ) ) )
. addPath ( new BezierCurve ( new Pose ( 72 , 72 ) , new Pose ( RADIUS + 72 , 72 ) , new Pose ( RADIUS + 72 , RADIUS + 72 ) ) )
. setHeadingInterpolation ( HeadingInterpolator . facingPoint ( 0 , RADIUS ) )
. setHeadingInterpolation ( HeadingInterpolator . facingPoint ( 72 , RADIUS + 72 ) )
. addPath ( new BezierCurve ( new Pose ( RADIUS , RADIUS ) , new Pose ( RADIUS , 2 * RADIUS ) , new Pose ( 0 , 2 * RADIUS ) ) )
. addPath ( new BezierCurve ( new Pose ( RADIUS + 72 , RADIUS + 72 ) , new Pose ( RADIUS + 72 , ( 2 * RADIUS ) + 72 ) , new Pose ( 72 , ( 2 * RADIUS ) + 72 ) ) )
. setHeadingInterpolation ( HeadingInterpolator . facingPoint ( 0 , RADIUS ) )
. setHeadingInterpolation ( HeadingInterpolator . facingPoint ( 72 , RADIUS + 72 ) )
. addPath ( new BezierCurve ( new Pose ( 0 , 2 * RADIUS ) , new Pose ( - RADIUS , 2 * RADIUS ) , new Pose ( - RADIUS , RADIUS ) ) )
. addPath ( new BezierCurve ( new Pose ( 72 , ( 2 * RADIUS ) + 72 ) , new Pose ( - RADIUS + 72 , ( 2 * RADIUS ) + 72 ) , new Pose ( - RADIUS + 72 , RADIUS + 72 ) ) )
. setHeadingInterpolation ( HeadingInterpolator . facingPoint ( 0 , RADIUS ) )
. setHeadingInterpolation ( HeadingInterpolator . facingPoint ( 72 , RADIUS + 72 ) )
. addPath ( new BezierCurve ( new Pose ( - RADIUS , RADIUS ) , new Pose ( - RADIUS , 0 ) , new Pose ( 0 , 0 ) ) )
. addPath ( new BezierCurve ( new Pose ( - RADIUS + 72 , RADIUS + 72 ) , new Pose ( - RADIUS + 72 , 72 ) , new Pose ( 72 , 72 ) ) )
. setHeadingInterpolation ( HeadingInterpolator . facingPoint ( 0 , RADIUS ) )
. setHeadingInterpolation ( HeadingInterpolator . facingPoint ( 72 , RADIUS + 72 ) )
. build ( ) ;
. build ( ) ;
follower . followPath ( circle ) ;
follower . followPath ( circle ) ;
}
}
@@ -1161,7 +1406,9 @@ class Circle extends OpMode {
}
}
@Override
@Override
public void init ( ) { }
public void init ( ) {
follower . setStartingPose ( new Pose ( 72 , 72 ) ) ;
}
/ * *
/ * *
* This runs the OpMode , updating the Follower as well as printing out the debug statements to
* This runs the OpMode , updating the Follower as well as printing out the debug statements to
@@ -1178,6 +1425,230 @@ class Circle extends OpMode {
}
}
}
}
/ * *
* Tuning OpMode to get the min and max encoder values for swerve pods
* @author Kabir Goyal
* /
class AnalogMinMaxTuner extends OpMode {
/ / populate the below with your names for the servos and encoders
public String [ ] encoderNames = { " leftFrontEncoder " , " rightFrontEncoder " , " leftBackEncoder " , " rightBackEncoder " } ;
public AnalogInput [ ] encoders = new AnalogInput [ encoderNames . length ] ;
public double [ ] minVoltages = new double [ encoderNames . length ] ;
public double [ ] maxVoltages = new double [ encoderNames . length ] ;
public List < LynxModule > lynxModules ; / / js to improve loop times a bit yk
public void start ( ) {
}
@Override
public void init_loop ( ) {
telemetryM . debug ( " Press START. Then, Spin each pod slowly for 4 to 5 full rotations. \ n " +
" The OpMode will keep track of the min and max voltages seen so far and print them to telemetry. " ) ;
telemetryM . update ( telemetry ) ;
}
@Override
public void init ( ) {
lynxModules = hardwareMap . getAll ( LynxModule . class ) ;
for ( LynxModule hub : lynxModules ) {
hub . setBulkCachingMode ( LynxModule . BulkCachingMode . MANUAL ) ;
}
for ( int i = 0 ; i < encoders . length ; i + + ) {
encoders [ i ] = hardwareMap . get ( AnalogInput . class , encoderNames [ i ] ) ;
minVoltages [ i ] = 5 ; / / bigger value than should ever be read
}
}
/ * *
* This runs the OpMode , updating the Follower as well as printing out the debug statements to
* the Telemetry , as well as the FTC Dashboard .
* /
@Override
public void loop ( ) {
for ( LynxModule hub : lynxModules ) {
hub . clearBulkCache ( ) ;
}
telemetryM . debug ( " Spin each pod slowly for 4 to 5 full rotations. \ n " +
" The OpMode will keep track of the min and max voltages seen so far and print them to telemetry. \ n \ n " ) ;
for ( int i = 0 ; i < encoders . length ; i + + ) {
double currentVoltage = encoders [ i ] . getVoltage ( ) ;
minVoltages [ i ] = Math . min ( minVoltages [ i ] , currentVoltage ) ;
maxVoltages [ i ] = Math . max ( maxVoltages [ i ] , currentVoltage ) ;
telemetryM . addData ( encoderNames [ i ] + " min value: " , minVoltages [ i ] ) ;
telemetryM . addData ( encoderNames [ i ] + " max value: " , maxVoltages [ i ] ) ;
telemetryM . addLine ( " " ) ;
}
telemetryM . update ( ) ;
}
}
/ * *
* This is the SwerveOffsetsTest
* You should use this to check how good your swerve angle offsets are and if your motor directions are correct
* @author Kabir Goyal
*
* /
class SwerveOffsetsTest extends OpMode {
boolean debugStringEnabled = false ;
@Override
public void init ( ) { }
/** This initializes the PoseUpdater, the drive motors, and the Panels telemetry. */
@Override
public void init_loop ( ) {
if ( gamepad1 . aWasPressed ( ) | | gamepad2 . aWasPressed ( ) ) {
debugStringEnabled = ! debugStringEnabled ;
}
telemetryM . debug ( " This OpMode will run all four swerve pods in the direction they think is forward "
+ " \ nensure your bot is not on the ground while running " ) ;
telemetryM . debug ( " Drivetrain debug string " + ( ( ( debugStringEnabled ) ? " enabled " : " disabled " ) ) +
" (press gamepad a to toggle) " ) ;
telemetryM . update ( telemetry ) ;
follower . update ( ) ;
drawCurrent ( ) ;
}
@Override
public void start ( ) {
follower . startTeleopDrive ( ) ;
follower . update ( ) ;
}
/ * *
* This updates the robot ' s pose estimate , the simple drive , and updates the
* Panels telemetry with the robot ' s position as well as draws the robot ' s position .
* /
@Override
public void loop ( ) {
if ( gamepad1 . aWasPressed ( ) | | gamepad2 . aWasPressed ( ) ) {
debugStringEnabled = ! debugStringEnabled ;
}
follower . setTeleOpDrive ( 0 . 25 , 0 , 0 , true ) ;
follower . update ( ) ;
if ( debugStringEnabled ) {
telemetryM . debug ( " Drivetrain Debug String: \ n " +
follower . getDrivetrain ( ) . debugString ( ) ) ;
}
telemetryM . update ( telemetry ) ;
drawCurrentAndHistory ( ) ;
}
}
/ * *
* This is the SwerveTurnTest
* You should use this to check your encoder directions and x / y pod offsets
* @author Kabir Goyal
*
* /
class SwerveTurnTest extends OpMode {
boolean debugStringEnabled = false ;
@Override
public void init ( ) { }
/** This initializes the PoseUpdater, the drive motors, and the Panels telemetry. */
@Override
public void init_loop ( ) {
if ( gamepad1 . aWasPressed ( ) | | gamepad2 . aWasPressed ( ) ) {
debugStringEnabled = ! debugStringEnabled ;
}
telemetryM . debug ( " This OpMode will run all four swerve pods in their turning direction (perpendicular to the center of the robot) "
+ " \ nrun this once off the ground to check servo directions and motor directions before testing on the ground " ) ;
telemetryM . debug ( " Drivetrain debug string " + ( ( ( debugStringEnabled ) ? " enabled " : " disabled " ) ) +
" (press gamepad a to toggle) " ) ;
telemetryM . update ( telemetry ) ;
follower . update ( ) ;
drawCurrent ( ) ;
}
@Override
public void start ( ) {
follower . startTeleopDrive ( ) ;
follower . update ( ) ;
}
/ * *
* This updates the robot ' s pose estimate , the simple drive , and updates the
* Panels telemetry with the robot ' s position as well as draws the robot ' s position .
* /
@Override
public void loop ( ) {
if ( gamepad1 . aWasPressed ( ) | | gamepad2 . aWasPressed ( ) ) {
debugStringEnabled = ! debugStringEnabled ;
}
follower . setTeleOpDrive ( 0 , 0 , 0 . 25 , true ) ;
follower . update ( ) ;
if ( debugStringEnabled ) {
telemetryM . debug ( " Drivetrain Debug String: \ n " +
follower . getDrivetrain ( ) . debugString ( ) ) ;
}
telemetryM . update ( telemetry ) ;
drawCurrentAndHistory ( ) ;
}
}
/ * *
* This is the OffsetsTuner OpMode . This tracks the movement of the robot as it turns 180 degrees ,
* and calculates what the robot ' s strafeX and forwardY offsets should be . Ensure that your strafeX and forwardY offsets
* are set to 0 before running this OpMode . After running , input the displayed offsets into your localizer constants .
*
* @author Havish Sripada - 12808 RevAmped Robotics
* @author Baron Henderson
* /
class OffsetsTuner extends OpMode {
@Override
public void init ( ) {
follower . setStartingPose ( new Pose ( 72 , 72 ) ) ;
follower . update ( ) ;
drawCurrent ( ) ;
}
/** This initializes the PoseUpdater as well as the Panels telemetry. */
@Override
public void init_loop ( ) {
telemetryM . debug ( " Prerequisite: Make sure both your offsets are set to 0 in your localizer constants. " ) ;
telemetryM . debug ( " Turn your robot " + Math . PI + " radians. Your offsets in inches will be shown on the telemetry. " ) ;
telemetryM . update ( telemetry ) ;
drawCurrent ( ) ;
}
/ * *
* This updates the robot ' s pose estimate , and updates the Panels telemetry with the
* calculated offsets and draws the robot .
* /
@Override
public void loop ( ) {
follower . update ( ) ;
telemetryM . debug ( " Total Angle: " + follower . getTotalHeading ( ) ) ;
telemetryM . debug ( " The following values are the offsets in inches that should be applied to your localizer. " ) ;
telemetryM . debug ( " strafeX: " + ( ( 72 . 0 - follower . getPose ( ) . getX ( ) ) / 2 . 0 ) ) ;
telemetryM . debug ( " forwardY: " + ( ( 72 . 0 - follower . getPose ( ) . getY ( ) ) / 2 . 0 ) ) ;
telemetryM . update ( telemetry ) ;
drawCurrentAndHistory ( ) ;
}
}
/ * *
/ * *
* This is the Drawing class . It handles the drawing of stuff on Panels Dashboard , like the robot .
* This is the Drawing class . It handles the drawing of stuff on Panels Dashboard , like the robot .
*
*
@@ -1189,10 +1660,10 @@ class Drawing {
private static final FieldManager panelsField = PanelsField . INSTANCE . getField ( ) ;
private static final FieldManager panelsField = PanelsField . INSTANCE . getField ( ) ;
private static final Style robotLook = new Style (
private static final Style robotLook = new Style (
" " , " #3F51B5 " , 0 . 0
" " , " #3F51B5 " , 0 . 75
) ;
) ;
private static final Style historyLook = new Style (
private static final Style historyLook = new Style (
" " , " #4CAF50 " , 0 . 0
" " , " #4CAF50 " , 0 . 75
) ;
) ;
/ * *
/ * *