Help with running a command for a set amount of time in Java

Hi ChiefDelphi,

I want my students to write a simple autonomous routine where we back up for a few seconds. (We are using Java with the wpilibj2 library)

In past years, I would have had them use a TimedCommand for this, but I can’t seem to find it in the new version of WPILib. Is there a simple way to run a command for a set amount of time?

It seems like TimedCommand should still be in the library based on this link
https://first.wpi.edu/wpilib/allwpilib/docs/release/java/edu/wpi/first/wpilibj/command/TimedCommand.html

If you can’t find it a work around might be to start a timer in the initialize, excute like normal, and then check for a certain time passed in the isFinished method to end.

The timer class will work for this Timer (WPILib API 2022.4.1)
Most likely you will use start() and hasElapsed()

You can subclass WaitCommand or WaitUntilCommand or use the withTimeout or until decorators.

4 Likes

You could also run a ParallelRaceGroup with a new WaitCommand(time in seconds) and your drive backwards command. Whenever the first command ends which would be the wait command it will end all of them. Not maybe the most elegant way of doing it, but it would work

1 Like

This is what the withTimeout decorator does under the hood.

2 Likes

How do you use the decorator? new to java so trying to learn

new FooCommand().withTimeout(5) will give you a FooCommand in a race with a 5 second WaitCommand.

3 Likes

Makes sense. What is the FooCommand() ?

1 Like

Literally any command.

2 Likes

From that link:

This class is provided by the OldCommands VendorDep

The OP is using the NewCommands library (wpilibj2).

2 Likes

Completely overlooked that good catch.

Except the Bar() command. It’s never the Bar() command.

1 Like

We just generally use a class level variable such as startTime

In the initialize
startTime=System.currentTimeMillis();

Then in isFinished
return System.currentTimeMillis()-startTime>=targetTime;
where targetTime is the time in milliseconds (usually provided by a parameter in the constructor.

A bit simplistic and other options above might be better but this is easy to understand.

1 Like

Thank you all for your fast replies. I’ll work with my students and see if withTimeout() works for us, if not we’ll try using System.currentTimeMillis() within the command.

You can show your students this command here, notice the user of the Timer class, and importantly down in the end() method the .hasElapsed() method call.

Functionally, using the new DriveBackwardCommand().withTimeout(5) results in the same behavior.

You should use the FPGA timer in any case. The WPILib Timer class exists for a reason!

I agree that my solution was not the actual best but, as a mentor, it depends on the knowledge level of students I am working with and where they are at. Assuming they don’t know about timers - is this a case where the simple low level solution is good enough or does this become the “teachable moment” for them to learn about timers (Java native or WPI). Actually what I would really love is for one of them to be curious enough to come here on CD and find a thread like this to see all those better solutions and explore them.

I disagree with this approach to teaching, I think. Why teach students how to do something the wrong way when it is not substantially harder to do it the right way? The method names aren’t any less obvious.

Learning is not linear; there is no knowledge baseline past which it is appropriate to learn about different system timers. The concept is simple, and should be taught as soon as it is relevant.

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