What is difference between toggleWhenPressed(), whileHeld(), and whenPressed(); why would a command running continuously under one of these be stuttering?

The documentation on these is pretty sparse. I’m just working off the wpilib screensteps live page on running command on joystick input, and the different things we’ve tried.
What is the difference between a command being ‘run’ when invoked from whenPressed(), and ‘run continuously’ under whileHeld()? Is it run only once from whenPressed()? And how is this different for toggleWhenPressed()?
We have a situation where we’re simply running a TalonSRX motor in the execute() method of our command whileHeld(), but the motor is stuttering severely. After checking the logs, we see the command repeatedly being Finished and then re-started. We were not setting anything that would have caused isFinished() to return true, so I think it was being interrupted. It almost looks like it’s fighting with another command for control of the required subsystem, but I haven’t been able to confirm that yet.
Another odd aspect is that adding a tiny delay (like 0.2 seconds) smoothes out the motor running. This makes no sense to me. Our students were trying a few different things and this appeared to fix it, but I’d really like to understand why.

whileHeld - Initiate the command when the button is pressed down, cancel the command when the button is let go

whenPressed - Initiate the command when the button is pressed down, never cancel the command (wait for it to finish on its own).

toggleWhenPressed - Each time the button is pressed, toggle whether the command is running or not (if it’s running then cancel, if it’s not running then initate).

Could you provide more information as to what button you’re using? It’s possible that the button is not returning a constant value.

What exactly do you mean by this? Where was the delay added?

Edit: See @RufflesRidge’s answer

This is not an accurate description. See the Javadocs here: http://first.wpi.edu/FRC/roborio/release/docs/java/edu/wpi/first/wpilibj/buttons/Button.html

whileHeld() continuously restarts the command while the button is held which may be related the the behaviour the OP is seeing depending o. How their command is structured

The truth for whileHeld is actually somewhere in between the two explanations given so far. Here comes mine. Perhaps someone else will add another subtlety.

During each scheduler cycle, if the whileHeld button is active, an attempt is made to start the command. More accurately, the Command.start() method marks the command to be started. Later in the cycle, when it comes time to actually start commands, if the command is already running, it is not restarted and it keeps running as before. If it is not running at that time, it is started fresh.

When the button is released, the command is cancelled.

It could be that the command in question is terminating soon after starting (isFinished returns true, explicitly cancelled from some other code, or another command interrupts it for the same subsystem). It would then get restarted frequently. That could lead to this behavior.

In order to make further progress I think we will need a link to the code in GitHub or elsewhere.


In the execute() method. So basically all that was there was the following

  • set motor to 100%
  • Timer.delay(0.2)

All command methods should complete quickly. Having a delay like this is a bad idea. I strongly suspect that it is just masking an underlying problem with your command terminating early. What does you isFinished look like or better yet can we get a link to the code? Most of the time, commands that are designed for whileHeld just return false from isFinished. Although, I have see some use cases that need something different.


1 Like

This may be too obvious but we had a similar problem but it had nothing to do with the whenPressed() function. What occurred for us was that the programmer had a command later in the sequence that acted on the same motor, causing an interruption of the motor operation. This could be consistent with the delay smoothing things out since execution of the later commands would be delayed (but I agree with the comment that it is probably not a good idea to have the delay like this).

As others suggested, posting the code would clarify.

This is incorrect. whileHeld continually re-schedules the command every iteration while the button is held.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.