Fix trapezoidal profile PID controller setpoint bug (#2210)

Co-Authored-By: Austin Shalit <austinshalit@gmail.com>
This commit is contained in:
Matt
2020-01-01 15:23:25 -08:00
committed by Peter Johnson
parent abe25b795b
commit 222669dc2c
8 changed files with 90 additions and 14 deletions

View File

@@ -113,7 +113,7 @@ public class ProfiledPIDCommand extends CommandBase {
@Override
public void initialize() {
m_controller.reset();
m_controller.reset(m_measurement.getAsDouble());
}
@Override

View File

@@ -93,7 +93,7 @@ public abstract class ProfiledPIDSubsystem extends SubsystemBase {
*/
public void enable() {
m_enabled = true;
m_controller.reset();
m_controller.reset(getMeasurement());
}
/**

View File

@@ -118,7 +118,7 @@ class ProfiledPIDCommand
ProfiledPIDCommand(const ProfiledPIDCommand& other) = default;
void Initialize() override { m_controller.Reset(); }
void Initialize() override { m_controller.Reset(m_measurement()); }
void Execute() override {
m_useOutput(m_controller.Calculate(m_measurement(), m_goal()),

View File

@@ -62,10 +62,10 @@ class ProfiledPIDSubsystem : public SubsystemBase {
void SetGoal(Distance_t goal) { m_goal = State{goal, Velocity_t(0)}; }
/**
* Enables the PID control. Resets the controller.
* Enables the PID control. Resets the controller.
*/
virtual void Enable() {
m_controller.Reset();
m_controller.Reset(GetMeasurement());
m_enabled = true;
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2019 FIRST. All Rights Reserved. */
/* Copyright (c) 2019-2020 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. */
@@ -46,7 +46,8 @@ class ProfiledPIDController
public:
/**
* Allocates a ProfiledPIDController with the given constants for Kp, Ki, and
* Kd.
* Kd. Users should call reset() when they first start running the controller
* to avoid unwanted behavior.
*
* @param Kp The proportional coefficient.
* @param Ki The integral coefficient.
@@ -292,9 +293,34 @@ class ProfiledPIDController
}
/**
* Reset the previous error, the integral term, and disable the controller.
* Reset the previous error and the integral term.
*
* @param measurement The current measured State of the system.
*/
void Reset() { m_controller.Reset(); }
void Reset(const State& measurement) {
m_controller.Reset();
m_setpoint = measurement;
}
/**
* Reset the previous error and the integral term.
*
* @param measuredPosition The current measured position of the system.
* @param measuredVelocity The current measured velocity of the system.
*/
void Reset(Distance_t measuredPosition, Velocity_t measuredVelocity) {
Reset(State{measuredPosition, measuredVelocity});
}
/**
* Reset the previous error and the integral term.
*
* @param measuredPosition The current measured position of the system. The
* velocity is assumed to be zero.
*/
void Reset(Distance_t measuredPosition) {
Reset(measuredPosition, Velocity_t(0));
}
void InitSendable(frc::SendableBuilder& builder) override {
builder.SetSmartDashboardType("ProfiledPIDController");

View File

@@ -328,7 +328,7 @@ public class PIDController implements Sendable, AutoCloseable {
}
/**
* Resets the previous error and the integral term. Also disables the controller.
* Resets the previous error and the integral term.
*/
public void reset() {
m_prevError = 0;

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2019 FIRST. All Rights Reserved. */
/* Copyright (c) 2019-2020 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. */
@@ -15,7 +15,8 @@ import edu.wpi.first.wpilibj.trajectory.TrapezoidProfile;
/**
* Implements a PID control loop whose setpoint is constrained by a trapezoid
* profile.
* profile. Users should call reset() when they first start running the controller
* to avoid unwanted behavior.
*/
@SuppressWarnings("PMD.TooManyMethods")
public class ProfiledPIDController implements Sendable {
@@ -319,10 +320,33 @@ public class ProfiledPIDController implements Sendable {
}
/**
* Reset the previous error, the integral term, and disable the controller.
* Reset the previous error and the integral term.
*
* @param measurement The current measured State of the system.
*/
public void reset() {
public void reset(TrapezoidProfile.State measurement) {
m_controller.reset();
m_setpoint = measurement;
}
/**
* Reset the previous error and the integral term.
*
* @param measuredPosition The current measured position of the system.
* @param measuredVelocity The current measured velocity of the system.
*/
public void reset(double measuredPosition, double measuredVelocity) {
reset(new TrapezoidProfile.State(measuredPosition, measuredVelocity));
}
/**
* Reset the previous error and the integral term.
*
* @param measuredPosition The current measured position of the system. The velocity is
* assumed to be zero.
*/
public void reset(double measuredPosition) {
reset(measuredPosition, 0.0);
}
@Override

View File

@@ -0,0 +1,26 @@
/*----------------------------------------------------------------------------*/
/* 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.controller;
import org.junit.jupiter.api.Test;
import edu.wpi.first.wpilibj.trajectory.TrapezoidProfile;
import static org.junit.jupiter.api.Assertions.assertEquals;
class ProfiledPIDControllerTest {
@Test
void testStartFromNonZeroPosition() {
ProfiledPIDController controller = new ProfiledPIDController(1.0, 0.0, 0.0,
new TrapezoidProfile.Constraints(1.0, 1.0));
controller.reset(20);
assertEquals(0.0, controller.calculate(20), 0.05);
}
}