Class Coroutine
Command.run(Coroutine) method to allow
commands to yield and compositions to run other commands. Commands are considered bound to
a coroutine while they're scheduled; attempting to use a coroutine outside the command bound to
it will result in an IllegalStateException being thrown.-
Method Summary
Modifier and TypeMethodDescriptionvoidAwaits completion of a command.voidawaitAll(Collection<? extends Command> commands) Awaits completion of all given commands.voidAwaits completion of all given commands.voidawaitAny(Collection<? extends Command> commands) Awaits completion of any given commands.voidAwaits completion of any given commands.voidfork(Collection<? extends Command> commands) Forks off some commands.voidSchedules a child command and then immediately returns.voidpark()Parks the current command.Advanced users only: this permits access to the backing command scheduler to run custom logic not provided by the standard coroutine methods.voidWaits for some duration of time to elapse.voidwaitUntil(BooleanSupplier condition) Yields until a condition is met.booleanyield()Yields control back to the scheduler to allow other commands to execute.
-
Method Details
-
yield
Yields control back to the scheduler to allow other commands to execute. This can be thought of as "pausing" the currently executing command.- Returns:
- true
- Throws:
IllegalStateException- if called anywhere other than the coroutine's running command
-
park
Parks the current command. No code in a command declared after callingpark()will be executed. A parked command will never complete naturally and must be interrupted or canceled.- Throws:
IllegalStateException- if called anywhere other than the coroutine's running command
-
fork
Schedules a child command and then immediately returns. The child command will run until its natural completion, the parent command exits, or the parent command cancels it.This is a nonblocking operation. To fork and then wait for the child command to complete, use
await(Command).The parent command will continue executing while the child command runs, and can resync with the child command using
await(Command).Command example() { return Command.noRequirements().executing(coroutine -> { Command child = ...; coroutine.fork(child); // ... do more things // then sync back up with the child command coroutine.await(child); }).named("Example"); }Note: forking a command that conflicts with a higher-priority command will fail. The forked command will not be scheduled, and the existing command will continue to run.
- Parameters:
commands- The commands to fork.- Throws:
IllegalStateException- if called anywhere other than the coroutine's running command- See Also:
-
fork
Forks off some commands. Each command will run until its natural completion, the parent command exits, or the parent command cancels it. The parent command will continue executing while the forked commands run, and can resync with the forked commands usingawaitAll(Collection).Command example() { return Command.noRequirements().executing(coroutine -> { Collection<Command> innerCommands = ...; coroutine.fork(innerCommands); // ... do more things // then sync back up with the inner commands coroutine.awaitAll(innerCommands); }).named("Example"); }Note: forking a command that conflicts with a higher-priority command will fail. The forked command will not be scheduled, and the existing command will continue to run.
- Parameters:
commands- The commands to fork.- Throws:
IllegalStateException- if called anywhere other than the coroutine's running command
-
await
Awaits completion of a command. If the command is not currently scheduled or running, it will be scheduled automatically. This is a blocking operation and will not return until the command completes or has been interrupted by another command scheduled by the same parent.- Parameters:
command- the command to await- Throws:
IllegalStateException- if called anywhere other than the coroutine's running command- See Also:
-
awaitAll
Awaits completion of all given commands. If any command is not current scheduled or running, it will be scheduled.- Parameters:
commands- the commands to await- Throws:
IllegalArgumentException- if any of the commands conflict with each otherIllegalStateException- if called anywhere other than the coroutine's running command
-
awaitAll
Awaits completion of all given commands. If any command is not current scheduled or running, it will be scheduled.- Parameters:
commands- the commands to await- Throws:
IllegalArgumentException- if any of the commands conflict with each otherIllegalStateException- if called anywhere other than the coroutine's running command
-
awaitAny
Awaits completion of any given commands. Any command that's not already scheduled or running will be scheduled. After any of the given commands completes, the rest will be canceled.- Parameters:
commands- the commands to await- Throws:
IllegalArgumentException- if any of the commands conflict with each otherIllegalStateException- if called anywhere other than the coroutine's running command
-
awaitAny
Awaits completion of any given commands. Any command that's not already scheduled or running will be scheduled. After any of the given commands completes, the rest will be canceled.- Parameters:
commands- the commands to await- Throws:
IllegalArgumentException- if any of the commands conflict with each otherIllegalStateException- if called anywhere other than the coroutine's running command
-
wait
Waits for some duration of time to elapse. Returns immediately if the given duration is zero or negative. Call this within a command or command composition to introduce a simple delay.For example, a basic autonomous routine that drives straight for 5 seconds:
Command timedDrive() { return drivebase.run(coroutine -> { drivebase.tankDrive(1, 1); coroutine.wait(Seconds.of(5)); drivebase.stop(); }).named("Timed Drive"); }Note that the resolution of the wait period is equal to the period at which
Scheduler.run()is called by the robot program. If using a 20 millisecond update period, the wait will be rounded up to the nearest 20 millisecond interval; in this scenario, callingwait(Milliseconds.of(1))andwait(Milliseconds.of(19))would have identical effects.Very small loop times near the loop period are sensitive to the order in which commands are executed. If a command waits for 10 ms at the end of a scheduler cycle, and then all the commands that ran before it complete or exit, and then the next cycle starts immediately, the wait will be evaluated at the start of that next cycle, which occurred less than 10 ms later. Therefore, the wait will see not enough time has passed and only exit after an additional cycle elapses, adding an unexpected extra 20 ms to the wait time. This becomes less of a problem with smaller loop periods, as the extra 1-loop delay becomes smaller.
- Parameters:
duration- the duration of time to wait- Throws:
IllegalStateException- if called anywhere other than the coroutine's running command
-
waitUntil
Yields until a condition is met.- Parameters:
condition- The condition to wait for- Throws:
IllegalStateException- if called anywhere other than the coroutine's running command
-
scheduler
Advanced users only: this permits access to the backing command scheduler to run custom logic not provided by the standard coroutine methods. Any commands manually scheduled through this will be canceled when the parent command exits - it's not possible to "fork" a command that lives longer than the command that scheduled it.- Returns:
- the command scheduler backing this coroutine
- Throws:
IllegalStateException- if called anywhere other than the coroutine's running command
-