56 Commits

Author SHA1 Message Date
855dac7122 teleop tweaks 2026-06-07 23:48:26 -05:00
4cd890cef8 gate cycle auto good 2026-06-07 23:24:35 -05:00
9d03e1125a a lot of stuff happened 2026-06-07 21:19:00 -05:00
104058bbce copied changes from Mr. Kruger's commit 2026-06-07 15:06:54 -05:00
a9b57fd792 new autos 2026-06-06 23:15:26 -05:00
b09ba449b1 new autos 2026-06-06 23:14:06 -05:00
49a9e380d7 small changes 2026-06-06 21:52:04 -05:00
12cabd40db gate auto 2026-06-06 20:56:04 -05:00
351cff99ec oops 2026-06-06 20:53:40 -05:00
47ef898127 a lot of changes 2026-06-06 19:35:13 -05:00
d1626b20da fixed issues 2026-06-06 13:12:05 -05:00
e065084964 tele pose transfer 2026-06-05 18:51:54 -05:00
c36cac12f2 sorting auto is done 2026-06-05 18:25:12 -05:00
f7a9f6aaf5 small tweaks: added current pose telemetry and reduced coasting from limelight track 2026-06-05 14:29:21 -05:00
cc38b98d6f small tweaks: added loop times measurement 2026-06-05 14:19:39 -05:00
755d74a829 small tweaks: added loop times measurement and simplified SortedSpindexerTest 2026-06-05 14:18:47 -05:00
9d29e0b56c tweaks were made and hardware changes are needed 2026-06-04 22:13:49 -05:00
e25b372eca added limelight 2026-06-04 20:57:19 -05:00
3ab905af0c added limelight 2026-06-04 20:38:53 -05:00
58c11f5241 removed bunch of things to remove dash cluter 2026-06-04 20:38:45 -05:00
3afab333ef added delay based on ticks 2026-06-04 19:51:57 -05:00
9b92a59a75 Sorting beta workish 2026-06-04 18:47:23 -05:00
cca86f3691 Added transfer stuff 2026-06-04 18:13:14 -05:00
8c2a655c5c Merge remote-tracking branch 'origin/cowtown-work' into add-sorted-spindexer
# Conflicts:
#	TeamCode/src/main/java/org/firstinspires/ftc/teamcode/utilsv2/SpindexerTransferIntake.java
2026-06-04 18:12:04 -05:00
9a4aca90ba Added sorted modes and shoot 2026-06-04 18:10:31 -05:00
a3479d8816 hello iwnvvtw 2026-06-04 18:08:18 -05:00
e9b9ffc3b8 added transfer power manual command 2026-06-04 17:40:49 -05:00
e7056812b4 shooting is ok but NOT PERFECT 2026-06-04 17:29:14 -05:00
c15b9d58d4 teleop almost there 2026-06-04 16:06:27 -05:00
deefa19be4 added regression 2026-06-04 15:18:08 -05:00
3ae976c16d Merge remote-tracking branch 'origin/add-tilt' into cowtown-work 2026-06-03 15:51:51 -05:00
05f59d1820 Yay 2026-06-03 15:51:03 -05:00
128826f4fd Added tilt thing 2026-06-03 15:26:48 -05:00
a89535830b Lots o changes basically works ig 2026-06-03 15:05:29 -05:00
209c34b3fd Merge remote-tracking branch 'origin/danielv5' into update-teleop
# Conflicts:
#	TeamCode/src/main/java/org/firstinspires/ftc/teamcode/tests/NewShooterTest.java
#	TeamCode/src/main/java/org/firstinspires/ftc/teamcode/utilsv2/Shooter.java
2026-06-03 14:12:26 -05:00
d8cf594828 Fix some intrinsic bugs, refactor constructor in shooter 2026-06-03 14:08:49 -05:00
e658ec044c fixed issue - two flywheel instances created a conflict 2026-06-03 10:20:13 -05:00
12e5fba938 fixed issue - two flywheel instances created a conflict 2026-06-03 10:18:13 -05:00
47c505742a fixes to flywheel in order to operate more globally 2026-06-03 10:03:34 -05:00
c8e9be1c08 Merge remote-tracking branch 'origin/danielv5' into danielv5 2026-06-03 00:22:11 -05:00
28451ce26d auto coded 2026-06-03 00:21:51 -05:00
9c3b4c2010 Add beam break sensors to Hardware_Tester 2026-06-03 00:04:20 -05:00
7665957c7a readjusted shooter test
@KeshavAnandCode please merge
2026-06-02 19:14:58 -05:00
ccc6a608fc Merge branch 'update-teleop' into danielv5 2026-06-02 18:28:00 -05:00
8eba32de94 new auto in progress 2026-06-02 18:22:41 -05:00
5c9ebf6eac some changes 2026-06-02 18:22:28 -05:00
a540d333f1 shoooooottteeer test 2026-06-02 18:12:32 -05:00
180e7629bf Added spindexer to teleopv4 2026-06-02 17:18:04 -05:00
ae25df0393 Fixed spidnexer i think 2026-06-02 17:08:26 -05:00
946deca751 middle of tuning 2026-06-02 17:04:45 -05:00
75b9b7b6b1 middle of tuning 2026-06-02 17:04:28 -05:00
1a1c99791d Made Robot Singleton 2026-06-02 16:31:33 -05:00
88cf03a230 Merge remote-tracking branch 'origin/danielv5' into update-teleop 2026-06-02 15:59:18 -05:00
82c8ebf941 umiddle of tuning 2026-06-02 15:58:49 -05:00
aabc746a2e Stash update 2026-06-02 15:57:31 -05:00
f14dc3681a setup robot confg 2026-06-02 15:41:01 -05:00
38 changed files with 3450 additions and 284 deletions

View File

