Working Spindexer prototype with original shoot all functionality.
This commit is contained in:
@@ -7,9 +7,9 @@ public class ServoPositions {
|
|||||||
|
|
||||||
public static double spindexer_intakePos1 = 0.39;
|
public static double spindexer_intakePos1 = 0.39;
|
||||||
|
|
||||||
public static double spindexer_intakePos2 = 0.5;
|
public static double spindexer_intakePos2 = 0.55;//0.5;
|
||||||
|
|
||||||
public static double spindexer_intakePos3 = 0.66;
|
public static double spindexer_intakePos3 = 0.71;//0.66;
|
||||||
|
|
||||||
public static double spindexer_outtakeBall3 = 0.47;
|
public static double spindexer_outtakeBall3 = 0.47;
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import org.firstinspires.ftc.teamcode.libs.RR.MecanumDrive;
|
|||||||
import org.firstinspires.ftc.teamcode.utils.Flywheel;
|
import org.firstinspires.ftc.teamcode.utils.Flywheel;
|
||||||
import org.firstinspires.ftc.teamcode.utils.Robot;
|
import org.firstinspires.ftc.teamcode.utils.Robot;
|
||||||
import org.firstinspires.ftc.teamcode.utils.Servos;
|
import org.firstinspires.ftc.teamcode.utils.Servos;
|
||||||
|
import org.firstinspires.ftc.teamcode.utils.Spindexer;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -70,6 +71,7 @@ public class TeleopV3 extends LinearOpMode {
|
|||||||
Servos servo;
|
Servos servo;
|
||||||
Flywheel flywheel;
|
Flywheel flywheel;
|
||||||
MecanumDrive drive;
|
MecanumDrive drive;
|
||||||
|
Spindexer spindexer;
|
||||||
double autoHoodOffset = 0.0;
|
double autoHoodOffset = 0.0;
|
||||||
|
|
||||||
int shooterTicker = 0;
|
int shooterTicker = 0;
|
||||||
@@ -94,7 +96,8 @@ public class TeleopV3 extends LinearOpMode {
|
|||||||
boolean shootA = true;
|
boolean shootA = true;
|
||||||
boolean shootB = true;
|
boolean shootB = true;
|
||||||
boolean shootC = true;
|
boolean shootC = true;
|
||||||
boolean autoSpintake = true;
|
boolean autoSpintake = false;
|
||||||
|
boolean enableSpindexerManager = true;
|
||||||
List<Integer> shootOrder = new ArrayList<>();
|
List<Integer> shootOrder = new ArrayList<>();
|
||||||
boolean outtake1 = false;
|
boolean outtake1 = false;
|
||||||
boolean outtake2 = false;
|
boolean outtake2 = false;
|
||||||
@@ -142,6 +145,7 @@ public class TeleopV3 extends LinearOpMode {
|
|||||||
servo = new Servos(hardwareMap);
|
servo = new Servos(hardwareMap);
|
||||||
flywheel = new Flywheel(hardwareMap);
|
flywheel = new Flywheel(hardwareMap);
|
||||||
drive = new MecanumDrive(hardwareMap, teleStart);
|
drive = new MecanumDrive(hardwareMap, teleStart);
|
||||||
|
spindexer = new Spindexer(hardwareMap);
|
||||||
|
|
||||||
PIDFController tController = new PIDFController(tp, ti, td, tf);
|
PIDFController tController = new PIDFController(tp, ti, td, tf);
|
||||||
|
|
||||||
@@ -529,7 +533,7 @@ public class TeleopV3 extends LinearOpMode {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if (gamepad1.left_bumper) {
|
if (gamepad1.left_bumper && !enableSpindexerManager) {
|
||||||
|
|
||||||
robot.transferServo.setPosition(transferServo_out);
|
robot.transferServo.setPosition(transferServo_out);
|
||||||
|
|
||||||
@@ -560,14 +564,14 @@ public class TeleopV3 extends LinearOpMode {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gamepad1.leftBumperWasReleased()) {
|
if (gamepad1.leftBumperWasReleased() && !enableSpindexerManager) {
|
||||||
shootStamp = getRuntime();
|
shootStamp = getRuntime();
|
||||||
shootAll = true;
|
shootAll = true;
|
||||||
|
|
||||||
shooterTicker = 0;
|
shooterTicker = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shootAll) {
|
if (shootAll && !enableSpindexerManager) {
|
||||||
|
|
||||||
TELE.addData("100% works", shootOrder);
|
TELE.addData("100% works", shootOrder);
|
||||||
|
|
||||||
@@ -765,7 +769,57 @@ public class TeleopV3 extends LinearOpMode {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
//EXTRA STUFFINESS:
|
//EXTRA STUFFINESS:
|
||||||
|
if (enableSpindexerManager) {
|
||||||
|
if (!shootAll) {
|
||||||
|
spindexer.processIntake();
|
||||||
|
}
|
||||||
|
|
||||||
|
// RIGHT_BUMPER
|
||||||
|
if (gamepad1.right_bumper) {
|
||||||
|
robot.intake.setPower(1);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
robot.intake.setPower(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// LEFT_BUMPER
|
||||||
|
if (gamepad1.leftBumperWasReleased()) {
|
||||||
|
shootStamp = getRuntime();
|
||||||
|
shootAll = true;
|
||||||
|
|
||||||
|
shooterTicker = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shootAll) {
|
||||||
|
|
||||||
|
TELE.addData("100% works", shootOrder);
|
||||||
|
|
||||||
|
intake = false;
|
||||||
|
reject = false;
|
||||||
|
|
||||||
|
shooterTicker++;
|
||||||
|
|
||||||
|
spindexPos = spindexer_intakePos1;
|
||||||
|
|
||||||
|
if (getRuntime() - shootStamp < 3.5) {
|
||||||
|
|
||||||
|
robot.transferServo.setPosition(transferServo_in);
|
||||||
|
|
||||||
|
robot.spin1.setPower(-spinPow);
|
||||||
|
robot.spin2.setPower(spinPow);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
robot.transferServo.setPosition(transferServo_out);
|
||||||
|
spindexPos = spindexer_intakePos1;
|
||||||
|
|
||||||
|
shootAll = false;
|
||||||
|
|
||||||
|
robot.transferServo.setPosition(transferServo_out);
|
||||||
|
|
||||||
|
spindexer.resetSpindexer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
drive.updatePoseEstimate();
|
drive.updatePoseEstimate();
|
||||||
|
|
||||||
for (LynxModule hub : allHubs) {
|
for (LynxModule hub : allHubs) {
|
||||||
@@ -786,9 +840,11 @@ public class TeleopV3 extends LinearOpMode {
|
|||||||
TELE.addData("oddColor", oddBallColor);
|
TELE.addData("oddColor", oddBallColor);
|
||||||
|
|
||||||
TELE.addData("spinEqual", servo.spinEqual(spindexer_intakePos1));
|
TELE.addData("spinEqual", servo.spinEqual(spindexer_intakePos1));
|
||||||
|
TELE.addData("spinCommmandedPos", spindexer.commandedIntakePosition);
|
||||||
|
TELE.addData("spinIntakeState", spindexer.currentIntakeState);
|
||||||
|
TELE.addData("spinTestCounter", spindexer.counter);
|
||||||
TELE.addData("autoSpintake", autoSpintake);
|
TELE.addData("autoSpintake", autoSpintake);
|
||||||
TELE.addData("timeSinceStamp", getRuntime() - shootStamp);
|
TELE.addData("timeSinceStamp", getRuntime() - shootStamp);
|
||||||
|
|
||||||
TELE.update();
|
TELE.update();
|
||||||
|
|
||||||
ticker++;
|
ticker++;
|
||||||
|
|||||||
@@ -0,0 +1,275 @@
|
|||||||
|
package org.firstinspires.ftc.teamcode.utils;
|
||||||
|
|
||||||
|
import com.acmerobotics.dashboard.telemetry.MultipleTelemetry;
|
||||||
|
import com.arcrobotics.ftclib.controller.PIDFController;
|
||||||
|
import com.qualcomm.robotcore.hardware.HardwareMap;
|
||||||
|
|
||||||
|
import static org.firstinspires.ftc.teamcode.constants.ServoPositions.spindexer_intakePos1;
|
||||||
|
import static org.firstinspires.ftc.teamcode.constants.ServoPositions.spindexer_intakePos2;
|
||||||
|
import static org.firstinspires.ftc.teamcode.constants.ServoPositions.spindexer_intakePos3;
|
||||||
|
import static org.firstinspires.ftc.teamcode.constants.ServoPositions.spindexer_outtakeBall1;
|
||||||
|
import static org.firstinspires.ftc.teamcode.constants.ServoPositions.spindexer_outtakeBall2;
|
||||||
|
import static org.firstinspires.ftc.teamcode.constants.ServoPositions.spindexer_outtakeBall3;
|
||||||
|
import static org.firstinspires.ftc.teamcode.utils.Servos.spinD;
|
||||||
|
import static org.firstinspires.ftc.teamcode.utils.Servos.spinF;
|
||||||
|
import static org.firstinspires.ftc.teamcode.utils.Servos.spinI;
|
||||||
|
import static org.firstinspires.ftc.teamcode.utils.Servos.spinP;
|
||||||
|
|
||||||
|
import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit;
|
||||||
|
import org.firstinspires.ftc.teamcode.libs.RR.MecanumDrive;
|
||||||
|
|
||||||
|
public class Spindexer {
|
||||||
|
Robot robot;
|
||||||
|
Servos servos;
|
||||||
|
Flywheel flywheel;
|
||||||
|
MecanumDrive drive;
|
||||||
|
double lastKnownSpinPos = 0.0;
|
||||||
|
MultipleTelemetry TELE;
|
||||||
|
|
||||||
|
PIDFController spinPID = new PIDFController(spinP, spinI, spinD, spinF);
|
||||||
|
|
||||||
|
double spinCurrentPos = 0.0;
|
||||||
|
|
||||||
|
public int commandedIntakePosition = 0;
|
||||||
|
|
||||||
|
enum IntakeState {
|
||||||
|
UNKNOWN,
|
||||||
|
INTAKE,
|
||||||
|
FINDNEXT,
|
||||||
|
MOVING,
|
||||||
|
FULL
|
||||||
|
};
|
||||||
|
|
||||||
|
public IntakeState currentIntakeState = IntakeState.UNKNOWN;
|
||||||
|
|
||||||
|
enum BallColor {
|
||||||
|
UNKNOWN,
|
||||||
|
GREEN,
|
||||||
|
PURPLE
|
||||||
|
};
|
||||||
|
|
||||||
|
class BallPosition {
|
||||||
|
boolean isEmpty = true;
|
||||||
|
BallColor ballColor = BallColor.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
BallPosition[] ballPositions = new BallPosition[3];
|
||||||
|
|
||||||
|
public boolean init () {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Spindexer(HardwareMap hardwareMap) {
|
||||||
|
robot = new Robot(hardwareMap);
|
||||||
|
servos = new Servos(hardwareMap);
|
||||||
|
flywheel = new Flywheel(hardwareMap);
|
||||||
|
//TELE = new MultipleTelemetry(telemetry, FtcDashboard.getInstance().getTelemetry());
|
||||||
|
|
||||||
|
lastKnownSpinPos = servos.getSpinPos();
|
||||||
|
|
||||||
|
ballPositions[0] = new BallPosition();
|
||||||
|
ballPositions[1] = new BallPosition();
|
||||||
|
ballPositions[2] = new BallPosition();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double[] outakePositions =
|
||||||
|
{spindexer_outtakeBall1, spindexer_outtakeBall2, spindexer_outtakeBall3};
|
||||||
|
|
||||||
|
double[] intakePositions =
|
||||||
|
{spindexer_intakePos1, spindexer_intakePos2, spindexer_intakePos3};
|
||||||
|
|
||||||
|
public int counter = 0;
|
||||||
|
|
||||||
|
// private double getTimeSeconds ()
|
||||||
|
// {
|
||||||
|
// return (double) System.currentTimeMillis()/1000.0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public double getPos() {
|
||||||
|
// robot.spin1Pos.getVoltage();
|
||||||
|
// robot.spin1Pos.getMaxVoltage();
|
||||||
|
// return (robot.spin1Pos.getVoltage()/robot.spin1Pos.getMaxVoltage());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void manageSpindexer() {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
public void resetSpindexer () {
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
ballPositions[i].isEmpty = true;
|
||||||
|
ballPositions[i].ballColor = BallColor.UNKNOWN;
|
||||||
|
}
|
||||||
|
currentIntakeState = IntakeState.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detects if a ball is found and what color.
|
||||||
|
// Returns true is there was a new ball found in Position 1
|
||||||
|
public boolean detectBalls() {
|
||||||
|
|
||||||
|
boolean newPos1Detection = false;
|
||||||
|
|
||||||
|
// Read Distances
|
||||||
|
double s1D = robot.color1.getDistance(DistanceUnit.MM);
|
||||||
|
double s2D = robot.color2.getDistance(DistanceUnit.MM);
|
||||||
|
double s3D = robot.color3.getDistance(DistanceUnit.MM);
|
||||||
|
|
||||||
|
// Position 1
|
||||||
|
if (s1D < 43) {
|
||||||
|
|
||||||
|
// Mark Ball Found
|
||||||
|
newPos1Detection = ballPositions[commandedIntakePosition].isEmpty;
|
||||||
|
|
||||||
|
// Detect which color
|
||||||
|
double green = robot.color1.getNormalizedColors().green;
|
||||||
|
double red = robot.color1.getNormalizedColors().red;
|
||||||
|
double blue = robot.color1.getNormalizedColors().blue;
|
||||||
|
|
||||||
|
double gP = green / (green + red + blue);
|
||||||
|
|
||||||
|
// FIXIT - Add filtering to improve accuracy.
|
||||||
|
if (gP >= 0.4) {
|
||||||
|
ballPositions[commandedIntakePosition].ballColor = BallColor.PURPLE; // purple
|
||||||
|
} else {
|
||||||
|
ballPositions[commandedIntakePosition].ballColor = BallColor.GREEN; // purple
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// FIXIT - Need to find Position base on rotation
|
||||||
|
// // Position 2
|
||||||
|
// if (s2D < 60) {
|
||||||
|
//
|
||||||
|
// double green = robot.color2.getNormalizedColors().green;
|
||||||
|
// double red = robot.color2.getNormalizedColors().red;
|
||||||
|
// double blue = robot.color2.getNormalizedColors().blue;
|
||||||
|
//
|
||||||
|
// double gP = green / (green + red + blue);
|
||||||
|
//
|
||||||
|
// if (gP >= 0.4) {
|
||||||
|
// b2 = 2; // purple
|
||||||
|
// } else {
|
||||||
|
// b2 = 1; // green
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Position 3
|
||||||
|
// if (s3D < 33) {
|
||||||
|
//
|
||||||
|
// double green = robot.color3.getNormalizedColors().green;
|
||||||
|
// double red = robot.color3.getNormalizedColors().red;
|
||||||
|
// double blue = robot.color3.getNormalizedColors().blue;
|
||||||
|
//
|
||||||
|
// double gP = green / (green + red + blue);
|
||||||
|
//
|
||||||
|
// if (gP >= 0.4) {
|
||||||
|
// b3 = 2; // purple
|
||||||
|
// } else {
|
||||||
|
// b3 = 1; // green
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// TELE.addData("Velocity", velo);
|
||||||
|
// TELE.addLine("Detecting");
|
||||||
|
// TELE.addData("Distance 1", s1D);
|
||||||
|
// TELE.addData("Distance 2", s2D);
|
||||||
|
// TELE.addData("Distance 3", s3D);
|
||||||
|
// TELE.addData("B1", b1);
|
||||||
|
// TELE.addData("B2", b2);
|
||||||
|
// TELE.addData("B3", b3);
|
||||||
|
// TELE.update();
|
||||||
|
|
||||||
|
return newPos1Detection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void moveSpindexerToPos(double pos) {
|
||||||
|
spinCurrentPos = servos.getSpinPos();
|
||||||
|
|
||||||
|
double spindexPID = spinPID.calculate(spinCurrentPos, pos);
|
||||||
|
|
||||||
|
robot.spin1.setPower(spindexPID);
|
||||||
|
robot.spin2.setPower(-spindexPID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopSpindexer() {
|
||||||
|
robot.spin1.setPower(0);
|
||||||
|
robot.spin2.setPower(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFull () {
|
||||||
|
return (!ballPositions[0].isEmpty && !ballPositions[1].isEmpty && !ballPositions[2].isEmpty);
|
||||||
|
}
|
||||||
|
public boolean processIntake() {
|
||||||
|
|
||||||
|
switch (currentIntakeState) {
|
||||||
|
case UNKNOWN:
|
||||||
|
// For now just set position ONE if UNKNOWN
|
||||||
|
commandedIntakePosition = 0;
|
||||||
|
servos.setSpinPos(intakePositions[0]);
|
||||||
|
currentIntakeState = Spindexer.IntakeState.MOVING;
|
||||||
|
break;
|
||||||
|
case INTAKE:
|
||||||
|
// Ready for intake and Detecting a New Ball
|
||||||
|
if (detectBalls()) {
|
||||||
|
ballPositions[commandedIntakePosition].isEmpty = false;
|
||||||
|
currentIntakeState = Spindexer.IntakeState.FINDNEXT;
|
||||||
|
} else {
|
||||||
|
// Maintain Position
|
||||||
|
moveSpindexerToPos(intakePositions[commandedIntakePosition]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FINDNEXT:
|
||||||
|
// Find Next Open Position and start movement
|
||||||
|
if (ballPositions[0].isEmpty) {
|
||||||
|
// Position 1
|
||||||
|
commandedIntakePosition = 0;
|
||||||
|
servos.setSpinPos(intakePositions[commandedIntakePosition]);
|
||||||
|
currentIntakeState = Spindexer.IntakeState.MOVING;
|
||||||
|
} else if (ballPositions[1].isEmpty) {
|
||||||
|
// Position 2
|
||||||
|
commandedIntakePosition = 1;
|
||||||
|
servos.setSpinPos(intakePositions[commandedIntakePosition]);
|
||||||
|
currentIntakeState = Spindexer.IntakeState.MOVING;
|
||||||
|
} else if (ballPositions[2].isEmpty) {
|
||||||
|
// Position 3
|
||||||
|
commandedIntakePosition = 2;
|
||||||
|
servos.setSpinPos(intakePositions[commandedIntakePosition]);
|
||||||
|
currentIntakeState = Spindexer.IntakeState.MOVING;
|
||||||
|
} else {
|
||||||
|
// Full
|
||||||
|
currentIntakeState = Spindexer.IntakeState.FULL;
|
||||||
|
}
|
||||||
|
moveSpindexerToPos(intakePositions[commandedIntakePosition]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MOVING:
|
||||||
|
// Stopping when we get to the new position
|
||||||
|
if (servos.spinEqual(intakePositions[commandedIntakePosition])) {
|
||||||
|
currentIntakeState = Spindexer.IntakeState.INTAKE;
|
||||||
|
stopSpindexer();
|
||||||
|
detectBalls();
|
||||||
|
} else {
|
||||||
|
// Keep moving the spindexer
|
||||||
|
moveSpindexerToPos(intakePositions[commandedIntakePosition]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FULL:
|
||||||
|
// Double Check Colors?
|
||||||
|
// Maintain Position
|
||||||
|
moveSpindexerToPos(intakePositions[commandedIntakePosition]);
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Statements to execute if no case matches
|
||||||
|
}
|
||||||
|
//TELE.addData("commandedIntakePosition", commandedIntakePosition);
|
||||||
|
//TELE.update();
|
||||||
|
// Signal a successful intake
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user