001// Copyright (c) FIRST and other WPILib contributors. 002// Open Source Software; you can modify and/or share it under the terms of 003// the WPILib BSD license file in the root directory of this project. 004 005package edu.wpi.first.wpilibj2.command; 006 007import static edu.wpi.first.util.ErrorMessages.requireNonNullParam; 008 009import edu.wpi.first.units.measure.Time; 010import java.util.Map; 011import java.util.Set; 012import java.util.function.BooleanSupplier; 013import java.util.function.Supplier; 014 015/** 016 * Namespace for command factory methods. 017 * 018 * <p>For convenience, you might want to static import the members of this class. 019 */ 020public final class Commands { 021 /** 022 * Constructs a command that does nothing, finishing immediately. 023 * 024 * @return the command 025 */ 026 public static Command none() { 027 return new InstantCommand(); 028 } 029 030 /** 031 * Constructs a command that does nothing until interrupted. 032 * 033 * @param requirements Subsystems to require 034 * @return the command 035 */ 036 public static Command idle(Subsystem... requirements) { 037 return run(() -> {}, requirements); 038 } 039 040 // Action Commands 041 042 /** 043 * Constructs a command that runs an action once and finishes. 044 * 045 * @param action the action to run 046 * @param requirements subsystems the action requires 047 * @return the command 048 * @see InstantCommand 049 */ 050 public static Command runOnce(Runnable action, Subsystem... requirements) { 051 return new InstantCommand(action, requirements); 052 } 053 054 /** 055 * Constructs a command that runs an action every iteration until interrupted. 056 * 057 * @param action the action to run 058 * @param requirements subsystems the action requires 059 * @return the command 060 * @see RunCommand 061 */ 062 public static Command run(Runnable action, Subsystem... requirements) { 063 return new RunCommand(action, requirements); 064 } 065 066 /** 067 * Constructs a command that runs an action once and another action when the command is 068 * interrupted. 069 * 070 * @param start the action to run on start 071 * @param end the action to run on interrupt 072 * @param requirements subsystems the action requires 073 * @return the command 074 * @see StartEndCommand 075 */ 076 public static Command startEnd(Runnable start, Runnable end, Subsystem... requirements) { 077 return new StartEndCommand(start, end, requirements); 078 } 079 080 /** 081 * Constructs a command that runs an action every iteration until interrupted, and then runs a 082 * second action. 083 * 084 * @param run the action to run every iteration 085 * @param end the action to run on interrupt 086 * @param requirements subsystems the action requires 087 * @return the command 088 */ 089 public static Command runEnd(Runnable run, Runnable end, Subsystem... requirements) { 090 requireNonNullParam(end, "end", "Command.runEnd"); 091 return new FunctionalCommand( 092 () -> {}, run, interrupted -> end.run(), () -> false, requirements); 093 } 094 095 /** 096 * Constructs a command that runs an action once, and then runs an action every iteration until 097 * interrupted. 098 * 099 * @param start the action to run on start 100 * @param run the action to run every iteration 101 * @param requirements subsystems the action requires 102 * @return the command 103 */ 104 public static Command startRun(Runnable start, Runnable run, Subsystem... requirements) { 105 return new FunctionalCommand(start, run, interrupted -> {}, () -> false, requirements); 106 } 107 108 /** 109 * Constructs a command that prints a message and finishes. 110 * 111 * @param message the message to print 112 * @return the command 113 * @see PrintCommand 114 */ 115 public static Command print(String message) { 116 return new PrintCommand(message); 117 } 118 119 // Idling Commands 120 121 /** 122 * Constructs a command that does nothing, finishing after a specified duration. 123 * 124 * @param seconds after how long the command finishes 125 * @return the command 126 * @see WaitCommand 127 */ 128 public static Command waitSeconds(double seconds) { 129 return new WaitCommand(seconds); 130 } 131 132 /** 133 * Constructs a command that does nothing, finishing after a specified duration. 134 * 135 * @param time after how long the command finishes 136 * @return the command 137 * @see WaitCommand 138 */ 139 public static Command waitTime(Time time) { 140 return new WaitCommand(time); 141 } 142 143 /** 144 * Constructs a command that does nothing, finishing once a condition becomes true. 145 * 146 * @param condition the condition 147 * @return the command 148 * @see WaitUntilCommand 149 */ 150 public static Command waitUntil(BooleanSupplier condition) { 151 return new WaitUntilCommand(condition); 152 } 153 154 // Selector Commands 155 156 /** 157 * Runs one of two commands, based on the boolean selector function. 158 * 159 * @param onTrue the command to run if the selector function returns true 160 * @param onFalse the command to run if the selector function returns false 161 * @param selector the selector function 162 * @return the command 163 * @see ConditionalCommand 164 */ 165 public static Command either(Command onTrue, Command onFalse, BooleanSupplier selector) { 166 return new ConditionalCommand(onTrue, onFalse, selector); 167 } 168 169 /** 170 * Runs one of several commands, based on the selector function. 171 * 172 * @param <K> The type of key used to select the command 173 * @param selector the selector function 174 * @param commands map of commands to select from 175 * @return the command 176 * @see SelectCommand 177 */ 178 public static <K> Command select(Map<K, Command> commands, Supplier<? extends K> selector) { 179 return new SelectCommand<>(commands, selector); 180 } 181 182 /** 183 * Runs the command supplied by the supplier. 184 * 185 * @param supplier the command supplier 186 * @param requirements the set of requirements for this command 187 * @return the command 188 * @see DeferredCommand 189 */ 190 public static Command defer(Supplier<Command> supplier, Set<Subsystem> requirements) { 191 return new DeferredCommand(supplier, requirements); 192 } 193 194 /** 195 * Constructs a command that schedules the command returned from the supplier when initialized, 196 * and ends when it is no longer scheduled. The supplier is called when the command is 197 * initialized. 198 * 199 * @param supplier the command supplier 200 * @return the command 201 * @see ProxyCommand 202 * @see DeferredCommand 203 */ 204 public static Command deferredProxy(Supplier<Command> supplier) { 205 return defer(() -> supplier.get().asProxy(), Set.of()); 206 } 207 208 // Command Groups 209 210 /** 211 * Runs a group of commands in series, one after the other. 212 * 213 * @param commands the commands to include 214 * @return the command group 215 * @see SequentialCommandGroup 216 */ 217 public static Command sequence(Command... commands) { 218 return new SequentialCommandGroup(commands); 219 } 220 221 /** 222 * Runs a group of commands in series, one after the other. Once the last command ends, the group 223 * is restarted. 224 * 225 * @param commands the commands to include 226 * @return the command group 227 * @see SequentialCommandGroup 228 * @see Command#repeatedly() 229 */ 230 public static Command repeatingSequence(Command... commands) { 231 return sequence(commands).repeatedly(); 232 } 233 234 /** 235 * Runs a group of commands at the same time. Ends once all commands in the group finish. 236 * 237 * @param commands the commands to include 238 * @return the command 239 * @see ParallelCommandGroup 240 */ 241 public static Command parallel(Command... commands) { 242 return new ParallelCommandGroup(commands); 243 } 244 245 /** 246 * Runs a group of commands at the same time. Ends once any command in the group finishes, and 247 * cancels the others. 248 * 249 * @param commands the commands to include 250 * @return the command group 251 * @see ParallelRaceGroup 252 */ 253 public static Command race(Command... commands) { 254 return new ParallelRaceGroup(commands); 255 } 256 257 /** 258 * Runs a group of commands at the same time. Ends once a specific command finishes, and cancels 259 * the others. 260 * 261 * @param deadline the deadline command 262 * @param otherCommands the other commands to include 263 * @return the command group 264 * @see ParallelDeadlineGroup 265 * @throws IllegalArgumentException if the deadline command is also in the otherCommands argument 266 */ 267 public static Command deadline(Command deadline, Command... otherCommands) { 268 return new ParallelDeadlineGroup(deadline, otherCommands); 269 } 270 271 private Commands() { 272 throw new UnsupportedOperationException("This is a utility class"); 273 } 274}