@@ -22,28 +22,26 @@ import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import org.firstinspires.ftc.teamcode.constants.Color; import org.firstinspires.ftc.teamcode.constants.Color;
import org.firstinspires.ftc.teamcode.pedroPathing.Constants; import org.firstinspires.ftc.teamcode.pedroPathing.Constants;
import org.firstinspires.ftc.teamcode.utils.Flywheel; import org.firstinspires.ftc.teamcode.utilsv2.Flywheel;
import org.firstinspires.ftc.teamcode.utils.MeasuringLoopTimes; import org.firstinspires.ftc.teamcode.utils.MeasuringLoopTimes;
import org.firstinspires.ftc.teamcode.utils.Robot; import org.firstinspires.ftc.teamcode.utilsv2.Robot;
import org.firstinspires.ftc.teamcode.utils.Servos; import org.firstinspires.ftc.teamcode.utils.Servos;
import org.firstinspires.ftc.teamcode.utils.Spindexer; import org.firstinspires.ftc.teamcode.utils.Spindexer;
import org.firstinspires.ftc.teamcode.utils.Targeting; import org.firstinspires.ftc.teamcode.utils.Targeting;
import org.firstinspires.ftc.teamcode.utils.Turret; import org.firstinspires.ftc.teamcode.utilsv2.Turret;
import java.util.List; import java.util.List;
@Config
@Autonomous (preselectTeleOp = "TeleopV3")
public class Auto12BallPedroPathing extends LinearOpMode { public class Auto12BallPedroPathing extends LinearOpMode {
Robot robot; Robot robot;
MultipleTelemetry TELE; MultipleTelemetry TELE;
Flywheel flywheel; // Flywheel flywheel;
Targeting targeting; // Targeting targeting;
Targeting.Settings targetingSettings; // Targeting.Settings targetingSettings;
Follower follower; Follower follower;
Turret turret; // Turret turret;
Spindexer spindexer; // Spindexer spindexer;
Servos servos; // Servos servos;
MeasuringLoopTimes loopTimes; MeasuringLoopTimes loopTimes;
// Wait Times // Wait Times
@@ -222,10 +220,10 @@ public class Auto12BallPedroPathing extends LinearOpMode {
driveShoot(PathState.WAIT_SHOOT3, currentTime); driveShoot(PathState.WAIT_SHOOT3, currentTime);
break; break;
case WAIT_SHOOT3: case WAIT_SHOOT3:
if (spindexer.shootAllComplete()){ // if (spindexer.shootAllComplete()){
spindexer.resetSpindexer(); // spindexer.resetSpindexer();
TELE.addLine("Done Auto"); // TELE.addLine("Done Auto");
} // }
break; break;
default: default:
break; break;
@@ -237,21 +235,21 @@ public class Auto12BallPedroPathing extends LinearOpMode {
private void intakePowerDown(double stamp, double currentTime) { private void intakePowerDown(double stamp, double currentTime) {
double pow = (stamp - currentTime) / 2; // adjust denominator to see how much time to adjust double pow = (stamp - currentTime) / 2; // adjust denominator to see how much time to adjust
if (pow < -1) {pow = 0;} if (pow < -1) {pow = 0;}
spindexer.setIntakePower(pow); // spindexer.setIntakePower(pow);
} }
private void driveShoot(PathState nextState, double currentTime){ private void driveShoot(PathState nextState, double currentTime){
if (!follower.isBusy()){ if (!follower.isBusy()){
pathState = nextState; pathState = nextState;
timeStamp = currentTime; timeStamp = currentTime;
spindexer.prepareShootAllContinous(); // spindexer.prepareShootAllContinous();
} }
} }
private void waitShoot(PathState nextState, PathChain nextPath, double currentTime) { private void waitShoot(PathState nextState, PathChain nextPath, double currentTime) {
if (spindexer.shootAllComplete() || currentTime - timeStamp > shootTime) { if (currentTime - timeStamp > shootTime) { // spindexer.shootAllComplete() ||
spindexer.resetSpindexer(); // spindexer.resetSpindexer();
pathState = nextState; pathState = nextState;
follower.followPath(nextPath, true); follower.followPath(nextPath, true);
spindexer.setIntakePower(1); // spindexer.setIntakePower(1);
} }
} }
private void drivePickup(PathState nextState, PathChain nextPath) { private void drivePickup(PathState nextState, PathChain nextPath) {
@@ -286,24 +284,25 @@ public class Auto12BallPedroPathing extends LinearOpMode {
@Override @Override
public void runOpMode() throws InterruptedException { public void runOpMode() throws InterruptedException {
robot = new Robot(hardwareMap); Robot.resetInstance();
robot = Robot.getInstance(hardwareMap);
List<LynxModule> allHubs = hardwareMap.getAll(LynxModule.class); List<LynxModule> allHubs = hardwareMap.getAll(LynxModule.class);
for (LynxModule hub : allHubs) { for (LynxModule hub : allHubs) {
hub.setBulkCachingMode(LynxModule.BulkCachingMode.MANUAL); hub.setBulkCachingMode(LynxModule.BulkCachingMode.MANUAL);
} }
TELE = new MultipleTelemetry(telemetry, FtcDashboard.getInstance().getTelemetry()); TELE = new MultipleTelemetry(telemetry, FtcDashboard.getInstance().getTelemetry());
flywheel = new Flywheel(hardwareMap); // flywheel = new Flywheel(hardwareMap);
targeting = new Targeting(); // targeting = new Targeting();
targetingSettings = new Targeting.Settings(0,0); // targetingSettings = new Targeting.Settings(0,0);
follower = Constants.createFollower(hardwareMap); follower = Constants.createFollower(hardwareMap);
follower.setStartingPose(new Pose(72,72,0)); follower.setStartingPose(new Pose(72,72,0));
turret = new Turret(robot, TELE, robot.limelight); // turret = new Turret(robot, TELE, robot.limelight);
spindexer = new Spindexer(hardwareMap); // spindexer = new Spindexer(hardwareMap);
servos = new Servos(hardwareMap); // servos = new Servos(hardwareMap);
loopTimes = new MeasuringLoopTimes(); loopTimes = new MeasuringLoopTimes();
loopTimes.init(); loopTimes.init();
robot.light.setPosition(Color.LightRed); // robot.light.setPosition(Color.LightRed);
boolean initializeRobot = false; boolean initializeRobot = false;
while (opModeInInit()){ while (opModeInInit()){
@@ -311,11 +310,11 @@ public class Auto12BallPedroPathing extends LinearOpMode {
if (gamepad1.crossWasPressed() && !initializeRobot){ if (gamepad1.crossWasPressed() && !initializeRobot){
Color.redAlliance = !Color.redAlliance; Color.redAlliance = !Color.redAlliance;
if (Color.redAlliance){ // if (Color.redAlliance){
robot.light.setPosition(Color.LightRed); // robot.light.setPosition(Color.LightRed);
} else { // } else {
robot.light.setPosition(Color.LightBlue); // robot.light.setPosition(Color.LightBlue);
} // }
double[] xPoses = {startPoseX, shoot0X, double[] xPoses = {startPoseX, shoot0X,
drivePickup1X, pickup1X, shoot1X, drivePickup1X, pickup1X, shoot1X,
@@ -336,10 +335,12 @@ public class Auto12BallPedroPathing extends LinearOpMode {
initializePoses(); initializePoses();
follower.setPose(startPose); follower.setPose(startPose);
buildPaths(); buildPaths();
// turret.switchPipeline(Turret.PipelineMode.OBELISK);
robot.limelight.start();
sleep(2000); sleep(2000);
turret.setTurret(turrDefault); // turret.setTurret(turrDefault);
servos.setSpinPos(spinStartPos); // servos.setSpinPos(spinStartPos);
} }
TELE.addData("Red Alliance?", Color.redAlliance); TELE.addData("Red Alliance?", Color.redAlliance);
@@ -352,27 +353,27 @@ public class Auto12BallPedroPathing extends LinearOpMode {
if (isStopRequested()) return; if (isStopRequested()) return;
robot.transfer.setPower(1); // robot.transfer.setPower(1);
limelightUsed = false; limelightUsed = false;
while (opModeIsActive()){ while (opModeIsActive()){
follower.update(); follower.update();
pathStateMachine(); pathStateMachine();
Pose currentPose = follower.getPose(); Pose currentPose = follower.getPose();
teleStartPoseX = currentPose.getX(); // teleStartPoseX = currentPose.getX();
teleStartPoseY = currentPose.getY(); // teleStartPoseY = currentPose.getY();
teleStartPoseH = Math.toDegrees(currentPose.getHeading()); // teleStartPoseH = Math.toDegrees(currentPose.getHeading());
//
turret.trackGoal(new Pose(shootX, shootY, Math.toRadians(shootH))); // turret.trackGoal(new Pose(shootX, shootY, Math.toRadians(shootH)));
targetingSettings = targeting.calculateSettings(shootX, shootY, Math.toRadians(shootH), 0, turretInterpolate); // targetingSettings = targeting.calculateSettings(shootX, shootY, Math.toRadians(shootH), 0, turretInterpolate);
//
double voltage = robot.voltage.getVoltage(); // double voltage = robot.voltage.getVoltage();
flywheel.setPIDF(Robot.shooterPIDF_P, Robot.shooterPIDF_I, Robot.shooterPIDF_D, Robot.shooterPIDF_F / voltage); // flywheel.setPIDF(Robot.shooterPIDF_P, Robot.shooterPIDF_I, Robot.shooterPIDF_D, Robot.shooterPIDF_F / voltage);
flywheel.manageFlywheel(targetingSettings.flywheelRPM); // flywheel.manageFlywheel(targetingSettings.flywheelRPM);
servos.setHoodPos(targetingSettings.hoodAngle); // servos.setHoodPos(targetingSettings.hoodAngle);
//
if (driveToShoot()){servos.setSpinPos(spinStartPos);} // if (driveToShoot()){servos.setSpinPos(spinStartPos);}
else {spindexer.processIntake();} // else {spindexer.processIntake();}
for (LynxModule hub : allHubs) { for (LynxModule hub : allHubs) {
hub.clearBulkCache(); hub.clearBulkCache();

View File

@@ -0,0 +1,421 @@
package org.firstinspires.ftc.teamcode.autonomous;
import static org.firstinspires.ftc.teamcode.utils.Turret.limelightUsed;
import com.acmerobotics.dashboard.FtcDashboard;
import com.acmerobotics.dashboard.config.Config;
import com.acmerobotics.dashboard.telemetry.MultipleTelemetry;
import com.pedropathing.follower.Follower;
import com.pedropathing.geometry.BezierCurve;
import com.pedropathing.geometry.BezierLine;
import com.pedropathing.geometry.Pose;
import com.pedropathing.paths.PathChain;
import com.qualcomm.hardware.lynx.LynxModule;
import com.qualcomm.robotcore.eventloop.opmode.Autonomous;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import org.firstinspires.ftc.teamcode.constants.Color;
import org.firstinspires.ftc.teamcode.constants.ServoPositions;
import org.firstinspires.ftc.teamcode.pedroPathing.Constants;
import org.firstinspires.ftc.teamcode.teleop.TeleopV4;
import org.firstinspires.ftc.teamcode.utilsv2.*;
import org.firstinspires.ftc.teamcode.utils.MeasuringLoopTimes;
import java.util.List;
@Config
@Autonomous (preselectTeleOp = "TeleopV4")
public class Auto12Ball_Back_Sorted extends LinearOpMode {
Robot robot;
MultipleTelemetry TELE;
Follower follower;
MeasuringLoopTimes loopTimes;
Shooter shooter;
Turret turret;
Flywheel flywheel;
VelocityCommander commander;
SpindexerTransferIntake spindexer;
// Wait Times
public static double sortedShootTime = 2.6;
public static double rapidWaitTime = 0.5;
public static double rapidShootTime = 0.8;
public static double openGateTime = 2.5;
public static double pushTime = 2;
// Extra Variables
public static double intakePower = 0.5;
double shootX, shootY, shootH;
// Initialize path state machine
private enum PathState {
PUSHBOT, DRIVE_SHOOT0, WAIT_SHOOT0,
PICKUP1, OPENGATE, DRIVE_SHOOT1, WAIT_SHOOT1,
DRIVE_PICKUP2, PICKUP2, DRIVE_SHOOT2, WAIT_SHOOT2,
DRIVE_PICKUP3, PICKUP3, DRIVE_SHOOT3, WAIT_SHOOT3
}
PathState pathState = PathState.PUSHBOT;
// Poses
public static double startPoseX = 12, startPoseY = -64, startPoseH = 90;
public static double pushBotX = 19, pushBotY = -63, pushBotH = 100;
public static double shoot0ControlX = 16.29667812142038, shoot0ControlY = -19.67493699885454;
public static double shoot0X = 19, shoot0Y = 10, shoot0H = 0;
public static double pickup1X = 54, pickup1Y = 10, pickup1H = 0;
public static double openGateControlX = 37.184421534937, openGateControlY = 2.24455899198165;
public static double openGateX = 59, openGateY = 2, openGateH = 0;
public static double shoot1ControlX = 40, shoot1ControlY = 3;
public static double shoot1X = 19, shoot1Y = 10, shoot1H = 0;
public static double drivePickup2X = 26, drivePickup2Y = -14, drivePickup2H = 0;
public static double pickup2X = 61, pickup2Y = -14.5, pickup2H = 0;
public static double shoot2ControlX = 30, shoot2ControlY = -9;
public static double shoot2X = 19, shoot2Y = 10, shoot2H = 0;
public static double drivePickup3X = 26, drivePickup3Y = -37.5, drivePickup3H = 0;
public static double pickup3X = 61, pickup3Y = -37.5, pickup3H = 0;
public static double shoot3ControlX = 25.62371134020621, shoot3ControlY = -38.813287514318446;
public static double shoot3X = 12, shoot3Y = 40, shoot3H = -90;
double[] xPoses = {startPoseX, pushBotX, shoot0ControlX, shoot0X,
pickup1X, openGateControlX, openGateX, shoot1ControlX, shoot1X,
drivePickup2X, pickup2X, shoot2ControlX, shoot2X,
drivePickup3X, pickup3X, shoot3ControlX, shoot3X};
double[] yPoses = {startPoseY, pushBotY, shoot0ControlY, shoot0Y,
pickup1Y, openGateControlY, openGateY, shoot1ControlY, shoot1Y,
drivePickup2Y, pickup2Y, shoot2ControlY, shoot2Y,
drivePickup3Y, pickup3Y, shoot3ControlY, shoot3Y};
double[] headings = {startPoseH, pushBotH, 0, shoot0H,
pickup1H, 0, openGateH, 0, shoot1H,
drivePickup2H, pickup2H, 0, shoot2H,
drivePickup3H, pickup3H, 0, shoot3H};
Pose startPose, pushBot, shoot0Control, shoot0,
pickup1, openGateControl, openGate, shoot1Control, shoot1,
drivePickup2, pickup2, shoot2Control, shoot2,
drivePickup3, pickup3, shoot3Control, shoot3;
private void initializePoses(){
startPose = new Pose(xPoses[0], yPoses[0], Math.toRadians(headings[0]));
pushBot = new Pose(xPoses[1], yPoses[1], Math.toRadians(headings[1]));
shoot0Control = new Pose(xPoses[2], yPoses[2]);
shoot0 = new Pose(xPoses[3], yPoses[3], Math.toRadians(headings[3]));
pickup1 = new Pose(xPoses[4], yPoses[4], Math.toRadians(headings[4]));
openGateControl = new Pose(xPoses[5], yPoses[5]);
openGate = new Pose(xPoses[6], yPoses[6], Math.toRadians(headings[6]));
shoot1Control = new Pose(xPoses[7], yPoses[7]);
shoot1 = new Pose(xPoses[8], yPoses[8], Math.toRadians(headings[8]));
drivePickup2 = new Pose(xPoses[9], yPoses[9], Math.toRadians(headings[9]));
pickup2 = new Pose(xPoses[10], yPoses[10], Math.toRadians(headings[10]));
shoot2Control = new Pose(xPoses[11], yPoses[11]);
shoot2 = new Pose(xPoses[12], yPoses[12], Math.toRadians(headings[12]));
drivePickup3 = new Pose(xPoses[13], yPoses[13], Math.toRadians(headings[13]));
pickup3 = new Pose(xPoses[14], yPoses[14], Math.toRadians(headings[14]));
shoot3Control = new Pose(xPoses[15], yPoses[15]);
shoot3 = new Pose(xPoses[16], yPoses[16], Math.toRadians(headings[16]));
}
//Building Paths
PathChain startPose_pushBot, pushBot_shoot0,
shoot0_pickup1, pickup1_openGate, openGate_shoot1,
shoot1_drivePickup2, drivePickup2_pickup2, pickup2_shoot2,
shoot2_drivePickup3, drivePickup3_pickup3, pickup3_shoot3;
private void buildPaths(){
startPose_pushBot = follower.pathBuilder()
.addPath(new BezierLine(startPose, pushBot))
.setLinearHeadingInterpolation(startPose.getHeading(), pushBot.getHeading())
.build();
pushBot_shoot0 = follower.pathBuilder()
.addPath(new BezierCurve(pushBot, shoot0Control, shoot0))
.setLinearHeadingInterpolation(pushBot.getHeading(), shoot0.getHeading())
.build();
shoot0_pickup1 = follower.pathBuilder()
.addPath(new BezierLine(shoot0, pickup1))
.setLinearHeadingInterpolation(shoot0.getHeading(), pickup1.getHeading())
.build();
pickup1_openGate = follower.pathBuilder()
.addPath(new BezierCurve(pickup1, openGateControl, openGate))
.setLinearHeadingInterpolation(pickup1.getHeading(), openGate.getHeading())
.build();
openGate_shoot1 = follower.pathBuilder()
.addPath(new BezierCurve(openGate, shoot1Control, shoot1))
.setLinearHeadingInterpolation(openGate.getHeading(), shoot1.getHeading())
.build();
shoot1_drivePickup2 = follower.pathBuilder()
.addPath(new BezierLine(shoot1, drivePickup2))
.setLinearHeadingInterpolation(shoot1.getHeading(), drivePickup2.getHeading())
.build();
drivePickup2_pickup2 = follower.pathBuilder()
.addPath(new BezierLine(drivePickup2, pickup2))
.setLinearHeadingInterpolation(drivePickup2.getHeading(), pickup2.getHeading())
.build();
pickup2_shoot2 = follower.pathBuilder()
.addPath(new BezierCurve(pickup2, shoot2Control, shoot2))
.setLinearHeadingInterpolation(pickup2.getHeading(), shoot2.getHeading())
.build();
shoot2_drivePickup3 = follower.pathBuilder()
.addPath(new BezierLine(shoot2, drivePickup3))
.setLinearHeadingInterpolation(shoot2.getHeading(), drivePickup3.getHeading())
.build();
drivePickup3_pickup3 = follower.pathBuilder()
.addPath(new BezierLine(drivePickup3, pickup3))
.setLinearHeadingInterpolation(drivePickup3.getHeading(), pickup3.getHeading())
.build();
pickup3_shoot3 = follower.pathBuilder()
.addPath(new BezierCurve(pickup3, shoot3Control, shoot3))
.setLinearHeadingInterpolation(pickup3.getHeading(), shoot3.getHeading())
.build();
}
//Path State Machine
private boolean startAuto = true;
private double timeStamp = 0;
private void pathStateMachine(){
double currentTime = (double) System.currentTimeMillis() / 1000;
switch(pathState){
case PUSHBOT:
spindexer.setSpindexerMode(SpindexerTransferIntake.SpindexerMode.RAPID);
shooter.setFlywheelVelocity(2400);
robot.setHoodPos(0.64);
if (startAuto){
follower.followPath(startPose_pushBot, false);
startAuto = false;
timeStamp = currentTime;
shootX = shoot0X;
shootY = shoot0Y;
shootH = shoot0H;
}
if (!follower.isBusy() || currentTime - timeStamp > pushTime){
follower.followPath(pushBot_shoot0, true);
pathState = PathState.DRIVE_SHOOT0;
}
break;
case DRIVE_SHOOT0:
if (!follower.isBusy() && currentTime - timeStamp > rapidWaitTime){
timeStamp = currentTime;
pathState = PathState.WAIT_SHOOT0;
spindexer.setRapidMode(SpindexerTransferIntake.RapidMode.OPEN_GATE);
} else if (follower.isBusy()){
timeStamp = currentTime;
}
break;
case WAIT_SHOOT0:
if (currentTime - timeStamp > rapidShootTime ||
(spindexer.getRapidState() != SpindexerTransferIntake.RapidMode.OPEN_GATE &&
spindexer.getRapidState() != SpindexerTransferIntake.RapidMode.SHOOT)){
follower.followPath(shoot0_pickup1, intakePower, false);
pathState = PathState.PICKUP1;
spindexer.setSpindexerMode(SpindexerTransferIntake.SpindexerMode.SORTED);
}
break;
case PICKUP1:
if (!follower.isBusy()){
follower.followPath(pickup1_openGate, false);
pathState = PathState.OPENGATE;
shootX = shoot1X;
shootY = shoot1Y;
shootH = shoot1H;
timeStamp = currentTime;
shooter.setFlywheelVelocity(2300);
robot.setHoodPos(0.68);
}
break;
case OPENGATE:
if (currentTime - timeStamp > openGateTime){
follower.followPath(openGate_shoot1, true);
pathState = PathState.DRIVE_SHOOT1;
}
break;
case DRIVE_SHOOT1:
if (!follower.isBusy()){
pathState = PathState.WAIT_SHOOT1;
timeStamp = currentTime;
spindexer.startSortedShoot();
}
break;
case WAIT_SHOOT1:
if (currentTime - timeStamp > sortedShootTime){
follower.followPath(shoot1_drivePickup2, true);
pathState = PathState.DRIVE_PICKUP2;
}
break;
case DRIVE_PICKUP2:
if (!follower.isBusy()) {
follower.followPath(drivePickup2_pickup2, intakePower, false);
pathState = PathState.PICKUP2;
}
break;
case PICKUP2:
if (!follower.isBusy()){
follower.followPath(pickup2_shoot2, true);
pathState = PathState.DRIVE_SHOOT2;
}
shootX = shoot2X;
shootY = shoot2Y;
shootH = shoot2H;
break;
case DRIVE_SHOOT2:
if (!follower.isBusy()){
pathState = PathState.WAIT_SHOOT2;
timeStamp = currentTime;
spindexer.startSortedShoot();
}
break;
case WAIT_SHOOT2:
if (currentTime - timeStamp > sortedShootTime){
follower.followPath(shoot2_drivePickup3, true);
pathState = PathState.DRIVE_PICKUP3;
}
break;
case DRIVE_PICKUP3:
if (!follower.isBusy()){
shooter.setFlywheelVelocity(2200);
robot.setHoodPos(0.75);
follower.followPath(drivePickup3_pickup3, intakePower, false);
pathState = PathState.PICKUP3;
}
break;
case PICKUP3:
if (!follower.isBusy()){
follower.followPath(pickup3_shoot3, true);
pathState = PathState.DRIVE_SHOOT3;
}
shootX = shoot3X;
shootY = shoot3Y;
shootH = shoot3H;
break;
case DRIVE_SHOOT3:
if (!follower.isBusy()){
pathState = PathState.WAIT_SHOOT3;
spindexer.startSortedShoot();
}
break;
case WAIT_SHOOT3:
// add line here to say "done auto"
break;
default:
break;
}
TELE.update(); // use for debugging
}
// Used for changing alliance
private double adjustXPoseBasedOnAlliance(double pose) {return -pose;}
private double adjustHeadingBasedOnAlliance(double heading){
heading = 180 - heading;
while (heading > 180) {heading-=360;}
while (heading <= -180) {heading+=360;}
return heading;
}
@Override
public void runOpMode() throws InterruptedException {
Robot.resetInstance();
robot = Robot.getInstance(hardwareMap);
List<LynxModule> allHubs = hardwareMap.getAll(LynxModule.class);
for (LynxModule hub : allHubs) {
hub.setBulkCachingMode(LynxModule.BulkCachingMode.MANUAL);
}
TELE = new MultipleTelemetry(telemetry, FtcDashboard.getInstance().getTelemetry());
follower = Constants.createFollower(hardwareMap);
sleep(1000);
follower.setStartingPose(new Pose(0,0,0));
loopTimes = new MeasuringLoopTimes();
loopTimes.init();
turret = new Turret(robot);
flywheel = new Flywheel(robot);
commander = new VelocityCommander();
shooter = new Shooter(robot, TELE, follower, Color.redAlliance, turret, flywheel, commander);
spindexer = new SpindexerTransferIntake(robot, TELE, commander);
ParkTilter park = new ParkTilter(robot);
boolean initializeRobot = false;
while (opModeInInit()){
follower.update();
if (gamepad1.squareWasPressed()){
robot.setSpinPos(ServoPositions.spindexer_A2);
robot.setRapidFireBlockerPos(ServoPositions.rapidFireBlocker_Closed);
robot.setSpindexBlockerPos(ServoPositions.spindexBlocker_Open);
}
if (gamepad1.crossWasPressed() && !initializeRobot){
Color.redAlliance = !Color.redAlliance;
shooter.setRedAlliance(Color.redAlliance);
}
if (!initializeRobot){
if ((Color.redAlliance && xPoses[0] < 0)
|| (!Color.redAlliance && xPoses[0] > 0)){
for (int i = 0; i < xPoses.length; i++) {xPoses[i] = adjustXPoseBasedOnAlliance(xPoses[i]);}
for (int i = 0; i < headings.length; i++) {headings[i] = adjustHeadingBasedOnAlliance(headings[i]);}
}
}
if (gamepad1.triangleWasPressed()){
initializeRobot = true;
initializePoses();
follower.setPose(startPose);
buildPaths();
sleep(2000);
turret.switchPipeline(Turret.PipelineMode.OBELISK);
robot.limelight.start();
limelightUsed = true;
park.unpark();
}
if (initializeRobot){
//add obelisk read here
shooter.setState(Shooter.ShooterState.READ_OBELISK);
int ID = turret.getObeliskID();
spindexer.setDesiredPatternAuto(ID);
TELE.addData("ID", ID);
shooter.update(robot.voltage.getVoltage());
}
TELE.addData("Red Alliance?", Color.redAlliance);
TELE.addData("Initialized Robot? (Don't change this until alliance is selected)", initializeRobot);
TELE.addData("Start Pose", follower.getPose());
TELE.addData("Current LL Pipeline", turret.pipeline());
TELE.update();
}
waitForStart();
if (isStopRequested()) return;
while (opModeIsActive()){
robot.setRapidFireBlockerPos(ServoPositions.rapidFireBlocker_Closed);
park.unpark();
shooter.setState(Shooter.ShooterState.MANUAL_FLYWHEEL_TRACK_TURR);
shooter.update(robot.voltage.getVoltage());
if (!isStopRequested()){
follower.update();
}
pathStateMachine();
TeleopV4.teleStart = follower.getPose();
spindexer.update();
for (LynxModule hub : allHubs) {
hub.clearBulkCache();
}
loopTimes.loop();
TELE.addData("Avg Loop Time", loopTimes.getAvgLoopTime());
TELE.addData("Min Loop Time", loopTimes.getMinLoopTimeOneMin());
TELE.addData("Max Loop Time", loopTimes.getMaxLoopTimeOneMin());
TELE.addData("X:", TeleopV4.teleStart.getX());
TELE.addData("Y:", TeleopV4.teleStart.getY());
TELE.addData("H:", TeleopV4.teleStart.getHeading());
TELE.update();
}
}
}

View File

@@ -0,0 +1,361 @@
package org.firstinspires.ftc.teamcode.autonomous;
import static org.firstinspires.ftc.teamcode.utils.Turret.limelightUsed;
import com.acmerobotics.dashboard.FtcDashboard;
import com.acmerobotics.dashboard.config.Config;
import com.acmerobotics.dashboard.telemetry.MultipleTelemetry;
import com.pedropathing.follower.Follower;
import com.pedropathing.geometry.BezierCurve;
import com.pedropathing.geometry.BezierLine;
import com.pedropathing.geometry.Pose;
import com.pedropathing.paths.PathChain;
import com.qualcomm.hardware.lynx.LynxModule;
import com.qualcomm.robotcore.eventloop.opmode.Autonomous;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import org.firstinspires.ftc.teamcode.constants.Color;
import org.firstinspires.ftc.teamcode.constants.ServoPositions;
import org.firstinspires.ftc.teamcode.pedroPathing.Constants;
import org.firstinspires.ftc.teamcode.teleop.TeleopV4;
import org.firstinspires.ftc.teamcode.utilsv2.*;
import org.firstinspires.ftc.teamcode.utils.MeasuringLoopTimes;
import java.util.List;
@Config
@Autonomous (preselectTeleOp = "TeleopV4")
public class Auto15Ball_Back extends LinearOpMode {
Robot robot;
MultipleTelemetry TELE;
Follower follower;
MeasuringLoopTimes loopTimes;
Shooter shooter;
Turret turret;
Flywheel flywheel;
VelocityCommander commander;
SpindexerTransferIntake spindexer;
// Wait Times
public static double rapidWaitTime = 0.5;
public static double rapidShootTime = 0.8;
public static double loadPickupTime = 3;
// Initialize path state machine
private enum PathState {
WAIT_VELOCITY, WAIT_SHOOT0,
PICKUP3, DRIVE_SHOOT3, WAIT_SHOOT3,
PICKUP_LOAD, DRIVE_SHOOT_LOAD, WAIT_SHOOT_LOAD,
INTAKE_GATE, DRIVE_SHOOT_GATE, WAIT_SHOOT_GATE, LEAVE
}
PathState pathState = PathState.WAIT_VELOCITY;
// Poses
public static double startPoseX = 12, startPoseY = -64, startPoseH = 90;
public static double pickup3ControlX = 12, pickup3ControlY = -37;
public static double pickup3X = 61, pickup3Y = -37, pickup3H = 0;
public static double shoot3X = 16, shoot3Y = -57, shoot3H = 0;
public static double pickupLoadControlX = 21.23654066437572, pickupLoadControlY = -62.311626575028637;
public static double pickupLoadX = 63, pickupLoadY = -63, pickupLoadH = 0;
public static double shootLoadControlX = 21.23654066437572, shootLoadControlY = -62.311626575028637;
public static double shootLoadX = 16, shootLoadY = -57, shootLoadH = 0;
public static double intakeGateControl1X = 51.9656357388316, intakeGateControl1Y = -65.506277205040073;
public static double intakeGateControl2X = 60.13459335624285, intakeGateControl2Y = -67.300458190148911;
public static double intakeGateX = 59, intakeGateY = -12, intakeGateH = 90;
public static double shootGateControlX = 53.8705612829324, shootGateControlY = -35.14501718213059;
public static double shootGateX = 16, shootGateY = -57, shootGateH = 0;
public static double leaveX = 40, leaveY = 14, leaveH = 0;
double[] xPoses = {startPoseX, pickup3ControlX, pickup3X, shoot3X,
pickupLoadControlX, pickupLoadX, shootLoadControlX, shootLoadX,
intakeGateControl1X, intakeGateControl2X, intakeGateX, shootGateControlX, shootGateX, leaveX};
double[] yPoses = {startPoseY, pickup3ControlY, pickup3Y, shoot3Y,
pickupLoadControlY, pickupLoadY, shootLoadControlY, shootLoadY,
intakeGateControl1Y, intakeGateControl2Y, intakeGateY, shootGateControlY, shootGateY, leaveY};
double[] headings = {startPoseH, 0, pickup3H, shoot3H,
0, pickupLoadH, 0, shootLoadH,
0, 0, intakeGateH, 0, shootGateH, leaveH};
Pose startPose, pickup3Control, pickup3, shoot3,
pickupLoadControl, pickupLoad, shootLoadControl, shootLoad,
intakeGateControl1, intakeGateControl2, intakeGate, shootGateControl, shootGate, leave;
private void initializePoses(){
startPose = new Pose(xPoses[0], yPoses[0], Math.toRadians(headings[0]));
pickup3Control = new Pose(xPoses[1], yPoses[1]);
pickup3 = new Pose(xPoses[2], yPoses[2], Math.toRadians(headings[2]));
shoot3 = new Pose(xPoses[3], yPoses[3], Math.toRadians(headings[3]));
pickupLoadControl = new Pose(xPoses[4], yPoses[4]);
pickupLoad = new Pose(xPoses[5], yPoses[5], Math.toRadians(headings[5]));
shootLoadControl = new Pose(xPoses[6], yPoses[6]);
shootLoad = new Pose(xPoses[7], yPoses[7], Math.toRadians(headings[7]));
intakeGateControl1 = new Pose(xPoses[8], yPoses[8]);
intakeGateControl2 = new Pose(xPoses[9], yPoses[9]);
intakeGate = new Pose(xPoses[10], yPoses[10], Math.toRadians(headings[10]));
shootGateControl = new Pose(xPoses[11], yPoses[11]);
shootGate = new Pose(xPoses[12], yPoses[12], Math.toRadians(headings[12]));
leave = new Pose(xPoses[13], yPoses[13], Math.toRadians(headings[13]));
}
//Building Paths
PathChain startPose_pickup3, pickup3_shoot3, shoot3_pickupLoad, pickupLoad_shootLoad,
shootLoad_intakeGate, intakeGate_shootGate, shootGate_intakeGate, shootGate_leave;
private void buildPaths(){
startPose_pickup3 = follower.pathBuilder()
.addPath(new BezierCurve(startPose, pickup3Control, pickup3))
.setTangentHeadingInterpolation()
.build();
pickup3_shoot3 = follower.pathBuilder()
.addPath(new BezierLine(pickup3, shoot3))
.setLinearHeadingInterpolation(pickup3.getHeading(), shoot3.getHeading())
.build();
shoot3_pickupLoad = follower.pathBuilder()
.addPath(new BezierCurve(shoot3, pickupLoadControl, pickupLoad))
.setLinearHeadingInterpolation(shoot3.getHeading(), pickupLoad.getHeading())
.build();
pickupLoad_shootLoad = follower.pathBuilder()
.addPath(new BezierCurve(pickupLoad, shootLoadControl, shootLoad))
.setLinearHeadingInterpolation(pickupLoad.getHeading(), shootLoad.getHeading())
.build();
shootLoad_intakeGate = follower.pathBuilder()
.addPath(new BezierCurve(shootLoad, intakeGateControl1, intakeGateControl2, intakeGate))
.setTangentHeadingInterpolation()
.build();
intakeGate_shootGate = follower.pathBuilder()
.addPath(new BezierCurve(intakeGate, shootGateControl, shootGate))
.setLinearHeadingInterpolation(intakeGate.getHeading(), shootGate.getHeading())
.build();
shootGate_intakeGate = follower.pathBuilder()
.addPath(new BezierCurve(shootGate, intakeGateControl1, intakeGateControl2, intakeGate))
.setTangentHeadingInterpolation()
.build();
shootGate_leave = follower.pathBuilder()
.addPath(new BezierLine(shootGate, leave))
.setLinearHeadingInterpolation(shootGate.getHeading(), leave.getHeading())
.build();
}
//Path State Machine
private int startAuto = 0;
private double timeStamp = 0;
private void pathStateMachine(){
double currentTime = (double) System.currentTimeMillis() / 1000;
switch(pathState){
case WAIT_VELOCITY:
spindexer.setSpindexerMode(SpindexerTransferIntake.SpindexerMode.RAPID);
shooter.setFlywheelVelocity(2400);
robot.setHoodPos(0.64);
if (flywheel.getSteady()){
startAuto++;
}
if (startAuto > 5){
spindexer.setRapidMode(SpindexerTransferIntake.RapidMode.OPEN_GATE);
timeStamp = currentTime;
pathState = PathState.WAIT_SHOOT0;
}
break;
case WAIT_SHOOT0:
if (currentTime - timeStamp > rapidShootTime ||
(spindexer.getRapidState() != SpindexerTransferIntake.RapidMode.OPEN_GATE &&
spindexer.getRapidState() != SpindexerTransferIntake.RapidMode.SHOOT)){
follower.followPath(startPose_pickup3, false);
pathState = PathState.PICKUP3;
}
break;
case PICKUP3:
if (!follower.isBusy()){
follower.followPath(pickup3_shoot3, false);
pathState = PathState.DRIVE_SHOOT3;
timeStamp = currentTime;
}
break;
case DRIVE_SHOOT3:
if (!follower.isBusy() && currentTime - timeStamp > rapidWaitTime){
timeStamp = currentTime;
pathState = PathState.WAIT_SHOOT3;
spindexer.setRapidMode(SpindexerTransferIntake.RapidMode.OPEN_GATE);
} else if (follower.isBusy()){
timeStamp = currentTime;
}
break;
case WAIT_SHOOT3:
if (currentTime - timeStamp > rapidShootTime ||
(spindexer.getRapidState() != SpindexerTransferIntake.RapidMode.OPEN_GATE &&
spindexer.getRapidState() != SpindexerTransferIntake.RapidMode.SHOOT)){
follower.followPath(shoot3_pickupLoad, false);
pathState = PathState.PICKUP_LOAD;
timeStamp = currentTime;
}
break;
case PICKUP_LOAD:
if (currentTime - timeStamp > loadPickupTime){
follower.followPath(pickupLoad_shootLoad, false);
pathState = PathState.DRIVE_SHOOT_LOAD;
timeStamp = currentTime;
}
break;
case DRIVE_SHOOT_LOAD:
if (!follower.isBusy() && currentTime - timeStamp > rapidWaitTime){
timeStamp = currentTime;
pathState = PathState.WAIT_SHOOT_LOAD;
spindexer.setRapidMode(SpindexerTransferIntake.RapidMode.OPEN_GATE);
} else if (follower.isBusy()){
timeStamp = currentTime;
}
break;
case WAIT_SHOOT_LOAD:
if (currentTime - timeStamp > rapidShootTime ||
(spindexer.getRapidState() != SpindexerTransferIntake.RapidMode.OPEN_GATE &&
spindexer.getRapidState() != SpindexerTransferIntake.RapidMode.SHOOT)){
follower.followPath(shootLoad_intakeGate, false);
pathState = PathState.INTAKE_GATE;
timeStamp = currentTime;
}
break;
case INTAKE_GATE:
if (!follower.isBusy()){
follower.followPath(intakeGate_shootGate, false);
pathState = PathState.DRIVE_SHOOT_GATE;
timeStamp = currentTime;
}
break;
case DRIVE_SHOOT_GATE:
if (!follower.isBusy() && currentTime - timeStamp > rapidWaitTime){
timeStamp = currentTime;
pathState = PathState.WAIT_SHOOT_GATE;
spindexer.setRapidMode(SpindexerTransferIntake.RapidMode.OPEN_GATE);
} else if (follower.isBusy()){
timeStamp = currentTime;
}
break;
case WAIT_SHOOT_GATE:
if (currentTime - timeStamp > rapidShootTime ||
(spindexer.getRapidState() != SpindexerTransferIntake.RapidMode.OPEN_GATE &&
spindexer.getRapidState() != SpindexerTransferIntake.RapidMode.SHOOT)){
follower.followPath(shootGate_intakeGate, false);
pathState = PathState.INTAKE_GATE;
timeStamp = currentTime;
// TODO: add logic for leave
}
break;
case LEAVE:
// add line here to say "done auto"
break;
default:
break;
}
TELE.update(); // use for debugging
}
// Used for changing alliance
private double adjustXPoseBasedOnAlliance(double pose) {return -pose;}
private double adjustHeadingBasedOnAlliance(double heading){
heading = 180 - heading;
while (heading > 180) {heading-=360;}
while (heading <= -180) {heading+=360;}
return heading;
}
@Override
public void runOpMode() throws InterruptedException {
Robot.resetInstance();
robot = Robot.getInstance(hardwareMap);
List<LynxModule> allHubs = hardwareMap.getAll(LynxModule.class);
for (LynxModule hub : allHubs) {
hub.setBulkCachingMode(LynxModule.BulkCachingMode.MANUAL);
}
TELE = new MultipleTelemetry(telemetry, FtcDashboard.getInstance().getTelemetry());
follower = Constants.createFollower(hardwareMap);
sleep(1000);
follower.setStartingPose(new Pose(0,0,0));
loopTimes = new MeasuringLoopTimes();
loopTimes.init();
turret = new Turret(robot);
flywheel = new Flywheel(robot);
commander = new VelocityCommander();
shooter = new Shooter(robot, TELE, follower, Color.redAlliance, turret, flywheel, commander);
spindexer = new SpindexerTransferIntake(robot, TELE, commander);
ParkTilter park = new ParkTilter(robot);
boolean initializeRobot = false;
while (opModeInInit()){
park.unpark();
robot.setSpindexBlockerPos(ServoPositions.spindexBlocker_Open);
follower.update();
if (gamepad1.squareWasPressed()){
robot.setSpinPos(ServoPositions.spindexer_A2);
robot.setRapidFireBlockerPos(ServoPositions.rapidFireBlocker_Closed);
robot.setSpindexBlockerPos(ServoPositions.spindexBlocker_Open);
}
if (gamepad1.crossWasPressed() && !initializeRobot){
Color.redAlliance = !Color.redAlliance;
shooter.setRedAlliance(Color.redAlliance);
}
if (!initializeRobot){
if ((Color.redAlliance && xPoses[0] < 0)
|| (!Color.redAlliance && xPoses[0] > 0)){
for (int i = 0; i < xPoses.length; i++) {xPoses[i] = adjustXPoseBasedOnAlliance(xPoses[i]);}
for (int i = 0; i < headings.length; i++) {headings[i] = adjustHeadingBasedOnAlliance(headings[i]);}
}
}
if (gamepad1.triangleWasPressed()){
initializeRobot = true;
initializePoses();
follower.setPose(startPose);
buildPaths();
sleep(2000);
turret.switchPipeline(Turret.PipelineMode.TRACKING);
robot.limelight.start();
limelightUsed = true;
park.unpark();
}
TELE.addData("Red Alliance?", Color.redAlliance);
TELE.addData("Initialized Robot? (Don't change this until alliance is selected)", initializeRobot);
TELE.addData("Start Pose", follower.getPose());
TELE.addData("Current LL Pipeline", turret.pipeline());
TELE.update();
}
waitForStart();
if (isStopRequested()) return;
while (opModeIsActive()){
shooter.setState(Shooter.ShooterState.MANUAL_FLYWHEEL_TRACK_TURR);
shooter.update(robot.voltage.getVoltage());
if (!isStopRequested()){
follower.update();
}
pathStateMachine();
TeleopV4.teleStart = follower.getPose();
spindexer.update();
for (LynxModule hub : allHubs) {
hub.clearBulkCache();
}
loopTimes.loop();
TELE.addData("Avg Loop Time", loopTimes.getAvgLoopTime());
TELE.addData("Min Loop Time", loopTimes.getMinLoopTimeOneMin());
TELE.addData("Max Loop Time", loopTimes.getMaxLoopTimeOneMin());
TELE.addData("X:", TeleopV4.teleStart.getX());
TELE.addData("Y:", TeleopV4.teleStart.getY());
TELE.addData("H:", TeleopV4.teleStart.getHeading());
TELE.update();
}
}
}

View File

@@ -0,0 +1,462 @@
package org.firstinspires.ftc.teamcode.autonomous;
import static org.firstinspires.ftc.teamcode.utils.Turret.limelightUsed;
import com.acmerobotics.dashboard.FtcDashboard;
import com.acmerobotics.dashboard.config.Config;
import com.acmerobotics.dashboard.telemetry.MultipleTelemetry;
import com.pedropathing.follower.Follower;
import com.pedropathing.geometry.BezierCurve;
import com.pedropathing.geometry.BezierLine;
import com.pedropathing.geometry.Pose;
import com.pedropathing.paths.PathChain;
import com.qualcomm.hardware.lynx.LynxModule;
import com.qualcomm.robotcore.eventloop.opmode.Autonomous;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import org.firstinspires.ftc.teamcode.constants.Color;
import org.firstinspires.ftc.teamcode.constants.ServoPositions;
import org.firstinspires.ftc.teamcode.pedroPathing.Constants;
import org.firstinspires.ftc.teamcode.teleop.TeleopV4;
import org.firstinspires.ftc.teamcode.utilsv2.*;
import org.firstinspires.ftc.teamcode.utils.MeasuringLoopTimes;
import java.util.List;
@Config
@Autonomous (preselectTeleOp = "TeleopV4")
public class Auto21Ball_Front_Gate extends LinearOpMode {
Robot robot;
MultipleTelemetry TELE;
Follower follower;
MeasuringLoopTimes loopTimes;
Shooter shooter;
Turret turret;
Flywheel flywheel;
VelocityCommander commander;
SpindexerTransferIntake spindexer;
double runtime = 0;
// Wait Times
public static double rapidWaitTime = 0.4;
public static double rapidShootTime = 0.45;
public static double openGate1Time = 1.5;
public static double openGate2Time = 1.5;
public static double openGateWaitTimeMax = 3;
public static double openGateWaitTimeMin = 1.75;
public static int maxLoopCycles = 3;
// Initialize path state machine
private enum PathState {
DRIVE_SHOOT0, WAIT_SHOOT0,
PICKUP1, OPENGATE1, DRIVE_SHOOT1, WAIT_SHOOT1,
PICKUP2, OPENGATE2, DRIVE_SHOOT2, WAIT_SHOOT2,
INTAKE_GATE, DRIVE_SHOOT_GATE, WAIT_SHOOT_GATE, DRIVE_SHOOT_LEAVE, WAIT_SHOOT_LEAVE
}
PathState pathState = PathState.DRIVE_SHOOT0;
// Poses
public static double startPoseX = 55, startPoseY = 39, startPoseH = 0;
public static double shoot0X = 25, shoot0Y = 18, shoot0H = 0;
public static double pickup1ControlX = 29.53321878579611, pickup1ControlY = 9.84077892325314;
public static double pickup1X = 50, pickup1Y = 10, pickup1H = 0;
public static double openGate1ControlX = 43.82989690721648, openGate1ControlY = 3.86540664375714;
public static double openGate1X = 59, openGate1Y = 2, openGate1H = 0;
public static double shoot1ControlX = 40, shoot1ControlY = 3;
public static double shoot1X = 25, shoot1Y = 11, shoot1H = -30;
public static double pickup2ControlX = 18, pickup2ControlY = -18;
public static double pickup2X = 61, pickup2Y = -14.5, pickup2H = 0;
public static double openGate2ControlX = 45.9782359679267, openGate2ControlY = -15.106643757159245;
public static double openGate2X = 57, openGate2Y = -8, openGate2H = 0;
public static double shoot2ControlX = 57, shoot2ControlY = -8;
public static double shoot2X = 25, shoot2Y = 11, shoot2H = -30;
public static double intakeGateControlX = 61, intakeGateControlY = -11;
public static double intakeGateX = 61, intakeGateY = -11, intakeGateH = 20;
public static double shootGateControlX = 56, shootGateControlY = -10;
public static double shootGateX = 25, shootGateY = 11, shootGateH = -30;
public static double shootLeaveControlX = 56, shootLeaveControlY = -10;
public static double shootLeaveX = 16, shootLeaveY = 36, shootLeaveH = -50;
public static double leaveX = 45, leaveY = 10, leaveH = 0;
public static double awayFromGateX = 40, awayFromGateY = -12, awayFromGateH = 0;
double[] xPoses = {startPoseX, shoot0X,
pickup1ControlX, pickup1X, openGate1ControlX, openGate1X, shoot1ControlX, shoot1X,
pickup2ControlX, pickup2X, openGate2ControlX, openGate2X, shoot2ControlX, shoot2X,
intakeGateControlX, intakeGateX, shootGateControlX, shootGateX,
shootLeaveControlX, shootLeaveX, leaveX, awayFromGateX};
double[] yPoses = {startPoseY, shoot0Y,
pickup1ControlY, pickup1Y, openGate1ControlY, openGate1Y, shoot1ControlY, shoot1Y,
pickup2ControlY, pickup2Y, openGate2ControlY, openGate2Y, shoot2ControlY, shoot2Y,
intakeGateControlY, intakeGateY, shootGateControlY, shootGateY,
shootLeaveControlY, shootLeaveY, leaveY, awayFromGateY};
double[] headings = {startPoseH, shoot0H,
0, pickup1H, 0, openGate1H, 0, shoot1H,
0, pickup2H, 0, openGate2H, 0, shoot2H,
0, intakeGateH, 0, shootGateH,
0, shootLeaveH, leaveH, awayFromGateH};
Pose startPose, shoot0,
pickup1Control, pickup1, openGate1Control, openGate1, shoot1Control, shoot1,
pickup2Control, pickup2, openGate2Control, openGate2, shoot2Control, shoot2,
intakeGateControl, intakeGate, shootGateControl, shootGate,
shootLeaveControl, shootLeave, leave, awayFromGate;
private void initializePoses(){
startPose = new Pose(xPoses[0], yPoses[0], Math.toRadians(headings[0]));
shoot0 = new Pose(xPoses[1], yPoses[1], Math.toRadians(headings[1]));
pickup1Control = new Pose(xPoses[2], yPoses[2]);
pickup1 = new Pose(xPoses[3], yPoses[3], Math.toRadians(headings[3]));
openGate1Control = new Pose(xPoses[4], yPoses[4]);
openGate1 = new Pose(xPoses[5], yPoses[5], Math.toRadians(headings[5]));
shoot1Control = new Pose(xPoses[6], yPoses[6]);
shoot1 = new Pose(xPoses[7], yPoses[7], Math.toRadians(headings[7]));
pickup2Control = new Pose(xPoses[8], yPoses[8]);
pickup2 = new Pose(xPoses[9], yPoses[9], Math.toRadians(headings[9]));
openGate2Control = new Pose(xPoses[10], yPoses[10]);
openGate2 = new Pose(xPoses[11], yPoses[11], Math.toRadians(headings[11]));
shoot2Control = new Pose(xPoses[12], yPoses[12]);
shoot2 = new Pose(xPoses[13], yPoses[13], Math.toRadians(headings[13]));
intakeGateControl = new Pose(xPoses[14], yPoses[14]);
intakeGate = new Pose(xPoses[15], yPoses[15], Math.toRadians(headings[15]));
shootGateControl = new Pose(xPoses[16], yPoses[16]);
shootGate = new Pose(xPoses[17], yPoses[17], Math.toRadians(headings[17]));
shootLeaveControl = new Pose(xPoses[18], yPoses[18]);
shootLeave = new Pose(xPoses[19], yPoses[19], Math.toRadians(headings[19]));
leave = new Pose(xPoses[20], yPoses[20], Math.toRadians(headings[20]));
awayFromGate = new Pose(xPoses[21], yPoses[21], Math.toRadians(headings[21]));
}
//Building Paths
PathChain startPose_shoot0, shoot0_pickup1, pickup1_openGate1, openGate1_shoot1,
shoot1_pickup2, pickup2_openGate2, openGate2_shoot2,
shoot2_intakeGate, intakeGate_shootGate, shootGate_intakeGate, intakeGate_shootLeave, shootGate_leave, intakeGate_awayFromGate;
private void buildPaths(){
startPose_shoot0 = follower.pathBuilder()
.addPath(new BezierLine(startPose, shoot0))
.setLinearHeadingInterpolation(startPose.getHeading(), shoot0.getHeading())
.build();
shoot0_pickup1 = follower.pathBuilder()
.addPath(new BezierCurve(shoot0, pickup1Control, pickup1))
.setLinearHeadingInterpolation(shoot0.getHeading(), pickup1.getHeading())
.build();
pickup1_openGate1 = follower.pathBuilder()
.addPath(new BezierCurve(pickup1, openGate1Control, openGate1))
.setLinearHeadingInterpolation(pickup1.getHeading(), openGate1.getHeading())
.build();
openGate1_shoot1 = follower.pathBuilder()
.addPath(new BezierCurve(openGate1, shoot1Control, shoot1))
.setLinearHeadingInterpolation(openGate1.getHeading(), shoot1.getHeading())
.build();
shoot1_pickup2 = follower.pathBuilder()
.addPath(new BezierCurve(shoot1, pickup2Control, pickup2))
.setLinearHeadingInterpolation(shoot1.getHeading(), pickup2.getHeading())
.build();
pickup2_openGate2 = follower.pathBuilder()
.addPath(new BezierCurve(pickup2, openGate2Control, openGate2))
.setLinearHeadingInterpolation(pickup2.getHeading(), openGate2.getHeading())
.build();
openGate2_shoot2 = follower.pathBuilder()
.addPath(new BezierCurve(openGate2, shoot2Control, shoot2))
.setLinearHeadingInterpolation(openGate2.getHeading(), shoot2.getHeading())
.build();
shoot2_intakeGate = follower.pathBuilder()
.addPath(new BezierCurve(shoot2, intakeGateControl, intakeGate))
.setLinearHeadingInterpolation(shoot2.getHeading(), intakeGate.getHeading())
.build();
intakeGate_shootGate = follower.pathBuilder()
.addPath(new BezierCurve(intakeGate, shootGateControl, shootGate))
.setLinearHeadingInterpolation(intakeGate.getHeading(), shootGate.getHeading())
.build();
shootGate_intakeGate = follower.pathBuilder()
.addPath(new BezierCurve(shootGate, intakeGateControl, intakeGate))
.setLinearHeadingInterpolation(shootGate.getHeading(), intakeGate.getHeading())
.build();
intakeGate_shootLeave = follower.pathBuilder()
.addPath(new BezierCurve(intakeGate, shootLeaveControl, shootLeave))
.setLinearHeadingInterpolation(intakeGate.getHeading(), shootLeave.getHeading())
.build();
shootGate_leave = follower.pathBuilder()
.addPath(new BezierLine(shootGate, leave))
.setLinearHeadingInterpolation(shootGate.getHeading(), leave.getHeading())
.build();
intakeGate_awayFromGate = follower.pathBuilder()
.addPath(new BezierLine(intakeGate, awayFromGate))
.setLinearHeadingInterpolation(intakeGate.getHeading(), awayFromGate.getHeading())
.build();
}
//Path State Machine
private boolean startAuto = true;
private double timeStamp = 0;
private int cycle = 0;
private void pathStateMachine(){
double currentTime = (double) System.currentTimeMillis() / 1000;
switch(pathState){
case DRIVE_SHOOT0:
spindexer.setSpindexerMode(SpindexerTransferIntake.SpindexerMode.RAPID);
shooter.setFlywheelVelocity(2300);
robot.setHoodPos(0.68);
if (startAuto){
follower.followPath(startPose_shoot0, false);
startAuto = false;
}
if (!follower.isBusy() && currentTime - timeStamp > rapidWaitTime){
timeStamp = currentTime;
pathState = PathState.WAIT_SHOOT0;
spindexer.setRapidMode(SpindexerTransferIntake.RapidMode.OPEN_GATE);
} else if (follower.isBusy()){
timeStamp = currentTime;
}
break;
case WAIT_SHOOT0:
if (currentTime - timeStamp > rapidShootTime ||
(spindexer.getRapidState() != SpindexerTransferIntake.RapidMode.OPEN_GATE &&
spindexer.getRapidState() != SpindexerTransferIntake.RapidMode.SHOOT)){
follower.followPath(shoot0_pickup1, false);
pathState = PathState.PICKUP1;
}
break;
case PICKUP1:
if (!follower.isBusy()){
follower.followPath(pickup1_openGate1, false);
pathState = PathState.OPENGATE1;
timeStamp = currentTime;
}
break;
case OPENGATE1:
if (currentTime - timeStamp > openGate1Time){
follower.followPath(openGate1_shoot1, false);
pathState = PathState.DRIVE_SHOOT1;
timeStamp = currentTime;
}
break;
case DRIVE_SHOOT1:
if (!follower.isBusy() && currentTime - timeStamp > rapidWaitTime){
timeStamp = currentTime;
pathState = PathState.WAIT_SHOOT1;
spindexer.setRapidMode(SpindexerTransferIntake.RapidMode.OPEN_GATE);
} else if (follower.isBusy()){
timeStamp = currentTime;
}
break;
case WAIT_SHOOT1:
if (currentTime - timeStamp > rapidShootTime ||
(spindexer.getRapidState() != SpindexerTransferIntake.RapidMode.OPEN_GATE &&
spindexer.getRapidState() != SpindexerTransferIntake.RapidMode.SHOOT)){
follower.followPath(shoot1_pickup2, false);
pathState = PathState.PICKUP2;
}
break;
case PICKUP2:
if (!follower.isBusy()){
follower.followPath(pickup2_openGate2, false);
pathState = PathState.OPENGATE2;
timeStamp = currentTime;
}
break;
case OPENGATE2:
if (currentTime - timeStamp > openGate2Time){
follower.followPath(openGate2_shoot2, false);
pathState = PathState.DRIVE_SHOOT2;
timeStamp = currentTime;
}
break;
case DRIVE_SHOOT2:
if (!follower.isBusy() && currentTime - timeStamp > rapidWaitTime){
timeStamp = currentTime;
pathState = PathState.WAIT_SHOOT2;
spindexer.setRapidMode(SpindexerTransferIntake.RapidMode.OPEN_GATE);
} else if (follower.isBusy()){
timeStamp = currentTime;
}
break;
case WAIT_SHOOT2:
if (currentTime - timeStamp > rapidShootTime ||
(spindexer.getRapidState() != SpindexerTransferIntake.RapidMode.OPEN_GATE &&
spindexer.getRapidState() != SpindexerTransferIntake.RapidMode.SHOOT)){
follower.followPath(shoot2_intakeGate, false);
pathState = PathState.INTAKE_GATE;
timeStamp = currentTime;
}
break;
case INTAKE_GATE:
if ((currentTime - timeStamp > openGateWaitTimeMax || (robot.insideBeam.isPressed() && robot.outsideBeam.isPressed()))
&& (currentTime - timeStamp > openGateWaitTimeMin)){
if (getRuntime() - runtime > 27){
follower.followPath(intakeGate_awayFromGate, true);
pathState = PathState.WAIT_SHOOT_LEAVE;
} else if (getRuntime() - runtime > 22 || cycle >= maxLoopCycles - 1){
follower.followPath(intakeGate_shootLeave, true);
pathState = PathState.DRIVE_SHOOT_LEAVE;
} else {
follower.followPath(intakeGate_shootGate, false);
pathState = PathState.DRIVE_SHOOT_GATE;
}
timeStamp = currentTime;
}
// TODO: add logic to shoot gate
break;
case DRIVE_SHOOT_GATE:
if (!follower.isBusy() && currentTime - timeStamp > rapidWaitTime){
timeStamp = currentTime;
pathState = PathState.WAIT_SHOOT_GATE;
spindexer.setRapidMode(SpindexerTransferIntake.RapidMode.OPEN_GATE);
} else if (follower.isBusy()){
timeStamp = currentTime;
}
break;
case WAIT_SHOOT_GATE:
if (currentTime - timeStamp > rapidShootTime ||
(spindexer.getRapidState() != SpindexerTransferIntake.RapidMode.OPEN_GATE &&
spindexer.getRapidState() != SpindexerTransferIntake.RapidMode.SHOOT)){
cycle++;
if (getRuntime() - runtime > 24 || cycle >= maxLoopCycles){
follower.followPath(shootGate_leave, true);
pathState = PathState.WAIT_SHOOT_LEAVE;
} else {
follower.followPath(shootGate_intakeGate, false);
pathState = PathState.INTAKE_GATE;
}
timeStamp = currentTime;
}
break;
case DRIVE_SHOOT_LEAVE:
if (!follower.isBusy() && currentTime - timeStamp > rapidWaitTime){
timeStamp = currentTime;
pathState = PathState.WAIT_SHOOT_LEAVE;
spindexer.setRapidMode(SpindexerTransferIntake.RapidMode.OPEN_GATE);
} else if (follower.isBusy()){
timeStamp = currentTime;
}
break;
case WAIT_SHOOT_LEAVE:
// add line here to say "done auto"
break;
default:
break;
}
TELE.addData("Moving?", follower.isBusy());
}
// Used for changing alliance
private double adjustXPoseBasedOnAlliance(double pose) {return -pose;}
private double adjustHeadingBasedOnAlliance(double heading){
heading = 180 - heading;
while (heading > 180) {heading-=360;}
while (heading <= -180) {heading+=360;}
return heading;
}
@Override
public void runOpMode() throws InterruptedException {
Robot.resetInstance();
robot = Robot.getInstance(hardwareMap);
List<LynxModule> allHubs = hardwareMap.getAll(LynxModule.class);
for (LynxModule hub : allHubs) {
hub.setBulkCachingMode(LynxModule.BulkCachingMode.MANUAL);
}
TELE = new MultipleTelemetry(telemetry, FtcDashboard.getInstance().getTelemetry());
follower = Constants.createFollower(hardwareMap);
sleep(1000);
follower.setStartingPose(new Pose(0,0,0));
loopTimes = new MeasuringLoopTimes();
loopTimes.init();
turret = new Turret(robot);
flywheel = new Flywheel(robot);
commander = new VelocityCommander();
shooter = new Shooter(robot, TELE, follower, Color.redAlliance, turret, flywheel, commander);
spindexer = new SpindexerTransferIntake(robot, TELE, commander);
ParkTilter park = new ParkTilter(robot);
boolean startAuto = true;
boolean initializeRobot = false;
while (opModeInInit()){
follower.update();
if (gamepad1.squareWasPressed()){
robot.setSpinPos(ServoPositions.spindexer_A2);
robot.setRapidFireBlockerPos(ServoPositions.rapidFireBlocker_Closed);
robot.setSpindexBlockerPos(ServoPositions.spindexBlocker_Open);
}
if (gamepad1.crossWasPressed() && !initializeRobot){
Color.redAlliance = !Color.redAlliance;
shooter.setRedAlliance(Color.redAlliance);
}
if (!initializeRobot){
if ((Color.redAlliance && xPoses[0] < 0)
|| (!Color.redAlliance && xPoses[0] > 0)){
for (int i = 0; i < xPoses.length; i++) {xPoses[i] = adjustXPoseBasedOnAlliance(xPoses[i]);}
for (int i = 0; i < headings.length; i++) {headings[i] = adjustHeadingBasedOnAlliance(headings[i]);}
}
}
if (gamepad1.triangleWasPressed()){
initializeRobot = true;
initializePoses();
follower.setPose(startPose);
buildPaths();
sleep(2000);
turret.switchPipeline(Turret.PipelineMode.TRACKING);
robot.limelight.start();
limelightUsed = true;
park.unpark();
}
TELE.addData("Red Alliance?", Color.redAlliance);
TELE.addData("Initialized Robot? (Don't change this until alliance is selected)", initializeRobot);
TELE.addData("Start Pose", follower.getPose());
TELE.addData("Current LL Pipeline", turret.pipeline());
TELE.update();
}
waitForStart();
if (isStopRequested()) return;
while (opModeIsActive()){
if (startAuto){
runtime = getRuntime();
startAuto = false;
}
park.unpark();
robot.setSpindexBlockerPos(ServoPositions.spindexBlocker_Open);
shooter.setState(Shooter.ShooterState.MANUAL_FLYWHEEL_TRACK_TURR);
shooter.update(robot.voltage.getVoltage());
if (!isStopRequested()){
follower.update();
}
pathStateMachine();
TeleopV4.teleStart = follower.getPose();
spindexer.update();
for (LynxModule hub : allHubs) {
hub.clearBulkCache();
}
loopTimes.loop();
TELE.addData("Avg Loop Time", loopTimes.getAvgLoopTime());
TELE.addData("Min Loop Time", loopTimes.getMinLoopTimeOneMin());
TELE.addData("Max Loop Time", loopTimes.getMaxLoopTimeOneMin());
TELE.addData("X:", TeleopV4.teleStart.getX());
TELE.addData("Y:", TeleopV4.teleStart.getY());
TELE.addData("H:", TeleopV4.teleStart.getHeading());
TELE.update();
}
}
}

View File

@@ -51,8 +51,7 @@ import org.firstinspires.ftc.teamcode.utils.Spindexer;
import org.firstinspires.ftc.teamcode.utils.Targeting; import org.firstinspires.ftc.teamcode.utils.Targeting;
import org.firstinspires.ftc.teamcode.utils.Turret; import org.firstinspires.ftc.teamcode.utils.Turret;
@Config
@Autonomous(preselectTeleOp = "TeleopV3")
public class Auto_LT_Close extends LinearOpMode { public class Auto_LT_Close extends LinearOpMode {
public static double shoot0Vel = 2300, shoot0Hood = 0.93; public static double shoot0Vel = 2300, shoot0Hood = 0.93;
public static double velGate0Start = 2700, hoodGate0Start = 0.6; public static double velGate0Start = 2700, hoodGate0Start = 0.6;

View File

@@ -43,8 +43,7 @@ import org.firstinspires.ftc.teamcode.utils.Spindexer;
import org.firstinspires.ftc.teamcode.utils.Targeting; import org.firstinspires.ftc.teamcode.utils.Targeting;
import org.firstinspires.ftc.teamcode.utils.Turret; import org.firstinspires.ftc.teamcode.utils.Turret;
@Config
@Autonomous(preselectTeleOp = "TeleopV3")
public class Auto_LT_Far extends LinearOpMode { public class Auto_LT_Far extends LinearOpMode {
public static double shoot0Vel = 3300, shoot0Hood = 0.48; public static double shoot0Vel = 3300, shoot0Hood = 0.48;
double xLeave, yLeave, hLeave; double xLeave, yLeave, hLeave;

View File

@@ -37,7 +37,6 @@ import org.firstinspires.ftc.teamcode.utils.Turret;
import java.util.Objects; import java.util.Objects;
@Config
public class AutoActions { public class AutoActions {
Robot robot; Robot robot;
MultipleTelemetry TELE; MultipleTelemetry TELE;

View File

@@ -85,9 +85,7 @@ import org.firstinspires.ftc.teamcode.utils.Spindexer;
import org.firstinspires.ftc.teamcode.utils.Targeting; import org.firstinspires.ftc.teamcode.utils.Targeting;
import org.firstinspires.ftc.teamcode.utils.Turret; import org.firstinspires.ftc.teamcode.utils.Turret;
@Disabled
@Config
@Autonomous(preselectTeleOp = "TeleopV3")
public class Auto_LT_Close_12Ball extends LinearOpMode { public class Auto_LT_Close_12Ball extends LinearOpMode {
public static double shoot0Vel = 2300, shoot0Hood = 0.93; public static double shoot0Vel = 2300, shoot0Hood = 0.93;
public static double autoSpinStartPos = 0.2; public static double autoSpinStartPos = 0.2;

View File

@@ -93,9 +93,7 @@ import org.firstinspires.ftc.teamcode.utils.Turret;
import java.util.Objects; import java.util.Objects;
@Disabled
@Config
@Autonomous(preselectTeleOp = "TeleopV3")
public class Auto_LT_Close_GateOpen extends LinearOpMode { public class Auto_LT_Close_GateOpen extends LinearOpMode {
public static double shoot0Vel = 2300, shoot0Hood = 0.93; public static double shoot0Vel = 2300, shoot0Hood = 0.93;
public static double autoSpinStartPos = 0.2; public static double autoSpinStartPos = 0.2;

View File

@@ -82,9 +82,7 @@ import org.firstinspires.ftc.teamcode.utils.Robot;
import org.firstinspires.ftc.teamcode.utils.Servos; import org.firstinspires.ftc.teamcode.utils.Servos;
import java.util.List; import java.util.List;
@Disabled
@Config
@Autonomous(preselectTeleOp = "TeleopV3")
public class ProtoAutoClose_V3 extends LinearOpMode { public class ProtoAutoClose_V3 extends LinearOpMode {
public static double intake1Time = 2.7; public static double intake1Time = 2.7;
public static double intake2Time = 3.0; public static double intake2Time = 3.0;

View File

@@ -5,6 +5,19 @@ import com.acmerobotics.dashboard.config.Config;
@Config @Config
public class ServoPositions { public class ServoPositions {
public static double rapidFireBlocker_Closed = 0.32;
public static double rapidFireBlocker_Open = 0.5;
public static double spindexBlocker_Closed = 0.31;
public static double spindexBlocker_Open = 0.5;
public static double spindexer_A1 = 0.16;
public static double spindexer_A2 = 0.35;
public static double spindexer_A3 = 0.54;
public static double spindexer_B1 = 0.73;
public static double spindexer_B2 = 0.92;
public static double spindexer_intakePos1 = 0.18; //0.13; public static double spindexer_intakePos1 = 0.18; //0.13;
public static double spindexer_intakePos2 = 0.37; //0.33;//0.5; public static double spindexer_intakePos2 = 0.37; //0.33;//0.5;
@@ -21,13 +34,13 @@ public class ServoPositions {
public static double shootAllSpindexerSpeedIncrease = 0.01; public static double shootAllSpindexerSpeedIncrease = 0.01;
public static double transferServo_out = 0.15; public static double transferServo_out = 0.28;
public static double transferServo_in = 0.38; public static double transferServo_in = 0.54;
public static double hoodAuto = 0.27; public static double hoodAuto = 0.27;
public static double hoodOffset = -0.05; // offset from 0.93 (or position at 0,0 in targeting class) public static double hoodOffset = 0; // offset from 0.93 (or position at 0,0 in targeting class)
public static double turret_redClose = 0; public static double turret_redClose = 0;
public static double turret_blueClose = 0; public static double turret_blueClose = 0;
@@ -44,4 +57,10 @@ public class ServoPositions {
public static double redTurretShootPos = 0.05; public static double redTurretShootPos = 0.05;
public static double blueTurretShootPos = -0.05; public static double blueTurretShootPos = -0.05;
public static double tilt1_down = 0.6;
public static double tilt2_down = 0.4;
public static double tilt1_up = 0.08;
public static double tilt2_up = 0.97;
} }

View File

@@ -5,7 +5,7 @@ import com.pedropathing.control.FilteredPIDFCoefficients;
import com.pedropathing.control.PIDFCoefficients; import com.pedropathing.control.PIDFCoefficients;
import com.pedropathing.follower.Follower; import com.pedropathing.follower.Follower;
import com.pedropathing.follower.FollowerConstants; import com.pedropathing.follower.FollowerConstants;
import com.pedropathing.ftc.FollowerBuilder; import org.firstinspires.ftc.teamcode.pedroPathing.FollowerBuilder;
import com.pedropathing.ftc.drivetrains.MecanumConstants; import com.pedropathing.ftc.drivetrains.MecanumConstants;
import com.pedropathing.ftc.localization.constants.PinpointConstants; import com.pedropathing.ftc.localization.constants.PinpointConstants;
import com.pedropathing.paths.PathConstraints; import com.pedropathing.paths.PathConstraints;
@@ -17,12 +17,12 @@ import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit;
@Config @Config
public class Constants { public class Constants {
public static FollowerConstants followerConstants = new FollowerConstants() public static FollowerConstants followerConstants = new FollowerConstants()
.mass(15.5) .mass(14.37888)
.forwardZeroPowerAcceleration(-29.512) .forwardZeroPowerAcceleration(-30.322)
.lateralZeroPowerAcceleration(-72.872) .lateralZeroPowerAcceleration(-60.876)
.translationalPIDFCoefficients(new PIDFCoefficients(0.35, 0, 0.03, 0.012)) .translationalPIDFCoefficients(new PIDFCoefficients(0.15, 0, 0.015, 0.02))
.headingPIDFCoefficients(new PIDFCoefficients(1, 0, 0.025, 0.02)) .headingPIDFCoefficients(new PIDFCoefficients(1, 0, 0.02, 0.02))
.drivePIDFCoefficients(new FilteredPIDFCoefficients(0.03, 0, 0, 0.6, 0.03)) .drivePIDFCoefficients(new FilteredPIDFCoefficients(0.013, 0, 0.00001, 0.6, 0.015))
.centripetalScaling(0.0005); .centripetalScaling(0.0005);
public static MecanumConstants driveConstants = new MecanumConstants() public static MecanumConstants driveConstants = new MecanumConstants()
@@ -35,15 +35,15 @@ public class Constants {
.leftRearMotorDirection(DcMotorSimple.Direction.REVERSE) .leftRearMotorDirection(DcMotorSimple.Direction.REVERSE)
.rightFrontMotorDirection(DcMotorSimple.Direction.FORWARD) .rightFrontMotorDirection(DcMotorSimple.Direction.FORWARD)
.rightRearMotorDirection(DcMotorSimple.Direction.FORWARD) .rightRearMotorDirection(DcMotorSimple.Direction.FORWARD)
.xVelocity(64.675) .xVelocity(84.376)
.yVelocity(49.583); .yVelocity(64.052);
public static double breakingStrength = 1; public static double breakingStrength = 1;
public static PathConstraints pathConstraints = new PathConstraints(0.99, 100, breakingStrength, 1); public static PathConstraints pathConstraints = new PathConstraints(0.99, 100, breakingStrength, 1);
public static PinpointConstants localizerConstants = new PinpointConstants() public static PinpointConstants localizerConstants = new PinpointConstants()
.forwardPodY(-7.5) .forwardPodY(-3.7795)
.strafePodX(-3.75) .strafePodX(-3.769)
.distanceUnit(DistanceUnit.INCH) .distanceUnit(DistanceUnit.INCH)
.hardwareMapName("pinpoint") .hardwareMapName("pinpoint")
.encoderResolution(GoBildaPinpointDriver.GoBildaOdometryPods.goBILDA_4_BAR_POD) .encoderResolution(GoBildaPinpointDriver.GoBildaOdometryPods.goBILDA_4_BAR_POD)
@@ -51,10 +51,16 @@ public class Constants {
.strafeEncoderDirection(GoBildaPinpointDriver.EncoderDirection.FORWARD); .strafeEncoderDirection(GoBildaPinpointDriver.EncoderDirection.FORWARD);
public static Follower createFollower(HardwareMap hardwareMap) { public static Follower createFollower(HardwareMap hardwareMap) {
return new FollowerBuilder(followerConstants, hardwareMap) FollowerBuilder followerBuilder;
followerBuilder = new FollowerBuilder(followerConstants, hardwareMap)
.pathConstraints(pathConstraints) .pathConstraints(pathConstraints)
.mecanumDrivetrain(driveConstants) .mecanumDrivetrain(driveConstants)
.pinpointLocalizer(localizerConstants) .pinpointLocalizer(localizerConstants);
.build();
followerBuilder.resetPinpoint();
followerBuilder.recalibrateIMU();
return followerBuilder.build();
} }
} }

View File

@@ -0,0 +1,106 @@
package org.firstinspires.ftc.teamcode.pedroPathing;
import com.pedropathing.drivetrain.Drivetrain;
import com.pedropathing.follower.Follower;
import com.pedropathing.follower.FollowerConstants;
import com.pedropathing.ftc.drivetrains.*;
import com.pedropathing.ftc.localization.constants.DriveEncoderConstants;
import com.pedropathing.ftc.localization.constants.OTOSConstants;
import com.pedropathing.ftc.localization.constants.PinpointConstants;
import com.pedropathing.ftc.localization.constants.ThreeWheelConstants;
import com.pedropathing.ftc.localization.constants.ThreeWheelIMUConstants;
import com.pedropathing.ftc.localization.constants.TwoWheelConstants;
import com.pedropathing.ftc.localization.localizers.DriveEncoderLocalizer;
import com.pedropathing.ftc.localization.localizers.OTOSLocalizer;
import com.pedropathing.ftc.localization.localizers.PinpointLocalizer;
import com.pedropathing.ftc.localization.localizers.ThreeWheelIMULocalizer;
import com.pedropathing.ftc.localization.localizers.ThreeWheelLocalizer;
import com.pedropathing.ftc.localization.localizers.TwoWheelLocalizer;
import com.pedropathing.localization.Localizer;
import com.pedropathing.paths.PathConstraints;
import com.qualcomm.robotcore.hardware.HardwareMap;
/** This is the FollowerBuilder.
* It is used to create Followers with a specific drivetrain + localizer without having to use a full constructor
*
* @author Baron Henderson - 20077 The Indubitables
*/
public class FollowerBuilder {
private final FollowerConstants constants;
private PathConstraints constraints;
private final HardwareMap hardwareMap;
private Localizer localizer;
private Drivetrain drivetrain;
public FollowerBuilder(FollowerConstants constants, HardwareMap hardwareMap) {
this.constants = constants;
this.hardwareMap = hardwareMap;
constraints = PathConstraints.defaultConstraints;
}
public FollowerBuilder setLocalizer(Localizer localizer) {
this.localizer = localizer;
return this;
}
public FollowerBuilder driveEncoderLocalizer(DriveEncoderConstants lConstants) {
return setLocalizer(new DriveEncoderLocalizer(hardwareMap, lConstants));
}
public FollowerBuilder OTOSLocalizer(OTOSConstants lConstants) {
return setLocalizer(new OTOSLocalizer(hardwareMap, lConstants));
}
PinpointLocalizer pinpointLocalizer;
public FollowerBuilder pinpointLocalizer(PinpointConstants lConstants) {
pinpointLocalizer = new PinpointLocalizer(hardwareMap, lConstants);
return setLocalizer(pinpointLocalizer);
}
public void resetPinpoint(){
pinpointLocalizer.resetIMU();
}
public void recalibrateIMU(){
pinpointLocalizer.recalibrate();
}
public FollowerBuilder threeWheelIMULocalizer(ThreeWheelIMUConstants lConstants) {
return setLocalizer(new ThreeWheelIMULocalizer(hardwareMap, lConstants));
}
public FollowerBuilder threeWheelLocalizer(ThreeWheelConstants lConstants) {
return setLocalizer(new ThreeWheelLocalizer(hardwareMap, lConstants));
}
public FollowerBuilder twoWheelLocalizer(TwoWheelConstants lConstants) {
return setLocalizer(new TwoWheelLocalizer(hardwareMap, lConstants));
}
public FollowerBuilder setDrivetrain(Drivetrain drivetrain) {
this.drivetrain = drivetrain;
return this;
}
public FollowerBuilder mecanumDrivetrain(MecanumConstants mecanumConstants) {
return setDrivetrain(new Mecanum(hardwareMap, mecanumConstants));
}
@Deprecated
public FollowerBuilder mecanumExDrivetrain(MecanumConstants mecanumConstants) {
return setDrivetrain(new MecanumEx(hardwareMap, mecanumConstants));
}
public FollowerBuilder swerveDrivetrain(SwerveConstants swerveConstants, SwervePod... pods) {
return setDrivetrain(new Swerve(hardwareMap, swerveConstants, pods));
}
public FollowerBuilder pathConstraints(PathConstraints pathConstraints) {
this.constraints = pathConstraints;
PathConstraints.setDefaultConstraints(pathConstraints);
return this;
}
public Follower build() {
return new Follower(constants, localizer, drivetrain, constraints);
}
}

View File

@@ -148,7 +148,7 @@ class LocalizationTest extends OpMode {
@Override @Override
public void init() { public void init() {
follower.setStartingPose(new Pose(72,72, 0)); follower.setStartingPose(new Pose(0,0, 0));
} }
/** This initializes the PoseUpdater, the drive motors, and the Panels telemetry. */ /** This initializes the PoseUpdater, the drive motors, and the Panels telemetry. */
@@ -416,7 +416,7 @@ class ForwardVelocityTuner extends OpMode {
if (!end) { if (!end) {
if (Math.abs(follower.getPose().getX()) > (DISTANCE + 72)) { if (Math.abs(follower.getPose().getX()) > (DISTANCE)) {
end = true; end = true;
stopRobot(); stopRobot();
} else { } else {
@@ -524,7 +524,7 @@ class LateralVelocityTuner extends OpMode {
drawCurrentAndHistory(); drawCurrentAndHistory();
if (!end) { if (!end) {
if (Math.abs(follower.getPose().getY()) > (DISTANCE + 72)) { if (Math.abs(follower.getPose().getY()) > (DISTANCE)) {
end = true; end = true;
stopRobot(); stopRobot();
} else { } else {
@@ -1272,7 +1272,7 @@ class CentripetalTuner extends OpMode {
public void start() { public void start() {
follower.activateAllPIDFs(); follower.activateAllPIDFs();
forwards = new Path(new BezierCurve(new Pose(0,0), new Pose(Math.abs(DISTANCE) ,0), new Pose(Math.abs(DISTANCE) ,DISTANCE ))); forwards = new Path(new BezierCurve(new Pose(0,0), new Pose(Math.abs(DISTANCE) ,0), new Pose(Math.abs(DISTANCE) ,DISTANCE )));
backwards = new Path(new BezierCurve(new Pose(Math.abs(DISTANCE) + 72,DISTANCE + 72), new Pose(Math.abs(DISTANCE) ,0), new Pose(0,0))); backwards = new Path(new BezierCurve(new Pose(Math.abs(DISTANCE) + 0,DISTANCE + 0), new Pose(Math.abs(DISTANCE) ,0), new Pose(0,0)));
backwards.setTangentHeadingInterpolation(); backwards.setTangentHeadingInterpolation();
backwards.reverseHeadingInterpolation(); backwards.reverseHeadingInterpolation();
@@ -1382,14 +1382,14 @@ class Circle extends OpMode {
public void start() { public void start() {
circle = follower.pathBuilder() circle = follower.pathBuilder()
.addPath(new BezierCurve(new Pose(72, 72), new Pose(RADIUS + 72, 72), new Pose(RADIUS + 72, RADIUS + 72))) .addPath(new BezierCurve(new Pose(0, 0), new Pose(RADIUS + 0, 0), new Pose(RADIUS + 0, RADIUS + 0)))
.setHeadingInterpolation(HeadingInterpolator.facingPoint(72, RADIUS + 72)) .setHeadingInterpolation(HeadingInterpolator.facingPoint(0, RADIUS + 0))
.addPath(new BezierCurve(new Pose(RADIUS + 72, RADIUS + 72), new Pose(RADIUS + 72, (2 * RADIUS) + 72), new Pose(72, (2 * RADIUS) + 72))) .addPath(new BezierCurve(new Pose(RADIUS + 0, RADIUS + 0), new Pose(RADIUS + 0, (2 * RADIUS) + 0), new Pose(0, (2 * RADIUS) + 0)))
.setHeadingInterpolation(HeadingInterpolator.facingPoint(72, RADIUS + 72)) .setHeadingInterpolation(HeadingInterpolator.facingPoint(0, RADIUS + 0))
.addPath(new BezierCurve(new Pose(72, (2 * RADIUS) + 72), new Pose(-RADIUS + 72, (2 * RADIUS) + 72), new Pose(-RADIUS + 72, RADIUS + 72))) .addPath(new BezierCurve(new Pose(0, (2 * RADIUS) + 0), new Pose(-RADIUS + 0, (2 * RADIUS) + 0), new Pose(-RADIUS + 0, RADIUS + 0)))
.setHeadingInterpolation(HeadingInterpolator.facingPoint(72, RADIUS + 72)) .setHeadingInterpolation(HeadingInterpolator.facingPoint(0, RADIUS + 0))
.addPath(new BezierCurve(new Pose(-RADIUS + 72, RADIUS + 72), new Pose(-RADIUS + 72, 72), new Pose(72, 72))) .addPath(new BezierCurve(new Pose(-RADIUS + 0, RADIUS + 0), new Pose(-RADIUS + 0, 0), new Pose(0, 0)))
.setHeadingInterpolation(HeadingInterpolator.facingPoint(72, RADIUS + 72)) .setHeadingInterpolation(HeadingInterpolator.facingPoint(0, RADIUS + 0))
.build(); .build();
follower.followPath(circle); follower.followPath(circle);
} }
@@ -1406,7 +1406,7 @@ class Circle extends OpMode {
@Override @Override
public void init() { public void init() {
follower.setStartingPose(new Pose(72, 72)); follower.setStartingPose(new Pose(0, 0));
} }
/** /**
@@ -1639,8 +1639,8 @@ class OffsetsTuner extends OpMode {
telemetry.addLine("Total Angle: " + follower.getTotalHeading()); telemetry.addLine("Total Angle: " + follower.getTotalHeading());
telemetry.addLine("The following values are the offsets in inches that should be applied to your localizer."); telemetry.addLine("The following values are the offsets in inches that should be applied to your localizer.");
telemetry.addLine("strafeX: " + ((72.0-follower.getPose().getX()) / 2.0)); telemetry.addLine("strafeX: " + ((0.0-follower.getPose().getX()) / 2.0));
telemetry.addLine("forwardY: " + ((72.0-follower.getPose().getY()) / 2.0)); telemetry.addLine("forwardY: " + ((0.0-follower.getPose().getY()) / 2.0));
telemetry.update(); telemetry.update();
drawCurrentAndHistory(); drawCurrentAndHistory();

View File

@@ -3,45 +3,237 @@ package org.firstinspires.ftc.teamcode.teleop;
import com.acmerobotics.dashboard.FtcDashboard; import com.acmerobotics.dashboard.FtcDashboard;
import com.acmerobotics.dashboard.config.Config; import com.acmerobotics.dashboard.config.Config;
import com.acmerobotics.dashboard.telemetry.MultipleTelemetry; import com.acmerobotics.dashboard.telemetry.MultipleTelemetry;
import com.pedropathing.follower.Follower;
import com.pedropathing.geometry.Pose;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp; import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode; import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import org.firstinspires.ftc.teamcode.utilsv2.Drivetrain; import org.firstinspires.ftc.teamcode.constants.Color;
import org.firstinspires.ftc.teamcode.utils.Robot; import org.firstinspires.ftc.teamcode.pedroPathing.Constants;
import org.firstinspires.ftc.teamcode.utils.MeasuringLoopTimes;
import org.firstinspires.ftc.teamcode.utilsv2.*;
import static org.firstinspires.ftc.teamcode.utilsv2.Turret.limelightUsed;
@TeleOp @TeleOp
@Config @Config
public class TeleopV4 extends LinearOpMode { public class TeleopV4 extends LinearOpMode {
Robot robot; Robot robot;
Drivetrain drivetrain; Drivetrain drivetrain;
Shooter shooter;
MultipleTelemetry TELE; MultipleTelemetry TELE;
Follower follower;
SpindexerTransferIntake spindexerTransferIntake;
Turret turret;
Flywheel flywheel;
VelocityCommander commander;
ParkTilter parkTilter;
MeasuringLoopTimes loopTimes;
public static Pose relocalizePose = new Pose(56, 11, 0);
public static Pose teleStart = new Pose(0,0,0);
private boolean firstTickFull = true;
private boolean intakeFull = true;
private boolean shooting = false;
@Override @Override
public void runOpMode() throws InterruptedException { public void runOpMode() throws InterruptedException {
robot = new Robot(hardwareMap); Robot.resetInstance();
robot = Robot.getInstance(hardwareMap);
TELE = new MultipleTelemetry( TELE = new MultipleTelemetry(
FtcDashboard.getInstance().getTelemetry(), telemetry FtcDashboard.getInstance().getTelemetry(), telemetry
); );
commander = new VelocityCommander();
drivetrain = new Drivetrain(robot, TELE); drivetrain = new Drivetrain(robot, TELE);
follower = Constants.createFollower(hardwareMap);
follower.setStartingPose(teleStart);
sleep(500);
follower.setPose(teleStart);
follower.update();
drivetrain.setTelemetry(true); flywheel = new Flywheel(robot);
turret = new Turret(robot);
parkTilter = new ParkTilter(robot);
parkTilter.unpark();
loopTimes = new MeasuringLoopTimes();
loopTimes.init();
shooter = new Shooter(robot, TELE, follower, Color.redAlliance, turret, flywheel, commander);
shooter.setState(Shooter.ShooterState.TRACK_GOAL);
shooter.setRedAlliance(Color.redAlliance);
spindexerTransferIntake = new SpindexerTransferIntake(robot, TELE, commander);
spindexerTransferIntake.setSpindexerMode(SpindexerTransferIntake.SpindexerMode.RAPID);
turret.switchPipeline(Turret.PipelineMode.TRACKING);
robot.limelight.start();
limelightUsed = true;
TELE.addLine("Initialization is done");
TELE.addData("Starting Position", follower.getPose());
TELE.addData("TELE START", teleStart);
TELE.update();
while (opModeInInit()){
if (gamepad1.triangleWasPressed()){
VelocityCommander.lockFront = true;
VelocityCommander.lockBack = false;
} else if (gamepad1.squareWasPressed()){
VelocityCommander.lockBack = true;
VelocityCommander.lockFront = false;
} else if (gamepad1.circleWasPressed()){
VelocityCommander.lockBack = false;
VelocityCommander.lockFront = false;
}
TELE.addLine("Initialization is done");
TELE.addData("Starting Position", follower.getPose());
TELE.addData("TELE START", teleStart);
TELE.addData("Front?:", VelocityCommander.lockFront);
TELE.addData("Back?:", VelocityCommander.lockBack);
TELE.update();
}
waitForStart(); waitForStart();
if (isStopRequested()) return; if (isStopRequested()) return;
while (opModeIsActive()){ int emptyTicks = 0;
while (opModeIsActive()) {
//Drivetrain //Drivetrain
drivetrain.drive( drivetrain.drive(
-gamepad1.right_stick_y, -gamepad1.right_stick_y,
gamepad1.right_stick_x, gamepad1.right_stick_x,
gamepad1.left_stick_x gamepad1.left_stick_x,
gamepad1.left_trigger
); );
if (gamepad1.crossWasPressed()){
if (Color.redAlliance){
relocalizePose = new Pose(57.5, 5, 0);
} else {
relocalizePose = new Pose(-57.5, 5, Math.toRadians(180));
}
follower.setPose(relocalizePose);
sleep(500);
gamepad1.rumble(100);
}
follower.update();
Pose currentPose = follower.getPose();
if (gamepad1.dpadLeftWasPressed()){
shooter.setState(Shooter.ShooterState.MANUAL_FLYWHEEL_TRACK_TURR);
}
if (gamepad1.dpadRightWasPressed()){
shooter.setState(Shooter.ShooterState.TRACK_GOAL);
}
if (shooter.getState() == Shooter.ShooterState.MANUAL_FLYWHEEL_TRACK_TURR || shooter.getState() == Shooter.ShooterState.MANUAL){
shooter.setFlywheelVelocity(2500);
robot.setHoodPos(0.6);
}
if (gamepad1.triangleWasPressed()){
VelocityCommander.lockFront = true;
VelocityCommander.lockBack = false;
TELE.addData("Front?:", true);
TELE.addData("Back?:", false);
} else if (gamepad1.squareWasPressed()){
VelocityCommander.lockBack = true;
VelocityCommander.lockFront = false;
TELE.addData("Front?:", false);
TELE.addData("Back?:", true);
} else if (gamepad1.circleWasPressed()){
VelocityCommander.lockBack = false;
VelocityCommander.lockFront = false;
TELE.addData("Front?:", false);
TELE.addData("Back?:", true);
}
shooter.update(robot.voltage.getVoltage());
spindexerTransferIntake.update();
SpindexerTransferIntake.RapidMode state = spindexerTransferIntake.getRapidState();
if (gamepad1.leftBumperWasPressed() &&
(state == SpindexerTransferIntake.RapidMode.INTAKE ||
state == SpindexerTransferIntake.RapidMode.TRANSFER_OFF ||
state == SpindexerTransferIntake.RapidMode.BEFORE_PULSE_OUT ||
state == SpindexerTransferIntake.RapidMode.PULSE_OUT ||
state == SpindexerTransferIntake.RapidMode.PULSE_IN ||
state == SpindexerTransferIntake.RapidMode.HOLD_BALLS)) {
spindexerTransferIntake.setRapidMode(SpindexerTransferIntake.RapidMode.OPEN_GATE);
intakeFull = false;
firstTickFull = true;
shooting = true;
}
if (state != SpindexerTransferIntake.RapidMode.OPEN_GATE && state != SpindexerTransferIntake.RapidMode.SHOOT){
shooting = false;
}
if (robot.insideBeam.isPressed() && robot.outsideBeam.isPressed() && !shooting){
intakeFull = true;
} else {
intakeFull = false;
firstTickFull = true;
}
if (intakeFull && firstTickFull){
gamepad1.rumble(100);
firstTickFull = false;
}
if (gamepad1.right_trigger > 0.5 &&
(state == SpindexerTransferIntake.RapidMode.INTAKE ||
state == SpindexerTransferIntake.RapidMode.TRANSFER_OFF)) {
spindexerTransferIntake.setRapidMode(
SpindexerTransferIntake.RapidMode.HOLD_BALLS
);
}
if (gamepad1.right_bumper && state != SpindexerTransferIntake.RapidMode.OPEN_GATE && state != SpindexerTransferIntake.RapidMode.SHOOT) {
robot.setIntakePower(1);
robot.setTransferPower(-0.7);
}
if (gamepad2.leftBumperWasPressed()){
limelightUsed = false;
} else if (gamepad2.rightBumperWasPressed()){
limelightUsed = true;
}
if (gamepad1.dpad_down){
parkTilter.park();
} else if (gamepad1.dpad_up) {
parkTilter.unpark();
}
loopTimes.loop();
// TELE.addData("Loop Time Average", loopTimes.getAvgLoopTime());
// TELE.addData("Loop Time Max", loopTimes.getMaxLoopTimeOneMin());
// TELE.addData("Loop Time Min", loopTimes.getMinLoopTimeOneMin());
//
TELE.addData("Distance From Goal", commander.getDistance());
// TELE.addData("Hood Position", commander.getHoodPredicted());
// TELE.addData("Transfer Power", robot.transfer.getPower());
TELE.addData("Theoretical Velocity RPM", commander.getPredictedRPM());
TELE.addData("Actual Velocity RPM", flywheel.getAverageVelocity());
//
// TELE.addData("Current Position", currentPose);
//
// TELE.addData("Current LL Pipeline", turret.pipeline());
//
TELE.update(); TELE.update();
} }

View File

@@ -9,8 +9,7 @@ import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import org.firstinspires.ftc.teamcode.utils.AprilTagWebcam; import org.firstinspires.ftc.teamcode.utils.AprilTagWebcam;
import org.firstinspires.ftc.teamcode.utils.Robot; import org.firstinspires.ftc.teamcode.utils.Robot;
@Config
@TeleOp
public class AprilTagWebcamExample extends OpMode { public class AprilTagWebcamExample extends OpMode {
MultipleTelemetry TELE; MultipleTelemetry TELE;

View File

@@ -12,8 +12,7 @@ import com.qualcomm.robotcore.hardware.NormalizedRGBA;
import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit; import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit;
import org.firstinspires.ftc.teamcode.utils.Robot; import org.firstinspires.ftc.teamcode.utils.Robot;
@Config
@TeleOp
public class ColorTest extends LinearOpMode { public class ColorTest extends LinearOpMode {
Robot robot; Robot robot;
MultipleTelemetry TELE; MultipleTelemetry TELE;

View File

@@ -1,13 +1,15 @@
package org.firstinspires.ftc.teamcode.tests; package org.firstinspires.ftc.teamcode.tests;
import com.acmerobotics.dashboard.FtcDashboard;
import com.acmerobotics.dashboard.config.Config; import com.acmerobotics.dashboard.config.Config;
import com.acmerobotics.dashboard.telemetry.MultipleTelemetry; import com.acmerobotics.dashboard.telemetry.MultipleTelemetry;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode; import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp; import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.hardware.DcMotor;
import com.qualcomm.robotcore.hardware.NormalizedRGBA; import com.qualcomm.robotcore.hardware.NormalizedRGBA;
import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit; import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit;
import org.firstinspires.ftc.teamcode.utils.Robot; import org.firstinspires.ftc.teamcode.utilsv2.Robot;
@Config @Config
@TeleOp @TeleOp
@@ -49,8 +51,14 @@ public class Hardware_Tester extends LinearOpMode {
@Override @Override
public void runOpMode() throws InterruptedException { public void runOpMode() throws InterruptedException {
robot = new Robot(hardwareMap); Robot.resetInstance();
TELE = new MultipleTelemetry(); robot = Robot.getInstance(hardwareMap);
TELE = new MultipleTelemetry(telemetry, FtcDashboard.getInstance().getTelemetry());
robot.shooter1.setMode(DcMotor.RunMode.RUN_WITHOUT_ENCODER);
robot.shooter2.setMode(DcMotor.RunMode.RUN_WITHOUT_ENCODER);
waitForStart();
if (isStopRequested()) return; if (isStopRequested()) return;
while (opModeIsActive()){ while (opModeIsActive()){
@@ -116,13 +124,14 @@ public class Hardware_Tester extends LinearOpMode {
// Sensor Data // Sensor Data
TELE.addData("Beam Break 1?", robot.beam1.isPressed()); TELE.addData("Beam Break insideBeam?", robot.insideBeam.isPressed());
TELE.addData("Beam Break 2?", robot.beam2.isPressed()); TELE.addData("Beam Break outsideBeam?", robot.outsideBeam.isPressed());
TELE.addData("Beam Break 3?", robot.beam3.isPressed()); // TELE.addData("Beam Break 2?", robot.beam2.isPressed());
// TELE.addData("Beam Break 3?", robot.beam3.isPressed());
NormalizedRGBA revColor = robot.revSensor.getNormalizedColors(); NormalizedRGBA revColor = robot.revSensor.getNormalizedColors();
TELE.addData("REV Distance", robot.revSensor.getDistance(DistanceUnit.MM)); TELE.addData("REV Distance", robot.revSensor.getDistance(DistanceUnit.CM));
TELE.addData("REV Green", revColor.green / (revColor.red + revColor.blue + revColor.green)); TELE.addData("REV Green", revColor.blue / (revColor.green + revColor.blue + revColor.red));
TELE.addData("Voltage Sensor", robot.voltage.getVoltage()); TELE.addData("Voltage Sensor", robot.voltage.getVoltage());

View File

@@ -7,8 +7,6 @@ import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import org.firstinspires.ftc.teamcode.utils.Robot; import org.firstinspires.ftc.teamcode.utils.Robot;
@Config
@TeleOp
public class MotorDirectionDebugger extends LinearOpMode { public class MotorDirectionDebugger extends LinearOpMode {
public static double flPower = 0.0; public static double flPower = 0.0;

View File

@@ -0,0 +1,168 @@
package org.firstinspires.ftc.teamcode.tests;
import static org.firstinspires.ftc.teamcode.utilsv2.Turret.limelightUsed;
import com.acmerobotics.dashboard.FtcDashboard;
import com.acmerobotics.dashboard.config.Config;
import com.acmerobotics.dashboard.telemetry.MultipleTelemetry;
import com.pedropathing.follower.Follower;
import com.pedropathing.geometry.Pose;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import org.firstinspires.ftc.teamcode.constants.Color;
import org.firstinspires.ftc.teamcode.pedroPathing.Constants;
import org.firstinspires.ftc.teamcode.teleop.TeleopV4;
import org.firstinspires.ftc.teamcode.utilsv2.*;
@TeleOp
@Config
public class NewShooterTest extends LinearOpMode {
Robot robot;
Drivetrain drivetrain;
Shooter shooter;
MultipleTelemetry TELE;
Follower follower;
SpindexerTransferIntake spindexerTransferIntake;
Turret turret;
Flywheel flywheel;
VelocityCommander commander;
ParkTilter parkTilter;
public static int flywheelVelo = 0;
public static double hoodPos = 0.5;
public static double transferPower = -0.8;
public static boolean overrideTransferPower = false;
@Override
public void runOpMode() throws InterruptedException {
Robot.resetInstance();
robot = Robot.getInstance(hardwareMap);
TELE = new MultipleTelemetry(
FtcDashboard.getInstance().getTelemetry(), telemetry
);
commander = new VelocityCommander();
drivetrain = new Drivetrain(robot, TELE);
follower = Constants.createFollower(hardwareMap);
follower.setStartingPose(new Pose(0,0,0));
sleep(500);
follower.setPose(new Pose(0,0,0));
flywheel = new Flywheel(robot);
turret = new Turret(robot);
parkTilter = new ParkTilter(robot);
parkTilter.unpark();
shooter = new Shooter(robot, TELE, follower, Color.redAlliance, turret, flywheel, commander);
shooter.setState(Shooter.ShooterState.MANUAL_FLYWHEEL_TRACK_TURR);
shooter.setRedAlliance(Color.redAlliance);
spindexerTransferIntake = new SpindexerTransferIntake(robot, TELE, commander);
spindexerTransferIntake.setSpindexerMode(SpindexerTransferIntake.SpindexerMode.RAPID);
turret.switchPipeline(Turret.PipelineMode.TRACKING);
robot.limelight.start();
limelightUsed = true;
TELE.addLine("Initialization Complete");
TELE.update();
waitForStart();
if (isStopRequested()) return;
while (opModeIsActive()) {
//Drivetrain
drivetrain.drive(
-gamepad1.right_stick_y,
gamepad1.right_stick_x,
gamepad1.left_stick_x,
gamepad1.left_trigger
);
if (gamepad1.crossWasPressed()){
if (Color.redAlliance){
TeleopV4.relocalizePose = new Pose(57.5, 5, 0);
} else {
TeleopV4.relocalizePose = new Pose(-57.5, 5, Math.toRadians(180));
}
follower.setPose(TeleopV4.relocalizePose);
sleep(500);
gamepad1.rumble(100);
}
follower.update();
if (gamepad1.dpadLeftWasPressed()){
shooter.setState(Shooter.ShooterState.MANUAL_FLYWHEEL_TRACK_TURR);
}
if (gamepad1.dpadRightWasPressed()){
shooter.setState(Shooter.ShooterState.TRACK_GOAL);
}
if (shooter.getState() == Shooter.ShooterState.MANUAL_FLYWHEEL_TRACK_TURR || shooter.getState() == Shooter.ShooterState.MANUAL){
shooter.setFlywheelVelocity(flywheelVelo);
robot.setHoodPos(hoodPos);
}
// shooter.setTurretPosition(turretPos);
shooter.update(robot.voltage.getVoltage());
spindexerTransferIntake.update();
if (gamepad2.leftBumperWasPressed()){
limelightUsed = false;
} else if (gamepad2.rightBumperWasPressed()){
limelightUsed = true;
}
SpindexerTransferIntake.RapidMode state = spindexerTransferIntake.getRapidState();
if (gamepad1.leftBumperWasPressed() &&
(state == SpindexerTransferIntake.RapidMode.INTAKE ||
state == SpindexerTransferIntake.RapidMode.TRANSFER_OFF ||
state == SpindexerTransferIntake.RapidMode.BEFORE_PULSE_OUT ||
state == SpindexerTransferIntake.RapidMode.PULSE_OUT ||
state == SpindexerTransferIntake.RapidMode.PULSE_IN ||
state == SpindexerTransferIntake.RapidMode.HOLD_BALLS)) {
spindexerTransferIntake.setRapidMode(SpindexerTransferIntake.RapidMode.OPEN_GATE);
}
if (gamepad1.right_trigger > 0.5 &&
(state == SpindexerTransferIntake.RapidMode.INTAKE ||
state == SpindexerTransferIntake.RapidMode.TRANSFER_OFF)) {
spindexerTransferIntake.setRapidMode(
SpindexerTransferIntake.RapidMode.HOLD_BALLS
);
}
if (gamepad1.right_bumper && state != SpindexerTransferIntake.RapidMode.OPEN_GATE && state != SpindexerTransferIntake.RapidMode.SHOOT) {
robot.setIntakePower(1);
}
if (gamepad1.dpad_down){
parkTilter.park();
} else if (gamepad1.dpad_up) {
parkTilter.unpark();
}
TELE.addData("Distance From Goal", commander.getDistance());
TELE.addData("Hood Position", commander.getHoodPredicted());
TELE.addData("Transfer Power", commander.getTransferPow());
TELE.addData("Theoretical Velocity RPM", commander.getPredictedRPM());
TELE.addData("Manuel Velocity RPM", flywheelVelo);
TELE.addData("Actual Velocity RPM", flywheel.getAverageVelocity());
TELE.addData("TX:", turret.getTX());
TELE.update();
}
}
}

View File

@@ -27,8 +27,6 @@ import org.firstinspires.ftc.teamcode.utils.Spindexer;
import org.firstinspires.ftc.teamcode.utils.Targeting; import org.firstinspires.ftc.teamcode.utils.Targeting;
import org.firstinspires.ftc.teamcode.utils.Turret; import org.firstinspires.ftc.teamcode.utils.Turret;
@Config
@TeleOp
public class ShooterTest extends LinearOpMode { public class ShooterTest extends LinearOpMode {
public static int mode = 1; public static int mode = 1;
public static double parameter = 0.0; public static double parameter = 0.0;

View File

@@ -0,0 +1,126 @@
package org.firstinspires.ftc.teamcode.tests;
import static org.firstinspires.ftc.teamcode.constants.Front_Poses.teleStartPoseH;
import static org.firstinspires.ftc.teamcode.constants.Front_Poses.teleStartPoseX;
import static org.firstinspires.ftc.teamcode.constants.Front_Poses.teleStartPoseY;
import com.acmerobotics.dashboard.FtcDashboard;
import com.acmerobotics.dashboard.config.Config;
import com.acmerobotics.dashboard.telemetry.MultipleTelemetry;
import com.pedropathing.follower.Follower;
import com.pedropathing.geometry.Pose;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import org.firstinspires.ftc.teamcode.constants.Color;
import org.firstinspires.ftc.teamcode.pedroPathing.Constants;
import org.firstinspires.ftc.teamcode.utilsv2.*;
@TeleOp
@Config
public class SortedSpindexerTest extends LinearOpMode {
Robot robot;
Drivetrain drivetrain;
Shooter shooter;
MultipleTelemetry TELE;
Follower follower;
SpindexerTransferIntake spindexerTransferIntake;
Turret turret;
Flywheel flywheel;
VelocityCommander commander;
ParkTilter parkTilter;
public static String order = "GPP";
@Override
public void runOpMode() throws InterruptedException {
Robot.resetInstance();
robot = Robot.getInstance(hardwareMap);
TELE = new MultipleTelemetry(
FtcDashboard.getInstance().getTelemetry(), telemetry
);
commander = new VelocityCommander();
drivetrain = new Drivetrain(robot, TELE);
follower = Constants.createFollower(hardwareMap);
Pose start = new Pose(teleStartPoseX, teleStartPoseY, Math.toRadians(teleStartPoseH));
follower.setStartingPose(start);
flywheel = new Flywheel(robot);
turret = new Turret(robot);
parkTilter = new ParkTilter(robot);
shooter = new Shooter(robot, TELE, follower, Color.redAlliance, turret, flywheel, commander);
shooter.setState(Shooter.ShooterState.TRACK_GOAL);
shooter.setRedAlliance(Color.redAlliance);
spindexerTransferIntake = new SpindexerTransferIntake(robot, TELE, commander);
spindexerTransferIntake.setSpindexerMode(SpindexerTransferIntake.SpindexerMode.SORTED);
waitForStart();
if (isStopRequested()) return;
while (opModeIsActive()) {
switch(order) {
case "PPG":
spindexerTransferIntake.setDesiredPattern(
SpindexerTransferIntake.DesiredPattern.PPG
);
break;
case "PGP":
spindexerTransferIntake.setDesiredPattern(
SpindexerTransferIntake.DesiredPattern.PGP
);
break;
default:
spindexerTransferIntake.setDesiredPattern(
SpindexerTransferIntake.DesiredPattern.GPP
);
}
//Drivetrain
drivetrain.drive(
-gamepad1.right_stick_y,
gamepad1.right_stick_x,
gamepad1.left_stick_x,
gamepad1.left_trigger
);
follower.update();
shooter.update(robot.voltage.getVoltage());
spindexerTransferIntake.update();
SpindexerTransferIntake.RapidMode state = spindexerTransferIntake.getRapidState();
if(gamepad1.leftBumperWasPressed()) {
spindexerTransferIntake.startSortedShoot();
}
if (gamepad1.dpad_down){
parkTilter.park();
} else if (gamepad1.dpad_up) {
parkTilter.unpark();
}
TELE.addData("Distance From Goal", commander.getDistance());
TELE.addData("Hood Position", commander.getHoodPredicted());
TELE.addData("Transfer Power", robot.transfer.getPower());
TELE.addData("Theoretical Velocity RPM", commander.getPredictedRPM());
TELE.addData("Actual Velocity RPM", flywheel.getAverageVelocity());
TELE.update();
}
}
}

View File

@@ -18,8 +18,6 @@ import org.firstinspires.ftc.teamcode.utils.Spindexer;
import org.firstinspires.ftc.teamcode.utils.Targeting; import org.firstinspires.ftc.teamcode.utils.Targeting;
import org.firstinspires.ftc.teamcode.utils.Turret; import org.firstinspires.ftc.teamcode.utils.Turret;
@Config
@TeleOp
public class SortingTest extends LinearOpMode { public class SortingTest extends LinearOpMode {
Robot robot; Robot robot;
MultipleTelemetry TELE; MultipleTelemetry TELE;

View File

@@ -15,8 +15,6 @@ import org.firstinspires.ftc.teamcode.pedroPathing.Constants;
import org.firstinspires.ftc.teamcode.utils.Robot; import org.firstinspires.ftc.teamcode.utils.Robot;
import org.firstinspires.ftc.teamcode.utils.Turret; import org.firstinspires.ftc.teamcode.utils.Turret;
@TeleOp
@Config
public class TurretTest extends LinearOpMode { public class TurretTest extends LinearOpMode {
public static boolean zeroTurr = false; public static boolean zeroTurr = false;
@Override @Override

View File

@@ -7,7 +7,6 @@ import org.firstinspires.ftc.teamcode.constants.Color;
import org.firstinspires.ftc.teamcode.constants.StateEnums.LightState; import org.firstinspires.ftc.teamcode.constants.StateEnums.LightState;
@Config
public final class Light { public final class Light {
private static Light instance; private static Light instance;

View File

@@ -43,13 +43,12 @@ public class MeasuringLoopTimes {
public void loop() { public void loop() {
currentTime = getTimeSeconds(); currentTime = getTimeSeconds();
if ((MeasurementStart + 5.0) < currentTime) if ((MeasurementStart + 60) < currentTime)
{ {
minLoopTime = 9999999.0; minLoopTime = 9999999.0;
maxLoopTime = 0.0; maxLoopTime = 0.0;
MeasurementStart = currentTime; MeasurementStart = currentTime;
avgLoopTime = avgLoopTimeSum / (double) avgLoopTimeTicker;
avgLoopTimeSum = 0.0; avgLoopTimeSum = 0.0;
avgLoopTimeTicker = 0; avgLoopTimeTicker = 0;
} }
@@ -59,6 +58,7 @@ public class MeasuringLoopTimes {
avgLoopTimeSum += mainLoopTime; avgLoopTimeSum += mainLoopTime;
avgLoopTimeTicker++; avgLoopTimeTicker++;
avgLoopTime = avgLoopTimeSum / (double) avgLoopTimeTicker;
minLoopTime = Math.min(minLoopTime,mainLoopTime); minLoopTime = Math.min(minLoopTime,mainLoopTime);
maxLoopTime = Math.max(maxLoopTime,mainLoopTime); maxLoopTime = Math.max(maxLoopTime,mainLoopTime);
} }

View File

@@ -10,8 +10,6 @@ import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import org.firstinspires.ftc.vision.apriltag.AprilTagDetection; import org.firstinspires.ftc.vision.apriltag.AprilTagDetection;
@TeleOp
@Config
public class PositionalServoProgrammer extends LinearOpMode { public class PositionalServoProgrammer extends LinearOpMode {
Robot robot; Robot robot;
MultipleTelemetry TELE; MultipleTelemetry TELE;

View File

@@ -16,7 +16,6 @@ import com.qualcomm.robotcore.hardware.VoltageSensor;
import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName; import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName;
import org.firstinspires.ftc.vision.apriltag.AprilTagProcessor; import org.firstinspires.ftc.vision.apriltag.AprilTagProcessor;
@Config
public class Robot { public class Robot {
//Initialize Public Components //Initialize Public Components
@@ -83,6 +82,7 @@ public class Robot {
backRight.setZeroPowerBehavior(DcMotor.ZeroPowerBehavior.FLOAT); backRight.setZeroPowerBehavior(DcMotor.ZeroPowerBehavior.FLOAT);
intake = hardwareMap.get(DcMotorEx.class, "intake"); intake = hardwareMap.get(DcMotorEx.class, "intake");
intake.setDirection(DcMotorSimple.Direction.REVERSE);
shooter1 = hardwareMap.get(DcMotorEx.class, "shooter1"); shooter1 = hardwareMap.get(DcMotorEx.class, "shooter1");
@@ -103,11 +103,12 @@ public class Robot {
turr2 = hardwareMap.get(Servo.class, "turr2"); turr2 = hardwareMap.get(Servo.class, "turr2");
spin1 = hardwareMap.get(Servo.class, "spin2"); spin1 = hardwareMap.get(Servo.class, "spin1");
spin2 = hardwareMap.get(Servo.class, "spin1"); spin2 = hardwareMap.get(Servo.class, "spin2");
transfer = hardwareMap.get(DcMotorEx.class, "transfer"); transfer = hardwareMap.get(DcMotorEx.class, "transfer");
transfer.setDirection(DcMotorSimple.Direction.REVERSE);
transferServo = hardwareMap.get(Servo.class, "transferServo"); transferServo = hardwareMap.get(Servo.class, "transferServo");
@@ -121,27 +122,27 @@ public class Robot {
tilt1 = hardwareMap.get(Servo.class, "tilt1"); tilt1 = hardwareMap.get(Servo.class, "tilt1");
tilt2 = hardwareMap.get(Servo.class, "tilt2"); tilt2 = hardwareMap.get(Servo.class, "tilt2");
beam1 = hardwareMap.get(TouchSensor.class, "beam1"); // beam1 = hardwareMap.get(TouchSensor.class, "beam1");
beam2 = hardwareMap.get(TouchSensor.class, "beam2"); // beam2 = hardwareMap.get(TouchSensor.class, "beam2");
beam3 = hardwareMap.get(TouchSensor.class, "beam3"); // beam3 = hardwareMap.get(TouchSensor.class, "beam3");
revSensor = hardwareMap.get(RevColorSensorV3.class, "rev"); revSensor = hardwareMap.get(RevColorSensorV3.class, "rev");
// Below is disregarded // Below is disregarded
turr1Pos = hardwareMap.get(AnalogInput.class, "t1Pos"); // Encoder of turret plugged in intake port // turr1Pos = hardwareMap.get(AnalogInput.class, "t1Pos"); // Encoder of turret plugged in intake port
//
spin1Pos = hardwareMap.get(AnalogInput.class, "spin1Pos"); // spin1Pos = hardwareMap.get(AnalogInput.class, "spin1Pos");
//
spin2Pos = hardwareMap.get(AnalogInput.class, "spin2Pos"); // spin2Pos = hardwareMap.get(AnalogInput.class, "spin2Pos");
//
transferServoPos = hardwareMap.get(AnalogInput.class, "tSPos"); // transferServoPos = hardwareMap.get(AnalogInput.class, "tSPos");
//
color1 = hardwareMap.get(RevColorSensorV3.class, "c1"); // color1 = hardwareMap.get(RevColorSensorV3.class, "c1");
//
color2 = hardwareMap.get(RevColorSensorV3.class, "c2"); // color2 = hardwareMap.get(RevColorSensorV3.class, "c2");
//
color3 = hardwareMap.get(RevColorSensorV3.class, "c3"); // color3 = hardwareMap.get(RevColorSensorV3.class, "c3");
if (usingLimelight) { if (usingLimelight) {
limelight = hardwareMap.get(Limelight3A.class, "limelight"); limelight = hardwareMap.get(Limelight3A.class, "limelight");
@@ -150,7 +151,8 @@ public class Robot {
aprilTagProcessor = AprilTagProcessor.easyCreateWithDefaults(); aprilTagProcessor = AprilTagProcessor.easyCreateWithDefaults();
} }
light = hardwareMap.get(Servo.class, "light"); // light = hardwareMap.get(Servo.class, "light");
voltage = hardwareMap.voltageSensor.iterator().next(); voltage = hardwareMap.voltageSensor.iterator().next();
} }

View File

@@ -6,7 +6,6 @@ import com.acmerobotics.dashboard.config.Config;
import com.arcrobotics.ftclib.controller.PIDFController; import com.arcrobotics.ftclib.controller.PIDFController;
import com.qualcomm.robotcore.hardware.HardwareMap; import com.qualcomm.robotcore.hardware.HardwareMap;
@Config
public class Servos { public class Servos {
//PID constants //PID constants
// TODO: get PIDF constants // TODO: get PIDF constants

View File

@@ -19,16 +19,15 @@ import org.firstinspires.ftc.teamcode.teleop.TeleopV3;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@Config
public class Turret { public class Turret {
public static double turretTolerance = 0.02; public static double turretTolerance = 0.02;
public static double turrPosScalar = 0.00011264432; public static double turrPosScalar = 0.00011264432;
public static double turret180Range = 0.55; public static double turret180Range = 0.58;
public static double turrDefault = 0.35; public static double turrDefault = 0.51;
public static double turrMin = 0; public static double turrMin = 0.05;
public static double turrMax = 0.69; public static double turrMax = 0.95;
public static boolean limelightUsed = true; public static boolean limelightUsed = true;
public static double limelightPosOffset = 5; public static double limelightPosOffset = 5;
public static double manualOffset = 0.0; public static double manualOffset = 0.0;

View File

@@ -4,8 +4,6 @@ import com.acmerobotics.dashboard.config.Config;
import com.acmerobotics.dashboard.telemetry.MultipleTelemetry; import com.acmerobotics.dashboard.telemetry.MultipleTelemetry;
import com.qualcomm.robotcore.hardware.DcMotor; import com.qualcomm.robotcore.hardware.DcMotor;
import org.firstinspires.ftc.teamcode.utils.Robot;
@Config @Config
public class Drivetrain { public class Drivetrain {
@@ -18,8 +16,8 @@ public class Drivetrain {
private static final double STRAFE_MULTIPLIER = 1.2; private static final double STRAFE_MULTIPLIER = 1.2;
public static double FORWARD_ROTATION_CORRECTION = 0.03; public static double FORWARD_ROTATION_CORRECTION = 0;
public static double STRAFE_ROTATION_CORRECTION = -0.03; public static double STRAFE_ROTATION_CORRECTION = -0;
private boolean tele = false; private boolean tele = false;
@@ -39,7 +37,7 @@ public class Drivetrain {
tele = input; tele = input;
} }
public void drive(double y, double x, double rx) { public void drive(double y, double x, double rx, double stop) {
boolean snappedForward = false; boolean snappedForward = false;
boolean snappedStrafe = false; boolean snappedStrafe = false;
@@ -81,18 +79,30 @@ public class Drivetrain {
robot.setFrontRightPower(frontRightPower); robot.setFrontRightPower(frontRightPower);
robot.setBackRightPower(backRightPower); robot.setBackRightPower(backRightPower);
if (tele) { if (stop > 0.5){
robot.frontLeft.setZeroPowerBehavior(DcMotor.ZeroPowerBehavior.BRAKE);
telemetry.addData("Forward Snap", snappedForward); robot.backLeft.setZeroPowerBehavior(DcMotor.ZeroPowerBehavior.BRAKE);
telemetry.addData("Strafe Snap", snappedStrafe); robot.frontRight.setZeroPowerBehavior(DcMotor.ZeroPowerBehavior.BRAKE);
robot.backRight.setZeroPowerBehavior(DcMotor.ZeroPowerBehavior.BRAKE);
telemetry.addData("Correction RX", correctionRX);
telemetry.addData("FL", frontLeftPower);
telemetry.addData("BL", backLeftPower);
telemetry.addData("FR", frontRightPower);
telemetry.addData("BR", backRightPower);
robot.setFrontLeftPower(0);
robot.setBackLeftPower(0);
robot.setFrontRightPower(0);
robot.setBackRightPower(0);
} }
// if (tele) {
//
// telemetry.addData("Forward Snap", snappedForward);
// telemetry.addData("Strafe Snap", snappedStrafe);
//
// telemetry.addData("Correction RX", correctionRX);
//
// telemetry.addData("FL", frontLeftPower);
// telemetry.addData("BL", backLeftPower);
// telemetry.addData("FR", frontRightPower);
// telemetry.addData("BR", backRightPower);
//
// }
} }
} }

View File

@@ -1,18 +1,37 @@
package org.firstinspires.ftc.teamcode.utilsv2; package org.firstinspires.ftc.teamcode.utilsv2;
import com.acmerobotics.dashboard.config.Config;
import com.arcrobotics.ftclib.controller.PIDFController;
import com.arcrobotics.ftclib.controller.wpilibcontroller.SimpleMotorFeedforward;
import com.qualcomm.robotcore.hardware.DcMotor; import com.qualcomm.robotcore.hardware.DcMotor;
import com.qualcomm.robotcore.hardware.HardwareMap;
import com.qualcomm.robotcore.hardware.HardwareMap;
import com.qualcomm.robotcore.hardware.PIDFCoefficients; import com.qualcomm.robotcore.hardware.PIDFCoefficients;
import org.firstinspires.ftc.teamcode.utils.Robot; import org.firstinspires.ftc.teamcode.utilsv2.Robot;
import java.util.LinkedList; import java.util.LinkedList;
@Config
public class Flywheel { public class Flywheel {
Robot robot; Robot robot;
public PIDFCoefficients shooterPIDF1, shooterPIDF2; // public PIDFCoefficients shooterPIDF1, shooterPIDF2;
public static PIDFCoefficients shooterPIDF;
PIDFController pidf;
SimpleMotorFeedforward feedforward;
public static double kS = 0.01; // Static feedforward
public static double kV = 0.0001935; // Velocity feedforward
public static double shooterPIDF_P = 500;
public static double shooterPIDF_I = 1;
public static double shooterPIDF_D = 0.0;
public static double shooterPIDF_F = 93;
// public static double shooterPIDF_P = 0.0001;
// public static double shooterPIDF_I = 0;
// public static double shooterPIDF_D = 0.00001;
// public static double shooterPIDF_F = 0;
private double velo = 0.0; private double velo = 0.0;
private double velo1 = 0.0; private double velo1 = 0.0;
@@ -27,10 +46,10 @@ public class Flywheel {
private final LinkedList<Double> velocityHistory = new LinkedList<>(); private final LinkedList<Double> velocityHistory = new LinkedList<>();
public Flywheel(Robot rob) { public Flywheel(Robot rob) {
robot = rob; robot = rob;
shooterPIDF1 = new PIDFCoefficients(Robot.shooterPIDF_P, Robot.shooterPIDF_I, Robot.shooterPIDF_D, Robot.shooterPIDF_F); shooterPIDF = new PIDFCoefficients(shooterPIDF_P, shooterPIDF_I, shooterPIDF_D, shooterPIDF_F / 12);
shooterPIDF2 = new PIDFCoefficients(Robot.shooterPIDF_P, Robot.shooterPIDF_I, Robot.shooterPIDF_D, Robot.shooterPIDF_F); // pidf = new PIDFController(shooterPIDF_P, shooterPIDF_I, shooterPIDF_D, 0);
// feedforward = new SimpleMotorFeedforward(kS, kV);
} }
public double getVelo() { public double getVelo() {
@@ -54,30 +73,31 @@ public class Flywheel {
} }
// Set the robot PIDF for the next cycle. // Set the robot PIDF for the next cycle.
private double prevF = 0;
public static double voltagePIDFDifference = 0.8;
public void setPIDF(double p, double i, double d, double f) { public void setPIDF(double p, double i, double d, double f) {
shooterPIDF1.p = p; shooterPIDF.p = p;
shooterPIDF1.i = i; shooterPIDF.i = i;
shooterPIDF1.d = d; shooterPIDF.d = d;
shooterPIDF1.f = f; shooterPIDF.f = f;
shooterPIDF2.p = p; // pidf.setPIDF(shooterPIDF_P, shooterPIDF_I, shooterPIDF_D, 0);
shooterPIDF2.i = i;
shooterPIDF2.d = d;
shooterPIDF2.f = f;
if (Math.abs(prevF - f) > voltagePIDFDifference) { robot.shooter1.setPIDFCoefficients(DcMotor.RunMode.RUN_USING_ENCODER, shooterPIDF);
}
robot.shooter1.setPIDFCoefficients(DcMotor.RunMode.RUN_USING_ENCODER, shooterPIDF1); private double prevF = 0;
robot.shooter2.setPIDFCoefficients(DcMotor.RunMode.RUN_USING_ENCODER, shooterPIDF2); public static double voltagePIDFDifference = 1;
double averageVoltage = 0;
prevF = f; public void setF(double voltage){
averageVoltage = ALPHA * voltage + (1 - ALPHA) * averageVoltage;
double f = shooterPIDF_F / voltage;
if (Math.abs(prevF - f) > voltagePIDFDifference && !steady) {
shooterPIDF.f = f;
robot.shooter1.setPIDFCoefficients(DcMotor.RunMode.RUN_USING_ENCODER, shooterPIDF);
} }
prevF = f;
} }
// Convert from RPM to Ticks per Second // Convert from RPM to Ticks per Second
@@ -90,24 +110,30 @@ public class Flywheel {
return (TPS * 60.0) / 28.0; return (TPS * 60.0) / 28.0;
} }
double ALPHA = 0.3;
private void updateVelocityAverage(double newVelocity) { private void updateVelocityAverage(double newVelocity) {
velocityHistory.add(newVelocity); // velocityHistory.add(newVelocity);
//
// int velocityHistorySize = 5;
// if (velocityHistory.size() > velocityHistorySize) {
// velocityHistory.removeFirst();
// }
//
// double sum = 0.0;
//
// for (double v : velocityHistory) {
// sum += v;
// }
//
// averageVelocity = sum / velocityHistory.size();
int velocityHistorySize = 5; averageVelocity = ALPHA * newVelocity + (1 - ALPHA) * averageVelocity;
if (velocityHistory.size() > velocityHistorySize) {
velocityHistory.removeFirst();
}
double sum = 0.0;
for (double v : velocityHistory) {
sum += v;
}
averageVelocity = sum / velocityHistory.size();
} }
double power;
double prevTargetTime = 0;
double prevTargetVelocity = 0;
public void manageFlywheel(double commandedVelocity) { public void manageFlywheel(double commandedVelocity) {
if (Math.abs(targetVelocity - commandedVelocity) > 0.0001) { if (Math.abs(targetVelocity - commandedVelocity) > 0.0001) {
@@ -115,17 +141,19 @@ public class Flywheel {
} }
robot.shooter1.setVelocity(RPM_to_TPS(targetVelocity)); robot.shooter1.setVelocity(RPM_to_TPS(targetVelocity));
power = robot.shooter1.getPower();
robot.shooter2.setVelocity(RPM_to_TPS(targetVelocity)); robot.shooter2.setPower(power);
velo1 = TPS_to_RPM(robot.shooter1.getVelocity()); velo1 = TPS_to_RPM(robot.shooter1.getVelocity());
velo2 = TPS_to_RPM(robot.shooter2.getVelocity()); velo2 = TPS_to_RPM(robot.shooter2.getVelocity());
velo = (velo1 + velo2) / 2.0; velo = velo1;
updateVelocityAverage(velo); updateVelocityAverage(velo);
steady = (Math.abs(commandedVelocity - averageVelocity) < 50); steady = (Math.abs(commandedVelocity - averageVelocity) < 50);
} }
public double getShooterPower(){return power;}
} }

View File

@@ -0,0 +1,22 @@
package org.firstinspires.ftc.teamcode.utilsv2;
import com.qualcomm.robotcore.hardware.Servo;
import org.firstinspires.ftc.teamcode.constants.ServoPositions;
public class ParkTilter {
Robot robot;
public ParkTilter (Robot rob) {
this.robot = rob;
}
public void park() {
robot.setTilt1Pos(ServoPositions.tilt1_down);
robot.setTilt2Pos(ServoPositions.tilt2_down);
}
public void unpark() {
robot.setTilt1Pos(ServoPositions.tilt1_up);
robot.setTilt2Pos(ServoPositions.tilt2_up);
}
}

View File

@@ -0,0 +1,305 @@
package org.firstinspires.ftc.teamcode.utilsv2;
import android.view.View;
import com.qualcomm.hardware.limelightvision.Limelight3A;
import com.qualcomm.hardware.rev.RevColorSensorV3;
import com.qualcomm.robotcore.hardware.AnalogInput;
import com.qualcomm.robotcore.hardware.DcMotor;
import com.qualcomm.robotcore.hardware.DcMotorEx;
import com.qualcomm.robotcore.hardware.DcMotorSimple;
import com.qualcomm.robotcore.hardware.HardwareMap;
import com.qualcomm.robotcore.hardware.PIDFCoefficients;
import com.qualcomm.robotcore.hardware.Servo;
import com.qualcomm.robotcore.hardware.TouchSensor;
import com.qualcomm.robotcore.hardware.VoltageSensor;
import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName;
import org.firstinspires.ftc.vision.apriltag.AprilTagProcessor;
public class Robot {
// Singleton instance
private static Robot instance;
/**
* Returns the existing Robot instance or creates one if it doesn't exist.
*/
public static Robot getInstance(HardwareMap hardwareMap) {
if (instance == null) {
instance = new Robot(hardwareMap);
}
return instance;
}
/**
* Optional: clears the singleton.
* Useful when switching OpModes.
*/
public static void resetInstance() {
instance = null;
}
public static boolean usingLimelight = true;
public static boolean usingCamera = false;
public DcMotorEx frontLeft;
public DcMotorEx frontRight;
public DcMotorEx backLeft;
public DcMotorEx backRight;
public DcMotorEx intake;
public DcMotorEx transfer;
// public double[] shooterPIDF_StepSizes = {10.0, 1.0, 0.001, 0.0001};
public DcMotorEx shooter1;
public DcMotorEx shooter2;
public Servo hood;
public Servo transferServo;
public Servo spindexBlocker;
public Servo rapidFireBlocker;
public Servo tilt1;
public Servo tilt2;
public Servo turr1;
public Servo turr2;
public Servo spin1;
public Servo spin2;
public TouchSensor insideBeam;
public TouchSensor outsideBeam;
public RevColorSensorV3 revSensor;
public VoltageSensor voltage;
// Below is disregarded
public AnalogInput spin1Pos;
public AnalogInput spin2Pos;
public AnalogInput turr1Pos;
public AnalogInput transferServoPos;
public AprilTagProcessor aprilTagProcessor;
public WebcamName webcam;
public RevColorSensorV3 color1;
public RevColorSensorV3 color2;
public RevColorSensorV3 color3;
public Limelight3A limelight;
public Servo light;
public Robot(HardwareMap hardwareMap) {
//Define components w/ hardware map
frontLeft = hardwareMap.get(DcMotorEx.class, "fl");
frontRight = hardwareMap.get(DcMotorEx.class, "fr");
backLeft = hardwareMap.get(DcMotorEx.class, "bl");
backRight = hardwareMap.get(DcMotorEx.class, "br");
frontLeft.setDirection(DcMotorSimple.Direction.REVERSE);
backLeft.setDirection(DcMotorSimple.Direction.REVERSE);
frontLeft.setZeroPowerBehavior(DcMotor.ZeroPowerBehavior.FLOAT);
frontRight.setZeroPowerBehavior(DcMotor.ZeroPowerBehavior.FLOAT);
backLeft.setZeroPowerBehavior(DcMotor.ZeroPowerBehavior.FLOAT);
backRight.setZeroPowerBehavior(DcMotor.ZeroPowerBehavior.FLOAT);
intake = hardwareMap.get(DcMotorEx.class, "intake");
intake.setDirection(DcMotorSimple.Direction.REVERSE);
shooter1 = hardwareMap.get(DcMotorEx.class, "shooter1");
shooter2 = hardwareMap.get(DcMotorEx.class, "shooter2");
shooter1.setDirection(DcMotorSimple.Direction.REVERSE);
// shooterPIDF = new PIDFCoefficients(shooterPIDF_P, shooterPIDF_I, shooterPIDF_D, shooterPIDF_F / 12);
shooter1.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
// shooter1.setPIDFCoefficients(DcMotor.RunMode.RUN_USING_ENCODER, shooterPIDF);
shooter2.setMode(DcMotor.RunMode.RUN_WITHOUT_ENCODER);
hood = hardwareMap.get(Servo.class, "hood");
turr1 = hardwareMap.get(Servo.class, "turr1");
turr2 = hardwareMap.get(Servo.class, "turr2");
spin1 = hardwareMap.get(Servo.class, "spin1");
spin2 = hardwareMap.get(Servo.class, "spin2");
transfer = hardwareMap.get(DcMotorEx.class, "transfer");
transferServo = hardwareMap.get(Servo.class, "transferServo");
transfer.setDirection(DcMotorSimple.Direction.REVERSE);
transfer.setMode(DcMotor.RunMode.RUN_WITHOUT_ENCODER);
spindexBlocker = hardwareMap.get(Servo.class, "spinB");
rapidFireBlocker = hardwareMap.get(Servo.class, "rapidB");
tilt1 = hardwareMap.get(Servo.class, "tilt1");
tilt2 = hardwareMap.get(Servo.class, "tilt2");
insideBeam = hardwareMap.get(TouchSensor.class, "beam1");
outsideBeam = hardwareMap.get(TouchSensor.class, "beam2");
revSensor = hardwareMap.get(RevColorSensorV3.class, "rev");
// Below is disregarded
// turr1Pos = hardwareMap.get(AnalogInput.class, "t1Pos"); // Encoder of turret plugged in intake port
//
// spin1Pos = hardwareMap.get(AnalogInput.class, "spin1Pos");
//
// spin2Pos = hardwareMap.get(AnalogInput.class, "spin2Pos");
//
// transferServoPos = hardwareMap.get(AnalogInput.class, "tSPos");
//
// color1 = hardwareMap.get(RevColorSensorV3.class, "c1");
//
// color2 = hardwareMap.get(RevColorSensorV3.class, "c2");
//
// color3 = hardwareMap.get(RevColorSensorV3.class, "c3");
if (usingLimelight) {
limelight = hardwareMap.get(Limelight3A.class, "limelight");
} else if (usingCamera) {
webcam = hardwareMap.get(WebcamName.class, "Webcam 1");
aprilTagProcessor = AprilTagProcessor.easyCreateWithDefaults();
}
// light = hardwareMap.get(Servo.class, "light");
voltage = hardwareMap.voltageSensor.iterator().next();
}
// Voids below are used to minimize hardware calls to minimize loop times
// Used to cut off digits that are negligible
private final int maxDigits = 3;
private final int roundingFactor = (int) Math.pow(10, maxDigits);
private double prevFrontLeftPower = -10.501;
public void setFrontLeftPower(double pow){
pow = (double) Math.round((float) pow * roundingFactor) / roundingFactor;
if (pow != prevFrontLeftPower){
frontLeft.setPower(pow);
}
prevFrontLeftPower = pow;
}
private double prevFrontRightPower = -10.501;
public void setFrontRightPower(double pow){
pow = (double) Math.round((float) pow * roundingFactor) / roundingFactor;
if (pow != prevFrontRightPower){
frontRight.setPower(pow);
}
prevFrontRightPower = pow;
}
private double prevBackLeftPower = -10.501;
public void setBackLeftPower(double pow){
pow = (double) Math.round((float) pow * roundingFactor) / roundingFactor;
if (pow != prevBackLeftPower){
backLeft.setPower(pow);
}
prevBackLeftPower = pow;
}
private double prevBackRightPower = -10.501;
public void setBackRightPower(double pow){
pow = (double) Math.round((float) pow * roundingFactor) / roundingFactor;
if (pow != prevBackRightPower){
backRight.setPower(pow);
}
prevBackRightPower = pow;
}
private double prevIntakePower = -10.501;
public void setIntakePower(double pow){
pow = (double) Math.round((float) pow * roundingFactor) / roundingFactor;
if (pow != prevIntakePower){
intake.setPower(pow);
}
prevIntakePower = pow;
}
private double prevTransferPower = -10.501;
public void setTransferPower(double pow){
pow = (double) Math.round((float) pow * roundingFactor) / roundingFactor;
if (pow != prevTransferPower){
transfer.setPower(pow);
}
prevTransferPower = pow;
}
// shooter motors are done in separate class
private double prevHoodPos = -10.501;
public void setHoodPos(double pos){
pos = (double) Math.round((float) pos * roundingFactor) / roundingFactor;
if (pos != prevHoodPos){
hood.setPosition(pos);
}
prevHoodPos = pos;
}
private double prevTransferServoPos = -10.501;
public void setTransferServoPos(double pos){
pos = (double) Math.round((float) pos * roundingFactor) / roundingFactor;
if (pos != prevTransferServoPos){
transferServo.setPosition(pos);
}
prevTransferServoPos = pos;
}
private double prevSpinPos = -10.501;
public void setSpinPos(double pos){
pos = (double) Math.round((float) pos * roundingFactor) / roundingFactor;
if (pos != prevSpinPos){
spin1.setPosition(pos);
spin2.setPosition(pos);
}
prevSpinPos = pos;
}
private double prevTurretPos = -10.501;
public void setTurretPos(double pos){
pos = (double) Math.round((float) pos * roundingFactor) / roundingFactor;
if (pos != prevTurretPos){
turr1.setPosition(pos);
turr2.setPosition(pos);
}
prevTurretPos = pos;
}
private double prevTilt1Pos = -10.501;
public void setTilt1Pos(double pos){
pos = (double) Math.round((float) pos * roundingFactor) / roundingFactor;
if (pos != prevTilt1Pos){
tilt1.setPosition(pos);
}
prevTilt1Pos = pos;
}
private double prevTilt2Pos = -10.501;
public void setTilt2Pos(double pos){
pos = (double) Math.round((float) pos * roundingFactor) / roundingFactor;
if (pos != prevTilt2Pos){
tilt2.setPosition(pos);
}
prevTilt2Pos = pos;
}
private double prevSpindexBlockerPos = -10.501;
public void setSpindexBlockerPos(double pos){
pos = (double) Math.round((float) pos * roundingFactor) / roundingFactor;
if (pos != prevSpindexBlockerPos){
spindexBlocker.setPosition(pos);
}
prevSpindexBlockerPos = pos;
}
private double prevRapidFireBlockerPos = -10.501;
public void setRapidFireBlockerPos(double pos){
pos = (double) Math.round((float) pos * roundingFactor) / roundingFactor;
if (pos != prevRapidFireBlockerPos){
rapidFireBlocker.setPosition(pos);
}
prevRapidFireBlockerPos = pos;
}
}

View File

@@ -1,10 +1,14 @@
package org.firstinspires.ftc.teamcode.utilsv2; package org.firstinspires.ftc.teamcode.utilsv2;
import static org.firstinspires.ftc.teamcode.utilsv2.Flywheel.*;
import com.acmerobotics.dashboard.config.Config;
import com.acmerobotics.dashboard.telemetry.MultipleTelemetry; import com.acmerobotics.dashboard.telemetry.MultipleTelemetry;
import com.pedropathing.follower.Follower; import com.pedropathing.follower.Follower;
import org.firstinspires.ftc.teamcode.utils.Robot; import org.firstinspires.ftc.teamcode.constants.Color;
@Config
public class Shooter { public class Shooter {
Robot robot; Robot robot;
@@ -16,38 +20,44 @@ public class Shooter {
double goalY = 0.0; double goalY = 0.0;
double obeliskX = 72; double obeliskX = 72;
double obeliskY = 144; double obeliskY = 144;
double turretGoalX = 0;
double turretGoalY = 0;
private boolean red = true; private boolean red = true;
public static boolean manualFlywheel = false;
Follower follow; Follower follow;
public Shooter(Robot rob, MultipleTelemetry TELE, Follower follower, boolean redAlliance) { public Shooter(Robot rob, MultipleTelemetry TELE, Follower follower, boolean redAlliance, Turret turret, Flywheel flywheel, VelocityCommander com) {
this.robot = rob; this.robot = rob;
this.fly = new Flywheel(rob); this.fly = flywheel;
this.turr = new Turret(rob); this.turr = turret;
this.follow = follower; this.follow = follower;
this.commander = new VelocityCommander(); this.commander = com;
setRedAlliance(redAlliance); setRedAlliance(redAlliance);
if (redAlliance) {
goalX = 144;
goalY = 144;
} else {
goalX = 0;
goalY = 144;
}
} }
public void setRedAlliance(boolean input) { public void setRedAlliance(boolean input) {
this.red = input; this.red = input;
if (this.red) {
goalX = 72;
turretGoalX = 68;
} else {
goalX = -72;
turretGoalX = -68;
}
goalY = 72;
turretGoalY = 68;
} }
private double flywheelVelocity = 0.0; private double flywheelVelocity = 0.0;
private double turretPosition = 0.5; private double turretPosition = 0.5;
enum ShooterState { public enum ShooterState {
READ_OBELISK, READ_OBELISK,
TRACK_GOAL, TRACK_GOAL,
MANUAL_FLYWHEEL_TRACK_TURR, MANUAL_FLYWHEEL_TRACK_TURR,
@@ -63,6 +73,10 @@ public class Shooter {
this.state = shooterState; this.state = shooterState;
} }
public ShooterState getState(){
return state;
}
public void setTurretPosition(double input) { public void setTurretPosition(double input) {
this.turretPosition = input; this.turretPosition = input;
} }
@@ -75,20 +89,34 @@ public class Shooter {
return turr.getObeliskID(); return turr.getObeliskID();
} }
private final double shooterDistFromCenter = 1.545;
public void update() { public void update(double voltage) {
setRedAlliance(Color.redAlliance);
switch (state) { switch (state) {
case NOTHING: case NOTHING:
break; break;
case MANUAL: case MANUAL:
manualFlywheel = true;
commander.getVeloPredictive(
(goalX - follow.getPose().getX() - shooterDistFromCenter*Math.cos(follow.getHeading())),
(goalY - follow.getPose().getY() - shooterDistFromCenter*Math.sin(follow.getHeading())),
follow.getVelocity().getXComponent(),
follow.getAcceleration().getXComponent(),
follow.getVelocity().getYComponent(),
follow.getAcceleration().getYComponent(),
voltage,
fly.getAverageVelocity()
);
fly.manageFlywheel(flywheelVelocity); fly.manageFlywheel(flywheelVelocity);
fly.setPIDF(shooterPIDF_P, shooterPIDF_I, shooterPIDF_D, shooterPIDF_F / voltage);
turr.manual(turretPosition); turr.manual(turretPosition);
break; break;
case TRACK_GOAL: case TRACK_GOAL:
manualFlywheel = false;
turr.trackGoal( turr.trackGoal(
(follow.getPose().getX() - goalX), (turretGoalX - follow.getPose().getX() - shooterDistFromCenter*Math.cos(follow.getHeading())),
(follow.getPose().getY() - goalY), (turretGoalY - follow.getPose().getY() - shooterDistFromCenter*Math.sin(follow.getHeading())),
follow.getHeading(), follow.getHeading(),
follow.getAngularVelocity(), follow.getAngularVelocity(),
follow.getVelocity().getXComponent(), follow.getVelocity().getXComponent(),
@@ -97,54 +125,71 @@ public class Shooter {
follow.getAcceleration().getYComponent() follow.getAcceleration().getYComponent()
); );
flywheelVelocity = commander.getVeloPredictive( commander.getVeloPredictive(
(follow.getPose().getX() - goalX), (goalX - follow.getPose().getX() - shooterDistFromCenter*Math.cos(follow.getHeading())),
(follow.getPose().getY() - goalY), (goalY - follow.getPose().getY() - shooterDistFromCenter*Math.sin(follow.getHeading())),
follow.getVelocity().getXComponent(), follow.getVelocity().getXComponent(),
follow.getAcceleration().getXComponent(), follow.getAcceleration().getXComponent(),
follow.getVelocity().getYComponent(), follow.getVelocity().getYComponent(),
follow.getAcceleration().getYComponent() follow.getAcceleration().getYComponent(),
voltage,
fly.getAverageVelocity()
); );
flywheelVelocity = commander.getPredictedRPM();
robot.setHoodPos(commander.getHoodPredicted());
fly.manageFlywheel(flywheelVelocity); fly.manageFlywheel(flywheelVelocity);
fly.setF(voltage);
break; break;
case READ_OBELISK: case READ_OBELISK:
turr.trackObelisk( manualFlywheel = false;
(follow.getPose().getX() - goalX), robot.setTurretPos(Turret.neutralPosition);
(follow.getPose().getY() - goalY),
follow.getHeading()
);
flywheelVelocity = commander.getVeloPredictive( turr.detectObelisk();
(follow.getPose().getX() - goalX),
(follow.getPose().getY() - goalY), commander.getVeloPredictive(
(goalX - follow.getPose().getX() - shooterDistFromCenter*Math.cos(follow.getHeading())),
(goalY - follow.getPose().getY() - shooterDistFromCenter*Math.sin(follow.getHeading())),
follow.getVelocity().getXComponent(), follow.getVelocity().getXComponent(),
follow.getAcceleration().getXComponent(), follow.getAcceleration().getXComponent(),
follow.getVelocity().getYComponent(), follow.getVelocity().getYComponent(),
follow.getAcceleration().getYComponent() follow.getAcceleration().getYComponent(),
voltage,
fly.getAverageVelocity()
); );
fly.manageFlywheel(flywheelVelocity); flywheelVelocity = commander.getPredictedRPM();
fly.manageFlywheel(0);
fly.setF(voltage);
break; break;
case MANUAL_TURRET_TRACK_FLY: case MANUAL_TURRET_TRACK_FLY:
manualFlywheel = false;
turr.manual(turretPosition); turr.manual(turretPosition);
flywheelVelocity = commander.getVeloPredictive( commander.getVeloPredictive(
(follow.getPose().getX() - goalX), (goalX - follow.getPose().getX() - shooterDistFromCenter*Math.cos(follow.getHeading())),
(follow.getPose().getY() - goalY), (goalY - follow.getPose().getY() - shooterDistFromCenter*Math.sin(follow.getHeading())),
follow.getVelocity().getXComponent(), follow.getVelocity().getXComponent(),
follow.getAcceleration().getXComponent(), follow.getAcceleration().getXComponent(),
follow.getVelocity().getYComponent(), follow.getVelocity().getYComponent(),
follow.getAcceleration().getYComponent() follow.getAcceleration().getYComponent(),
voltage,
fly.getAverageVelocity()
); );
flywheelVelocity = commander.getPredictedRPM();
robot.setHoodPos(commander.getHoodPredicted());
fly.manageFlywheel(flywheelVelocity); fly.manageFlywheel(flywheelVelocity);
break; break;
case MANUAL_FLYWHEEL_TRACK_TURR: case MANUAL_FLYWHEEL_TRACK_TURR:
manualFlywheel = true;
turr.trackGoal( turr.trackGoal(
(follow.getPose().getX() - goalX), (turretGoalX - follow.getPose().getX() - shooterDistFromCenter*Math.cos(follow.getHeading())),
(follow.getPose().getY() - goalY), (turretGoalY - follow.getPose().getY() - shooterDistFromCenter*Math.sin(follow.getHeading())),
follow.getHeading(), follow.getHeading(),
follow.getAngularVelocity(), follow.getAngularVelocity(),
follow.getVelocity().getXComponent(), follow.getVelocity().getXComponent(),
@@ -152,11 +197,26 @@ public class Shooter {
follow.getVelocity().getYComponent(), follow.getVelocity().getYComponent(),
follow.getAcceleration().getYComponent() follow.getAcceleration().getYComponent()
); );
commander.getVeloPredictive(
(goalX - follow.getPose().getX() - shooterDistFromCenter*Math.cos(follow.getHeading())),
(goalY - follow.getPose().getY() - shooterDistFromCenter*Math.sin(follow.getHeading())),
follow.getVelocity().getXComponent(),
follow.getAcceleration().getXComponent(),
follow.getVelocity().getYComponent(),
follow.getAcceleration().getYComponent(),
voltage,
fly.getAverageVelocity()
);
fly.manageFlywheel(flywheelVelocity); fly.manageFlywheel(flywheelVelocity);
fly.setPIDF(shooterPIDF_P, shooterPIDF_I, shooterPIDF_D, shooterPIDF_F / voltage);
fly.setF(voltage);
break; break;
} }
} }
public double getDistance(){return commander.getDistance();}
} }

View File

@@ -0,0 +1,746 @@
package org.firstinspires.ftc.teamcode.utilsv2;
import android.health.connect.datatypes.units.Velocity;
import com.acmerobotics.dashboard.config.Config;
import com.acmerobotics.dashboard.telemetry.MultipleTelemetry;
import com.qualcomm.robotcore.hardware.NormalizedRGBA;
import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit;
import org.firstinspires.ftc.teamcode.constants.ServoPositions;
import org.firstinspires.ftc.teamcode.tests.NewShooterTest;
@Config
public class SpindexerTransferIntake {
private final Robot robot;
VelocityCommander commander;
private MultipleTelemetry TELE;
public SpindexerTransferIntake(Robot rob, MultipleTelemetry tele, VelocityCommander com) {
this.robot = rob;
this.commander = com;
this.TELE = tele;
}
public enum DesiredPattern {
PPG,
PGP,
GPP
}
public enum SortedShootState {
IDLE,
MOVE_TO_1,
WAIT_FOR_1,
SHOOT_1,
RETRACT_1,
MOVE_TO_2,
WAIT_FOR_2,
SHOOT_2,
RETRACT_2,
MOVE_TO_3,
WAIT_FOR_3,
SHOOT_3,
RETRACT_3,
DONE
}
int[] shootOrder = {0, 1, 2};
final double sensorDistanceThreshold = 5.3;
final long pulseTime = 100; // ms
private DesiredPattern desiredPattern = DesiredPattern.GPP;
private SortedShootState shootState = SortedShootState.IDLE;
private long shootStateStartTime = System.currentTimeMillis();
private void setShootState(SortedShootState newState) {
shootState = newState;
shootStateStartTime = System.currentTimeMillis();
}
private long shootStateTime() {
return System.currentTimeMillis() - shootStateStartTime;
}
private int[] buildShootOrder(
BallStates[] loaded,
DesiredPattern desired) {
BallStates[] target;
switch (desired) {
case PPG:
target = new BallStates[]{
BallStates.PURPLE,
BallStates.PURPLE,
BallStates.GREEN
};
break;
case PGP:
target = new BallStates[]{
BallStates.PURPLE,
BallStates.GREEN,
BallStates.PURPLE
};
break;
default: // GPP
target = new BallStates[]{
BallStates.GREEN,
BallStates.PURPLE,
BallStates.PURPLE
};
}
int[] order = new int[3];
boolean[] used = new boolean[3];
// first pass: exact color matches
for (int i = 0; i < 3; i++) {
order[i] = -1;
for (int slot = 0; slot < 3; slot++) {
if (!used[slot]
&& loaded[slot] == target[i]) {
order[i] = slot;
used[slot] = true;
break;
}
}
}
// second pass: fill leftovers
for (int i = 0; i < 3; i++) {
if (order[i] != -1)
continue;
for (int slot = 0; slot < 3; slot++) {
if (!used[slot]) {
order[i] = slot;
used[slot] = true;
break;
}
}
}
return order;
}
private void moveToSlot(int slot) {
switch (slot) {
case 0:
robot.setSpinPos(
ServoPositions.spindexer_A1
);
break;
case 1:
robot.setSpinPos(
ServoPositions.spindexer_A2
);
break;
case 2:
robot.setSpinPos(
ServoPositions.spindexer_A3
);
break;
}
}
public enum SortedIntakeStates {
NOTHING,
IDLE,
INTAKE_1,
DELAY_1,
INTAKE_2,
DELAY_2,
INTAKE_3,
REVERSE,
}
public enum SpindexerMode {
RAPID,
SORTED,
SHOOT_SORTED
}
public enum BallStates {
GREEN,
PURPLE,
UNKNOWN
}
public enum RapidMode {
INTAKE,
TRANSFER_OFF,
BEFORE_PULSE_OUT,
PULSE_OUT,
PULSE_IN,
HOLD_BALLS,
OPEN_GATE,
SHOOT
}
private SpindexerMode mode = SpindexerMode.RAPID;
private RapidMode rapidMode = RapidMode.INTAKE;
private SortedIntakeStates sortedIntakeStates = SortedIntakeStates.IDLE;
private BallStates[] ballColors = {BallStates.UNKNOWN, BallStates.UNKNOWN, BallStates.UNKNOWN};
final double greenThresh = 0.39;
final double spinMovementTime = 250;
/**
* Time when current state was entered.
*/
private long stateStartTime = System.currentTimeMillis();
private long sortedStateStartTime = System.currentTimeMillis();
public void setDesiredPattern(DesiredPattern pattern) {
desiredPattern = pattern;
}
public void setDesiredPatternAuto(int id) {
if (id == 22){
desiredPattern = DesiredPattern.PGP;
} else if (id == 23){
desiredPattern = DesiredPattern.PPG;
} else {
desiredPattern = DesiredPattern.GPP;
}
}
public void startSortedShoot() {
shootOrder = buildShootOrder(
ballColors,
desiredPattern
);
setShootState(
SortedShootState.IDLE
);
setSpindexerMode(
SpindexerMode.SHOOT_SORTED
);
}
public void setRapidMode(RapidMode newMode) {
if (rapidMode != newMode) {
rapidMode = newMode;
stateStartTime = System.currentTimeMillis();
}
}
public void setSortedIntakeMode(SortedIntakeStates newMode) {
if (sortedIntakeStates != newMode) {
sortedIntakeStates = newMode;
sortedStateStartTime = System.currentTimeMillis();
}
}
public void setSpindexerMode(SpindexerMode spindexerMode) {
this.mode = spindexerMode;
}
public RapidMode getRapidState() {
return this.rapidMode;
}
private long stateTime() {
return System.currentTimeMillis() - stateStartTime;
}
private long sortedStateTime() {
return System.currentTimeMillis() - sortedStateStartTime;
}
private int greenTicks = 0;
private int ballTicks = 0;
private int holdBallsTicker = 0;
public void update() {
// TELE.addData("Sorted State", sortedIntakeStates);
// TELE.addData("Ball0", ballColors[0]);
// TELE.addData("Ball1", ballColors[1]);
// TELE.addData("Ball2", ballColors[2]);
//
// TELE.addData("Shoot0", shootOrder[0]);
// TELE.addData("Shoot1", shootOrder[1]);
// TELE.addData("Shoot2", shootOrder[2]);
//
// TELE.addData("Color0", ballColors[0]);
// TELE.addData("Color1", ballColors[1]);
// TELE.addData("Color2", ballColors[2]);
//
// TELE.addData("Shoot State", shootState);
switch (mode) {
case RAPID:
robot.setSpindexBlockerPos(
ServoPositions.spindexBlocker_Open
);
switch (rapidMode) {
case INTAKE:
robot.setIntakePower(1);
robot.setRapidFireBlockerPos(
ServoPositions.rapidFireBlocker_Closed
);
robot.setSpinPos(
ServoPositions.spindexer_A2
);
robot.setTransferPower(-0.7);
robot.setTransferServoPos(
ServoPositions.transferServo_out
);
if (robot.insideBeam.isPressed() && robot.revSensor.getDistance(DistanceUnit.CM) < sensorDistanceThreshold) {
holdBallsTicker++;
}
if (holdBallsTicker > 10){
setRapidMode(RapidMode.TRANSFER_OFF);
holdBallsTicker = 0;
}
break;
case TRANSFER_OFF:
if (robot.insideBeam.isPressed() && robot.outsideBeam.isPressed()) {
setRapidMode(RapidMode.BEFORE_PULSE_OUT);
}
robot.setTransferPower(-0.3);
break;
case BEFORE_PULSE_OUT:
robot.setIntakePower(1.0);
if (stateTime() >= 300) {
setRapidMode(RapidMode.PULSE_OUT);
}
break;
case PULSE_OUT:
robot.setIntakePower(-0.1);
if (stateTime() >= pulseTime) {
setRapidMode(RapidMode.PULSE_IN);
}
break;
case PULSE_IN:
robot.setIntakePower(1.0);
if (stateTime() >= 200) {
setRapidMode(RapidMode.HOLD_BALLS);
}
break;
case HOLD_BALLS:
if (robot.insideBeam.isPressed()
&& robot.outsideBeam.isPressed()) {
robot.setTransferPower(0);
robot.setIntakePower(0.1);
robot.setTransferServoPos(ServoPositions.transferServo_in);
} else {
holdBallsTicker++;
robot.setIntakePower(1);
}
break;
case OPEN_GATE:
if (stateTime() >= 100) {
setRapidMode(RapidMode.SHOOT);
}
robot.setTransferServoPos(ServoPositions.transferServo_in);
robot.setRapidFireBlockerPos(
ServoPositions.rapidFireBlocker_Open
);
if (Shooter.manualFlywheel) {
robot.setTransferPower(NewShooterTest.transferPower);
robot.setIntakePower(-NewShooterTest.transferPower);
} else {
robot.setTransferPower(commander.getTransferPow());
robot.setIntakePower(-commander.getTransferPow());
}
break;
case SHOOT:
if (stateTime() >= 500) {
setRapidMode(RapidMode.INTAKE);
}
if (Shooter.manualFlywheel) {
robot.setTransferPower(NewShooterTest.transferPower);
robot.setIntakePower(-NewShooterTest.transferPower);
} else {
robot.setTransferPower(commander.getTransferPow());
robot.setIntakePower(-commander.getTransferPow());
}
holdBallsTicker = 0;
break;
}
break;
case SORTED:
robot.setRapidFireBlockerPos(ServoPositions.rapidFireBlocker_Open);
switch (sortedIntakeStates) {
case NOTHING:
break;
case IDLE:
ballColors[0] = BallStates.UNKNOWN;
ballColors[1] = BallStates.UNKNOWN;
ballColors[2] = BallStates.UNKNOWN;
robot.setRapidFireBlockerPos(
ServoPositions.rapidFireBlocker_Open
);
robot.setSpindexBlockerPos(
ServoPositions.spindexBlocker_Closed
);
robot.setSpinPos(
ServoPositions.spindexer_A1
);
robot.setTransferServoPos(
ServoPositions.transferServo_out
);
robot.setIntakePower(1);
robot.setTransferPower(-0.7);
if (sortedStateTime() > 200) {
setSortedIntakeMode(SortedIntakeStates.INTAKE_1);
}
break;
case INTAKE_1:
robot.setIntakePower(1);
robot.setTransferPower(-0.7);
if (robot.insideBeam.isPressed() && robot.revSensor.getDistance(DistanceUnit.CM) < sensorDistanceThreshold) {
NormalizedRGBA revColor = robot.revSensor.getNormalizedColors();
if ((revColor.green / (revColor.red + revColor.blue + revColor.green)) > greenThresh) {
greenTicks++;
}
ballTicks++;
if (ballTicks > 15) {
if (greenTicks > 10){
ballColors[0] = BallStates.GREEN;
} else {
ballColors[0] = BallStates.PURPLE;
}
robot.setSpinPos(ServoPositions.spindexer_A2);
setSortedIntakeMode(SortedIntakeStates.DELAY_1);
ballTicks = 0;
greenTicks = 0;
}
}
break;
case DELAY_1:
robot.setSpinPos(ServoPositions.spindexer_A2);
if (sortedStateTime() > spinMovementTime) {
setSortedIntakeMode(SortedIntakeStates.INTAKE_2);
}
break;
case INTAKE_2:
robot.setIntakePower(1);
robot.setTransferPower(-1);
if (robot.insideBeam.isPressed() && robot.revSensor.getDistance(DistanceUnit.CM) < sensorDistanceThreshold) {
NormalizedRGBA revColor = robot.revSensor.getNormalizedColors();
if ((revColor.green / (revColor.red + revColor.blue + revColor.green)) > greenThresh) {
greenTicks++;
}
ballTicks++;
if (ballTicks > 15) {
if (greenTicks > 10){
ballColors[1] = BallStates.GREEN;
} else {
ballColors[1] = BallStates.PURPLE;
}
robot.setSpinPos(ServoPositions.spindexer_A3);
setSortedIntakeMode(SortedIntakeStates.DELAY_2);
ballTicks = 0;
greenTicks = 0;
}
}
break;
case DELAY_2:
robot.setSpinPos(
ServoPositions.spindexer_A3
);
if (sortedStateTime() > spinMovementTime) {
setSortedIntakeMode(
SortedIntakeStates.INTAKE_3
);
}
break;
case INTAKE_3:
robot.setIntakePower(1);
robot.setTransferPower(-1);
if (robot.insideBeam.isPressed() && robot.revSensor.getDistance(DistanceUnit.CM) < sensorDistanceThreshold) {
NormalizedRGBA revColor = robot.revSensor.getNormalizedColors();
if ((revColor.green / (revColor.red + revColor.blue + revColor.green)) > greenThresh) {
greenTicks++;
}
ballTicks++;
if (ballTicks > 15) {
if (greenTicks > 10){
ballColors[2] = BallStates.GREEN;
} else {
ballColors[2] = BallStates.PURPLE;
}
setSortedIntakeMode(SortedIntakeStates.REVERSE);
ballTicks = 0;
greenTicks = 0;
}
}
break;
case REVERSE:
robot.setTransferPower(-0.3);
robot.setIntakePower(-0.1);
break;
}
break;
case SHOOT_SORTED:
robot.setRapidFireBlockerPos(ServoPositions.rapidFireBlocker_Open);
if (Shooter.manualFlywheel) {
robot.setTransferPower(NewShooterTest.transferPower);
} else {
robot.setTransferPower(commander.getTransferPow());
}
switch (shootState) {
case IDLE:
shootOrder = buildShootOrder(
ballColors,
desiredPattern
);
setShootState(SortedShootState.MOVE_TO_1);
mode = SpindexerMode.SHOOT_SORTED;
break;
case MOVE_TO_1:
moveToSlot(shootOrder[0]);
robot.setRapidFireBlockerPos(
ServoPositions.rapidFireBlocker_Open
);
robot.setSpindexBlockerPos(
ServoPositions.spindexBlocker_Closed
);
setShootState(
SortedShootState.WAIT_FOR_1
);
break;
case WAIT_FOR_1:
if (shootStateTime() > 400) {
setShootState(
SortedShootState.SHOOT_1
);
}
break;
case SHOOT_1:
robot.setSpindexBlockerPos(ServoPositions.spindexBlocker_Open);
robot.setTransferServoPos(ServoPositions.transferServo_in);
if (shootStateTime() > 300) {
setShootState(
SortedShootState.RETRACT_1
);
}
break;
case RETRACT_1:
robot.setSpindexBlockerPos(ServoPositions.spindexBlocker_Closed);
robot.setTransferServoPos(ServoPositions.transferServo_out);
if (shootStateTime() > 150) {
setShootState(
SortedShootState.MOVE_TO_2
);
}
break;
case MOVE_TO_2:
moveToSlot(shootOrder[1]);
setShootState(
SortedShootState.WAIT_FOR_2
);
break;
case WAIT_FOR_2:
if (shootStateTime() > 400) {
setShootState(
SortedShootState.SHOOT_2
);
}
break;
case SHOOT_2:
robot.setSpindexBlockerPos(ServoPositions.spindexBlocker_Open);
robot.setTransferServoPos(ServoPositions.transferServo_in);
if (shootStateTime() > 300) {
setShootState(
SortedShootState.RETRACT_2
);
}
break;
case RETRACT_2:
robot.setSpindexBlockerPos(ServoPositions.spindexBlocker_Closed);
robot.setTransferServoPos(ServoPositions.transferServo_out);
if (shootStateTime() > 150) {
setShootState(
SortedShootState.MOVE_TO_3
);
}
break;
case MOVE_TO_3:
moveToSlot(shootOrder[2]);
setShootState(
SortedShootState.WAIT_FOR_3
);
break;
case WAIT_FOR_3:
if (shootStateTime() > 400) {
setShootState(
SortedShootState.SHOOT_3
);
}
break;
case SHOOT_3:
robot.setSpindexBlockerPos(ServoPositions.spindexBlocker_Open);
robot.setTransferServoPos(ServoPositions.transferServo_in);
if (shootStateTime() > 300) {
setShootState(
SortedShootState.RETRACT_3
);
}
break;
case RETRACT_3:
robot.setTransferServoPos(ServoPositions.transferServo_out);
if (shootStateTime() > 150) {
setShootState(
SortedShootState.DONE
);
}
break;
case DONE:
robot.setRapidFireBlockerPos(
ServoPositions.rapidFireBlocker_Open
);
robot.setSpindexBlockerPos(
ServoPositions.spindexBlocker_Closed
);
robot.setSpinPos(
ServoPositions.spindexer_A1
);
robot.setTransferServoPos(
ServoPositions.transferServo_out
);
robot.setIntakePower(1);
robot.setTransferPower(-0.7);
if (shootStateTime() > 250) {
setSortedIntakeMode(
SortedIntakeStates.IDLE
);
mode = SpindexerMode.SORTED;
}
break;
}
break;
}
}
}

View File

@@ -1,11 +1,13 @@
package org.firstinspires.ftc.teamcode.utilsv2; package org.firstinspires.ftc.teamcode.utilsv2;
import com.acmerobotics.dashboard.config.Config; import com.acmerobotics.dashboard.config.Config;
import com.arcrobotics.ftclib.controller.PIDController;
import com.qualcomm.hardware.limelightvision.LLResult; import com.qualcomm.hardware.limelightvision.LLResult;
import com.qualcomm.hardware.limelightvision.LLResultTypes; import com.qualcomm.hardware.limelightvision.LLResultTypes;
import com.qualcomm.robotcore.util.Range; import com.qualcomm.robotcore.util.Range;
import org.firstinspires.ftc.teamcode.utils.Robot;
import org.firstinspires.ftc.teamcode.constants.Color;
import java.util.List; import java.util.List;
@@ -13,10 +15,23 @@ import java.util.List;
public class Turret { public class Turret {
Robot robot; Robot robot;
private final double servoTicksPer180 = 0.6; // TODO: Tune private final double servoTicksPer180 = 0.58;
private final double neutralPosition = 0.5; //TODO: Tune public static double neutralPosition = 0.51;
private final double turretMin = 0.04; //TODO: Tune private final double turretMin = 0.05;
private final double turretMax = 0.94; //TODO: Tune private final double turretMax = 0.95;
public static boolean limelightUsed = true;
public static double B_PID_P = 0.0001, B_PID_I = 0.0, B_PID_D = 0.000005;
LLResult result;
PIDController bearingPID;
boolean bearingAligned = false;
public int LL_COAST_TICKS = 5;
public static double TARGET_POSITION_TOLERANCE = 0.65;
public static double alphaTX = 0.5;
private double targetTx = 0;
private double currentTrackOffset = 0;
private double llCoast = 0;
private double servoAngle = 0.51;
double tx = 0.0;
private final double hVelK = 0; // TODO: Tune private final double hVelK = 0; // TODO: Tune
private final double xVelK = 0; // TODO: Tune private final double xVelK = 0; // TODO: Tune
private final double xAccK = 0; // TODO: Tune private final double xAccK = 0; // TODO: Tune
@@ -29,6 +44,7 @@ public class Turret {
public Turret(Robot rob) { public Turret(Robot rob) {
this.robot = rob; this.robot = rob;
bearingPID = new PIDController(B_PID_P, B_PID_I, B_PID_D);
} }
private double wrapAngle(double angle) { private double wrapAngle(double angle) {
@@ -37,6 +53,43 @@ public class Turret {
return angle; return angle;
} }
private void limelightRead() { // only for tracking purposes, not general reads
switchPipeline(PipelineMode.TRACKING);
result = robot.limelight.getLatestResult();
tx = 1000;
if (result != null) {
if (result.isValid()) {
tx = result.getTx();
}
}
}
public double getTX(){return tx;}
public enum PipelineMode{
OBELISK,
TRACKING
}
private int prevPipeline = 0;
public void switchPipeline(PipelineMode pipelineMode){
int pipeline = 0;
if (pipelineMode == PipelineMode.OBELISK){
pipeline = 1;
} else if (pipelineMode == PipelineMode.TRACKING){
if (Color.redAlliance){
pipeline = 4;
} else {
pipeline = 2;
}
}
if (pipeline != prevPipeline){
robot.limelight.pipelineSwitch(pipeline);
}
prevPipeline = pipeline;
}
public int pipeline(){return prevPipeline;}
public void trackObelisk(double dx, double dy, double h) { public void trackObelisk(double dx, double dy, double h) {
double heading = wrapAngle(h); double heading = wrapAngle(h);
@@ -53,8 +106,7 @@ public class Turret {
servoAngle = Range.clip(servoAngle, turretMin, turretMax); servoAngle = Range.clip(servoAngle, turretMin, turretMax);
robot.turr1.setPosition(servoAngle); robot.setTurretPos(servoAngle);
robot.turr2.setPosition(1.0 - servoAngle);
detectObelisk(); detectObelisk();
@@ -64,32 +116,26 @@ public class Turret {
return obeliskID; return obeliskID;
} }
private int detectObelisk() { public void detectObelisk() {
robot.limelight.pipelineSwitch(1); result = robot.limelight.getLatestResult();
LLResult result = robot.limelight.getLatestResult();
if (result != null && result.isValid()) { if (result != null && result.isValid()) {
List<LLResultTypes.FiducialResult> fiducials = result.getFiducialResults(); List<LLResultTypes.FiducialResult> fiducials = result.getFiducialResults();
double prevTx = -1000;
for (LLResultTypes.FiducialResult fiducial : fiducials) { for (LLResultTypes.FiducialResult fiducial : fiducials) {
double currentTx = fiducial.getTargetXDegrees(); obeliskID = fiducial.getFiducialId();
if (currentTx > prevTx){
obeliskID = fiducial.getFiducialId();
}
} }
} }
return obeliskID;
} }
public void manual (double pos) { public void manual (double pos) {
robot.turr1.setPosition(pos); robot.setTurretPos(pos);
robot.turr2.setPosition(pos);
} }
public void trackGoal(double dx, double dy, double h, double hVel, double xVel, double xAcc, double yVel, double yAcc) { public void trackGoal(double dx, double dy, double h, double hVel, double xVel, double xAcc, double yVel, double yAcc) {
// dx, dy, dz is target - robot // dx, dy, dz is target - robot
// h is the raw heading where 0 degrees is positive x in the system of x, y // h is the raw heading where 0 degrees is positive x in the system of x, y
bearingPID = new PIDController(B_PID_P, B_PID_I, B_PID_D); // Keep when debugging/tuning, comment out when doing teleop
double predictedDx = dx - (xVel * xVelK) - (0.5 * xAcc * xAccK); // Negative bc dx = target - robot double predictedDx = dx - (xVel * xVelK) - (0.5 * xAcc * xAccK); // Negative bc dx = target - robot
double predictedDy = dy - (yVel * yVelK) - (0.5 * yAcc * yAccK); // Negative bc dy = target - robot double predictedDy = dy - (yVel * yVelK) - (0.5 * yAcc * yAccK); // Negative bc dy = target - robot
double predictedH = h + (hVel * hVelK); // Positive bc h = robot heading double predictedH = h + (hVel * hVelK); // Positive bc h = robot heading
@@ -99,15 +145,37 @@ public class Turret {
double fieldRelativeHeading = Math.atan2(predictedDy, predictedDx); double fieldRelativeHeading = Math.atan2(predictedDy, predictedDx);
double angleDelta = fieldRelativeHeading - predictedH; double angleDelta = fieldRelativeHeading - predictedH;
angleDelta = wrapAngle(angleDelta); angleDelta = wrapAngle(angleDelta) / (2.0 * Math.PI);
double servoTicksFromNeutral = (angleDelta / (2.0 * Math.PI)) * (2.0 * servoTicksPer180); double bearingOffset = 0;
if (limelightUsed && servoAngle > turretMin && servoAngle < turretMax){
limelightRead();
if (result.isValid() && tx < 100){
targetTx = (tx*alphaTX)+(targetTx*(1-alphaTX));
bearingAligned = Math.abs(targetTx) < TARGET_POSITION_TOLERANCE;
if (!bearingAligned){
bearingOffset = (bearingPID.calculate(targetTx, 0.0));
}
} else {
targetTx = 0;
bearingOffset = 0;
}
currentTrackOffset += bearingOffset;
llCoast = LL_COAST_TICKS;
} else {
if (llCoast <= 0){
currentTrackOffset = 0;
} else {
llCoast--;
}
}
double servoAngle = neutralPosition + servoTicksFromNeutral; double servoTicksFromNeutral = (angleDelta+currentTrackOffset) * (2.0 * servoTicksPer180);
servoAngle = neutralPosition + servoTicksFromNeutral;
servoAngle = Range.clip(servoAngle, turretMin, turretMax); servoAngle = Range.clip(servoAngle, turretMin, turretMax);
robot.turr1.setPosition(servoAngle); robot.setTurretPos(servoAngle);
robot.turr2.setPosition(servoAngle);
} }
} }

View File

@@ -1,34 +1,112 @@
package org.firstinspires.ftc.teamcode.utilsv2; package org.firstinspires.ftc.teamcode.utilsv2;
import com.acmerobotics.dashboard.config.Config;
@Config
public class VelocityCommander { public class VelocityCommander {
private final double goalH = 20.0; //TODO: Tune public static double xVelK = 0.05; // TODO: Tune
private final double xVelK = 0; // TODO: Tune public static double xAccK = 0.025; // TODO: Tune
private final double xAccK = 0; // TODO: Tune public static double yVelK = 0.05; // TODO: Tune
private final double yVelK = 0; // TODO: Tune public static double yAccK = 0.025; // TODO: Tune
private final double yAccK = 0; // TODO: Tune public static boolean lockFront = false;
public static boolean lockBack = false;
public static int farBound = 140;
public static int closeBound = 110;
public static double errorHoodAdjustment = 0.0005;
private double hoodPos = 0.88;
private double transferPow = -1;
private int velo = 0;
public VelocityCommander() { public VelocityCommander() {}
}
final double veloA = -0.00000133612;
final double veloB = 0.000542733;
final double veloC = -0.0739531;
final double veloD = 5.16759;
final double veloE = 62.45781;
private double distToRPM (double dist){ private double distToRPM (double dist){
return Math.sqrt(dist*dist + goalH*goalH); double currentVelo;
//TODO: Add regression here using goalH if (lockFront && dist > closeBound){
dist = closeBound;
} else if (lockBack && dist < farBound){
dist = farBound;
}
if (dist < 54) {
velo = 2000;
} else if (dist > 181){
velo = 3600;
} else {
currentVelo = veloA*Math.pow(dist, 4) +
veloB*Math.pow(dist, 3) +
veloC*Math.pow(dist, 2) +
veloD*Math.pow(dist, 1) +
veloE;
velo = 10 * Math.round((float) Math.max(200, Math.min(360, currentVelo)));
}
return velo;
} }
final double hoodA = 9.04203*Math.pow(10, -8);
final double hoodB = -0.0000204165;
final double hoodC = -0.00252089;
final double hoodD = 1.06154;
private void distToHood (double dist){
if (dist > 174){
hoodPos = 0.48;
} else if (dist < 54){
hoodPos = 0.88;
} else {
hoodPos = hoodA*Math.pow(dist, 3) +
hoodB*Math.pow(dist, 2) +
hoodC*Math.pow(dist, 1) +
hoodD;
}
hoodPos = Math.max(0.48, Math.min(0.88, hoodPos));
}
public double getHoodPredicted(){
return hoodPos;
}
private void distToTransferPow(double dist, double voltage){
if (dist < 140){
transferPow = -0.8;
} else {
transferPow = -0.5;
}
}
public double getTransferPow(){return transferPow;}
// 27
public double getVeloStationary (double distance){ public double getVeloStationary (double distance){
return distToRPM(distance); return distToRPM(distance);
} }
public double getVeloPredictive(double dx, double dy, double xVel, double xAcc, double yVel, double yAcc) { double predictedDist = 0;
public void getVeloPredictive(double dx, double dy, double xVel, double xAcc, double yVel, double yAcc, double voltage, double velocity) {
double predictedDx = dx - (xVel * xVelK) - (0.5 * xAcc * xAccK); // Negative bc dx = target - robot double predictedDx = dx - (xVel * xVelK) - (0.5 * xAcc * xAccK); // Negative bc dx = target - robot
double predictedDy = dy - (yVel * yVelK) - (0.5 * yAcc * yAccK); // Negative bc dy = target - robot double predictedDy = dy - (yVel * yVelK) - (0.5 * yAcc * yAccK); // Negative bc dy = target - robot
double predictedDist = Math.sqrt(dx*dx + dy*dy); double goalHeight = 28;
predictedDist = Math.sqrt(predictedDx*predictedDx + predictedDy*predictedDy + goalHeight * goalHeight);
return distToRPM(predictedDist); distToHood(predictedDist);
distToTransferPow(predictedDist, voltage);
distToRPM(predictedDist);
hoodPos += adjustHood(predictedDist, velocity, velo);
} }
public double adjustHood(double dist, double currentVelocity, double targetVelocity){
double error = targetVelocity - currentVelocity;
if (dist < farBound || error < 0){
error = 0;
}
System.out.println("Error "+ error);
return error * errorHoodAdjustment;
}
public double getPredictedRPM(){return velo;}
public double getDistance(){return predictedDist;}
} }