diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/Command.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/Command.java
index a53d792d0e4..f87e9ea4a96 100644
--- a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/Command.java
+++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/Command.java
@@ -218,6 +218,56 @@ public ParallelRaceGroup onlyWhile(BooleanSupplier condition) {
return until(() -> !condition.getAsBoolean());
}
+ /**
+ * Decorates this command to run once a condition becomes true.
+ *
+ *
Note: This decorator works by adding this command to a composition. The command the
+ * decorator was called on cannot be scheduled independently or be added to a different
+ * composition (namely, decorators), unless it is manually cleared from the list of composed
+ * commands with {@link CommandScheduler#removeComposedCommand(Command)}. The command composition
+ * returned from this method can be further decorated without issue.
+ *
+ * @param condition the condition to wait for
+ * @return the decorated command
+ */
+ public SequentialCommandGroup after(BooleanSupplier condition) {
+ // if we want this to bypass the `WaitUntilCommand` if the condition is already true,
+ // we can use a conditional command but it proposes some compositional issues
+ return new SequentialCommandGroup(new WaitUntilCommand(condition), this);
+ }
+
+ /**
+ * Decorates this command to run after a time delay.
+ *
+ *
Note: This decorator works by adding this command to a composition. The command the
+ * decorator was called on cannot be scheduled independently or be added to a different
+ * composition (namely, decorators), unless it is manually cleared from the list of composed
+ * commands with {@link CommandScheduler#removeComposedCommand(Command)}. The command composition
+ * returned from this method can be further decorated without issue.
+ *
+ * @param seconds the seconds to wait
+ * @return the decorated command
+ */
+ public SequentialCommandGroup afterSeconds(double seconds) {
+ return new SequentialCommandGroup(new WaitCommand(seconds), this);
+ }
+
+ /**
+ * Decorates this command to run after a time delay.
+ *
+ *
Note: This decorator works by adding this command to a composition. The command the
+ * decorator was called on cannot be scheduled independently or be added to a different
+ * composition (namely, decorators), unless it is manually cleared from the list of composed
+ * commands with {@link CommandScheduler#removeComposedCommand(Command)}. The command composition
+ * returned from this method can be further decorated without issue.
+ *
+ * @param time the time to wait
+ * @return the decorated command
+ */
+ public SequentialCommandGroup afterTime(Time time) {
+ return afterSeconds(time.in(Seconds));
+ }
+
/**
* Decorates this command with a runnable to run before this command starts.
*
diff --git a/wpilibNewCommands/src/main/native/cpp/frc2/command/Command.cpp b/wpilibNewCommands/src/main/native/cpp/frc2/command/Command.cpp
index ff5e8f6aa51..bf549c5d20b 100644
--- a/wpilibNewCommands/src/main/native/cpp/frc2/command/Command.cpp
+++ b/wpilibNewCommands/src/main/native/cpp/frc2/command/Command.cpp
@@ -84,6 +84,14 @@ CommandPtr Command::OnlyWhile(std::function condition) && {
return std::move(*this).ToPtr().OnlyWhile(std::move(condition));
}
+CommandPtr After(std::function condition) && {
+ return std::move(*this).ToPtr().After(std::move(condition));
+}
+
+CommandPtr AfterTime(units::second_t duration) && {
+ return std::move(*this).ToPtr().AfterTime(duration);
+}
+
CommandPtr Command::IgnoringDisable(bool doesRunWhenDisabled) && {
return std::move(*this).ToPtr().IgnoringDisable(doesRunWhenDisabled);
}
diff --git a/wpilibNewCommands/src/main/native/cpp/frc2/command/CommandPtr.cpp b/wpilibNewCommands/src/main/native/cpp/frc2/command/CommandPtr.cpp
index ee7182a7847..f4515e73553 100644
--- a/wpilibNewCommands/src/main/native/cpp/frc2/command/CommandPtr.cpp
+++ b/wpilibNewCommands/src/main/native/cpp/frc2/command/CommandPtr.cpp
@@ -165,6 +165,24 @@ CommandPtr CommandPtr::OnlyIf(std::function condition) && {
return std::move(*this).Unless(std::not_fn(std::move(condition)));
}
+CommandPtr CommandPtr::After(std::function condition) && {
+ AssertValid();
+ std::vector> temp;
+ temp.emplace_back(std::make_unique(std::move(condition)));
+ temp.emplace_back(std::move(m_ptr));
+ m_ptr = std::make_unique(std::move(temp));
+ return std::move(*this);
+}
+
+CommandPtr CommandPtr::AfterTime(units::second_t duration) && {
+ AssertValid();
+ std::vector> temp;
+ temp.emplace_back(std::make_unique(duration));
+ temp.emplace_back(std::move(m_ptr));
+ m_ptr = std::make_unique(std::move(temp));
+ return std::move(*this);
+}
+
CommandPtr CommandPtr::DeadlineWith(CommandPtr&& parallel) && {
AssertValid();
std::vector> vec;
diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/Command.h b/wpilibNewCommands/src/main/native/include/frc2/command/Command.h
index c4af1afe81b..e1228614be4 100644
--- a/wpilibNewCommands/src/main/native/include/frc2/command/Command.h
+++ b/wpilibNewCommands/src/main/native/include/frc2/command/Command.h
@@ -217,6 +217,24 @@ class Command : public wpi::Sendable, public wpi::SendableHelper {
[[nodiscard]]
CommandPtr OnlyWhile(std::function condition) &&;
+ /**
+ * Decorates this command to run after a condition becomes true.
+ *
+ * @param condition the condition to run after
+ * @return the decorated command
+ */
+ [[nodiscard]]
+ CommandPtr After(std::function condition) &&;
+
+ /**
+ * Decorates this command to run after a specified amount of time.
+ *
+ * @param duration the time to wait before running
+ * @return the decorated command
+ */
+ [[nodiscard]]
+ CommandPtr AfterTime(units::second_t duration) &&;
+
/**
* Decorates this command with a runnable to run before this command starts.
*
diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/CommandPtr.h b/wpilibNewCommands/src/main/native/include/frc2/command/CommandPtr.h
index e2f534f7547..b3bb65ded04 100644
--- a/wpilibNewCommands/src/main/native/include/frc2/command/CommandPtr.h
+++ b/wpilibNewCommands/src/main/native/include/frc2/command/CommandPtr.h
@@ -182,6 +182,24 @@ class CommandPtr final {
[[nodiscard]]
CommandPtr OnlyIf(std::function condition) &&;
+ /**
+ * Decorates this command to run after a condition becomes true.
+ *
+ * @param condition the condition to run after
+ * @return the decorated command
+ */
+ [[nodiscard]]
+ CommandPtr After(std::function condition) &&;
+
+ /**
+ * Decorates this command to run after a specified amount of time.
+ *
+ * @param duration the time to wait before running
+ * @return the decorated command
+ */
+ [[nodiscard]]
+ CommandPtr AfterTime(units::second_t duration) &&;
+
/**
* Decorates this command with a set of commands to run parallel to it, ending
* when the calling command ends and interrupting all the others. Often more