I’m currently trying to program a wheeled intake that is deployed via pneumatic. I was hoping to be able to deploy and run the intake before retracting then continuing to run the motors for about a second after the deploy command is called. I initially thought to do this via a Thread.sleep() call but was told this would lock the robot code(even though I’m pretty sure each command call can get threaded) my idea is as follows
In Intake subsystem:
public void stop() {
retract();
Thread.sleep(1000);
m_motor.stopMotor();
}
Then schedule it as so:
new JoystickButton(ctl, XboxController.Button.kB.value)
.whenPressed(() -> m_intake.intake())
.whenReleased(() -> m_intake.stop());
Would this only cause a sleep to occur for the current command or would this hold up the entire scheduler, including stuff like driving.
Another way which I was sort of able to get working but ran into the issue that while it would delay as intended it wouldn’t allow the command to be rescheduled until the delay was finished(basically the delay command couldn’t be interupted)
FloorIntake:
public class FloorIntake extends CommandBase {
private final Intake m_intake;
public FloorIntake(Intake intake) {
m_intake = intake;
addRequirements(intake);
}
@Override
public void initialize() {
m_intake.extend();
}
@Override
public void execute() {
m_intake.set(IntakeConstants.RPM);
}
@Override
public void end(boolean interrupted) {
m_intake.retract();
}
}
Can you clarify in numerical steps what you’re trying to do? I’m confused by what you said here:
So you want to:
Deploy the intake pneumatics
Run the intake motors
Wait for some amount of time (in this case a second)
Do something else not yet spoken of here
If that assumption is true, Fletch’s advice is definitely the simplest way to go. A sequential command group is the way to go.
For your delay, you could either use the .withTimeout() decorator on your run intake motors command, or just insert a WaitCommand(1) in the command sequence.
Definitely this. If you’re trying to make complex logic built on top if commands you already have, command groups should be the first idea you look at. Also, if you haven’t looked at the convenience features section of wpilib’s command based docs, I would recommend doing so. There are a lot of nice command types built into wpilib that help with complex functionality.
I’ve discussed a bit more with my teammates and we’ve come up with the idea of extending the SequentialCommandGroup class like so
package frc.robot.commands;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.SequentialCommandGroup;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
import edu.wpi.first.wpilibj2.command.WaitCommand;
public class DelayedCommandGroup extends SequentialCommandGroup {
/**
* Schedule a set of commands with a delay between each except the last
*
* @param delay
* Time to wait between each command in seconds
* @param systems
* The required subsystems to hold
* @param commands
* The runnables to add
*/
public DelayedCommandGroup(int delay, Command[] commands, SubsystemBase[] systems) {
// Use an indexed for loop here becuase we don't want to add the last command with a delay
for (int i = 0; i < commands.length - 2; i++) {
addCommands(commands[i]);
addCommands(new WaitCommand(delay));
}
addCommands(commands[commands.length - 1]);
for (SubsystemBase system : systems) {
addRequirements(system);
}
}
}
I also think this covers what you mean when you say hiding the sequential command logic