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