Files
allwpilib/wpilibNewCommands/src/main/native/cpp/frc2/command/RamseteCommand.cpp

152 lines
5.2 KiB
C++
Raw Normal View History

2019-10-27 00:33:41 -04:00
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2019-2020 FIRST. All Rights Reserved. */
2019-10-27 00:33:41 -04:00
/* 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. */
/*----------------------------------------------------------------------------*/
#include "frc2/command/RamseteCommand.h"
using namespace frc2;
using namespace units;
RamseteCommand::RamseteCommand(
frc::Trajectory trajectory, std::function<frc::Pose2d()> pose,
frc::RamseteController controller,
frc::SimpleMotorFeedforward<units::meters> feedforward,
2019-10-27 00:33:41 -04:00
frc::DifferentialDriveKinematics kinematics,
std::function<frc::DifferentialDriveWheelSpeeds()> wheelSpeeds,
2019-10-27 00:33:41 -04:00
frc2::PIDController leftController, frc2::PIDController rightController,
std::function<void(volt_t, volt_t)> output,
std::initializer_list<Subsystem*> requirements)
: m_trajectory(trajectory),
m_pose(pose),
m_controller(controller),
m_feedforward(feedforward),
2019-10-27 00:33:41 -04:00
m_kinematics(kinematics),
m_speeds(wheelSpeeds),
2019-10-27 00:33:41 -04:00
m_leftController(std::make_unique<frc2::PIDController>(leftController)),
m_rightController(std::make_unique<frc2::PIDController>(rightController)),
2019-11-01 12:26:48 -04:00
m_outputVolts(output),
m_usePID(true) {
2019-10-27 00:33:41 -04:00
AddRequirements(requirements);
}
RamseteCommand::RamseteCommand(
frc::Trajectory trajectory, std::function<frc::Pose2d()> pose,
frc::RamseteController controller,
frc::SimpleMotorFeedforward<units::meters> feedforward,
frc::DifferentialDriveKinematics kinematics,
std::function<frc::DifferentialDriveWheelSpeeds()> wheelSpeeds,
frc2::PIDController leftController, frc2::PIDController rightController,
std::function<void(volt_t, volt_t)> output,
wpi::ArrayRef<Subsystem*> requirements)
: m_trajectory(trajectory),
m_pose(pose),
m_controller(controller),
m_feedforward(feedforward),
m_kinematics(kinematics),
m_speeds(wheelSpeeds),
m_leftController(std::make_unique<frc2::PIDController>(leftController)),
m_rightController(std::make_unique<frc2::PIDController>(rightController)),
m_outputVolts(output),
m_usePID(true) {
AddRequirements(requirements);
}
2019-10-27 00:33:41 -04:00
RamseteCommand::RamseteCommand(
frc::Trajectory trajectory, std::function<frc::Pose2d()> pose,
frc::RamseteController controller,
frc::DifferentialDriveKinematics kinematics,
std::function<void(units::meters_per_second_t, units::meters_per_second_t)>
output,
std::initializer_list<Subsystem*> requirements)
: m_trajectory(trajectory),
m_pose(pose),
m_controller(controller),
m_kinematics(kinematics),
2019-11-01 12:26:48 -04:00
m_outputVel(output),
m_usePID(false) {
2019-10-27 00:33:41 -04:00
AddRequirements(requirements);
}
RamseteCommand::RamseteCommand(
frc::Trajectory trajectory, std::function<frc::Pose2d()> pose,
frc::RamseteController controller,
frc::DifferentialDriveKinematics kinematics,
std::function<void(units::meters_per_second_t, units::meters_per_second_t)>
output,
wpi::ArrayRef<Subsystem*> requirements)
: m_trajectory(trajectory),
m_pose(pose),
m_controller(controller),
m_kinematics(kinematics),
m_outputVel(output),
m_usePID(false) {
AddRequirements(requirements);
}
2019-10-27 00:33:41 -04:00
void RamseteCommand::Initialize() {
m_prevTime = -1_s;
2019-10-27 00:33:41 -04:00
auto initialState = m_trajectory.Sample(0_s);
m_prevSpeeds = m_kinematics.ToWheelSpeeds(
frc::ChassisSpeeds{initialState.velocity, 0_mps,
initialState.velocity * initialState.curvature});
m_timer.Reset();
m_timer.Start();
2019-11-01 12:26:48 -04:00
if (m_usePID) {
m_leftController->Reset();
m_rightController->Reset();
}
2019-10-27 00:33:41 -04:00
}
void RamseteCommand::Execute() {
auto curTime = m_timer.Get();
auto dt = curTime - m_prevTime;
if (m_prevTime < 0_s) {
if (m_usePID)
m_outputVolts(0_V, 0_V);
else
m_outputVel(0_mps, 0_mps);
m_prevTime = curTime;
return;
}
2019-10-27 00:33:41 -04:00
auto targetWheelSpeeds = m_kinematics.ToWheelSpeeds(
m_controller.Calculate(m_pose(), m_trajectory.Sample(curTime)));
2019-11-01 12:26:48 -04:00
if (m_usePID) {
auto leftFeedforward = m_feedforward.Calculate(
targetWheelSpeeds.left,
(targetWheelSpeeds.left - m_prevSpeeds.left) / dt);
2019-10-27 00:33:41 -04:00
auto rightFeedforward = m_feedforward.Calculate(
targetWheelSpeeds.right,
(targetWheelSpeeds.right - m_prevSpeeds.right) / dt);
2019-10-27 00:33:41 -04:00
auto leftOutput = volt_t(m_leftController->Calculate(
m_speeds().left.to<double>(),
targetWheelSpeeds.left.to<double>())) +
leftFeedforward;
2019-10-27 00:33:41 -04:00
auto rightOutput = volt_t(m_rightController->Calculate(
m_speeds().right.to<double>(),
2019-10-27 00:33:41 -04:00
targetWheelSpeeds.right.to<double>())) +
rightFeedforward;
m_outputVolts(leftOutput, rightOutput);
} else {
m_outputVel(targetWheelSpeeds.left, targetWheelSpeeds.right);
}
m_prevSpeeds = targetWheelSpeeds;
m_prevTime = curTime;
2019-10-27 00:33:41 -04:00
}
void RamseteCommand::End(bool interrupted) { m_timer.Stop(); }
bool RamseteCommand::IsFinished() {
return m_timer.HasElapsed(m_trajectory.TotalTime());
2019-10-27 00:33:41 -04:00
}