mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-03 03:01:44 +00:00
[commands] Add command factories (#4476)
Co-authored-by: oblarg <emichaelbarnett@gmail.com>
This commit is contained in:
@@ -430,14 +430,32 @@ public interface Command {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this Command.
|
||||
* Gets the name of this Command. Defaults to the simple class name if not overridden.
|
||||
*
|
||||
* @return Name
|
||||
* @return The display name of the Command
|
||||
*/
|
||||
default String getName() {
|
||||
return this.getClass().getSimpleName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of this Command. Nullop if not overridden.
|
||||
*
|
||||
* @param name The display name of the Command.
|
||||
*/
|
||||
default void setName(String name) {}
|
||||
|
||||
/**
|
||||
* Decorates this Command with a name. Is an inline function for #setName(String);
|
||||
*
|
||||
* @param name name
|
||||
* @return the decorated Command
|
||||
*/
|
||||
default Command withName(String name) {
|
||||
this.setName(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* An enum describing the command's behavior when another command with a shared requirement is
|
||||
* scheduled.
|
||||
|
||||
@@ -51,21 +51,11 @@ public abstract class CommandBase implements Sendable, Command {
|
||||
*
|
||||
* @param name name
|
||||
*/
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
SendableRegistry.setName(this, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decorates this Command with a name. Is an inline function for #setName(String);
|
||||
*
|
||||
* @param name name
|
||||
* @return the decorated Command
|
||||
*/
|
||||
public CommandBase withName(String name) {
|
||||
this.setName(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the subsystem name of this Command.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.wpilibj2.command;
|
||||
|
||||
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Namespace for command factory methods.
|
||||
*
|
||||
* <p>For convenience, you might want to static import the members of this class.
|
||||
*/
|
||||
public final class Commands {
|
||||
/**
|
||||
* Constructs a command that does nothing, finishing immediately.
|
||||
*
|
||||
* @return the command
|
||||
*/
|
||||
public static Command none() {
|
||||
return new InstantCommand();
|
||||
}
|
||||
|
||||
// Action Commands
|
||||
|
||||
/**
|
||||
* Constructs a command that runs an action once and finishes.
|
||||
*
|
||||
* @param action the action to run
|
||||
* @param requirements subsystems the action requires
|
||||
* @return the command
|
||||
* @see InstantCommand
|
||||
*/
|
||||
public static Command runOnce(Runnable action, Subsystem... requirements) {
|
||||
return new InstantCommand(action, requirements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a command that runs an action every iteration until interrupted.
|
||||
*
|
||||
* @param action the action to run
|
||||
* @param requirements subsystems the action requires
|
||||
* @return the command
|
||||
* @see RunCommand
|
||||
*/
|
||||
public static Command run(Runnable action, Subsystem... requirements) {
|
||||
return new RunCommand(action, requirements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a command that runs an action once and another action when the command is
|
||||
* interrupted.
|
||||
*
|
||||
* @param start the action to run on start
|
||||
* @param end the action to run on interrupt
|
||||
* @param requirements subsystems the action requires
|
||||
* @return the command
|
||||
* @see StartEndCommand
|
||||
*/
|
||||
public static Command startEnd(Runnable start, Runnable end, Subsystem... requirements) {
|
||||
return new StartEndCommand(start, end, requirements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a command that runs an action every iteration until interrupted, and then runs a
|
||||
* second action.
|
||||
*
|
||||
* @param run the action to run every iteration
|
||||
* @param end the action to run on interrupt
|
||||
* @param requirements subsystems the action requires
|
||||
* @return the command
|
||||
*/
|
||||
public static Command runEnd(Runnable run, Runnable end, Subsystem... requirements) {
|
||||
requireNonNullParam(end, "end", "Command.runEnd");
|
||||
return new FunctionalCommand(
|
||||
() -> {}, run, interrupted -> end.run(), () -> false, requirements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a command that prints a message and finishes.
|
||||
*
|
||||
* @param message the message to print
|
||||
* @return the command
|
||||
* @see PrintCommand
|
||||
*/
|
||||
public static Command print(String message) {
|
||||
return new PrintCommand(message);
|
||||
}
|
||||
|
||||
// Idling Commands
|
||||
|
||||
/**
|
||||
* Constructs a command that does nothing, finishing after a specified duration.
|
||||
*
|
||||
* @param seconds after how long the command finishes
|
||||
* @return the command
|
||||
* @see WaitCommand
|
||||
*/
|
||||
public static Command wait(double seconds) {
|
||||
return new WaitCommand(seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a command that does nothing, finishing once a command becomes true.
|
||||
*
|
||||
* @param condition the condition
|
||||
* @return the command
|
||||
* @see WaitUntilCommand
|
||||
*/
|
||||
public static Command waitUntil(BooleanSupplier condition) {
|
||||
return new WaitUntilCommand(condition);
|
||||
}
|
||||
|
||||
// Selector Commands
|
||||
|
||||
/**
|
||||
* Runs one of two commands, based on the boolean selector function.
|
||||
*
|
||||
* @param onTrue the command to run if the selector function returns true
|
||||
* @param onFalse the command to run if the selector function returns false
|
||||
* @param selector the selector function
|
||||
* @return the command
|
||||
* @see ConditionalCommand
|
||||
*/
|
||||
public static Command either(Command onTrue, Command onFalse, BooleanSupplier selector) {
|
||||
return new ConditionalCommand(onTrue, onFalse, selector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs one of several commands, based on the selector function.
|
||||
*
|
||||
* @param selector the selector function
|
||||
* @param commands map of commands to select from
|
||||
* @return the command
|
||||
* @see SelectCommand
|
||||
*/
|
||||
public static Command select(Map<Object, Command> commands, Supplier<Object> selector) {
|
||||
return new SelectCommand(commands, selector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a group of commands in series, one after the other.
|
||||
*
|
||||
* @param commands the commands to include
|
||||
* @return the command group
|
||||
* @see SequentialCommandGroup
|
||||
*/
|
||||
public static Command sequence(Command... commands) {
|
||||
return new SequentialCommandGroup(commands);
|
||||
}
|
||||
|
||||
// Command Groups
|
||||
|
||||
/**
|
||||
* Runs a group of commands in series, one after the other. Once the last command ends, the group
|
||||
* is restarted.
|
||||
*
|
||||
* @param commands the commands to include
|
||||
* @return the command group
|
||||
* @see SequentialCommandGroup
|
||||
* @see Command#repeatedly()
|
||||
*/
|
||||
public static Command repeatingSequence(Command... commands) {
|
||||
return sequence(commands).repeatedly();
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a group of commands at the same time. Ends once all commands in the group finish.
|
||||
*
|
||||
* @param commands the commands to include
|
||||
* @return the command
|
||||
* @see ParallelCommandGroup
|
||||
*/
|
||||
public static Command parallel(Command... commands) {
|
||||
return new ParallelCommandGroup(commands);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a group of commands at the same time. Ends once any command in the group finishes, and
|
||||
* cancels the others.
|
||||
*
|
||||
* @param commands the commands to include
|
||||
* @return the command group
|
||||
* @see ParallelRaceGroup
|
||||
*/
|
||||
public static Command race(Command... commands) {
|
||||
return new ParallelRaceGroup(commands);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a group of commands at the same time. Ends once a specific command finishes, and cancels
|
||||
* the others.
|
||||
*
|
||||
* @param deadline the deadline command
|
||||
* @param commands the commands to include
|
||||
* @return the command group
|
||||
* @see ParallelDeadlineGroup
|
||||
*/
|
||||
public static Command deadline(Command deadline, Command... commands) {
|
||||
return new ParallelDeadlineGroup(deadline, commands);
|
||||
}
|
||||
|
||||
private Commands() {
|
||||
throw new UnsupportedOperationException("This is a utility class");
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "frc2/command/ParallelCommandGroup.h"
|
||||
#include "frc2/command/ParallelDeadlineGroup.h"
|
||||
#include "frc2/command/ParallelRaceGroup.h"
|
||||
#include "frc2/command/PerpetualCommand.h"
|
||||
#include "frc2/command/PrintCommand.h"
|
||||
#include "frc2/command/ProxyScheduleCommand.h"
|
||||
#include "frc2/command/RepeatCommand.h"
|
||||
#include "frc2/command/SequentialCommandGroup.h"
|
||||
|
||||
135
wpilibNewCommands/src/main/native/cpp/frc2/command/Commands.cpp
Normal file
135
wpilibNewCommands/src/main/native/cpp/frc2/command/Commands.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "frc2/command/Commands.h"
|
||||
|
||||
#include "frc2/command/ConditionalCommand.h"
|
||||
#include "frc2/command/FunctionalCommand.h"
|
||||
#include "frc2/command/InstantCommand.h"
|
||||
#include "frc2/command/ParallelCommandGroup.h"
|
||||
#include "frc2/command/ParallelDeadlineGroup.h"
|
||||
#include "frc2/command/ParallelRaceGroup.h"
|
||||
#include "frc2/command/PerpetualCommand.h"
|
||||
#include "frc2/command/PrintCommand.h"
|
||||
#include "frc2/command/ProxyScheduleCommand.h"
|
||||
#include "frc2/command/RunCommand.h"
|
||||
#include "frc2/command/SelectCommand.h"
|
||||
#include "frc2/command/SequentialCommandGroup.h"
|
||||
#include "frc2/command/WaitCommand.h"
|
||||
#include "frc2/command/WaitUntilCommand.h"
|
||||
|
||||
using namespace frc2;
|
||||
|
||||
// Factories
|
||||
|
||||
CommandPtr cmd::None() {
|
||||
return InstantCommand().ToPtr();
|
||||
}
|
||||
|
||||
CommandPtr cmd::RunOnce(std::function<void()> action,
|
||||
std::initializer_list<Subsystem*> requirements) {
|
||||
return InstantCommand(std::move(action), requirements).ToPtr();
|
||||
}
|
||||
|
||||
CommandPtr cmd::RunOnce(std::function<void()> action,
|
||||
std::span<Subsystem* const> requirements) {
|
||||
return InstantCommand(std::move(action), requirements).ToPtr();
|
||||
}
|
||||
|
||||
CommandPtr cmd::Run(std::function<void()> action,
|
||||
std::initializer_list<Subsystem*> requirements) {
|
||||
return RunCommand(std::move(action), requirements).ToPtr();
|
||||
}
|
||||
|
||||
CommandPtr cmd::Run(std::function<void()> action,
|
||||
std::span<Subsystem* const> requirements) {
|
||||
return RunCommand(std::move(action), requirements).ToPtr();
|
||||
}
|
||||
|
||||
CommandPtr cmd::StartEnd(std::function<void()> start, std::function<void()> end,
|
||||
std::initializer_list<Subsystem*> requirements) {
|
||||
return FunctionalCommand(
|
||||
std::move(start), [] {},
|
||||
[end = std::move(end)](bool interrupted) { end(); },
|
||||
[] { return false; }, requirements)
|
||||
.ToPtr();
|
||||
}
|
||||
|
||||
CommandPtr cmd::StartEnd(std::function<void()> start, std::function<void()> end,
|
||||
std::span<Subsystem* const> requirements) {
|
||||
return FunctionalCommand(
|
||||
std::move(start), [] {},
|
||||
[end = std::move(end)](bool interrupted) { end(); },
|
||||
[] { return false; }, requirements)
|
||||
.ToPtr();
|
||||
}
|
||||
|
||||
CommandPtr cmd::RunEnd(std::function<void()> run, std::function<void()> end,
|
||||
std::initializer_list<Subsystem*> requirements) {
|
||||
return FunctionalCommand([] {}, std::move(run),
|
||||
[end = std::move(end)](bool interrupted) { end(); },
|
||||
[] { return false; }, requirements)
|
||||
.ToPtr();
|
||||
}
|
||||
|
||||
CommandPtr cmd::RunEnd(std::function<void()> run, std::function<void()> end,
|
||||
std::span<Subsystem* const> requirements) {
|
||||
return FunctionalCommand([] {}, std::move(run),
|
||||
[end = std::move(end)](bool interrupted) { end(); },
|
||||
[] { return false; }, requirements)
|
||||
.ToPtr();
|
||||
}
|
||||
|
||||
CommandPtr cmd::Print(std::string_view msg) {
|
||||
return PrintCommand(msg).ToPtr();
|
||||
}
|
||||
|
||||
CommandPtr cmd::Wait(units::second_t duration) {
|
||||
return WaitCommand(duration).ToPtr();
|
||||
}
|
||||
|
||||
CommandPtr cmd::WaitUntil(std::function<bool()> condition) {
|
||||
return WaitUntilCommand(condition).ToPtr();
|
||||
}
|
||||
|
||||
CommandPtr cmd::Either(CommandPtr&& onTrue, CommandPtr&& onFalse,
|
||||
std::function<bool()> selector) {
|
||||
return ConditionalCommand(std::move(onTrue).Unwrap(),
|
||||
std::move(onFalse).Unwrap(), std::move(selector))
|
||||
.ToPtr();
|
||||
}
|
||||
|
||||
template <typename Key>
|
||||
CommandPtr cmd::Select(std::function<Key()> selector,
|
||||
std::vector<std::pair<Key, CommandPtr>> commands) {
|
||||
return SelectCommand(std::move(selector),
|
||||
CommandPtr::UnwrapVector(std::move(commands)))
|
||||
.ToPtr();
|
||||
}
|
||||
|
||||
CommandPtr cmd::Sequence(std::vector<CommandPtr>&& commands) {
|
||||
return SequentialCommandGroup(CommandPtr::UnwrapVector(std::move(commands)))
|
||||
.ToPtr();
|
||||
}
|
||||
|
||||
CommandPtr cmd::RepeatingSequence(std::vector<CommandPtr>&& commands) {
|
||||
return Sequence(std::move(commands)).Repeatedly();
|
||||
}
|
||||
|
||||
CommandPtr cmd::Parallel(std::vector<CommandPtr>&& commands) {
|
||||
return ParallelCommandGroup(CommandPtr::UnwrapVector(std::move(commands)))
|
||||
.ToPtr();
|
||||
}
|
||||
|
||||
CommandPtr cmd::Race(std::vector<CommandPtr>&& commands) {
|
||||
return ParallelRaceGroup(CommandPtr::UnwrapVector(std::move(commands)))
|
||||
.ToPtr();
|
||||
}
|
||||
|
||||
CommandPtr cmd::Deadline(CommandPtr&& deadline,
|
||||
std::vector<CommandPtr>&& others) {
|
||||
return ParallelDeadlineGroup(std::move(deadline).Unwrap(),
|
||||
CommandPtr::UnwrapVector(std::move(others)))
|
||||
.ToPtr();
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "frc2/command/CommandPtr.h"
|
||||
|
||||
namespace frc2 {
|
||||
class Subsystem;
|
||||
|
||||
/**
|
||||
* Namespace for command factories.
|
||||
*/
|
||||
namespace cmd {
|
||||
|
||||
/**
|
||||
* Constructs a command that does nothing, finishing immediately.
|
||||
*/
|
||||
[[nodiscard]] CommandPtr None();
|
||||
|
||||
// Action Commands
|
||||
|
||||
/**
|
||||
* Constructs a command that runs an action once and finishes.
|
||||
*
|
||||
* @param action the action to run
|
||||
* @param requirements subsystems the action requires
|
||||
*/
|
||||
[[nodiscard]] CommandPtr RunOnce(
|
||||
std::function<void()> action,
|
||||
std::initializer_list<Subsystem*> requirements);
|
||||
|
||||
/**
|
||||
* Constructs a command that runs an action once and finishes.
|
||||
*
|
||||
* @param action the action to run
|
||||
* @param requirements subsystems the action requires
|
||||
*/
|
||||
[[nodiscard]] CommandPtr RunOnce(std::function<void()> action,
|
||||
std::span<Subsystem* const> requirements = {});
|
||||
|
||||
/**
|
||||
* Constructs a command that runs an action every iteration until interrupted.
|
||||
*
|
||||
* @param action the action to run
|
||||
* @param requirements subsystems the action requires
|
||||
*/
|
||||
[[nodiscard]] CommandPtr Run(std::function<void()> action,
|
||||
std::initializer_list<Subsystem*> requirements);
|
||||
|
||||
/**
|
||||
* Constructs a command that runs an action every iteration until interrupted.
|
||||
*
|
||||
* @param action the action to run
|
||||
* @param requirements subsystems the action requires
|
||||
*/
|
||||
[[nodiscard]] CommandPtr Run(std::function<void()> action,
|
||||
std::span<Subsystem* const> requirements = {});
|
||||
|
||||
/**
|
||||
* Constructs a command that runs an action once and another action when the
|
||||
* command is interrupted.
|
||||
*
|
||||
* @param start the action to run on start
|
||||
* @param end the action to run on interrupt
|
||||
* @param requirements subsystems the action requires
|
||||
*/
|
||||
[[nodiscard]] CommandPtr StartEnd(
|
||||
std::function<void()> start, std::function<void()> end,
|
||||
std::initializer_list<Subsystem*> requirements);
|
||||
|
||||
/**
|
||||
* Constructs a command that runs an action once and another action when the
|
||||
* command is interrupted.
|
||||
*
|
||||
* @param start the action to run on start
|
||||
* @param end the action to run on interrupt
|
||||
* @param requirements subsystems the action requires
|
||||
*/
|
||||
[[nodiscard]] CommandPtr StartEnd(
|
||||
std::function<void()> start, std::function<void()> end,
|
||||
std::span<Subsystem* const> requirements = {});
|
||||
|
||||
/**
|
||||
* Constructs a command that runs an action every iteration until interrupted,
|
||||
* and then runs a second action.
|
||||
*
|
||||
* @param run the action to run every iteration
|
||||
* @param end the action to run on interrupt
|
||||
* @param requirements subsystems the action requires
|
||||
*/
|
||||
[[nodiscard]] CommandPtr RunEnd(std::function<void()> run,
|
||||
std::function<void()> end,
|
||||
std::initializer_list<Subsystem*> requirements);
|
||||
|
||||
/**
|
||||
* Constructs a command that runs an action every iteration until interrupted,
|
||||
* and then runs a second action.
|
||||
*
|
||||
* @param run the action to run every iteration
|
||||
* @param end the action to run on interrupt
|
||||
* @param requirements subsystems the action requires
|
||||
*/
|
||||
[[nodiscard]] CommandPtr RunEnd(std::function<void()> run,
|
||||
std::function<void()> end,
|
||||
std::span<Subsystem* const> requirements = {});
|
||||
|
||||
/**
|
||||
* Constructs a command that prints a message and finishes.
|
||||
*
|
||||
* @param msg the message to print
|
||||
*/
|
||||
[[nodiscard]] CommandPtr Print(std::string_view msg);
|
||||
|
||||
// Idling Commands
|
||||
|
||||
/**
|
||||
* Constructs a command that does nothing, finishing after a specified duration.
|
||||
*
|
||||
* @param duration after how long the command finishes
|
||||
*/
|
||||
[[nodiscard]] CommandPtr Wait(units::second_t duration);
|
||||
|
||||
/**
|
||||
* Constructs a command that does nothing, finishing once a command becomes
|
||||
* true.
|
||||
*
|
||||
* @param condition the condition
|
||||
*/
|
||||
[[nodiscard]] CommandPtr WaitUntil(std::function<bool()> condition);
|
||||
|
||||
// Selector Commands
|
||||
|
||||
/**
|
||||
* Runs one of two commands, based on the boolean selector function.
|
||||
*
|
||||
* @param onTrue the command to run if the selector function returns true
|
||||
* @param onFalse the command to run if the selector function returns false
|
||||
* @param selector the selector function
|
||||
*/
|
||||
[[nodiscard]] CommandPtr Either(CommandPtr&& onTrue, CommandPtr&& onFalse,
|
||||
std::function<bool()> selector);
|
||||
|
||||
/**
|
||||
* Runs one of several commands, based on the selector function.
|
||||
*
|
||||
* @param selector the selector function
|
||||
* @param commands map of commands to select from
|
||||
*/
|
||||
template <typename Key>
|
||||
[[nodiscard]] CommandPtr Select(
|
||||
std::function<Key()> selector,
|
||||
std::vector<std::pair<Key, CommandPtr>> commands);
|
||||
|
||||
// Command Groups
|
||||
|
||||
/**
|
||||
* Runs a group of commands in series, one after the other.
|
||||
*/
|
||||
[[nodiscard]] CommandPtr Sequence(std::vector<CommandPtr>&& commands);
|
||||
|
||||
/**
|
||||
* Runs a group of commands in series, one after the other. Once the last
|
||||
* command ends, the group is restarted.
|
||||
*/
|
||||
[[nodiscard]] CommandPtr RepeatingSequence(std::vector<CommandPtr>&& commands);
|
||||
|
||||
/**
|
||||
* Runs a group of commands at the same time. Ends once all commands in the
|
||||
* group finish.
|
||||
*/
|
||||
[[nodiscard]] CommandPtr Parallel(std::vector<CommandPtr>&& commands);
|
||||
|
||||
/**
|
||||
* Runs a group of commands at the same time. Ends once any command in the group
|
||||
* finishes, and cancels the others.
|
||||
*/
|
||||
[[nodiscard]] CommandPtr Race(std::vector<CommandPtr>&& commands);
|
||||
|
||||
/**
|
||||
* Runs a group of commands at the same time. Ends once a specific command
|
||||
* finishes, and cancels the others.
|
||||
*/
|
||||
[[nodiscard]] CommandPtr Deadline(CommandPtr&& deadline,
|
||||
std::vector<CommandPtr>&& others);
|
||||
} // namespace cmd
|
||||
|
||||
} // namespace frc2
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
package edu.wpi.first.wpilibj2.command;
|
||||
|
||||
import static edu.wpi.first.wpilibj2.command.CommandGroupBase.parallel;
|
||||
import static edu.wpi.first.wpilibj2.command.Commands.parallel;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user