// 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 #include #include "CommandBase.h" #include "CommandHelper.h" #pragma once namespace frc2 { /** * A command that uses two PID controllers ({@link PIDController}) and a * ProfiledPIDController ({@link ProfiledPIDController}) to follow a trajectory * {@link Trajectory} with a mecanum 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 wheel speeds from the 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. */ class MecanumControllerCommand : public CommandHelper { public: /** * Constructs a new MecanumControllerCommand that when executed will follow * the provided trajectory. PID control and feedforward are handled * internally. Outputs are scaled from -12 to 12 as a voltage output to the * motor. * *

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 feedforward The feedforward to use for the drivetrain. * @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 robot should be facing. * This is sampled at each time step. * @param maxWheelVelocity The maximum velocity of a drivetrain wheel. * @param frontLeftController The front left wheel velocity PID. * @param rearLeftController The rear left wheel velocity PID. * @param frontRightController The front right wheel velocity PID. * @param rearRightController The rear right wheel velocity PID. * @param currentWheelSpeeds A MecanumDriveWheelSpeeds object containing * the current wheel speeds. * @param output The output of the velocity PIDs. * @param requirements The subsystems to require. */ MecanumControllerCommand( frc::Trajectory trajectory, std::function pose, frc::SimpleMotorFeedforward feedforward, frc::MecanumDriveKinematics kinematics, frc2::PIDController xController, frc2::PIDController yController, frc::ProfiledPIDController thetaController, std::function desiredRotation, units::meters_per_second_t maxWheelVelocity, std::function currentWheelSpeeds, frc2::PIDController frontLeftController, frc2::PIDController rearLeftController, frc2::PIDController frontRightController, frc2::PIDController rearRightController, std::function output, std::initializer_list requirements); /** * Constructs a new MecanumControllerCommand that when executed will follow * the provided trajectory. PID control and feedforward are handled * internally. Outputs are scaled from -12 to 12 as a voltage output to the * motor. * *

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 feedforward The feedforward to use for the drivetrain. * @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 maxWheelVelocity The maximum velocity of a drivetrain wheel. * @param frontLeftController The front left wheel velocity PID. * @param rearLeftController The rear left wheel velocity PID. * @param frontRightController The front right wheel velocity PID. * @param rearRightController The rear right wheel velocity PID. * @param currentWheelSpeeds A MecanumDriveWheelSpeeds object containing * the current wheel speeds. * @param output The output of the velocity PIDs. * @param requirements The subsystems to require. */ MecanumControllerCommand( frc::Trajectory trajectory, std::function pose, frc::SimpleMotorFeedforward feedforward, frc::MecanumDriveKinematics kinematics, frc2::PIDController xController, frc2::PIDController yController, frc::ProfiledPIDController thetaController, units::meters_per_second_t maxWheelVelocity, std::function currentWheelSpeeds, frc2::PIDController frontLeftController, frc2::PIDController rearLeftController, frc2::PIDController frontRightController, frc2::PIDController rearRightController, std::function output, std::initializer_list requirements); /** * Constructs a new MecanumControllerCommand that when executed will follow * the provided trajectory. PID control and feedforward are handled * internally. Outputs are scaled from -12 to 12 as a voltage output to the * motor. * *

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 feedforward The feedforward to use for the drivetrain. * @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 robot should be facing. * This is sampled at each time step. * @param maxWheelVelocity The maximum velocity of a drivetrain wheel. * @param frontLeftController The front left wheel velocity PID. * @param rearLeftController The rear left wheel velocity PID. * @param frontRightController The front right wheel velocity PID. * @param rearRightController The rear right wheel velocity PID. * @param currentWheelSpeeds A MecanumDriveWheelSpeeds object containing * the current wheel speeds. * @param output The output of the velocity PIDs. * @param requirements The subsystems to require. */ MecanumControllerCommand( frc::Trajectory trajectory, std::function pose, frc::SimpleMotorFeedforward feedforward, frc::MecanumDriveKinematics kinematics, frc2::PIDController xController, frc2::PIDController yController, frc::ProfiledPIDController thetaController, std::function desiredRotation, units::meters_per_second_t maxWheelVelocity, std::function currentWheelSpeeds, frc2::PIDController frontLeftController, frc2::PIDController rearLeftController, frc2::PIDController frontRightController, frc2::PIDController rearRightController, std::function output, wpi::ArrayRef requirements = {}); /** * Constructs a new MecanumControllerCommand that when executed will follow * the provided trajectory. PID control and feedforward are handled * internally. Outputs are scaled from -12 to 12 as a voltage output to the * motor. * *

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 feedforward The feedforward to use for the drivetrain. * @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 maxWheelVelocity The maximum velocity of a drivetrain wheel. * @param frontLeftController The front left wheel velocity PID. * @param rearLeftController The rear left wheel velocity PID. * @param frontRightController The front right wheel velocity PID. * @param rearRightController The rear right wheel velocity PID. * @param currentWheelSpeeds A MecanumDriveWheelSpeeds object containing * the current wheel speeds. * @param output The output of the velocity PIDs. * @param requirements The subsystems to require. */ MecanumControllerCommand( frc::Trajectory trajectory, std::function pose, frc::SimpleMotorFeedforward feedforward, frc::MecanumDriveKinematics kinematics, frc2::PIDController xController, frc2::PIDController yController, frc::ProfiledPIDController thetaController, units::meters_per_second_t maxWheelVelocity, std::function currentWheelSpeeds, frc2::PIDController frontLeftController, frc2::PIDController rearLeftController, frc2::PIDController frontRightController, frc2::PIDController rearRightController, std::function output, wpi::ArrayRef requirements = {}); /** * Constructs a new MecanumControllerCommand that when executed will follow * the provided trajectory. The user should implement a velocity PID on the * desired output wheel velocities. * *

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 non-stationary end-states. * * @param trajectory The trajectory to follow. * @param pose A function that supplies the robot pose - use one * of the odometry classes to provide this. * @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 robot should be facing. * This is sampled at each time step. * @param maxWheelVelocity The maximum velocity of a drivetrain wheel. * @param output The output of the position PIDs. * @param requirements The subsystems to require. */ MecanumControllerCommand( frc::Trajectory trajectory, std::function pose, frc::MecanumDriveKinematics kinematics, frc2::PIDController xController, frc2::PIDController yController, frc::ProfiledPIDController thetaController, std::function desiredRotation, units::meters_per_second_t maxWheelVelocity, std::function output, std::initializer_list requirements); /** * Constructs a new MecanumControllerCommand that when executed will follow * the provided trajectory. The user should implement a velocity PID on the * desired output wheel velocities. * *

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 non-stationary end-states. * *

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 - use one * of the odometry classes to provide this. * @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 maxWheelVelocity The maximum velocity of a drivetrain wheel. * @param output The output of the position PIDs. * @param requirements The subsystems to require. */ MecanumControllerCommand( frc::Trajectory trajectory, std::function pose, frc::MecanumDriveKinematics kinematics, frc2::PIDController xController, frc2::PIDController yController, frc::ProfiledPIDController thetaController, units::meters_per_second_t maxWheelVelocity, std::function output, std::initializer_list requirements); /** * Constructs a new MecanumControllerCommand that when executed will follow * the provided trajectory. The user should implement a velocity PID on the * desired output wheel velocities. * *

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 non-stationary end-states. * * @param trajectory The trajectory to follow. * @param pose A function that supplies the robot pose - use one * of the odometry classes to provide this. * @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 robot should be facing. * This is sampled at every time step. * @param maxWheelVelocity The maximum velocity of a drivetrain wheel. * @param output The output of the position PIDs. * @param requirements The subsystems to require. */ MecanumControllerCommand( frc::Trajectory trajectory, std::function pose, frc::MecanumDriveKinematics kinematics, frc2::PIDController xController, frc2::PIDController yController, frc::ProfiledPIDController thetaController, std::function desiredRotation, units::meters_per_second_t maxWheelVelocity, std::function output, wpi::ArrayRef requirements = {}); /** * Constructs a new MecanumControllerCommand that when executed will follow * the provided trajectory. The user should implement a velocity PID on the * desired output wheel velocities. * *

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 non-stationary end-states. * *

Note2: 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 - use one * of the odometry classes to provide this. * @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 maxWheelVelocity The maximum velocity of a drivetrain wheel. * @param output The output of the position PIDs. * @param requirements The subsystems to require. */ MecanumControllerCommand( frc::Trajectory trajectory, std::function pose, frc::MecanumDriveKinematics kinematics, frc2::PIDController xController, frc2::PIDController yController, frc::ProfiledPIDController thetaController, units::meters_per_second_t maxWheelVelocity, std::function output, wpi::ArrayRef 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::SimpleMotorFeedforward m_feedforward; frc::MecanumDriveKinematics m_kinematics; frc::HolonomicDriveController m_controller; std::function m_desiredRotation; const units::meters_per_second_t m_maxWheelVelocity; std::unique_ptr m_frontLeftController; std::unique_ptr m_rearLeftController; std::unique_ptr m_frontRightController; std::unique_ptr m_rearRightController; std::function m_currentWheelSpeeds; std::function m_outputVel; std::function m_outputVolts; bool m_usePID; frc::Timer m_timer; frc::MecanumDriveWheelSpeeds m_prevSpeeds; units::second_t m_prevTime; }; } // namespace frc2