2022-02-25 20:18:21 -07:00
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
2022-03-14 20:10:12 -06:00
package frc4388.robot.commands.ShooterCommands ;
2022-02-25 20:18:21 -07:00
2022-03-06 18:02:04 -07:00
import edu.wpi.first.math.geometry.Pose2d ;
import edu.wpi.first.math.geometry.Translation2d ;
2022-03-06 00:05:54 -07:00
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard ;
2022-02-25 20:18:21 -07:00
import edu.wpi.first.wpilibj2.command.CommandBase ;
2022-03-19 22:16:20 -06:00
import frc4388.robot.Constants ;
2022-03-20 15:24:48 -06:00
import frc4388.robot.Robot ;
import frc4388.robot.RobotContainer ;
2022-03-05 11:07:54 -07:00
import frc4388.robot.Constants.ShooterConstants ;
2022-03-06 18:02:04 -07:00
import frc4388.robot.Constants.SwerveDriveConstants ;
2022-02-25 20:18:21 -07:00
import frc4388.robot.subsystems.BoomBoom ;
import frc4388.robot.subsystems.Hood ;
import frc4388.robot.subsystems.SwerveDrive ;
2022-02-26 15:00:09 -07:00
import frc4388.robot.subsystems.Turret ;
2022-03-20 15:47:07 -06:00
import frc4388.robot.subsystems.VisionOdometry ;
2022-03-05 11:07:54 -07:00
import frc4388.utility.DummySensor ;
import frc4388.utility.Gains ;
2022-02-25 20:18:21 -07:00
public class Shoot extends CommandBase {
2022-02-26 15:00:09 -07:00
// subsystems
2022-03-19 21:03:01 -06:00
private SwerveDrive swerve ;
private Turret turret ;
2022-03-19 22:16:20 -06:00
private BoomBoom drum ;
2022-03-19 21:03:01 -06:00
private Hood hood ;
2022-03-20 15:47:07 -06:00
private VisionOdometry visionOdometry ;
2022-02-25 20:18:21 -07:00
2022-03-19 21:31:34 -06:00
private boolean toShoot ;
2022-02-26 15:00:09 -07:00
// given
2022-03-19 22:16:20 -06:00
private double odoX , odoY ;
2022-03-19 21:03:01 -06:00
private double distance ;
2022-03-19 22:16:20 -06:00
private double gyroAngle ;
2022-02-26 15:00:09 -07:00
// targets
2022-03-19 22:16:20 -06:00
private double targetAngle , targetVel , targetHood ;
2022-02-26 15:00:09 -07:00
// pid
2022-03-20 14:25:38 -06:00
private Gains turretGains = ShooterConstants . TURRET_SHOOT_GAINS ;
private Gains swerveGains = ShooterConstants . SWERVE_SHOOT_GAINS ;
2022-03-18 20:02:23 -06:00
private double error ;
private double prevError ;
private double kP , kI , kD ;
private double proportional , integral , derivative ;
2022-03-19 22:16:20 -06:00
private double output , normOutput ;
2022-03-18 20:02:23 -06:00
private double tolerance ;
2022-03-20 14:25:38 -06:00
boolean timerStarted ;
long startTime ;
private double timeTolerance ;
2022-03-18 20:02:23 -06:00
private boolean isAimedInTolerance ;
private int inverted ;
private double initialSwerveRotation ;
2022-02-26 15:00:09 -07:00
2022-03-20 15:47:07 -06:00
private boolean endsWithLimelight ;
2022-03-05 11:07:54 -07:00
/**
* Creates a new shoot command, allowing the robot to aim and be ready to fire a ball
2022-03-19 21:03:01 -06:00
*
* @param swerve Drive Train
* @param drum Shooter Drum
* @param turret Shooter Turret
* @param hood Shooter Hood
*
* @author Aarav Shah
2022-03-05 11:07:54 -07:00
*/
2022-03-20 15:47:07 -06:00
public Shoot ( SwerveDrive swerve , BoomBoom drum , Turret turret , Hood hood , VisionOdometry visionOdometry , boolean toShoot , boolean endsWithLimelight ) {
2022-02-25 20:18:21 -07:00
// Use addRequirements() here to declare subsystem dependencies.
2022-03-19 21:03:01 -06:00
this . swerve = swerve ;
this . drum = drum ;
this . turret = turret ;
this . hood = hood ;
2022-03-20 16:22:11 -06:00
this . visionOdometry = visionOdometry ;
2022-03-19 21:31:34 -06:00
this . toShoot = toShoot ;
2022-03-20 15:47:07 -06:00
this . endsWithLimelight = endsWithLimelight ;
2022-03-20 14:25:38 -06:00
kP = turretGains . kP ;
kI = turretGains . kI ;
kD = turretGains . kD ;
2022-03-01 17:18:25 -07:00
proportional = 0 ;
2022-02-26 15:00:09 -07:00
integral = 0 ;
derivative = 0 ;
2022-03-20 14:25:38 -06:00
2022-03-19 21:31:34 -06:00
tolerance = 10 . 0 ;
2022-03-20 14:25:38 -06:00
timeTolerance = 500 ;
2022-03-06 00:05:54 -07:00
isAimedInTolerance = false ;
2022-03-19 22:16:20 -06:00
2022-03-20 14:25:38 -06:00
this . inverted = 1 ;
2022-03-05 11:07:54 -07:00
2022-03-20 15:47:07 -06:00
addRequirements ( this . swerve , this . drum , this . turret , this . hood , this . visionOdometry ) ;
2022-02-25 20:18:21 -07:00
}
2022-03-20 14:25:38 -06:00
// public Shoot(SwerveDrive swerve, BoomBoom drum, Turret turret, Hood hood) {
// this(swerve, drum, turret, hood, false);
// }
2022-03-01 17:18:25 -07:00
2022-03-20 14:25:38 -06:00
/**
* Updates error for custom PID.
*/
public void updateError ( ) {
targetAngle = AimToCenter . aaravAngleToCenter ( odoX , odoY , swerve . getRegGyro ( ) . getDegrees ( ) ) ;
error = ( targetAngle - turret . getBoomBoomAngleDegrees ( ) ) % 360 ;
// if (error > 180) {
// error = 360 - error; // TODO: error - 360
// this.inverted = -1; } else { this.inverted = 1; }
isAimedInTolerance = ( Math . abs ( error ) < = tolerance ) ;
}
// Called when the command is initially scheduled.
@Override
public void initialize ( ) {
timerStarted = false ;
startTime = 0 ;
2022-03-20 17:28:10 -06:00
this . odoX = 0 . 9398 ; //-this.swerve.getOdometry().getY(); // 3.2766
this . odoY = - 3 . 2766 ; //-this.swerve.getOdometry().getX(); // 0.9398
2022-03-20 14:25:38 -06:00
this . distance = Math . hypot ( odoX , odoY ) ;
this . gyroAngle = this . swerve . getRegGyro ( ) . getDegrees ( ) ;
this . initialSwerveRotation = gyroAngle ;
// get targets (shooter tables)
this . targetVel = drum . getVelocity ( distance ) ;
this . targetHood = drum . getHood ( distance ) ;
this . targetAngle = AimToCenter . aaravAngleToCenter ( odoX , odoY , swerve . getRegGyro ( ) . getDegrees ( ) ) ;
// initial error
updateError ( ) ;
prevError = error ;
}
/**
* Run custom PID.
*/
public void runPID ( ) {
prevError = error ;
updateError ( ) ;
this . proportional = error ;
this . integral = integral + ( error * Constants . LOOP_TIME ) ;
this . derivative = ( error - prevError ) / Constants . LOOP_TIME ;
this . output = kP * proportional + kI * integral + kD * derivative ;
this . normOutput = ( output / 360 ) * inverted ;
}
2022-02-25 20:18:21 -07:00
// Called every time the scheduler runs while the command is scheduled.
@Override
public void execute ( ) {
2022-03-20 14:25:38 -06:00
2022-03-19 19:58:21 -06:00
runPID ( ) ;
2022-03-20 14:25:38 -06:00
2022-03-19 19:58:21 -06:00
SmartDashboard . putNumber ( " Error " , this . error ) ;
2022-03-19 21:03:01 -06:00
SmartDashboard . putNumber ( " Shoot.java TargetAngle " , this . targetAngle ) ;
2022-03-19 22:16:20 -06:00
SmartDashboard . putNumber ( " Normalized Output " , this . normOutput ) ;
2022-03-19 21:31:34 -06:00
2022-03-20 14:25:38 -06:00
this . turret . runTurretWithCustomPID ( normOutput ) ;
// this.turret.m_boomBoomRotateMotor.set(normOutput);
2022-03-20 15:24:48 -06:00
this . swerve . driveWithInput ( RobotContainer . getDriverController ( ) . getLeftX ( ) , RobotContainer . getDriverController ( ) . getLeftY ( ) , normOutput * ( this . swerveGains . kP / this . turretGains . kP ) , true ) ; // ? should the output be field relative
2022-03-19 21:31:34 -06:00
if ( this . toShoot ) {
this . hood . runAngleAdjustPID ( this . targetHood ) ;
this . drum . runDrumShooterVelocityPID ( this . targetVel ) ;
}
2022-02-25 20:18:21 -07:00
}
// Called once the command ends or is interrupted.
@Override
2022-03-18 20:02:23 -06:00
public void end ( boolean interrupted ) {
2022-03-19 22:24:45 -06:00
2022-03-20 14:25:38 -06:00
System . err . println ( " SHOOT IS FINISHED: " + Boolean . toString ( interrupted ) . toUpperCase ( ) ) ;
2022-03-19 22:24:45 -06:00
// ? return to initial swerve rotation
2022-03-19 21:31:34 -06:00
// swerve.driveWithInput(0, 0, initialSwerveRotation, true);
2022-03-19 22:24:45 -06:00
2022-03-20 01:42:34 -06:00
// this.swerve.driveWithInput(0.0, 0.0, 0.0, 0.0, true);
2022-03-20 12:09:41 -06:00
// this.turret.m_boomBoomRotateMotor.set(0.0);
// ? should stop the turret and the swerve
////this.swerve.stopModules();
2022-03-20 16:22:11 -06:00
this . turret . runTurretWithInput ( 0 . 0 ) ;
2022-03-19 22:24:45 -06:00
if ( this . toShoot ) {
this . hood . runHood ( 0 . 0 ) ;
this . drum . runDrumShooter ( 0 . 0 ) ;
}
2022-03-18 20:02:23 -06:00
}
2022-02-25 20:18:21 -07:00
// Returns true when the command should end.
@Override
public boolean isFinished ( ) {
2022-03-20 15:47:07 -06:00
if ( ! endsWithLimelight ) {
if ( isAimedInTolerance & & ! timerStarted ) {
timerStarted = true ;
startTime = System . currentTimeMillis ( ) ;
}
SmartDashboard . putBoolean ( " isDone " , isAimedInTolerance & & timerStarted & & ( ( System . currentTimeMillis ( ) - startTime ) > timeTolerance ) ) ;
return ( isAimedInTolerance & & timerStarted & & ( ( System . currentTimeMillis ( ) - startTime ) > timeTolerance ) ) ;
} else {
return this . visionOdometry . m_camera . getLatestResult ( ) . hasTargets ( ) ;
2022-03-20 14:25:38 -06:00
}
2022-02-25 20:18:21 -07:00
}
}