mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-06 03:31:43 +00:00
Add TrapezoidProfile example (#1814)
This commit is contained in:
committed by
Peter Johnson
parent
8f386f6bb3
commit
a216b9e9ee
@@ -0,0 +1,56 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* 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. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include <frc/Encoder.h>
|
||||
#include <frc/Joystick.h>
|
||||
#include <frc/Spark.h>
|
||||
#include <frc/TimedRobot.h>
|
||||
#include <frc/controller/PIDController.h>
|
||||
#include <frc/trajectory/TrapezoidProfile.h>
|
||||
|
||||
class Robot : public frc::TimedRobot {
|
||||
public:
|
||||
static constexpr units::second_t kDt = 20_ms;
|
||||
|
||||
Robot() { m_encoder.SetDistancePerPulse(1.0 / 360.0 * 2.0 * 3.1415 * 1.5); }
|
||||
|
||||
void TeleopPeriodic() override {
|
||||
if (m_joystick.GetRawButtonPressed(2)) {
|
||||
m_goal = {5_m, 0_mps};
|
||||
} else if (m_joystick.GetRawButtonPressed(3)) {
|
||||
m_goal = {0_m, 0_mps};
|
||||
}
|
||||
|
||||
// Create a motion profile with the given maximum velocity and maximum
|
||||
// acceleration constraints for the next setpoint, the desired goal, and the
|
||||
// current setpoint.
|
||||
frc::TrapezoidProfile profile{m_constraints, m_goal, m_setpoint};
|
||||
|
||||
// Retrieve the profiled setpoint for the next timestep. This setpoint moves
|
||||
// toward the goal while obeying the constraints.
|
||||
m_setpoint = profile.Calculate(kDt);
|
||||
|
||||
// Run controller with profiled setpoint and update motor output
|
||||
double output = m_controller.Calculate(m_encoder.GetDistance(),
|
||||
m_setpoint.position.to<double>());
|
||||
m_motor.Set(output);
|
||||
}
|
||||
|
||||
private:
|
||||
frc::Joystick m_joystick{1};
|
||||
frc::Encoder m_encoder{1, 2};
|
||||
frc::Spark m_motor{1};
|
||||
frc2::PIDController m_controller{1.3, 0.0, 0.7, kDt.to<double>()};
|
||||
|
||||
frc::TrapezoidProfile::Constraints m_constraints{1.75_mps, 0.75_mps_sq};
|
||||
frc::TrapezoidProfile::State m_goal;
|
||||
frc::TrapezoidProfile::State m_setpoint;
|
||||
};
|
||||
|
||||
#ifndef RUNNING_FRC_TESTS
|
||||
int main() { return frc::StartRobot<Robot>(); }
|
||||
#endif
|
||||
@@ -166,6 +166,18 @@
|
||||
"foldername": "PotentiometerPID",
|
||||
"gradlebase": "cpp"
|
||||
},
|
||||
{
|
||||
"name": "Elevator with trapezoid profiled PID",
|
||||
"description": "An example to demonstrate the use of an encoder and trapezoid profiled PID control to reach elevator position setpoints.",
|
||||
"tags": [
|
||||
"Digital",
|
||||
"Sensors",
|
||||
"Actuators",
|
||||
"Joystick"
|
||||
],
|
||||
"foldername": "ElevatorTrapezoidProfile",
|
||||
"gradlebase": "cpp"
|
||||
},
|
||||
{
|
||||
"name": "Getting Started",
|
||||
"description": "An example program which demonstrates the simplest autonomous and teleoperated routines.",
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* 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. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
package edu.wpi.first.wpilibj.examples.elevatortrapezoidprofile;
|
||||
|
||||
import edu.wpi.first.wpilibj.RobotBase;
|
||||
|
||||
/**
|
||||
* Do NOT add any static variables to this class, or any initialization at all.
|
||||
* Unless you know what you are doing, do not modify this file except to
|
||||
* change the parameter class to the startRobot call.
|
||||
*/
|
||||
public final class Main {
|
||||
private Main() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Main initialization function. Do not perform any initialization here.
|
||||
*
|
||||
* <p>If you change your main robot class, change the parameter type.
|
||||
*/
|
||||
public static void main(String... args) {
|
||||
RobotBase.startRobot(Robot::new);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* 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. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
package edu.wpi.first.wpilibj.examples.elevatortrapezoidprofile;
|
||||
|
||||
import edu.wpi.first.wpilibj.Encoder;
|
||||
import edu.wpi.first.wpilibj.Joystick;
|
||||
import edu.wpi.first.wpilibj.Spark;
|
||||
import edu.wpi.first.wpilibj.TimedRobot;
|
||||
import edu.wpi.first.wpilibj.controller.PIDController;
|
||||
import edu.wpi.first.wpilibj.trajectory.TrapezoidProfile;
|
||||
|
||||
public class Robot extends TimedRobot {
|
||||
private static double kDt = 0.02;
|
||||
|
||||
private final Joystick m_joystick = new Joystick(1);
|
||||
private final Encoder m_encoder = new Encoder(1, 2);
|
||||
private final Spark m_motor = new Spark(1);
|
||||
private final PIDController m_controller = new PIDController(1.3, 0.0, 0.7, kDt);
|
||||
|
||||
private final TrapezoidProfile.Constraints m_constraints =
|
||||
new TrapezoidProfile.Constraints(1.75, 0.75);
|
||||
private TrapezoidProfile.State m_goal = new TrapezoidProfile.State();
|
||||
private TrapezoidProfile.State m_setpoint = new TrapezoidProfile.State();
|
||||
|
||||
@Override
|
||||
public void robotInit() {
|
||||
m_encoder.setDistancePerPulse(1.0 / 360.0 * 2.0 * 3.1415 * 1.5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teleopPeriodic() {
|
||||
if (m_joystick.getRawButtonPressed(2)) {
|
||||
m_goal = new TrapezoidProfile.State(5, 0);
|
||||
} else if (m_joystick.getRawButtonPressed(3)) {
|
||||
m_goal = new TrapezoidProfile.State(0, 0);
|
||||
}
|
||||
|
||||
// Create a motion profile with the given maximum velocity and maximum
|
||||
// acceleration constraints for the next setpoint, the desired goal, and the
|
||||
// current setpoint.
|
||||
var profile = new TrapezoidProfile(m_constraints, m_goal, m_setpoint);
|
||||
|
||||
// Retrieve the profiled setpoint for the next timestep. This setpoint moves
|
||||
// toward the goal while obeying the constraints.
|
||||
m_setpoint = profile.calculate(kDt);
|
||||
|
||||
double output = m_controller.calculate(m_encoder.getDistance(),
|
||||
m_setpoint.position);
|
||||
|
||||
// Run controller with profiled setpoint and update motor output
|
||||
m_motor.set(output);
|
||||
}
|
||||
}
|
||||
@@ -131,6 +131,19 @@
|
||||
"gradlebase": "java",
|
||||
"mainclass": "Main"
|
||||
},
|
||||
{
|
||||
"name": "Elevator with trapezoid profiled PID",
|
||||
"description": "An example to demonstrate the use of an encoder and trapezoid profiled PID control to reach elevator position setpoints.",
|
||||
"tags": [
|
||||
"Digital",
|
||||
"Sensors",
|
||||
"Actuators",
|
||||
"Joystick"
|
||||
],
|
||||
"foldername": "elevatortrapezoidprofile",
|
||||
"gradlebase": "java",
|
||||
"mainclass": "Main"
|
||||
},
|
||||
{
|
||||
"name": "Gyro",
|
||||
"description": "An example program showing how to drive straight with using a gyro sensor.",
|
||||
|
||||
Reference in New Issue
Block a user