Skip to content

Commit

Permalink
Merge pull request #54 from aaditsangvikar/main
Browse files Browse the repository at this point in the history
An on the fly shooting command that actually makes it possible to work - to be tested
  • Loading branch information
zaneal authored Mar 16, 2024
2 parents fe8794d + 8a98774 commit beaa4b6
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 24 deletions.
25 changes: 17 additions & 8 deletions src/main/java/frc/robot/commands/IntakeCommand.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package frc.robot.commands;

import edu.wpi.first.wpilibj.GenericHID;
import edu.wpi.first.wpilibj.XboxController;
import edu.wpi.first.wpilibj2.command.Command;
import frc.robot.subsystems.IndexerSubsystem;
import frc.robot.subsystems.IntakeSubsystem;
import frc.robot.subsystems.LEDSubsystem;

import java.rmi.MarshalException;

public class IntakeCommand extends Command {
private final IntakeSubsystem intakeSubsystem;
Expand All @@ -16,22 +15,30 @@ public class IntakeCommand extends Command {

private final boolean source;



private final XboxController primaryController;
private final XboxController secondaryController;

//private LEDSubsystem ledSubsystem;

/**
* Command to run the intake
* @param intakeSubsystem The instance of {@link IntakeSubsystem}
* @param indexerSubsystem The instance of {@link IndexerSubsystem} (needed for limebreak detection to stop intake motor)
*/
public IntakeCommand(IntakeSubsystem intakeSubsystem, IndexerSubsystem indexerSubsystem, Targets target, boolean source) {
public IntakeCommand(IntakeSubsystem intakeSubsystem, IndexerSubsystem indexerSubsystem, Targets target, boolean source, XboxController primaryController, XboxController secondaryController) {
this.intakeSubsystem = intakeSubsystem;
this.indexerSubsystem = indexerSubsystem;
this.target = target;
this.source = source;
this.primaryController = primaryController;
this.secondaryController = secondaryController;

addRequirements(intakeSubsystem, indexerSubsystem);
}


@Override
public void execute() {
// if (!indexerSubsystem.isCenter()) {
Expand All @@ -42,12 +49,12 @@ public void execute() {
// intakeSubsystem.setSpeed(0);
// indexerSubsystem.rotateAllWheelsPercent(0);
// }
if (source) {
indexerSubsystem.moveIndexerToPos(Math.toRadians(140));
} else {
// if (source) {
// indexerSubsystem.moveIndexerToPos(Math.toRadians(140));
// } else {
// indexerSubsystem.moveIndexerToPos(Math.toRadians(7.0));
// indexerSubsystem.rotateMotorVolts(IndexerSubsystem.IndexerMotors.INDEXER_ROTATE, 0.0);
}
// }

switch (target) {
case AMP -> {
Expand Down Expand Up @@ -76,6 +83,8 @@ public void execute() {
if (indexerSubsystem.isCenter()) {
indexerSubsystem.rotateAllWheelsPercent(0);
intakeSubsystem.setSpeed(0.0);
primaryController.setRumble(GenericHID.RumbleType.kBothRumble, 1.0);
secondaryController.setRumble(GenericHID.RumbleType.kBothRumble, 1.0);
}

}
Expand Down
154 changes: 154 additions & 0 deletions src/main/java/frc/robot/commands/OnTheFlyShootCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
package frc.robot.commands;

import edu.wpi.first.math.controller.ProfiledPIDController;
import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.wpilibj.DriverStation;
import edu.wpi.first.wpilibj2.command.Command;
import frc.robot.constants.ShooterConstants;
import frc.robot.subsystems.IndexerSubsystem;
import frc.robot.subsystems.SwerveSubsystem;

import java.util.function.DoubleSupplier;

public class OnTheFlyShootCommand extends Command {
private final SwerveSubsystem swerveSubsystem;
private final IndexerSubsystem indexerSubsystem;
private final DoubleSupplier forward;
private final DoubleSupplier sideways;


private final ProfiledPIDController rotationPID = new ProfiledPIDController(
ShooterConstants.rotateP,
ShooterConstants.rotateI,
ShooterConstants.rotateD,
ShooterConstants.rotateConstraints
);

/**
* Rotates the robot to face the speaker, while still allowing the driver to control forward and backward movement
* @param swerveSubsystem The instance of {@link SwerveSubsystem}
* @param forward The desired forward percentage of the robot
* @param sideways The desired sideways percentage of the robot
*/
public OnTheFlyShootCommand(SwerveSubsystem swerveSubsystem, IndexerSubsystem indexerSubsystem, DoubleSupplier forward, DoubleSupplier sideways) {
this.swerveSubsystem = swerveSubsystem;
this.indexerSubsystem = indexerSubsystem;
this.forward = forward;
this.sideways = sideways;

//Rotation tolerance in radians
rotationPID.setTolerance(0.05);


addRequirements(swerveSubsystem, indexerSubsystem);

}

@Override
public void execute() {


//ROTATION CALCULATIONS
double odometryRotation;

//Robot speed toward/away from the speaker (y-direction)
double robotYSpeed = swerveSubsystem.getFieldRelativeChassisSpeeds().vyMetersPerSecond;
//Robot speed toward/away from the speaker (x-direction)
double robotXSpeed = swerveSubsystem.getFieldRelativeChassisSpeeds().vxMetersPerSecond;
//Note speed in x-direction(forward, as opposed to up)
double noteSpeedX = robotXSpeed + ShooterConstants.shooterNoteSpeedX;
Pose2d speakerPose;

//Getting speaker pose relative to alliance color
if (DriverStation.getAlliance().isPresent()) {
speakerPose = (DriverStation.getAlliance().get() == DriverStation.Alliance.Blue)? ShooterConstants.speakerPoseBlue : ShooterConstants.speakerPoseRed;
} else {
speakerPose = ShooterConstants.speakerPoseBlue;
}

//Current robot pose
Pose2d robotPose = swerveSubsystem.getPose();

//'Moving' speaker position based on robot speed
double speakerYTranslation = robotYSpeed * ((speakerPose.getX()-robotPose.getX()) / noteSpeedX);

//Calculated angle to rotate to
double angle = Math.atan2((speakerPose.getY() + speakerYTranslation) - robotPose.getY(), speakerPose.getX()-robotPose.getX());

//Rotation PID Calculations
rotationPID.setGoal(angle);
odometryRotation = rotationPID.calculate(robotPose.getRotation().getRadians());





//SHOOTING TIME CALCULATIONS

//Initial calculated distance to shoot from the speaker
double shootingDistanceFromSpeaker = noteSpeedX * ShooterConstants.timeToSpeakerHeightWithGravity;

//Robot distance to speaker
double robotDistanceFromSpeaker = Math.sqrt(
Math.pow(
(
(DriverStation.getAlliance().get() == DriverStation.Alliance.Red)?
ShooterConstants.speakerPoseRed.getX():
ShooterConstants.speakerPoseBlue.getX()
) - swerveSubsystem.getPose().getX(),
2
)
+ Math.pow(
(
(DriverStation.getAlliance().get() == DriverStation.Alliance.Red)?
ShooterConstants.speakerPoseRed.getY():
ShooterConstants.speakerPoseBlue.getY()
) - swerveSubsystem.getPose().getY(),
2
)
);

//Difference between optimal location and current location
double difference = robotDistanceFromSpeaker - shootingDistanceFromSpeaker;

//Accounting for indexer spin time
if (difference > 0) {
shootingDistanceFromSpeaker += noteSpeedX * ShooterConstants.shootDelayTime;
} else {
shootingDistanceFromSpeaker -= noteSpeedX * ShooterConstants.shootDelayTime;
}

//Removing negatives
difference = Math.abs(robotDistanceFromSpeaker - shootingDistanceFromSpeaker);

System.out.println("Robot Speed: " + robotXSpeed +
"\n Note Speed: " + noteSpeedX +
"\n Calculated Distance To Shoot: " + shootingDistanceFromSpeaker +
"\n Robot Distance: " + robotDistanceFromSpeaker+
"\n Difference: " + difference
);




//Actual Execute
swerveSubsystem.drive(
forward.getAsDouble(),
sideways.getAsDouble(),
odometryRotation,
true,
true
);

if (difference < 0.4){
indexerSubsystem.rotateAllWheelsPercent(0.6);
System.out.println("Shooting!!!!!");
}

}

@Override
public void end(boolean interrupted) {
indexerSubsystem.rotateAllWheelsPercent(0.0);
}
}
6 changes: 3 additions & 3 deletions src/main/java/frc/robot/constants/DrivetrainConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@

public class DrivetrainConstants {

public static final double maxSpeedMetersPerSecond = 6.0; //note, maybe it needs to come down, if its too high it will stop working or something, troubleshoot from coronado
public static final double maxSpeedMetersPerSecond = 6.0;
public static final double maxAngularSpeed = 2 * Math.PI;

public static final double directionSlewRate = 20; // rads/sec - turning was 4.0
public static final double magnitudeSlewRate = 20; // percent/second (1 = 100%) - forward/backward/traverse
public static final double rotationalSlewRate = 50; // percent/second (1 = 100%) - rotation was 12.0
public static final double magnitudeSlewRate = 1000; // percent/second (1 = 100%) - forward/backward/traverse - was 20.0
public static final double rotationalSlewRate = 1000; // percent/second (1 = 100%) - rotation was 50.0

public static final double drivingSpeedScalar = -1.0; //make positive so gyroreset with intake forward
public static final double rotationSpeedScalar = -2.0;//make positive so gyroreset with intake forward
Expand Down
10 changes: 7 additions & 3 deletions src/main/java/frc/robot/constants/ShooterConstants.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package frc.robot.constants;

import edu.wpi.first.math.controller.ArmFeedforward;
import edu.wpi.first.math.controller.PIDController;
import edu.wpi.first.math.controller.SimpleMotorFeedforward;
import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.math.geometry.Rotation2d;
import edu.wpi.first.math.trajectory.TrapezoidProfile;

public class ShooterConstants {

Expand All @@ -20,11 +20,15 @@ public class ShooterConstants {

public static final PIDController shooterPID = new PIDController(ShooterConstants.shooterP,ShooterConstants.shooterI, ShooterConstants.shooterD);
public static boolean isActive = false;
public static double rotateP = 0.1;
public static double rotateI = 0.0;
public static double rotateD = 0.0;
public static final TrapezoidProfile.Constraints rotateConstraints = new TrapezoidProfile.Constraints(Math.PI, Math.PI/2);

public static final double shooterRPM = 6500;
public static final double shooterWheelDiameterInches = 4.0;
public static final double shooterWheelDiameterMeters = shooterWheelDiameterInches/39.37;
public static final double shooterAngle = Math.toRadians(38);
public static final double sweetSpotDistance = 3.0;
public static final double shooterNoteSpeedMPS = 2 * Math.PI * (shooterWheelDiameterMeters/2) * shooterRPM / 60;
public static final double shooterNoteSpeedX = shooterNoteSpeedMPS * Math.cos(shooterAngle);
public static final double shooterNoteSpeedY = shooterNoteSpeedMPS * Math.sin(shooterAngle);
Expand All @@ -45,7 +49,7 @@ public class ShooterConstants {



public static final double shootDelayTime = 0.1;
public static final double shootDelayTime = 0.25;

public static final Pose2d speakerPoseRed = new Pose2d(0.0,2.5, Rotation2d.fromRadians(0.0));
public static final Pose2d speakerPoseBlue = new Pose2d(0.0,5.5, Rotation2d.fromRadians(0.0));
Expand Down
20 changes: 10 additions & 10 deletions src/main/java/frc/robot/utils/CANUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@
public class CANUtils {

public static CANSparkMax configure(CANSparkMax motor) {
motor.setPeriodicFramePeriod(CANSparkLowLevel.PeriodicFrame.kStatus0, 5000);
motor.setPeriodicFramePeriod(CANSparkLowLevel.PeriodicFrame.kStatus3, 5000);
motor.setPeriodicFramePeriod(CANSparkLowLevel.PeriodicFrame.kStatus4, 5000);
motor.setPeriodicFramePeriod(CANSparkLowLevel.PeriodicFrame.kStatus5, 5000);
motor.setPeriodicFramePeriod(CANSparkLowLevel.PeriodicFrame.kStatus6, 5000);
motor.setPeriodicFramePeriod(CANSparkLowLevel.PeriodicFrame.kStatus0, 1000);
motor.setPeriodicFramePeriod(CANSparkLowLevel.PeriodicFrame.kStatus3, 1000);
motor.setPeriodicFramePeriod(CANSparkLowLevel.PeriodicFrame.kStatus4, 1000);
motor.setPeriodicFramePeriod(CANSparkLowLevel.PeriodicFrame.kStatus5, 1000);
motor.setPeriodicFramePeriod(CANSparkLowLevel.PeriodicFrame.kStatus6, 1000);
return motor;
}

public static CANSparkFlex configure(CANSparkFlex motor) {
motor.setPeriodicFramePeriod(CANSparkLowLevel.PeriodicFrame.kStatus0, 5000);
motor.setPeriodicFramePeriod(CANSparkLowLevel.PeriodicFrame.kStatus3, 5000);
motor.setPeriodicFramePeriod(CANSparkLowLevel.PeriodicFrame.kStatus4, 5000);
motor.setPeriodicFramePeriod(CANSparkLowLevel.PeriodicFrame.kStatus5, 5000);
motor.setPeriodicFramePeriod(CANSparkLowLevel.PeriodicFrame.kStatus6, 5000);
motor.setPeriodicFramePeriod(CANSparkLowLevel.PeriodicFrame.kStatus0, 1000);
motor.setPeriodicFramePeriod(CANSparkLowLevel.PeriodicFrame.kStatus3, 1000);
motor.setPeriodicFramePeriod(CANSparkLowLevel.PeriodicFrame.kStatus4, 1000);
motor.setPeriodicFramePeriod(CANSparkLowLevel.PeriodicFrame.kStatus5, 1000);
motor.setPeriodicFramePeriod(CANSparkLowLevel.PeriodicFrame.kStatus6, 1000);
return motor;
}
}

0 comments on commit beaa4b6

Please sign in to comment.