|
Re: PID loops using rate
Quote:
Originally Posted by geel9
Hey,
We're trying to get our PID loops to control the motors' rate, as opposed to their distance.
Here is our code:
Code:
//Initializes the motors.
private final SpeedController left = new Jaguar(1);
private final SpeedController right = new Jaguar(2);
//Initializes the Encoders.
private final Encoder leftEncoder = new Encoder(1, 2);
private final Encoder rightEncoder = new Encoder(3, 4);
//Proportional, Integral, and Dervative constants.
//These values will need to be tuned for your robot.
private final double Kp = 0.1;
private final double Ki = 0.001;
private final double Kd = 0;
//This must be fully initialized in the constructor, after the settings
//for the encoders have been done.
private final PIDController leftPID;
private final PIDController rightPID;
public PIDDrive() {
//Sets the distance per pulse in inches.
leftEncoder.setDistancePerPulse(-1);
rightEncoder.setDistancePerPulse(-1);
//Starts the encoders.
leftEncoder.start();
rightEncoder.start();
//Sets the encoders to use distance for PID.
//If this is not done, the robot may not go anywhere.
//It is also possible to use rate, by changing kDistance to kRate.
leftEncoder.setPIDSourceParameter(Encoder.PIDSourceParameter.kRate);
rightEncoder.setPIDSourceParameter(Encoder.PIDSourceParameter.kRate);
//Initializes the PID Controllers
leftPID = new PIDController(Kp, Ki, Kd, leftEncoder, left);
rightPID = new PIDController(Kp, Ki, Kd, rightEncoder, right);
leftPID.setPercentTolerance(25);
rightPID.setPercentTolerance(25);
leftPID.setContinuous();
rightPID.setContinuous();
//Enables the PID Controllers.
leftPID.enable();
rightPID.enable();
}
public static void WriteDriverStationLine(DriverStationLCD.Line line, String text){
DriverStationLCD.getInstance().println(line, 1, text);
DriverStationLCD.getInstance().updateLCD();
}
/**
* This function is called once each time the robot enters operator control.
* Teleop commands are put in here
*/
public void operatorControl() {
leftPID.setSetpoint(1000);
rightPID.setSetpoint(1000);
while(isOperatorControl()){
WriteDriverStationLine(DriverStationLCD.Line.kUser1, "E: " + leftPID.getError());
WriteDriverStationLine(DriverStationLCD.Line.kUser2, "E2: " + rightPID.getError());
WriteDriverStationLine(DriverStationLCD.Line.kUser3, "D: " + leftEncoder.getRate());
WriteDriverStationLine(DriverStationLCD.Line.kUser4, "D2: " + rightEncoder.getRate());
}
The wheels spin forward, then rapidly switch directions.
|
I would need to study the WPIJ PID class to see what its actually doing... to see if it clips the values, helps with integral windup and other control stuff to give you a complete answer... but off the bat, how did you get your gains?
Your setPoint is 1000 so your first iteration is 1000*0.1 = 100, because PWM only accepts +1 to -1 as inputs to the motor controllers.that instantly drives your motor to full power. I am not sure what the units of your 1000 but if your motor can spin faster than that, then your gains will cause your motor to oscillate... try reducing your gains.
__________________
Controls Engineer, Team 2168 - The Aluminum Falcons
[2016 Season] - World Championship Controls Award, District Controls Award, 3rd BlueBanner
-World Championship- #45 seed in Quals, World Championship Innovation in Controls Award - Curie
-NE Championship- #26 seed in Quals, winner(195,125,2168)
[2015 Season] - NE Championship Controls Award, 2nd Blue Banner
-NE Championship- #26 seed in Quals, NE Championship Innovation in Controls Award
-MA District Event- #17 seed in Quals, Winner(2168,3718,3146)
[2014 Season] - NE Championship Controls Award & Semi-finalists, District Controls Award, Creativity Award, & Finalists
-NE Championship- #36 seed in Quals, SemiFinalist(228,2168,3525), NE Championship Innovation in Controls Award
-RI District Event- #7 seed in Quals, Finalist(1519,2168,5163), Innovation in Controls Award
-Groton District Event- #9 seed in Quals, QuarterFinalist(2168, 125, 5112), Creativity Award
[2013 Season] - WPI Regional Winner - 1st Blue Banner
|