// 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "CommandBase.h" #include "CommandHelper.h" #pragma once namespace frc2 { /** * A command that uses two PID controllers (PIDController) and a profiled PID * controller (ProfiledPIDController) to follow a trajectory (Trajectory) with a * swerve drive. * *

The command handles trajectory-following, Velocity PID calculations, and * feedforwards internally. This is intended to be a more-or-less "complete * solution" that can be used by teams without a great deal of controls * expertise. * *

Advanced teams seeking more flexibility (for example, those who wish to * use the onboard PID functionality of a "smart" motor controller) may use the * secondary constructor that omits the PID and feedforward functionality, * returning only the raw module states from the position PID controllers. * *

The robot angle controller does not follow the angle given by * the trajectory but rather goes to the angle given in the final state of the * trajectory. */ template class SwerveControllerCommand : public CommandHelper> { using voltsecondspermeter = units::compound_unit>; using voltsecondssquaredpermeter = units::compound_unit, units::inverse>; public: /** * Constructs a new SwerveControllerCommand that when executed will follow the * provided trajectory. This command will not return output voltages but * rather raw module states from the position controllers which need to be put * into a velocity PID. * *

Note: The controllers will *not* set the outputVolts to zero upon * completion of the path- this is left to the user, since it is not * appropriate for paths with nonstationary endstates. * * @param trajectory The trajectory to follow. * @param pose A function that supplies the robot pose, * provided by the odometry class. * @param kinematics The kinematics for the robot drivetrain. * @param xController The Trajectory Tracker PID controller * for the robot's x position. * @param yController The Trajectory Tracker PID controller * for the robot's y position. * @param thetaController The Trajectory Tracker PID controller * for angle for the robot. * @param desiredRotation The angle that the drivetrain should be * facing. This is sampled at each time step. * @param output The raw output module states from the * position controllers. * @param requirements The subsystems to require. */ SwerveControllerCommand( frc::Trajectory trajectory, std::function pose, frc::SwerveDriveKinematics kinematics, frc2::PIDController xController, frc2::PIDController yController, frc::ProfiledPIDController thetaController, std::function desiredRotation, std::function)> output, std::initializer_list requirements); /** * Constructs a new SwerveControllerCommand that when executed will follow the * provided trajectory. This command will not return output voltages but * rather raw module states from the position controllers which need to be put * into a velocity PID. * *

Note: The controllers will *not* set the outputVolts to zero upon * completion of the path- this is left to the user, since it is not * appropriate for paths with nonstationary endstates. * *

Note 2: The final rotation of the robot will be set to the rotation of * the final pose in the trajectory. The robot will not follow the rotations * from the poses at each timestep. If alternate rotation behavior is desired, * the other constructor with a supplier for rotation should be used. * * @param trajectory The trajectory to follow. * @param pose A function that supplies the robot pose, * provided by the odometry class. * @param kinematics The kinematics for the robot drivetrain. * @param xController The Trajectory Tracker PID controller * for the robot's x position. * @param yController The Trajectory Tracker PID controller * for the robot's y position. * @param thetaController The Trajectory Tracker PID controller * for angle for the robot. * @param output The raw output module states from the * position controllers. * @param requirements The subsystems to require. */ SwerveControllerCommand( frc::Trajectory trajectory, std::function pose, frc::SwerveDriveKinematics kinematics, frc2::PIDController xController, frc2::PIDController yController, frc::ProfiledPIDController thetaController, std::function)> output, std::initializer_list requirements); /** * Constructs a new SwerveControllerCommand that when executed will follow the * provided trajectory. This command will not return output voltages but * rather raw module states from the position controllers which need to be put * into a velocity PID. * *

Note: The controllers will *not* set the outputVolts to zero upon * completion of the path- this is left to the user, since it is not * appropriate for paths with nonstationary endstates. * * * @param trajectory The trajectory to follow. * @param pose A function that supplies the robot pose, * provided by the odometry class. * @param kinematics The kinematics for the robot drivetrain. * @param xController The Trajectory Tracker PID controller * for the robot's x position. * @param yController The Trajectory Tracker PID controller * for the robot's y position. * @param thetaController The Trajectory Tracker PID controller * for angle for the robot. * @param desiredRotation The angle that the drivetrain should be * facing. This is sampled at each time step. * @param output The raw output module states from the * position controllers. * @param requirements The subsystems to require. */ SwerveControllerCommand( frc::Trajectory trajectory, std::function pose, frc::SwerveDriveKinematics kinematics, frc2::PIDController xController, frc2::PIDController yController, frc::ProfiledPIDController thetaController, std::function desiredRotation, std::function)> output, wpi::span requirements = {}); /** * Constructs a new SwerveControllerCommand that when executed will follow the * provided trajectory. This command will not return output voltages but * rather raw module states from the position controllers which need to be put * into a velocity PID. * *

Note: The controllers will *not* set the outputVolts to zero upon * completion of the path- this is left to the user, since it is not * appropriate for paths with nonstationary endstates. * *

Note 2: The final rotation of the robot will be set to the rotation of * the final pose in the trajectory. The robot will not follow the rotations * from the poses at each timestep. If alternate rotation behavior is desired, * the other constructor with a supplier for rotation should be used. * * @param trajectory The trajectory to follow. * @param pose A function that supplies the robot pose, * provided by the odometry class. * @param kinematics The kinematics for the robot drivetrain. * @param xController The Trajectory Tracker PID controller * for the robot's x position. * @param yController The Trajectory Tracker PID controller * for the robot's y position. * @param thetaController The Trajectory Tracker PID controller * for angle for the robot. * @param output The raw output module states from the * position controllers. * @param requirements The subsystems to require. */ SwerveControllerCommand( frc::Trajectory trajectory, std::function pose, frc::SwerveDriveKinematics kinematics, frc2::PIDController xController, frc2::PIDController yController, frc::ProfiledPIDController thetaController, std::function)> output, wpi::span requirements = {}); void Initialize() override; void Execute() override; void End(bool interrupted) override; bool IsFinished() override; private: frc::Trajectory m_trajectory; std::function m_pose; frc::SwerveDriveKinematics m_kinematics; frc::HolonomicDriveController m_controller; std::function)> m_outputStates; std::function m_desiredRotation; frc::Timer m_timer; units::second_t m_prevTime; frc::Rotation2d m_finalRotation; }; } // namespace frc2 #include "SwerveControllerCommand.inc"