Split the two command implementations into separate libraries (#2012)

This will allow us at the user code side to determine to include old commands, new commands or both.
This commit is contained in:
Thad House
2019-11-01 21:58:54 -07:00
committed by Peter Johnson
parent 2ad15cae19
commit 509819d83f
271 changed files with 470 additions and 91 deletions

View File

@@ -0,0 +1,73 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include "frc/buttons/Trigger.h"
#include "frc/commands/Command.h"
namespace frc {
/**
* This class provides an easy way to link commands to OI inputs.
*
* It is very easy to link a button to a command. For instance, you could link
* the trigger button of a joystick to a "score" command.
*
* This class represents a subclass of Trigger that is specifically aimed at
* buttons on an operator interface as a common use case of the more generalized
* Trigger objects. This is a simple wrapper around Trigger with the method
* names renamed to fit the Button object use.
*/
class Button : public Trigger {
public:
Button() = default;
Button(Button&&) = default;
Button& operator=(Button&&) = default;
/**
* Specifies the command to run when a button is first pressed.
*
* @param command The pointer to the command to run
*/
virtual void WhenPressed(Command* command);
/**
* Specifies the command to be scheduled while the button is pressed.
*
* The command will be scheduled repeatedly while the button is pressed and
* will be canceled when the button is released.
*
* @param command The pointer to the command to run
*/
virtual void WhileHeld(Command* command);
/**
* Specifies the command to run when the button is released.
*
* The command will be scheduled a single time.
*
* @param command The pointer to the command to run
*/
virtual void WhenReleased(Command* command);
/**
* Cancels the specificed command when the button is pressed.
*
* @param command The command to be canceled
*/
virtual void CancelWhenPressed(Command* command);
/**
* Toggle the specified command when the button is pressed.
*
* @param command The command to be toggled
*/
virtual void ToggleWhenPressed(Command* command);
};
} // namespace frc

View File

@@ -0,0 +1,32 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
namespace frc {
class Trigger;
class Command;
class ButtonScheduler {
public:
ButtonScheduler(bool last, Trigger* button, Command* orders);
virtual ~ButtonScheduler() = default;
ButtonScheduler(ButtonScheduler&&) = default;
ButtonScheduler& operator=(ButtonScheduler&&) = default;
virtual void Execute() = 0;
void Start();
protected:
bool m_pressedLast;
Trigger* m_button;
Command* m_command;
};
} // namespace frc

View File

@@ -0,0 +1,28 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include "frc/buttons/ButtonScheduler.h"
namespace frc {
class Trigger;
class Command;
class CancelButtonScheduler : public ButtonScheduler {
public:
CancelButtonScheduler(bool last, Trigger* button, Command* orders);
virtual ~CancelButtonScheduler() = default;
CancelButtonScheduler(CancelButtonScheduler&&) = default;
CancelButtonScheduler& operator=(CancelButtonScheduler&&) = default;
virtual void Execute();
};
} // namespace frc

View File

@@ -0,0 +1,28 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include "frc/buttons/ButtonScheduler.h"
namespace frc {
class Trigger;
class Command;
class HeldButtonScheduler : public ButtonScheduler {
public:
HeldButtonScheduler(bool last, Trigger* button, Command* orders);
virtual ~HeldButtonScheduler() = default;
HeldButtonScheduler(HeldButtonScheduler&&) = default;
HeldButtonScheduler& operator=(HeldButtonScheduler&&) = default;
virtual void Execute();
};
} // namespace frc

View File

@@ -0,0 +1,33 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include "frc/buttons/Button.h"
namespace frc {
class InternalButton : public Button {
public:
InternalButton() = default;
explicit InternalButton(bool inverted);
virtual ~InternalButton() = default;
InternalButton(InternalButton&&) = default;
InternalButton& operator=(InternalButton&&) = default;
void SetInverted(bool inverted);
void SetPressed(bool pressed);
virtual bool Get();
private:
bool m_pressed = false;
bool m_inverted = false;
};
} // namespace frc

View File

@@ -0,0 +1,30 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include "frc/GenericHID.h"
#include "frc/buttons/Button.h"
namespace frc {
class JoystickButton : public Button {
public:
JoystickButton(GenericHID* joystick, int buttonNumber);
virtual ~JoystickButton() = default;
JoystickButton(JoystickButton&&) = default;
JoystickButton& operator=(JoystickButton&&) = default;
virtual bool Get();
private:
GenericHID* m_joystick;
int m_buttonNumber;
};
} // namespace frc

View File

@@ -0,0 +1,36 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <memory>
#include <networktables/NetworkTable.h>
#include <networktables/NetworkTableEntry.h>
#include <wpi/Twine.h>
#include "frc/buttons/Button.h"
namespace frc {
class NetworkButton : public Button {
public:
NetworkButton(const wpi::Twine& tableName, const wpi::Twine& field);
NetworkButton(std::shared_ptr<nt::NetworkTable> table,
const wpi::Twine& field);
virtual ~NetworkButton() = default;
NetworkButton(NetworkButton&&) = default;
NetworkButton& operator=(NetworkButton&&) = default;
virtual bool Get();
private:
nt::NetworkTableEntry m_entry;
};
} // namespace frc

View File

@@ -0,0 +1,36 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2018-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include "frc/GenericHID.h"
#include "frc/buttons/Button.h"
namespace frc {
class POVButton : public Button {
public:
/**
* Creates a POV button for triggering commands.
*
* @param joystick The GenericHID object that has the POV
* @param angle The desired angle in degrees (e.g. 90, 270)
* @param povNumber The POV number (@see GenericHID#GetPOV)
*/
POVButton(GenericHID& joystick, int angle, int povNumber = 0);
virtual ~POVButton() = default;
POVButton(POVButton&&) = default;
POVButton& operator=(POVButton&&) = default;
bool Get() override;
private:
GenericHID* m_joystick;
int m_angle;
int m_povNumber;
};
} // namespace frc

View File

@@ -0,0 +1,28 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include "frc/buttons/ButtonScheduler.h"
namespace frc {
class Trigger;
class Command;
class PressedButtonScheduler : public ButtonScheduler {
public:
PressedButtonScheduler(bool last, Trigger* button, Command* orders);
virtual ~PressedButtonScheduler() = default;
PressedButtonScheduler(PressedButtonScheduler&&) = default;
PressedButtonScheduler& operator=(PressedButtonScheduler&&) = default;
virtual void Execute();
};
} // namespace frc

View File

@@ -0,0 +1,28 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include "frc/buttons/ButtonScheduler.h"
namespace frc {
class Trigger;
class Command;
class ReleasedButtonScheduler : public ButtonScheduler {
public:
ReleasedButtonScheduler(bool last, Trigger* button, Command* orders);
virtual ~ReleasedButtonScheduler() = default;
ReleasedButtonScheduler(ReleasedButtonScheduler&&) = default;
ReleasedButtonScheduler& operator=(ReleasedButtonScheduler&&) = default;
virtual void Execute();
};
} // namespace frc

View File

@@ -0,0 +1,28 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include "frc/buttons/ButtonScheduler.h"
namespace frc {
class Trigger;
class Command;
class ToggleButtonScheduler : public ButtonScheduler {
public:
ToggleButtonScheduler(bool last, Trigger* button, Command* orders);
virtual ~ToggleButtonScheduler() = default;
ToggleButtonScheduler(ToggleButtonScheduler&&) = default;
ToggleButtonScheduler& operator=(ToggleButtonScheduler&&) = default;
virtual void Execute();
};
} // namespace frc

View File

@@ -0,0 +1,56 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <atomic>
#include "frc/smartdashboard/Sendable.h"
#include "frc/smartdashboard/SendableHelper.h"
namespace frc {
class Command;
/**
* This class provides an easy way to link commands to inputs.
*
* It is very easy to link a polled input to a command. For instance, you could
* link the trigger button of a joystick to a "score" command or an encoder
* reaching a particular value.
*
* It is encouraged that teams write a subclass of Trigger if they want to have
* something unusual (for instance, if they want to react to the user holding
* a button while the robot is reading a certain sensor input). For this, they
* only have to write the {@link Trigger#Get()} method to get the full
* functionality of the Trigger class.
*/
class Trigger : public Sendable, public SendableHelper<Trigger> {
public:
Trigger() = default;
~Trigger() override = default;
Trigger(const Trigger& rhs);
Trigger& operator=(const Trigger& rhs);
Trigger(Trigger&& rhs);
Trigger& operator=(Trigger&& rhs);
bool Grab();
virtual bool Get() = 0;
void WhenActive(Command* command);
void WhileActive(Command* command);
void WhenInactive(Command* command);
void CancelWhenActive(Command* command);
void ToggleWhenActive(Command* command);
void InitSendable(SendableBuilder& builder) override;
private:
std::atomic_bool m_sendablePressed{false};
};
} // namespace frc

View File

@@ -0,0 +1,492 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <memory>
#include <string>
#include <wpi/SmallPtrSet.h>
#include <wpi/Twine.h>
#include "frc/ErrorBase.h"
#include "frc/commands/Subsystem.h"
#include "frc/smartdashboard/Sendable.h"
#include "frc/smartdashboard/SendableHelper.h"
namespace frc {
class CommandGroup;
/**
* The Command class is at the very core of the entire command framework.
*
* Every command can be started with a call to Start(). Once a command is
* started it will call Initialize(), and then will repeatedly call Execute()
* until the IsFinished() returns true. Once it does,End() will be called.
*
* However, if at any point while it is running Cancel() is called, then the
* command will be stopped and Interrupted() will be called.
*
* If a command uses a Subsystem, then it should specify that it does so by
* calling the Requires() method in its constructor. Note that a Command may
* have multiple requirements, and Requires() should be called for each one.
*
* If a command is running and a new command with shared requirements is
* started, then one of two things will happen. If the active command is
* interruptible, then Cancel() will be called and the command will be removed
* to make way for the new one. If the active command is not interruptible, the
* other one will not even be started, and the active one will continue
* functioning.
*
* @see CommandGroup
* @see Subsystem
*/
class Command : public ErrorBase,
public Sendable,
public SendableHelper<Command> {
friend class CommandGroup;
friend class Scheduler;
public:
/**
* Creates a new command.
*
* The name of this command will be default.
*/
Command();
/**
* Creates a new command with the given name and no timeout.
*
* @param name the name for this command
*/
explicit Command(const wpi::Twine& name);
/**
* Creates a new command with the given timeout and a default name.
*
* @param timeout the time (in seconds) before this command "times out"
* @see IsTimedOut()
*/
explicit Command(double timeout);
/**
* Creates a new command with the given timeout and a default name.
*
* @param subsystem the subsystem that the command requires
*/
explicit Command(Subsystem& subsystem);
/**
* Creates a new command with the given name and timeout.
*
* @param name the name of the command
* @param timeout the time (in seconds) before this command "times out"
* @see IsTimedOut()
*/
Command(const wpi::Twine& name, double timeout);
/**
* Creates a new command with the given name and timeout.
*
* @param name the name of the command
* @param subsystem the subsystem that the command requires
*/
Command(const wpi::Twine& name, Subsystem& subsystem);
/**
* Creates a new command with the given name and timeout.
*
* @param timeout the time (in seconds) before this command "times out"
* @param subsystem the subsystem that the command requires @see IsTimedOut()
*/
Command(double timeout, Subsystem& subsystem);
/**
* Creates a new command with the given name and timeout.
*
* @param name the name of the command
* @param timeout the time (in seconds) before this command "times out"
* @param subsystem the subsystem that the command requires @see IsTimedOut()
*/
Command(const wpi::Twine& name, double timeout, Subsystem& subsystem);
~Command() override = default;
Command(Command&&) = default;
Command& operator=(Command&&) = default;
/**
* Returns the time since this command was initialized (in seconds).
*
* This function will work even if there is no specified timeout.
*
* @return the time since this command was initialized (in seconds).
*/
double TimeSinceInitialized() const;
/**
* This method specifies that the given Subsystem is used by this command.
*
* This method is crucial to the functioning of the Command System in general.
*
* Note that the recommended way to call this method is in the constructor.
*
* @param subsystem The Subsystem required
* @see Subsystem
*/
void Requires(Subsystem* s);
/**
* Starts up the command. Gets the command ready to start.
*
* Note that the command will eventually start, however it will not
* necessarily do so immediately, and may in fact be canceled before
* initialize is even called.
*/
void Start();
/**
* The run method is used internally to actually run the commands.
*
* @return Whether or not the command should stay within the Scheduler.
*/
bool Run();
/**
* This will cancel the current command.
*
* This will cancel the current command eventually. It can be called multiple
* times. And it can be called when the command is not running. If the command
* is running though, then the command will be marked as canceled and
* eventually removed.
*
* A command can not be canceled if it is a part of a command group, you must
* cancel the command group instead.
*/
void Cancel();
/**
* Returns whether or not the command is running.
*
* This may return true even if the command has just been canceled, as it may
* not have yet called Interrupted().
*
* @return whether or not the command is running
*/
bool IsRunning() const;
/**
* Returns whether or not the command has been initialized.
*
* @return whether or not the command has been initialized.
*/
bool IsInitialized() const;
/**
* Returns whether or not the command has completed running.
*
* @return whether or not the command has completed running.
*/
bool IsCompleted() const;
/**
* Returns whether or not this has been canceled.
*
* @return whether or not this has been canceled
*/
bool IsCanceled() const;
/**
* Returns whether or not this command can be interrupted.
*
* @return whether or not this command can be interrupted
*/
bool IsInterruptible() const;
/**
* Sets whether or not this command can be interrupted.
*
* @param interruptible whether or not this command can be interrupted
*/
void SetInterruptible(bool interruptible);
/**
* Checks if the command requires the given Subsystem.
*
* @param system the system
* @return whether or not the subsystem is required (false if given nullptr)
*/
bool DoesRequire(Subsystem* subsystem) const;
using SubsystemSet = wpi::SmallPtrSetImpl<Subsystem*>;
/**
* Returns the requirements (as an std::set of Subsystem pointers) of this
* command.
*
* @return The requirements (as an std::set of Subsystem pointers) of this
* command
*/
const SubsystemSet& GetRequirements() const;
/**
* Returns the CommandGroup that this command is a part of.
*
* Will return null if this Command is not in a group.
*
* @return The CommandGroup that this command is a part of (or null if not in
* group)
*/
CommandGroup* GetGroup() const;
/**
* Sets whether or not this Command should run when the robot is disabled.
*
* By default a command will not run when the robot is disabled, and will in
* fact be canceled.
*
* @param run Whether this command should run when the robot is disabled.
*/
void SetRunWhenDisabled(bool run);
/**
* Returns whether or not this Command will run when the robot is disabled, or
* if it will cancel itself.
*
* @return Whether this Command will run when the robot is disabled, or if it
* will cancel itself.
*/
bool WillRunWhenDisabled() const;
/**
* Get the ID (sequence number) for this command.
*
* The ID is a unique sequence number that is incremented for each command.
*
* @return The ID of this command
*/
int GetID() const;
protected:
/**
* Sets the timeout of this command.
*
* @param timeout the timeout (in seconds)
* @see IsTimedOut()
*/
void SetTimeout(double timeout);
/**
* Returns whether or not the TimeSinceInitialized() method returns a number
* which is greater than or equal to the timeout for the command.
*
* If there is no timeout, this will always return false.
*
* @return whether the time has expired
*/
bool IsTimedOut() const;
/**
* If changes are locked, then this will generate a CommandIllegalUse error.
*
* @param message The message to report on error (it is appended by a default
* message)
* @return True if assert passed, false if assert failed.
*/
bool AssertUnlocked(const std::string& message);
/**
* Sets the parent of this command. No actual change is made to the group.
*
* @param parent the parent
*/
void SetParent(CommandGroup* parent);
/**
* Returns whether the command has a parent.
*
* @param True if the command has a parent.
*/
bool IsParented() const;
/**
* Clears list of subsystem requirements.
*
* This is only used by ConditionalCommand so cancelling the chosen command
* works properly in CommandGroup.
*/
void ClearRequirements();
/**
* The initialize method is called the first time this Command is run after
* being started.
*/
virtual void Initialize();
/**
* The execute method is called repeatedly until this Command either finishes
* or is canceled.
*/
virtual void Execute();
/**
* Returns whether this command is finished.
*
* If it is, then the command will be removed and End() will be called.
*
* It may be useful for a team to reference the IsTimedOut() method for
* time-sensitive commands.
*
* Returning false will result in the command never ending automatically.
* It may still be cancelled manually or interrupted by another command.
* Returning true will result in the command executing once and finishing
* immediately. We recommend using InstantCommand for this.
*
* @return Whether this command is finished.
* @see IsTimedOut()
*/
virtual bool IsFinished() = 0;
/**
* Called when the command ended peacefully.
*
* This is where you may want to wrap up loose ends, like shutting off a motor
* that was being used in the command.
*/
virtual void End();
/**
* Called when the command ends because somebody called Cancel() or another
* command shared the same requirements as this one, and booted it out.
*
* This is where you may want to wrap up loose ends, like shutting off a motor
* that was being used in the command.
*
* Generally, it is useful to simply call the End() method within this method,
* as done here.
*/
virtual void Interrupted();
virtual void _Initialize();
virtual void _Interrupted();
virtual void _Execute();
virtual void _End();
/**
* This works like Cancel(), except that it doesn't throw an exception if it
* is a part of a command group.
*
* Should only be called by the parent command group.
*/
virtual void _Cancel();
friend class ConditionalCommand;
/**
* Gets the name of this Command.
*
* @return Name
*/
std::string GetName() const;
/**
* Sets the name of this Command.
*
* @param name name
*/
void SetName(const wpi::Twine& name);
/**
* Gets the subsystem name of this Command.
*
* @return Subsystem name
*/
std::string GetSubsystem() const;
/**
* Sets the subsystem name of this Command.
*
* @param subsystem subsystem name
*/
void SetSubsystem(const wpi::Twine& subsystem);
private:
/**
* Prevents further changes from being made.
*/
void LockChanges();
/**
* Called when the command has been removed.
*
* This will call Interrupted() or End().
*/
void Removed();
/**
* This is used internally to mark that the command has been started.
*
* The lifecycle of a command is:
*
* StartRunning() is called. Run() is called (multiple times potentially).
* Removed() is called.
*
* It is very important that StartRunning() and Removed() be called in order
* or some assumptions of the code will be broken.
*/
void StartRunning();
/**
* Called to indicate that the timer should start.
*
* This is called right before Initialize() is, inside the Run() method.
*/
void StartTiming();
// The time since this command was initialized
double m_startTime = -1;
// The time (in seconds) before this command "times out" (-1 if no timeout)
double m_timeout;
// Whether or not this command has been initialized
bool m_initialized = false;
// The requirements (or null if no requirements)
wpi::SmallPtrSet<Subsystem*, 4> m_requirements;
// Whether or not it is running
bool m_running = false;
// Whether or not it is interruptible
bool m_interruptible = true;
// Whether or not it has been canceled
bool m_canceled = false;
// Whether or not it has been locked
bool m_locked = false;
// Whether this command should run when the robot is disabled
bool m_runWhenDisabled = false;
// The CommandGroup this is in
CommandGroup* m_parent = nullptr;
// Whether or not this command has completed running
bool m_completed = false;
int m_commandID = m_commandCounter++;
static int m_commandCounter;
public:
void InitSendable(SendableBuilder& builder) override;
};
} // namespace frc

View File

@@ -0,0 +1,180 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <vector>
#include <wpi/Twine.h>
#include "frc/commands/Command.h"
#include "frc/commands/CommandGroupEntry.h"
namespace frc {
/**
* A CommandGroup is a list of commands which are executed in sequence.
*
* Commands in a CommandGroup are added using the AddSequential() method and are
* called sequentially. CommandGroups are themselves Commands and can be given
* to other CommandGroups.
*
* CommandGroups will carry all of the requirements of their Command
* subcommands. Additional requirements can be specified by calling Requires()
* normally in the constructor.
*
* CommandGroups can also execute commands in parallel, simply by adding them
* using AddParallel().
*
* @see Command
* @see Subsystem
*/
class CommandGroup : public Command {
public:
CommandGroup() = default;
/**
* Creates a new CommandGroup with the given name.
*
* @param name The name for this command group
*/
explicit CommandGroup(const wpi::Twine& name);
virtual ~CommandGroup() = default;
CommandGroup(CommandGroup&&) = default;
CommandGroup& operator=(CommandGroup&&) = default;
/**
* Adds a new Command to the group. The Command will be started after all the
* previously added Commands.
*
* Note that any requirements the given Command has will be added to the
* group. For this reason, a Command's requirements can not be changed after
* being added to a group.
*
* It is recommended that this method be called in the constructor.
*
* @param command The Command to be added
*/
void AddSequential(Command* command);
/**
* Adds a new Command to the group with a given timeout. The Command will be
* started after all the previously added commands.
*
* Once the Command is started, it will be run until it finishes or the time
* expires, whichever is sooner. Note that the given Command will have no
* knowledge that it is on a timer.
*
* Note that any requirements the given Command has will be added to the
* group. For this reason, a Command's requirements can not be changed after
* being added to a group.
*
* It is recommended that this method be called in the constructor.
*
* @param command The Command to be added
* @param timeout The timeout (in seconds)
*/
void AddSequential(Command* command, double timeout);
/**
* Adds a new child Command to the group. The Command will be started after
* all the previously added Commands.
*
* Instead of waiting for the child to finish, a CommandGroup will have it run
* at the same time as the subsequent Commands. The child will run until
* either it finishes, a new child with conflicting requirements is started,
* or the main sequence runs a Command with conflicting requirements. In the
* latter two cases, the child will be canceled even if it says it can't be
* interrupted.
*
* Note that any requirements the given Command has will be added to the
* group. For this reason, a Command's requirements can not be changed after
* being added to a group.
*
* It is recommended that this method be called in the constructor.
*
* @param command The command to be added
*/
void AddParallel(Command* command);
/**
* Adds a new child Command to the group with the given timeout. The Command
* will be started after all the previously added Commands.
*
* Once the Command is started, it will run until it finishes, is interrupted,
* or the time expires, whichever is sooner. Note that the given Command will
* have no knowledge that it is on a timer.
*
* Instead of waiting for the child to finish, a CommandGroup will have it run
* at the same time as the subsequent Commands. The child will run until
* either it finishes, the timeout expires, a new child with conflicting
* requirements is started, or the main sequence runs a Command with
* conflicting requirements. In the latter two cases, the child will be
* canceled even if it says it can't be interrupted.
*
* Note that any requirements the given Command has will be added to the
* group. For this reason, a Command's requirements can not be changed after
* being added to a group.
*
* It is recommended that this method be called in the constructor.
*
* @param command The command to be added
* @param timeout The timeout (in seconds)
*/
void AddParallel(Command* command, double timeout);
bool IsInterruptible() const;
int GetSize() const;
protected:
/**
* Can be overridden by teams.
*/
virtual void Initialize();
/**
* Can be overridden by teams.
*/
virtual void Execute();
/**
* Can be overridden by teams.
*/
virtual bool IsFinished();
/**
* Can be overridden by teams.
*/
virtual void End();
/**
* Can be overridden by teams.
*/
virtual void Interrupted();
virtual void _Initialize();
virtual void _Execute();
virtual void _End();
virtual void _Interrupted();
private:
void CancelConflicts(Command* command);
// The commands in this group (stored in entries)
std::vector<CommandGroupEntry> m_commands;
// The active children in this group (stored in entries)
std::vector<CommandGroupEntry*> m_children;
// The current command, -1 signifies that none have been run
int m_currentCommandIndex = -1;
};
} // namespace frc

View File

@@ -0,0 +1,35 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
namespace frc {
class Command;
class CommandGroupEntry {
public:
enum Sequence {
kSequence_InSequence,
kSequence_BranchPeer,
kSequence_BranchChild
};
CommandGroupEntry() = default;
CommandGroupEntry(Command* command, Sequence state, double timeout = -1.0);
CommandGroupEntry(CommandGroupEntry&&) = default;
CommandGroupEntry& operator=(CommandGroupEntry&&) = default;
bool IsTimedOut() const;
double m_timeout = -1.0;
Command* m_command = nullptr;
Sequence m_state = kSequence_InSequence;
};
} // namespace frc

View File

@@ -0,0 +1,84 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <wpi/Twine.h>
#include "frc/commands/Command.h"
namespace frc {
/**
* A ConditionalCommand is a Command that starts one of two commands.
*
* A ConditionalCommand uses the Condition method to determine whether it should
* run onTrue or onFalse.
*
* A ConditionalCommand adds the proper Command to the Scheduler during
* Initialize() and then IsFinished() will return true once that Command has
* finished executing.
*
* If no Command is specified for onFalse, the occurrence of that condition
* will be a no-op.
*
* A ConditionalCommand will require the superset of subsystems of the onTrue
* and onFalse commands.
*
* @see Command
* @see Scheduler
*/
class ConditionalCommand : public Command {
public:
/**
* Creates a new ConditionalCommand with given onTrue and onFalse Commands.
*
* @param onTrue The Command to execute if Condition() returns true
* @param onFalse The Command to execute if Condition() returns false
*/
explicit ConditionalCommand(Command* onTrue, Command* onFalse = nullptr);
/**
* Creates a new ConditionalCommand with given onTrue and onFalse Commands.
*
* @param name The name for this command group
* @param onTrue The Command to execute if Condition() returns true
* @param onFalse The Command to execute if Condition() returns false
*/
ConditionalCommand(const wpi::Twine& name, Command* onTrue,
Command* onFalse = nullptr);
virtual ~ConditionalCommand() = default;
ConditionalCommand(ConditionalCommand&&) = default;
ConditionalCommand& operator=(ConditionalCommand&&) = default;
protected:
/**
* The Condition to test to determine which Command to run.
*
* @return true if m_onTrue should be run or false if m_onFalse should be run.
*/
virtual bool Condition() = 0;
void _Initialize() override;
void _Cancel() override;
bool IsFinished() override;
void _Interrupted() override;
private:
// The Command to execute if Condition() returns true
Command* m_onTrue;
// The Command to execute if Condition() returns false
Command* m_onFalse;
// Stores command chosen by condition
Command* m_chosenCommand = nullptr;
};
} // namespace frc

View File

@@ -0,0 +1,93 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <functional>
#include <wpi/Twine.h>
#include "frc/commands/Command.h"
#include "frc/commands/Subsystem.h"
namespace frc {
/**
* This command will execute once, then finish immediately afterward.
*
* Subclassing InstantCommand is shorthand for returning true from IsFinished().
*/
class InstantCommand : public Command {
public:
/**
* Creates a new InstantCommand with the given name.
*
* @param name The name for this command
*/
explicit InstantCommand(const wpi::Twine& name);
/**
* Creates a new InstantCommand with the given requirement.
*
* @param subsystem The subsystem that the command requires
*/
explicit InstantCommand(Subsystem& subsystem);
/**
* Creates a new InstantCommand with the given name.
*
* @param name The name for this command
* @param subsystem The subsystem that the command requires
*/
InstantCommand(const wpi::Twine& name, Subsystem& subsystem);
/**
* Create a command that calls the given function when run.
*
* @param func The function to run when Initialize() is run.
*/
explicit InstantCommand(std::function<void()> func);
/**
* Create a command that calls the given function when run.
*
* @param subsystem The subsystems that this command runs on.
* @param func The function to run when Initialize() is run.
*/
InstantCommand(Subsystem& subsystem, std::function<void()> func);
/**
* Create a command that calls the given function when run.
*
* @param name The name of the command.
* @param func The function to run when Initialize() is run.
*/
InstantCommand(const wpi::Twine& name, std::function<void()> func);
/**
* Create a command that calls the given function when run.
*
* @param name The name of the command.
* @param subsystem The subsystems that this command runs on.
* @param func The function to run when Initialize() is run.
*/
InstantCommand(const wpi::Twine& name, Subsystem& subsystem,
std::function<void()> func);
InstantCommand() = default;
virtual ~InstantCommand() = default;
InstantCommand(InstantCommand&&) = default;
InstantCommand& operator=(InstantCommand&&) = default;
protected:
std::function<void()> m_func = nullptr;
void _Initialize() override;
bool IsFinished() override;
};
} // namespace frc

View File

@@ -0,0 +1,74 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <memory>
#include <wpi/Twine.h>
#include "frc/PIDController.h"
#include "frc/PIDOutput.h"
#include "frc/PIDSource.h"
#include "frc/commands/Command.h"
namespace frc {
class PIDCommand : public Command, public PIDOutput, public PIDSource {
public:
PIDCommand(const wpi::Twine& name, double p, double i, double d);
PIDCommand(const wpi::Twine& name, double p, double i, double d,
double period);
PIDCommand(const wpi::Twine& name, double p, double i, double d, double f,
double period);
PIDCommand(double p, double i, double d);
PIDCommand(double p, double i, double d, double period);
PIDCommand(double p, double i, double d, double f, double period);
PIDCommand(const wpi::Twine& name, double p, double i, double d,
Subsystem& subsystem);
PIDCommand(const wpi::Twine& name, double p, double i, double d,
double period, Subsystem& subsystem);
PIDCommand(const wpi::Twine& name, double p, double i, double d, double f,
double period, Subsystem& subsystem);
PIDCommand(double p, double i, double d, Subsystem& subsystem);
PIDCommand(double p, double i, double d, double period, Subsystem& subsystem);
PIDCommand(double p, double i, double d, double f, double period,
Subsystem& subsystem);
virtual ~PIDCommand() = default;
PIDCommand(PIDCommand&&) = default;
PIDCommand& operator=(PIDCommand&&) = default;
void SetSetpointRelative(double deltaSetpoint);
// PIDOutput interface
void PIDWrite(double output) override;
// PIDSource interface
double PIDGet() override;
protected:
std::shared_ptr<PIDController> GetPIDController() const;
void _Initialize() override;
void _Interrupted() override;
void _End() override;
void SetSetpoint(double setpoint);
double GetSetpoint() const;
double GetPosition();
virtual double ReturnPIDInput() = 0;
virtual void UsePIDOutput(double output) = 0;
private:
// The internal PIDController
std::shared_ptr<PIDController> m_controller;
public:
void InitSendable(SendableBuilder& builder) override;
};
} // namespace frc

View File

@@ -0,0 +1,236 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <memory>
#include <wpi/Twine.h>
#include "frc/PIDController.h"
#include "frc/PIDOutput.h"
#include "frc/PIDSource.h"
#include "frc/commands/Subsystem.h"
namespace frc {
/**
* This class is designed to handle the case where there is a Subsystem which
* uses a single PIDController almost constantly (for instance, an elevator
* which attempts to stay at a constant height).
*
* It provides some convenience methods to run an internal PIDController. It
* also allows access to the internal PIDController in order to give total
* control to the programmer.
*/
class PIDSubsystem : public Subsystem, public PIDOutput, public PIDSource {
public:
/**
* Instantiates a PIDSubsystem that will use the given P, I, and D values.
*
* @param name the name
* @param p the proportional value
* @param i the integral value
* @param d the derivative value
*/
PIDSubsystem(const wpi::Twine& name, double p, double i, double d);
/**
* Instantiates a PIDSubsystem that will use the given P, I, and D values.
*
* @param name the name
* @param p the proportional value
* @param i the integral value
* @param d the derivative value
* @param f the feedforward value
*/
PIDSubsystem(const wpi::Twine& name, double p, double i, double d, double f);
/**
* Instantiates a PIDSubsystem that will use the given P, I, and D values.
*
* It will also space the time between PID loop calculations to be equal to
* the given period.
*
* @param name the name
* @param p the proportional value
* @param i the integral value
* @param d the derivative value
* @param f the feedfoward value
* @param period the time (in seconds) between calculations
*/
PIDSubsystem(const wpi::Twine& name, double p, double i, double d, double f,
double period);
/**
* Instantiates a PIDSubsystem that will use the given P, I, and D values.
*
* It will use the class name as its name.
*
* @param p the proportional value
* @param i the integral value
* @param d the derivative value
*/
PIDSubsystem(double p, double i, double d);
/**
* Instantiates a PIDSubsystem that will use the given P, I, and D values.
*
* It will use the class name as its name.
*
* @param p the proportional value
* @param i the integral value
* @param d the derivative value
* @param f the feedforward value
*/
PIDSubsystem(double p, double i, double d, double f);
/**
* Instantiates a PIDSubsystem that will use the given P, I, and D values.
*
* It will use the class name as its name. It will also space the time
* between PID loop calculations to be equal to the given period.
*
* @param p the proportional value
* @param i the integral value
* @param d the derivative value
* @param f the feedforward value
* @param period the time (in seconds) between calculations
*/
PIDSubsystem(double p, double i, double d, double f, double period);
~PIDSubsystem() override = default;
PIDSubsystem(PIDSubsystem&&) = default;
PIDSubsystem& operator=(PIDSubsystem&&) = default;
/**
* Enables the internal PIDController.
*/
void Enable();
/**
* Disables the internal PIDController.
*/
void Disable();
// PIDOutput interface
void PIDWrite(double output) override;
// PIDSource interface
double PIDGet() override;
/**
* Sets the setpoint to the given value.
*
* If SetRange() was called, then the given setpoint will be trimmed to fit
* within the range.
*
* @param setpoint the new setpoint
*/
void SetSetpoint(double setpoint);
/**
* Adds the given value to the setpoint.
*
* If SetRange() was used, then the bounds will still be honored by this
* method.
*
* @param deltaSetpoint the change in the setpoint
*/
void SetSetpointRelative(double deltaSetpoint);
/**
* Sets the maximum and minimum values expected from the input.
*
* @param minimumInput the minimum value expected from the input
* @param maximumInput the maximum value expected from the output
*/
void SetInputRange(double minimumInput, double maximumInput);
/**
* Sets the maximum and minimum values to write.
*
* @param minimumOutput the minimum value to write to the output
* @param maximumOutput the maximum value to write to the output
*/
void SetOutputRange(double minimumOutput, double maximumOutput);
/**
* Return the current setpoint.
*
* @return The current setpoint
*/
double GetSetpoint();
/**
* Returns the current position.
*
* @return the current position
*/
double GetPosition();
/**
* Returns the current rate.
*
* @return the current rate
*/
double GetRate();
/**
* Set the absolute error which is considered tolerable for use with
* OnTarget.
*
* @param absValue absolute error which is tolerable
*/
virtual void SetAbsoluteTolerance(double absValue);
/**
* Set the percentage error which is considered tolerable for use with
* OnTarget().
*
* @param percent percentage error which is tolerable
*/
virtual void SetPercentTolerance(double percent);
/**
* Return true if the error is within the percentage of the total input range,
* determined by SetTolerance().
*
* This asssumes that the maximum and minimum input were set using SetInput().
* Use OnTarget() in the IsFinished() method of commands that use this
* subsystem.
*
* Currently this just reports on target as the actual value passes through
* the setpoint. Ideally it should be based on being within the tolerance for
* some period of time.
*
* @return True if the error is within the percentage tolerance of the input
* range
*/
virtual bool OnTarget() const;
protected:
/**
* Returns the PIDController used by this PIDSubsystem.
*
* Use this if you would like to fine tune the PID loop.
*
* @return The PIDController used by this PIDSubsystem
*/
std::shared_ptr<PIDController> GetPIDController();
virtual double ReturnPIDInput() = 0;
virtual void UsePIDOutput(double output) = 0;
private:
// The internal PIDController
std::shared_ptr<PIDController> m_controller;
};
} // namespace frc

View File

@@ -0,0 +1,33 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <string>
#include <wpi/Twine.h>
#include "frc/commands/InstantCommand.h"
namespace frc {
class PrintCommand : public InstantCommand {
public:
explicit PrintCommand(const wpi::Twine& message);
virtual ~PrintCommand() = default;
PrintCommand(PrintCommand&&) = default;
PrintCommand& operator=(PrintCommand&&) = default;
protected:
virtual void Initialize();
private:
std::string m_message;
};
} // namespace frc

View File

@@ -0,0 +1,100 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <memory>
#include "frc/ErrorBase.h"
#include "frc/smartdashboard/Sendable.h"
#include "frc/smartdashboard/SendableHelper.h"
namespace frc {
class ButtonScheduler;
class Command;
class Subsystem;
class Scheduler : public ErrorBase,
public Sendable,
public SendableHelper<Scheduler> {
public:
/**
* Returns the Scheduler, creating it if one does not exist.
*
* @return the Scheduler
*/
static Scheduler* GetInstance();
/**
* Add a command to be scheduled later.
*
* In any pass through the scheduler, all commands are added to the additions
* list, then at the end of the pass, they are all scheduled.
*
* @param command The command to be scheduled
*/
void AddCommand(Command* command);
void AddButton(ButtonScheduler* button);
/**
* Registers a Subsystem to this Scheduler, so that the Scheduler might know
* if a default Command needs to be run.
*
* All Subsystems should call this.
*
* @param system the system
*/
void RegisterSubsystem(Subsystem* subsystem);
/**
* Runs a single iteration of the loop.
*
* This method should be called often in order to have a functioning
* Command system. The loop has five stages:
*
* <ol>
* <li>Poll the Buttons</li>
* <li>Execute/Remove the Commands</li>
* <li>Send values to SmartDashboard</li>
* <li>Add Commands</li>
* <li>Add Defaults</li>
* </ol>
*/
void Run();
/**
* Removes the Command from the Scheduler.
*
* @param command the command to remove
*/
void Remove(Command* command);
void RemoveAll();
/**
* Completely resets the scheduler. Undefined behavior if running.
*/
void ResetAll();
void SetEnabled(bool enabled);
void InitSendable(SendableBuilder& builder) override;
private:
Scheduler();
~Scheduler() override;
Scheduler(Scheduler&&) = default;
Scheduler& operator=(Scheduler&&) = default;
struct Impl;
std::unique_ptr<Impl> m_impl;
};
} // namespace frc

View File

@@ -0,0 +1,29 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include "frc/commands/InstantCommand.h"
namespace frc {
class StartCommand : public InstantCommand {
public:
explicit StartCommand(Command* commandToStart);
virtual ~StartCommand() = default;
StartCommand(StartCommand&&) = default;
StartCommand& operator=(StartCommand&&) = default;
protected:
virtual void Initialize();
private:
Command* m_commandToFork;
};
} // namespace frc

View File

@@ -0,0 +1,199 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <memory>
#include <string>
#include <wpi/StringRef.h>
#include <wpi/Twine.h>
#include "frc/ErrorBase.h"
#include "frc/smartdashboard/Sendable.h"
#include "frc/smartdashboard/SendableHelper.h"
namespace frc {
class Command;
class Subsystem : public ErrorBase,
public Sendable,
public SendableHelper<Subsystem> {
friend class Scheduler;
public:
/**
* Creates a subsystem with the given name.
*
* @param name the name of the subsystem
*/
explicit Subsystem(const wpi::Twine& name);
Subsystem(Subsystem&&) = default;
Subsystem& operator=(Subsystem&&) = default;
/**
* Sets the default command. If this is not called or is called with null,
* then there will be no default command for the subsystem.
*
* <b>WARNING:</b> This should <b>NOT</b> be called in a constructor if the
* subsystem is a singleton.
*
* @param command the default command (or null if there should be none)
*/
void SetDefaultCommand(Command* command);
/**
* Returns the default command (or null if there is none).
*
* @return the default command
*/
Command* GetDefaultCommand();
/**
* Returns the default command name, or empty string is there is none.
*
* @return the default command name
*/
wpi::StringRef GetDefaultCommandName();
/**
* Sets the current command.
*
* @param command the new current command
*/
void SetCurrentCommand(Command* command);
/**
* Returns the command which currently claims this subsystem.
*
* @return the command which currently claims this subsystem
*/
Command* GetCurrentCommand() const;
/**
* Returns the current command name, or empty string if no current command.
*
* @return the current command name
*/
wpi::StringRef GetCurrentCommandName() const;
/**
* When the run method of the scheduler is called this method will be called.
*/
virtual void Periodic();
/**
* Initialize the default command for this subsystem.
*
* This is meant to be the place to call SetDefaultCommand in a subsystem and
* will be called on all the subsystems by the CommandBase method before the
* program starts running by using the list of all registered Subsystems
* inside the Scheduler.
*
* This should be overridden by a Subsystem that has a default Command
*/
virtual void InitDefaultCommand();
/**
* Gets the name of this Subsystem.
*
* @return Name
*/
std::string GetName() const;
/**
* Sets the name of this Subsystem.
*
* @param name name
*/
void SetName(const wpi::Twine& name);
/**
* Gets the subsystem name of this Subsystem.
*
* @return Subsystem name
*/
std::string GetSubsystem() const;
/**
* Sets the subsystem name of this Subsystem.
*
* @param subsystem subsystem name
*/
void SetSubsystem(const wpi::Twine& subsystem);
/**
* Associate a Sendable with this Subsystem.
* Also update the child's name.
*
* @param name name to give child
* @param child sendable
*/
void AddChild(const wpi::Twine& name, std::shared_ptr<Sendable> child);
/**
* Associate a Sendable with this Subsystem.
* Also update the child's name.
*
* @param name name to give child
* @param child sendable
*/
void AddChild(const wpi::Twine& name, Sendable* child);
/**
* Associate a Sendable with this Subsystem.
* Also update the child's name.
*
* @param name name to give child
* @param child sendable
*/
void AddChild(const wpi::Twine& name, Sendable& child);
/**
* Associate a {@link Sendable} with this Subsystem.
*
* @param child sendable
*/
void AddChild(std::shared_ptr<Sendable> child);
/**
* Associate a {@link Sendable} with this Subsystem.
*
* @param child sendable
*/
void AddChild(Sendable* child);
/**
* Associate a {@link Sendable} with this Subsystem.
*
* @param child sendable
*/
void AddChild(Sendable& child);
private:
/**
* Call this to alert Subsystem that the current command is actually the
* command.
*
* Sometimes, the Subsystem is told that it has no command while the Scheduler
* is going through the loop, only to be soon after given a new one. This will
* avoid that situation.
*/
void ConfirmCommand();
Command* m_currentCommand = nullptr;
bool m_currentCommandChanged = true;
Command* m_defaultCommand = nullptr;
bool m_initializedDefaultCommand = false;
public:
void InitSendable(SendableBuilder& builder) override;
};
} // namespace frc

View File

@@ -0,0 +1,67 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <wpi/Twine.h>
#include "frc/commands/Command.h"
namespace frc {
/**
* A TimedCommand will wait for a timeout before finishing.
*
* TimedCommand is used to execute a command for a given amount of time.
*/
class TimedCommand : public Command {
public:
/**
* Creates a new TimedCommand with the given name and timeout.
*
* @param name the name of the command
* @param timeout the time (in seconds) before this command "times out"
*/
TimedCommand(const wpi::Twine& name, double timeout);
/**
* Creates a new WaitCommand with the given timeout.
*
* @param timeout the time (in seconds) before this command "times out"
*/
explicit TimedCommand(double timeout);
/**
* Creates a new TimedCommand with the given name and timeout.
*
* @param name the name of the command
* @param timeout the time (in seconds) before this command "times out"
* @param subsystem the subsystem that the command requires
*/
TimedCommand(const wpi::Twine& name, double timeout, Subsystem& subsystem);
/**
* Creates a new WaitCommand with the given timeout.
*
* @param timeout the time (in seconds) before this command "times out"
* @param subsystem the subsystem that the command requires
*/
TimedCommand(double timeout, Subsystem& subsystem);
virtual ~TimedCommand() = default;
TimedCommand(TimedCommand&&) = default;
TimedCommand& operator=(TimedCommand&&) = default;
protected:
/**
* Ends command when timed out.
*/
bool IsFinished() override;
};
} // namespace frc

View File

@@ -0,0 +1,39 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <wpi/Twine.h>
#include "frc/commands/TimedCommand.h"
namespace frc {
class WaitCommand : public TimedCommand {
public:
/**
* Creates a new WaitCommand with the given name and timeout.
*
* @param name the name of the command
* @param timeout the time (in seconds) before this command "times out"
*/
explicit WaitCommand(double timeout);
/**
* Creates a new WaitCommand with the given timeout.
*
* @param timeout the time (in seconds) before this command "times out"
*/
WaitCommand(const wpi::Twine& name, double timeout);
virtual ~WaitCommand() = default;
WaitCommand(WaitCommand&&) = default;
WaitCommand& operator=(WaitCommand&&) = default;
};
} // namespace frc

View File

@@ -0,0 +1,29 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <wpi/Twine.h>
#include "frc/commands/Command.h"
namespace frc {
class WaitForChildren : public Command {
public:
explicit WaitForChildren(double timeout);
WaitForChildren(const wpi::Twine& name, double timeout);
virtual ~WaitForChildren() = default;
WaitForChildren(WaitForChildren&&) = default;
WaitForChildren& operator=(WaitForChildren&&) = default;
protected:
virtual bool IsFinished();
};
} // namespace frc

View File

@@ -0,0 +1,45 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2011-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <wpi/Twine.h>
#include "frc/commands/Command.h"
namespace frc {
class WaitUntilCommand : public Command {
public:
/**
* A WaitCommand will wait until a certain match time before finishing.
*
* This will wait until the game clock reaches some value, then continue to
* the next command.
*
* @see CommandGroup
*/
explicit WaitUntilCommand(double time);
WaitUntilCommand(const wpi::Twine& name, double time);
virtual ~WaitUntilCommand() = default;
WaitUntilCommand(WaitUntilCommand&&) = default;
WaitUntilCommand& operator=(WaitUntilCommand&&) = default;
protected:
/**
* Check if we've reached the actual finish time.
*/
virtual bool IsFinished();
private:
double m_time;
};
} // namespace frc