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..10974f45b11 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
@@ -398,6 +398,23 @@ public ProxyCommand asProxy() {
return new ProxyCommand(this);
}
+ /**
+ * Decorates this command to run "forked" by wrapping it in a {@link ScheduleCommand}. Use this
+ * for "forking off" from command compositions when the user does not wish to extend the command's
+ * requirements to the entire command composition. Note that if run from a composition, the
+ * composition will not know about the status of the scheduled commands, and will treat this
+ * command as finishing instantly.
+ *
+ * @return the decorated command
+ * @see ScheduleCommand
+ * @see WPILib
+ * docs
+ */
+ public ScheduleCommand fork() {
+ return new ScheduleCommand(this);
+ }
+
/**
* Decorates this command to only run if this condition is not met. If the command is already
* running and the condition changes to true, the command will not stop running. The requirements
diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/Commands.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/Commands.java
index c53409a033d..8c81106f83b 100644
--- a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/Commands.java
+++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/Commands.java
@@ -209,6 +209,25 @@ public static Command deferredProxy(Supplier supplier) {
return new ProxyCommand(supplier);
}
+ /**
+ * Constructs a command by wrapping the provided commands in a {@link ScheduleCommand}. Use this
+ * for "forking off" from command compositions when the user does not wish to extend the command's
+ * requirements to the entire command composition. Note that if run from a composition, the
+ * composition will not know about the status of the scheduled commands, and will treat this
+ * command as finishing instantly. Multiple commands can be added to this and will be scheduled in
+ * order.
+ *
+ * @param commands the commands to schedule in order
+ * @return the command
+ * @see ScheduleCommand
+ * @see WPILib
+ * docs
+ */
+ public static Command fork(Command... commands) {
+ return new ScheduleCommand(commands);
+ }
+
// Command Groups
/**
diff --git a/wpilibNewCommands/src/main/native/cpp/frc2/command/CommandPtr.cpp b/wpilibNewCommands/src/main/native/cpp/frc2/command/CommandPtr.cpp
index 298cc2e50ca..6b373b7f01e 100644
--- a/wpilibNewCommands/src/main/native/cpp/frc2/command/CommandPtr.cpp
+++ b/wpilibNewCommands/src/main/native/cpp/frc2/command/CommandPtr.cpp
@@ -18,6 +18,7 @@
#include "frc2/command/ParallelRaceGroup.h"
#include "frc2/command/ProxyCommand.h"
#include "frc2/command/RepeatCommand.h"
+#include "frc2/command/ScheduleCommand.h"
#include "frc2/command/SequentialCommandGroup.h"
#include "frc2/command/WaitCommand.h"
#include "frc2/command/WaitUntilCommand.h"
@@ -56,6 +57,13 @@ CommandPtr CommandPtr::AsProxy() && {
return std::move(*this);
}
+CommandPtr CommandPtr::Fork() && {
+ AssertValid();
+ std::vector vec{m_ptr.get()};
+ m_ptr = make_unique(std::span(vec));
+ return std::move(*this);
+}
+
class RunsWhenDisabledCommand : public WrapperCommand {
public:
RunsWhenDisabledCommand(std::unique_ptr&& command,
diff --git a/wpilibNewCommands/src/main/native/cpp/frc2/command/Commands.cpp b/wpilibNewCommands/src/main/native/cpp/frc2/command/Commands.cpp
index bc4bd39da73..0650d6e4be3 100644
--- a/wpilibNewCommands/src/main/native/cpp/frc2/command/Commands.cpp
+++ b/wpilibNewCommands/src/main/native/cpp/frc2/command/Commands.cpp
@@ -6,7 +6,7 @@
#include
#include
-
+#include
#include
#include "frc2/command/ConditionalCommand.h"
@@ -83,6 +83,21 @@ CommandPtr cmd::DeferredProxy(wpi::unique_function supplier) {
}
WPI_UNIGNORE_DEPRECATED
+CommandPtr cmd::Fork(CommandPtr&& other) {
+ std::vector vec{other.get()};
+ auto m_ptr = make_unique(std::span(vec));
+ return ScheduleCommand(std::move(*m_ptr)).ToPtr();
+}
+
+CommandPtr cmd::Fork(std::vector&& commands) {
+ std::vector vec{};
+ for (auto&& ptr : commands) {
+ vec.emplace_back(std::move(ptr).Unwrap().get());
+ }
+ auto m_ptr = make_unique(std::span(vec));
+ return ScheduleCommand(std::move(*m_ptr)).ToPtr();
+}
+
CommandPtr cmd::Wait(units::second_t duration) {
return WaitCommand(duration).ToPtr();
}
diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/CommandPtr.h b/wpilibNewCommands/src/main/native/include/frc2/command/CommandPtr.h
index e2f534f7547..17fa93c8b3a 100644
--- a/wpilibNewCommands/src/main/native/include/frc2/command/CommandPtr.h
+++ b/wpilibNewCommands/src/main/native/include/frc2/command/CommandPtr.h
@@ -63,6 +63,20 @@ class CommandPtr final {
[[nodiscard]]
CommandPtr AsProxy() &&;
+ /**
+ * Decorates this command to run "forked" by wrapping it in a {@link
+ * ScheduleCommand}. Use this for "forking off" from command compositions when
+ * the user does not wish to extend the command's requirements to the entire
+ * command composition. Note that if run from a composition, the composition
+ * will not know about the status of the scheduled commands, and will treat
+ * this command as finishing instantly.
+ *
+ * @return the decorated command
+ * @see ScheduleCommand
+ */
+ [[nodiscard]]
+ CommandPtr Fork() &&;
+
/**
* Decorates this command to run or stop when disabled.
*
diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/Commands.h b/wpilibNewCommands/src/main/native/include/frc2/command/Commands.h
index 6cfad01b1f0..fca01f1f11d 100644
--- a/wpilibNewCommands/src/main/native/include/frc2/command/Commands.h
+++ b/wpilibNewCommands/src/main/native/include/frc2/command/Commands.h
@@ -16,6 +16,7 @@
#include "frc2/command/CommandPtr.h"
#include "frc2/command/Requirements.h"
+#include "frc2/command/ScheduleCommand.h"
#include "frc2/command/SelectCommand.h"
namespace frc2 {
@@ -192,6 +193,36 @@ CommandPtr DeferredProxy(wpi::unique_function supplier);
"Defer(supplier).AsProxy() instead.")]]
CommandPtr DeferredProxy(wpi::unique_function supplier);
WPI_UNIGNORE_DEPRECATED
+
+ /**
+ * Constructs a command by wrapping the provided commands in a {@link ScheduleCommand}. Use this
+ * for "forking off" from command compositions when the user does not wish to extend the command's
+ * requirements to the entire command composition. Note that if run from a composition, the
+ * composition will not know about the status of the scheduled commands, and will treat this
+ * command as finishing instantly. Multiple commands can be added to this and will be scheduled in order.
+ *
+ * @param commands the commands to schedule in order
+ * @return the command
+ * @see ScheduleCommand
+ */
+ [[nodiscard]]
+ CommandPtr Fork(CommandPtr&& commands);
+
+ /**
+ * Constructs a command by wrapping the provided commands in a {@link ScheduleCommand}. Use this
+ * for "forking off" from command compositions when the user does not wish to extend the command's
+ * requirements to the entire command composition. Note that if run from a composition, the
+ * composition will not know about the status of the scheduled commands, and will treat this
+ * command as finishing instantly. Multiple commands can be added to this and will be scheduled in order.
+ *
+ * @param commands the commands to schedule in order
+ * @return the command
+ * @see ScheduleCommand
+ */
+ [[nodiscard]]
+ CommandPtr Fork(std::vector&& commands);
+
+
// Command Groups
namespace impl {