I’m trying to make it so when you hold a button it extends pneumatics then it retracts when you let go. This is my code and it doesn’t work, after testing I found that it is immediately running isFinished().
package frc.robot.commands;
import com.ctre.phoenix.motorcontrol.ControlMode;
import edu.wpi.first.wpilibj.DoubleSolenoid.Value;
//import static edu.wpi.first.wpilibj.DoubleSolenoid.Value.*;
//import edu.wpi.first.wpilibj.PneumaticsModuleType;
//import edu.wpi.first.wpilibj.Compressor;
import edu.wpi.first.wpilibj.command.Command;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import frc.robot.Robot;
import frc.robot.RobotMap;
public class StartIntake extends Command {
public StartIntake() {
// Use requires() here to declare subsystem dependencies
requires(Robot.intake);
}
// Called just before this Command runs the first time
@Override
protected void initialize() {
SmartDashboard.putBoolean("reversed", false);
RobotMap.pneumaticDoubleSolenoid.set(Value.kForward);
RobotMap.timeSinceStartedBeingReleasedForSolenoids = System.currentTimeMillis();
RobotMap.IntakeMotor1.set(ControlMode.PercentOutput, .8);
}
// Called repeatedly when this Command is scheduled to run
@Override
protected void execute() {
}
// Make this return true when this Command no longer needs to run execute()
@Override
protected boolean isFinished() {
return true;
}
// Called once after isFinished returns true
@Override
protected void end() {
SmartDashboard.putBoolean("reversed", true);
RobotMap.IntakeMotor1.set(ControlMode.PercentOutput, 0.0);
RobotMap.timeSinceStartedBeingReleasedForSolenoids = -1;
RobotMap.pneumaticDoubleSolenoid.set(Value.kReverse);
}
// Called when another command which requires one or more of the same
// subsystems is scheduled to run
@Override
protected void interrupted() {
}
}// class
Is finished is a method used by the scheduler every time it runs to determine when the command should be unscheduled. When the method returns true, the command ends. WhileHeld ends the command when the button is released. So leave isFinished as return true, and it should work.
I believe WhileHeld will actually reschedule a command after it ends, which is why return true works that way. WhenPressed will schedule a command exactly once on button press and whenever it ends, it ends. WhenReleased using a command that requires the same subsystem will interrupt the other one if it hasn’t already ended.
We have had good success running shooters only when a button is pressed by making it a whileheld command and isFinished being false. If it reschedules on release, that is a bug and should be reported to WPILib.
#1 you should Set the isFinnished to return False in the extend command.
Then use your whileHeld. Whit this the initialize() will execute once then the execute() will run every 20ms. Finnaly when you release the button the end() method will run.
OR
Use whenPressed to call the Extend command then whenReleased to call the Retract command. The Retract command could be an instant command (That is what you had programed above)
Correct. The downside of option 1 is that your intake can no longer run any other commands (think running rollers/wheels) due to the requires(…). This is why I generally recommend the pressed/released approach
Fully agree, I suspect the best approach here would be to create a few simple commands for each actuator or subsystem, then group them up in a paralleCommanGroup