hey there. we’re having some issues with out PID speed controller. we are working on setting the appropriate P value, and things are just not working. does anyone have any ball park estimates for the values?
Not working how?
does anyone have any ball park estimates for the values?
depends on the dynamics of what you are trying to control. you’ll need to provide a lot more detail to get a useful answer. The effort you put into framing the question will be proportional to the quality of the responses to your post.
*
*
we are trying to control a drive motor using an encoder and a jaguar. it is not working in that, we have the motor set point on and off every so many seconds. we range the P up and up and up, looking for any change. it does not change until the P value is at 10*10^4, then it stops the motor, and it will not turn on again until we are at a P value of 1. we are using a single cim motor, up on blocks.
thanks in advance, don’t hesitate if you need more info.
does the motor operate properly open loop?
what’s the motor connected to?
is the encoder signal going to the Jag or the DS?
what PID are you using?
what value of setpoint are you using?
how did you scale the value of the encoder?
what does this mean: “we range the up and up and up”?
you get the idea.
*
*
does the motor operate properly open loop?
yes it does
what’s the motor connected to?
black Jag PWM
is the encoder signal going to the Jag or the DS?
Digital Sidecar
what PID are you using?
PIDController
what value of setpoint are you using?
every few seconds, it alternates between 0, and 0.3
how did you scale the value of the encoder?
what ever the default is. that there could be the problem, but i am unsure. i could post the code if you want.
what does this mean: “we range the up and up and up”?
sorry, i fixed that later. we ranged the P value up and up. nothing seemed to change. we are further trouble shooting my getting the exact Jag value.
tell me if you need anything else thanks again.
what’s the business end of the motor connected to?
is the encoder signal going to the Jag or the DS?
Digital Sidecar
are you getting a proper signal from the encoder? e.g. if you run the motor open loop and just read the encoder value, does it change linearly with the open-loop voltage supplied to the motor?
what PID are you using?
PIDController
I assume you mean from from WPIlib?
what value of setpoint are you using?
every few seconds, it alternates between 0, and 0.3
0 and .3 what? fraction of 100% command?
how did you scale the value of the encoder?
what ever the default is. that there could be the problem, but i am unsure.
you need to scale the encoder signal so that it corresponds to the setpoint. otherwise the PID cannot form a proper error signal.
*
*
what’s the business end of the motor connected to?
the motor is connected to a gear box, where it interacts with the wheel. the encoder and wheel are in a 1:1 ratio, but the motor spindle to encoder is not. i’ll find out what it is if you need it.
are you getting a proper signal from the encoder? e.g. if you run the motor open loop and just read the encoder value, does it change linearly with the open-loop voltage supplied to the motor?
we thoroughly tested the encoder before hand, and all funtions seemed to work fine.
I assume you mean from from WPIlib?
yes
0 and .3 what? fraction of 100% command?
yes. as the jags take an input value of -1-1, i assumed that that was the what the setpoint was supposed to be in.
you need to scale the encoder signal so that it corresponds to the setpoint. otherwise the PID cannot form a proper error signal.
ok, how would i find out what that is? I assume that that is the SetDistancePerPulse function?
anything else?
Yes.
SetDistancePerPulse() so that a call to GetRate() returns +1 when the speed is what you expect to get when setpoint is +1.
As for tuning a speed PID, read this thread:
http://www.chiefdelphi.com/forums/showthread.php?p=1115090#post1115090
*
*
do you know what that might be? ive spent the morning trying to figure out what that number is. the GetRate() is DistancePerPulse/GetPeriod();
is there something i can do that would make this relitivly easy?
tell me what rpm you expect to get at the encoder when setpoint is +1
(and explain how you got that)
tell me your encoder part number
*
*
hey. thank you so much. i found the correct number for that now. it was 1/2000 which was the reciprical of the max speed. now we have the issue in which the P value seems to be a scaler for the jaguar, as opposed to a proportional controler. as we increse P, the target speed seems to incress. any ideas?
Read these posts/threads:
http://www.chiefdelphi.com/forums/showpost.php?p=1114338&postcount=4
http://www.chiefdelphi.com/forums/showthread.php?p=1115090#post1115090
Thank you so much. PID is working fine. one more issue that we met was that the encoder direction was reversed, but that was easily enough solved. now the PID is working fine, and this record will be kept for future years of this team.
Thank you so much for your patiance and help
GO TEAMS!
On second thought, we are having issues implementing one of the methods you recommended earlier. We have decided to use the
Output= Output +…
method, but out issue is, how do we get the value of the PIDControllor without setting a PIDOutput? could we just make an output object, feed it to the controller, and further ignore it?
Jaguar leftJ=new Jaguar(1,1);
Encoder leftE= new Encoder(1,1,1,2);
PIDOutput myoutput;
PIDController leftController= new PIDController(P,I,D, leftE, myoutput);
double speed=0;
{
speed=speed+ leftController.get();
leftJ.set(speed);
}
excluding ofcourse some details, but this is the general idea.
I actually did some stuff with this quite recently; my image tracking code outputs an angle that the robot should be at, and this angle is fed into a PIDController. For testing, I wanted this same setup to remain there, but also didn’t want it to be doing anything.
2 things I learned about the PIDController: 1) it does not like either its PIDSource or its PIDOutput being null. It will crash if either is null. 2) interface/abstract class implementation is extremely convenient.
The basic setup I had was this:
PIDController pid = new PIDController(PID_P,PID_I,PID_D,
new PIDSource() { public double pidGet() { return 0; } },
new PIDOutput() { public void pidWrite(double) {} });
This let me set and get the PIDController’s setpoint without messing anything up, and at the same time made it so that when I actually got the PIDController up and running, I wouldn’t have to change too much.
If you wanted to put in a valid PIDSource that would work just as well.
Which method, and what issues?
We have decided to use the
Output= Output +…
method, but out issue is, how do we get the value of the PIDControllor without setting a PIDOutput? could we just make an output object, feed it to the controller, and further ignore it?
Instead of sending the PID output directly to the Jaguar, you want to intercept it, process it, and send the processed value to the Jaguar.
*
*
So if you want to add feedforward, you’d do something like this:
processed_output = PIDoutput+feedforward;
if (processed_output>1) processed_output=1;
else if (processed_output<-1) processed_output=-1;
… then send processed_output to the Jaguar.
*
*
If you want to integrate the PID output, you’d do something like this:
processed_output += K*PIDoutput;
if (processed_output>1) processed_output=1;
else if (processed_output<-1) processed_output=-1;
… then send processed_output to the Jaguar.
*
thanks again all. you guys are awesome!