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

134 lines
4.1 KiB
C++
Raw Normal View History

// 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.
2019-10-27 00:33:41 -04:00
#include "frc2/command/RamseteCommand.h"
2020-12-28 10:12:52 -08:00
#include <utility>
#include <units/velocity.h>
#include <units/voltage.h>
#include <wpi/sendable/SendableBuilder.h>
2019-10-27 00:33:41 -04:00
using namespace frc2;
using kv_unit = units::compound_unit<units::volts,
units::inverse<units::meters_per_second>>;
2019-10-27 00:33:41 -04:00
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,
frc::PIDController leftController, frc::PIDController rightController,
std::function<void(units::volt_t, units::volt_t)> output,
Requirements requirements)
2020-12-28 10:12:52 -08:00
: m_trajectory(std::move(trajectory)),
m_pose(std::move(pose)),
2019-10-27 00:33:41 -04:00
m_controller(controller),
m_feedforward(feedforward),
m_kinematics(std::move(kinematics)),
2020-12-28 10:12:52 -08:00
m_speeds(std::move(wheelSpeeds)),
m_leftController(std::make_unique<frc::PIDController>(leftController)),
m_rightController(std::make_unique<frc::PIDController>(rightController)),
2020-12-28 10:12:52 -08:00
m_outputVolts(std::move(output)),
2019-11-01 12:26:48 -04:00
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::DifferentialDriveKinematics kinematics,
std::function<void(units::meters_per_second_t, units::meters_per_second_t)>
output,
Requirements requirements)
2020-12-28 10:12:52 -08:00
: m_trajectory(std::move(trajectory)),
m_pose(std::move(pose)),
m_controller(controller),
m_feedforward(0_V, units::unit_t<kv_unit>{0}),
m_kinematics(std::move(kinematics)),
2020-12-28 10:12:52 -08:00
m_outputVel(std::move(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});
2023-01-29 10:21:07 -05:00
m_timer.Restart();
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();
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(m_prevSpeeds.left, targetWheelSpeeds.left);
2019-10-27 00:33:41 -04:00
auto rightFeedforward =
m_feedforward.Calculate(m_prevSpeeds.right, targetWheelSpeeds.right);
2019-10-27 00:33:41 -04:00
auto leftOutput =
units::volt_t{m_leftController->Calculate(
m_speeds().left.value(), targetWheelSpeeds.left.value())} +
leftFeedforward;
auto rightOutput =
units::volt_t{m_rightController->Calculate(
m_speeds().right.value(), targetWheelSpeeds.right.value())} +
rightFeedforward;
2019-10-27 00:33:41 -04:00
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();
if (interrupted) {
if (m_usePID) {
m_outputVolts(0_V, 0_V);
} else {
m_outputVel(0_mps, 0_mps);
}
}
}
2019-10-27 00:33:41 -04:00
bool RamseteCommand::IsFinished() {
return m_timer.HasElapsed(m_trajectory.TotalTime());
2019-10-27 00:33:41 -04:00
}
void RamseteCommand::InitSendable(wpi::SendableBuilder& builder) {
Command::InitSendable(builder);
builder.AddDoubleProperty(
"leftVelocity", [this] { return m_prevSpeeds.left.value(); }, nullptr);
builder.AddDoubleProperty(
"rightVelocity", [this] { return m_prevSpeeds.right.value(); }, nullptr);
}