/*----------------------------------------------------------------------------*/ /* Copyright (c) 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 #include #include #include #include #include "frc2/command/CommandBase.h" #include "frc2/command/CommandHelper.h" namespace frc2 { /** * A command that controls an output with a ProfiledPIDController. Runs forever * by default - to add exit conditions and/or other behavior, subclass this * class. The controller calculation and output are performed synchronously in * the command's execute() method. * * @see ProfiledPIDController */ template class ProfiledPIDCommand : public CommandHelper> { using Distance_t = units::unit_t; using Velocity = units::compound_unit>; using Velocity_t = units::unit_t; using State = typename frc::TrapezoidProfile::State; public: /** * Creates a new PIDCommand, which controls the given output with a * ProfiledPIDController. * * @param controller the controller that controls the output. * @param measurementSource the measurement of the process variable * @param goalSource the controller's goal * @param useOutput the controller's output * @param requirements the subsystems required by this command */ ProfiledPIDCommand(frc::ProfiledPIDController controller, std::function> measurementSource, std::function goalSource, std::function useOutput, std::initializer_list requirements = {}) : m_controller{controller}, m_measurement{std::move(measurementSource)}, m_goal{std::move(goalSource)}, m_useOutput{std::move(useOutput)} { AddRequirements(requirements); } /** * Creates a new PIDCommand, which controls the given output with a * ProfiledPIDController. * * @param controller the controller that controls the output. * @param measurementSource the measurement of the process variable * @param goalSource the controller's goal * @param useOutput the controller's output * @param requirements the subsystems required by this command */ ProfiledPIDCommand(frc::ProfiledPIDController controller, std::function> measurementSource, std::function> goalSource, std::function useOutput, std::initializer_list requirements) : ProfiledPIDCommand(controller, measurementSource, [&goalSource]() { return State{goalSource(), 0_mps}; }, useOutput, requirements) {} /** * Creates a new PIDCommand, which controls the given output with a * ProfiledPIDController with a constant goal. * * @param controller the controller that controls the output. * @param measurementSource the measurement of the process variable * @param goal the controller's goal * @param useOutput the controller's output * @param requirements the subsystems required by this command */ ProfiledPIDCommand(frc::ProfiledPIDController controller, std::function> measurementSource, State goal, std::function useOutput, std::initializer_list requirements) : ProfiledPIDCommand(controller, measurementSource, [goal] { return goal; }, useOutput, requirements) {} /** * Creates a new PIDCommand, which controls the given output with a * ProfiledPIDController with a constant goal. * * @param controller the controller that controls the output. * @param measurementSource the measurement of the process variable * @param goal the controller's goal * @param useOutput the controller's output * @param requirements the subsystems required by this command */ ProfiledPIDCommand(frc::ProfiledPIDController controller, std::function> measurementSource, units::meter_t goal, std::function useOutput, std::initializer_list requirements) : ProfiledPIDCommand(controller, measurementSource, [goal] { return goal; }, useOutput, requirements) {} ProfiledPIDCommand(ProfiledPIDCommand&& other) = default; ProfiledPIDCommand(const ProfiledPIDCommand& other) = default; void Initialize() override { m_controller.Reset(); } void Execute() override { m_useOutput(m_controller.Calculate(m_measurement(), m_goal()), m_controller.GetSetpoint()); } void End(bool interrupted) override { m_useOutput(0, State{Distance_t(0), Velocity_t(0)}); } /** * Returns the ProfiledPIDController used by the command. * * @return The ProfiledPIDController */ frc::ProfiledPIDController& GetController() { return m_controller; } protected: frc::ProfiledPIDController m_controller; std::function m_measurement; std::function m_goal; std::function m_useOutput; }; } // namespace frc2