Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Made convenience functions for tuning a CustomPIDController on SmartDashboard #197

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
62 changes: 62 additions & 0 deletions custom/motioncontrollers/CustomPIDController.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.usfirst.frc4904.standard.custom.sensors.PIDSensor;
import edu.wpi.first.wpilibj.PIDSource;
import edu.wpi.first.wpilibj.PIDSourceType;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import edu.wpi.first.wpilibj.util.BoundaryException;

/**
Expand All @@ -24,6 +25,7 @@ public class CustomPIDController extends MotionController {
protected double lastError;
protected long lastTime;
protected double minimumNominalOutput = 0.0;
protected static final String DEFAULT_SMARTDASHBOARD_PREFIX = "PID";

/**
* An extremely basic PID controller.
Expand Down Expand Up @@ -350,4 +352,64 @@ public double get() {
return 0;
}
}

/**
* Put the PID controller to SmartDashboard for tuning.
* Puts the error, setpoint, sensor value, and output.
* This method adds a very small random value to everything
* so that graphs show properly on SmartDashboard.
*
* @param prefix
* The prefix to use when putting things on SmartDashboard.
*/
public void putToSmartDashboard(String prefix) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be added as an abstract function to MotionController (same for the other functions).

double noise = (Math.random() - 0.5) * 0.0000001; // Generate very small noise centered at zero
SmartDashboard.putNumber(prefix + "_Error", getError() + noise);
SmartDashboard.putNumber(prefix + "_Setpoint", getSetpoint() + noise);
SmartDashboard.putNumber(prefix + "_Sensor", getSensorValue() + noise);
SmartDashboard.putNumber(prefix + "_Output", get() + noise);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, did we decide that the mutating effects of calling get() (of the I and D) calculations are not big enough to matter?

Copy link
Contributor

@carturn carturn Mar 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have decided to fix that in the future. It should not make too much of a difference, as it does calculate time deltas every time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool -- and the sensor updates fast enough that each few ticks will probably have a different value.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is on the list to be fixed. (In fact I have a list of PID changes we need to make that various programmers will be doing before SVR)

}

/**
* Put the PID controller to SmartDashboard for tuning.
* Puts the error, setpoint, sensor value, and output.
* This method adds a very small random value to everything
* so that graphs show properly on SmartDashboard.
*/
public void putToSmartDashboard() {
putToSmartDashboard(CustomPIDController.DEFAULT_SMARTDASHBOARD_PREFIX);
}

/**
* Update the PID controller from SmartDashboard for tuning.
* Gets the P, I, D, and F constants from SmartDashboard,
* or puts the current ones there if there's no constants.
*
* @param prefix
* The prefix to use when putting things on SmartDashboard.
*/
public void updateFromSmartDashboard(String prefix) {
// If we're missing any constants on SmartDashboard, put the current ones
if (!(SmartDashboard.containsKey(prefix + "_P") && SmartDashboard.containsKey(prefix + "_I")
&& SmartDashboard.containsKey(prefix + "_D") && SmartDashboard.containsKey(prefix + "_F"))) {
SmartDashboard.putNumber(prefix + "_P", getP());
SmartDashboard.putNumber(prefix + "_I", getI());
SmartDashboard.putNumber(prefix + "_D", getD());
SmartDashboard.putNumber(prefix + "_F", getD());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

D != F

return;
}
setPIDF(SmartDashboard.getNumber(prefix + "_P", getP()),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to use the two-argument version with a default value? We've done this in the past while testing (with default 0).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a good way of doing it, it will default to the previous P/I/D/F value.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is what I'm doing...?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes -- I have... room to improve.

SmartDashboard.getNumber(prefix + "_I", getI()),
SmartDashboard.getNumber(prefix + "_D", getD()),
SmartDashboard.getNumber(prefix + "_F", getF()));
}

/**
* Update the PID controller from SmartDashboard for tuning.
* Gets the P, I, D, and F constants from SmartDashboard,
* or puts the current ones there if there's no constants.
*/
public void updateFromSmartDashboard() {
updateFromSmartDashboard(CustomPIDController.DEFAULT_SMARTDASHBOARD_PREFIX);
}
}