public static final SequentialCommandGroup loadShooter = new RunCommand(() -> mIntake.setSpeed(-1), mIntake).withTimeout(0.5).andThen(() -> mIntake.setSpeed(1), mIntake);
The goal is to make the intake take the balls away from the shooter slightly before loading them into the shooter. Will the .andThen decorator allow this to happen until I stop pressing a button if I am controlling it with a joystick button like this:
new JoystickButton(mJoystick, 1).whileHeld(CommandUtility.loadShooter);
Not to take away from the question, but this seems like a lot of code for an inline command. Have you considered making it an actual command to improve readability?
You’re using whileHeld which will restart the command, so you probably want to use whenHeld.
To be more descriptive on what will happen:
The intake will run backwards for 0.5 seconds, then for one cycle of the command scheduler (0.02 seconds) it will run forwards, then it will run backwards again for 0.5 seconds etc. I would recommend changing whileHeld to whenHeld and putting everything in the andThen inside a StartEnd command so when you stop holding the button the intake can be set to a safe state of off.
agreed, this may be better used in its own class where the “end()” method can turn the motor off.
an alternative is to inline everything in the button binding so that they can use “whenReleased” to turn the motor off, but it seems they are trying to put all their inlined commands in a sperate file called “CommandUtility” meaning in that file they may want to put some thing like
public static final SequentialCommandGroup loadShooter = new RunCommand(() -> mIntake.setSpeed(-1.0), mIntake).withTimeout(0.5).andThen(() -> mIntake.setSpeed(1.0), mIntake);
public static final InstantCommand stopLoad = new InstantCommand(()->mIntake.setSpeed(0.0));
Then inside the button bindings put
new JoystickButton(mJoystick, 1).whenPressed(CommandUtility.loadShooter).whenReleased(CommandUtility.stopLoad);
Just depends on the goal of what they are trying to do and what kind of structure they want to use for their code, for us we probably would’ve chose to inline everything in the button binding or just wrote a separate class. All 3 methods should work i think.
What we really want here to ensure the thing cleans up after the sequence is a finally decorator that lets you decorate composite commands with a single piece of end behavior. I’ve added a github issue for this addition, if anyone wants to contribute it.
Ngl, I find that properly-structured inline commands are much more readable and less verbose than full command classes. For an example from 6738’s 2022 code:
new ParallelDeadlineGroup(
new WaitUntilCommand(intake::isEmpty),
shooter.accelerateFenderCommand(),
new RepeatingCommand(
sequence(
new WaitUntilCommand(new Trigger(shooter::isAtTargetVelocity).debounce(0.2)),
intake.pullIntoShooter(Falling(shooter.ballShotTrigger)))),
sequence(intake.intakeTick()),
leds.setColorCommand(LedMode.VIOLET));
It’s true that the docs about structuring and inline commands are lacking; there are a few PRs attempting to change that and if anyone has any wisdom they’re willing to PR it will be happily accepted.