import com.ctre.phoenix6.configs.MotorOutputConfigs;
import com.ctre.phoenix6.configs.TalonFXConfiguration;
+import com.ctre.phoenix6.controls.VelocityDutyCycle;
+import com.ctre.phoenix6.controls.VelocityTorqueCurrentFOC;
import com.ctre.phoenix6.controls.VelocityVoltage;
import com.ctre.phoenix6.hardware.TalonFX;
import com.ctre.phoenix6.signals.InvertedValue;
private ShooterIOInputsAutoLogged inputs = new ShooterIOInputsAutoLogged();
+ // for tracking current phase: used to adjust the setting
+ private FlywheelPhase phase;
+
public Shooter(){
TalonFXConfiguration config = new TalonFXConfiguration();
- config.Slot0.kP = 0.2; //tune p value
+ config.Slot0.kP = 676767.0; //tune p value
config.Slot0.kI = 0;
config.Slot0.kD = 0;
config.Slot0.kV = 0.12; //Maximum rps = 100 --> 12V/100rps
+
+ config.TorqueCurrent.PeakForwardTorqueCurrent = 40; // this is the constant torque velocity
+ config.TorqueCurrent.PeakReverseTorqueCurrent = 0; // we are making this a BANG BANG controller for talon fx
+ config.MotorOutput.PeakForwardDutyCycle = 1.0;
+ config.MotorOutput.PeakReverseDutyCycle = 0.0;
+
shooterMotorLeft.getConfigurator().apply(config);
shooterMotorRight.getConfigurator().apply(config);
.withNeutralMode(NeutralModeValue.Coast)
);
+ // set start up for phase initially:
+ phase = FlywheelPhase.START_UP;
+
SmartDashboard.putData("Turn on shooter", new InstantCommand(() -> setShooter(ShooterConstants.SHOOTER_VELOCITY)));
SmartDashboard.putData("Turn on feeder", new InstantCommand(() -> setFeeder(ShooterConstants.FEEDER_RUN_POWER)));
SmartDashboard.putData("Turn ALL off", new InstantCommand(() -> deactivateShooterAndFeeder()));
SmartDashboard.putNumber("Shot Power", shooterPower);
shooterPower = SmartDashboard.getNumber("Shot Power", shooterPower);
- shooterMotorLeft.setControl(voltageRequest.withVelocity(shooterTargetSpeed));
- shooterMotorRight.setControl(voltageRequest.withVelocity(shooterTargetSpeed));
+ if (phase == FlywheelPhase.MAX) { // shooter target speed is in RPS
+ // Duty-cycle bang-bang (apply to both)
+ shooterMotorLeft.setControl(new VelocityDutyCycle(shooterTargetSpeed)); // spin as fast as possible shooter target speed
+ shooterMotorRight.setControl(new VelocityDutyCycle(shooterTargetSpeed)); // same here
+ } else {
+ // Torque-current bang-bang
+ shooterMotorLeft.setControl(new VelocityTorqueCurrentFOC(shooterTargetSpeed)); // apply constant torque current
+ shooterMotorRight.setControl(new VelocityTorqueCurrentFOC(shooterTargetSpeed)); // again
+ }
+
// shooterMotorLeft.set(-shooterPower);
// shooterMotorRight.set(-shooterPower);
feederMotor.set(feederPower);
}
+ public void updatePhase() {
+ if (Math.abs(shooterMotorLeft.getVelocity().getValueAsDouble() - shooterTargetSpeed) < ShooterConstants.TORQUE_CURRENT_CONTROL_TOLERANCE) {
+ phase = FlywheelPhase.MAX; // we need to recover from ball velocity in order to be back to idle
+ } else {
+ phase = FlywheelPhase.CONSTANT_TORQUE;
+ }
+ }
+
public void deactivateShooterAndFeeder() {
setFeeder(0);
setShooter(0);