Skip to content

Commit bafe3d6

Browse files
committed
Small documentation updates
1 parent f5d450f commit bafe3d6

File tree

2 files changed

+124
-48
lines changed

2 files changed

+124
-48
lines changed
Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
package com.stormbots;
22

3-
public class main {
3+
public class Main {
44

55
/**
6-
* @param args
6+
* @param args Any arguments passed from stdin
77
*/
88
public static void main(String[] args) {
9-
// TODO Auto-generated method stub
109
MiniPID miniPID;
1110

12-
miniPID=new MiniPID( .25,0.01,.4);
11+
miniPID = new MiniPID(0.25, 0.01, 0.4);
1312
miniPID.setOutputLimits(10);
1413
//miniPID.setMaxIOutput(2);
1514
//miniPID.setOutputRampRate(3);
@@ -24,29 +23,28 @@ public static void main(String[] args) {
2423
miniPID.setSetpoint(0);
2524
miniPID.setSetpoint(target);
2625

27-
System.err.printf("Target,Actual\tOutput\tError\n");
26+
System.err.printf("Target\tActual\tOutput\tError\n");
2827
//System.err.printf("Output\tP\tI\tD\n");
2928

30-
//* Position based test code
31-
for (int i=0;i<100 ;i++){
29+
// Position based test code
30+
for (int i = 0; i < 100; i++){
3231

3332
//if(i==50)miniPID.setI(.05);
34-
if(i==60)target=(50);
33+
34+
if (i == 60)
35+
target = 50;
36+
3537
//if(i==75)target=(100);
3638
//if(i>50 && i%4==0)target=target+(Math.random()-.5)*50;
3739

38-
output=miniPID.getOutput(actual,target);
39-
actual=actual+output;
40+
output = miniPID.getOutput(actual, target);
41+
actual = actual + output;
4042

4143
//System.out.println("==========================");
4244
//System.out.printf("Current: %3.2f , Actual: %3.2f, Error: %3.2f\n",actual, output, (target-actual));
43-
System.err.printf("%3.2f\t%3.2f\t%3.2f\t%3.2f\n",target,actual, output, (target-actual));
44-
45+
System.err.printf("%3.2f\t%3.2f\t%3.2f\t%3.2f\n", target, actual, output, (target-actual));
4546

4647
//if(i>80 && i%5==0)actual+=(Math.random()-.5)*20;
47-
}
48-
//*/
49-
48+
}
5049
}
51-
5250
}

src/com/stormbots/MiniPID.java

Lines changed: 110 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
/**
33
* Small, easy to use PID implementation with advanced controller capability.<br>
44
* Minimal usage:<br>
5-
* setPID(p,i,d); <br>
5+
* MiniPID pid = new MiniPID(p,i,d); <br>
66
* ...looping code...{ <br>
7-
* output=getOutput(sensorvalue,target); <br>
7+
* output= pid.getOutput(sensorvalue,target); <br>
88
* }
99
*
1010
* @see http://brettbeauregard.com/blog/2011/04/improving-the-beginners-pid-direction/improving-the-beginners-pid-introduction
@@ -43,10 +43,27 @@ public class MiniPID{
4343
//**********************************
4444
// Constructor functions
4545
//**********************************
46+
47+
/**
48+
* Create a MiniPID class object.
49+
* See setP, setI, setD methods for more detailed parameters.
50+
* @param p Proportional gain. Large if large difference between setpoint and target.
51+
* @param i Integral gain. Becomes large if setpoint cannot reach target quickly.
52+
* @param d Derivative gain. Responds quickly to large changes in error. Small values prevents P and I terms from causing overshoot.
53+
*/
4654
public MiniPID(double p, double i, double d){
4755
P=p; I=i; D=d;
4856
checkSigns();
4957
}
58+
59+
/**
60+
* Create a MiniPID class object.
61+
* See setP, setI, setD, setF methods for more detailed parameters.
62+
* @param p Proportional gain. Large if large difference between setpoint and target.
63+
* @param i Integral gain. Becomes large if setpoint cannot reach target quickly.
64+
* @param d Derivative gain. Responds quickly to large changes in error. Small values prevents P and I terms from causing overshoot.
65+
* @param f Feed-forward gain. Open loop "best guess" for the output should be. Only useful if setpoint represents a rate.
66+
*/
5067
public MiniPID(double p, double i, double d, double f){
5168
P=p; I=i; D=d; F=f;
5269
checkSigns();
@@ -57,7 +74,7 @@ public MiniPID(double p, double i, double d, double f){
5774
//**********************************
5875
/**
5976
* Configure the Proportional gain parameter. <br>
60-
* This responds quicly to changes in setpoint, and provides most of the initial driving force
77+
* This responds quickly to changes in setpoint, and provides most of the initial driving force
6178
* to make corrections. <br>
6279
* Some systems can be used with only a P gain, and many can be operated with only PI.<br>
6380
* For position based controllers, this is the first parameter to tune, with I second. <br>
@@ -95,37 +112,68 @@ public void setI(double i){
95112
// output change due to the I term constant during the transition.
96113
}
97114

115+
/**
116+
* Changes the D parameter <br>
117+
* This has two primary effects:
118+
* <list>
119+
* <li> Adds a "startup kick" and speeds up system response during setpoint changes
120+
* <li> Adds "drag" and slows the system when moving toward the target
121+
* </list>
122+
* A small D value can be useful for both improving response times, and preventing overshoot.
123+
* However, in many systems a large D value will cause significant instability, particularly
124+
* for large setpoint changes.
125+
* <br>
126+
* Affects output through <b>output += -D*(current_input_value - last_input_value)</b>
127+
*
128+
* @param d New gain value for the Derivative term
129+
*/
98130
public void setD(double d){
99131
D=d;
100132
checkSigns();
101133
}
102134

103135
/**
104136
* Configure the FeedForward parameter. <br>
105-
* This is excellent for Velocity, rate, and other continuous control modes where you can
137+
* This is excellent for velocity, rate, and other continuous control modes where you can
106138
* expect a rough output value based solely on the setpoint.<br>
107-
* Should not be used in "position" based control modes.
139+
* Should not be used in "position" based control modes.<br>
140+
* Affects output according to <b>output+=F*Setpoint</b>. Note, that a F-only system is actually open loop.
108141
*
109-
* @param f Feed forward gain. Affects output according to <b>output+=F*Setpoint</b>;
142+
* @param f Feed forward gain.
110143
*/
111144
public void setF(double f){
112145
F=f;
113146
checkSigns();
114-
}
147+
}
115148

116149
/**
117-
* Create a new PID object.
150+
* Configure the PID object.
151+
* See setP, setI, setD methods for more detailed parameters.
118152
* @param p Proportional gain. Large if large difference between setpoint and target.
119153
* @param i Integral gain. Becomes large if setpoint cannot reach target quickly.
120154
* @param d Derivative gain. Responds quickly to large changes in error. Small values prevents P and I terms from causing overshoot.
121155
*/
122156
public void setPID(double p, double i, double d){
123-
P=p;I=i;D=d;
157+
P=p;D=d;
158+
//Note: the I term has additional calculations, so we need to use it's
159+
//specific method for setting it.
160+
setI(i);
124161
checkSigns();
125162
}
126163

164+
/**
165+
* Configure the PID object.
166+
* See setP, setI, setD, setF methods for more detailed parameters.
167+
* @param p Proportional gain. Large if large difference between setpoint and target.
168+
* @param i Integral gain. Becomes large if setpoint cannot reach target quickly.
169+
* @param d Derivative gain. Responds quickly to large changes in error. Small values prevents P and I terms from causing overshoot.
170+
* @param f Feed-forward gain. Open loop "best guess" for the output should be. Only useful if setpoint represents a rate.
171+
*/
127172
public void setPID(double p, double i, double d,double f){
128-
P=p;I=i;D=d;F=f;
173+
P=p;D=d;F=f;
174+
//Note: the I term has additional calculations, so we need to use it's
175+
//specific method for setting it.
176+
setI(i);
129177
checkSigns();
130178
}
131179

@@ -145,16 +193,19 @@ public void setMaxIOutput(double maximum){
145193
}
146194

147195
/**
148-
* Specify a maximum output. If a single parameter is specified, the minimum is
149-
* set to (-maximum).
150-
* @param output
196+
* Specify a maximum output range. <br>
197+
* When one input is specified, output range is configured to
198+
* <b>[-output, output]</b>
199+
* @param output
151200
*/
152201
public void setOutputLimits(double output){
153202
setOutputLimits(-output,output);
154203
}
155204

156205
/**
157206
* Specify a maximum output.
207+
* When two inputs specified, output range is configured to
208+
* <b>[minimum, maximum]</b>
158209
* @param minimum possible output value
159210
* @param maximum possible output value
160211
*/
@@ -182,19 +233,21 @@ public void setDirection(boolean reversed){
182233
//**********************************
183234

184235
/**
185-
* Set the target for the PID calculations
236+
* Configure setpoint for the PID calculations<br>
237+
* This represents the target for the PID system's, such as a
238+
* position, velocity, or angle. <br>
239+
* @see MiniPID#getOutput(actual) <br>
186240
* @param setpoint
187241
*/
188242
public void setSetpoint(double setpoint){
189243
this.setpoint=setpoint;
190-
}
244+
}
191245

192246
/**
193-
* Calculate the PID value needed to hit the target setpoint.
194-
* Automatically re-calculates the output at each call.
195-
* @param actual The monitored value
196-
* @param target The target value
197-
* @return calculated output value for driving the actual to the target
247+
* Calculate the output value for the current PID cycle.<br>
248+
* @param actual The monitored value, typically as a sensor input.
249+
* @param setpoint The target value for the system
250+
* @return calculated output value for driving the system
198251
*/
199252
public double getOutput(double actual, double setpoint){
200253
double output;
@@ -287,32 +340,49 @@ else if(maxIOutput!=0){
287340
}
288341

289342
/**
290-
* Calculates the PID value using the last provided setpoint and actual valuess
291-
* @return calculated output value for driving the actual to the target
343+
* Calculate the output value for the current PID cycle.<br>
344+
* In no-parameter mode, this uses the last sensor value,
345+
* and last setpoint value. <br>
346+
* Not typically useful, and use of parameter modes is suggested. <br>
347+
* @return calculated output value for driving the system
292348
*/
293349
public double getOutput(){
294350
return getOutput(lastActual,setpoint);
295351
}
296352

297353
/**
298-
* @param actual
299-
* @return calculated output value for driving the actual to the target
354+
* Calculate the output value for the current PID cycle.<br>
355+
* In one parameter mode, the last configured setpoint will be used.<br>
356+
* @see MiniPID#setSetpoint()
357+
* @param actual The monitored value, typically as a sensor input.
358+
* @param setpoint The target value for the system
359+
* @return calculated output value for driving the system
300360
*/
301361
public double getOutput(double actual){
302362
return getOutput(actual,setpoint);
303363
}
304364

305365
/**
306-
* Resets the controller. This erases the I term buildup, and removes D gain on the next loop.
366+
* Resets the controller. This erases the I term buildup, and removes
367+
* D gain on the next loop.<br>
368+
* This should be used any time the PID is disabled or inactive for extended
369+
* duration, and the controlled portion of the system may have changed due to
370+
* external forces.
307371
*/
308372
public void reset(){
309373
firstRun=true;
310374
errorSum=0;
311375
}
312376

313377
/**
314-
* Set the maximum rate the output can increase per cycle.
315-
* @param rate
378+
* Set the maximum rate the output can increase per cycle.<br>
379+
* This can prevent sharp jumps in output when changing setpoints or
380+
* enabling a PID system, which might cause stress on physical or electrical
381+
* systems. <br>
382+
* Can be very useful for fast-reacting control loops, such as ones
383+
* with large P or D values and feed-forward systems.
384+
*
385+
* @param rate, with units being the same as the output
316386
*/
317387
public void setOutputRampRate(double rate){
318388
outputRampRate=rate;
@@ -323,17 +393,21 @@ public void setOutputRampRate(double rate){
323393
* <br>Can simplify tuning by helping tuning over a small range applies to a much larger range.
324394
* <br>This limits the reactivity of P term, and restricts impact of large D term
325395
* during large setpoint adjustments. Increases lag and I term if range is too small.
326-
* @param range
396+
* @param range, with units being the same as the expected sensor range.
327397
*/
328398
public void setSetpointRange(double range){
329399
setpointRange=range;
330400
}
331401

332402
/**
333403
* Set a filter on the output to reduce sharp oscillations. <br>
334-
* 0.1 is likely a sane starting value. Larger values P and D oscillations, but force larger I values.
335-
* Uses an exponential rolling sum filter, according to a simple <br>
336-
* <pre>output*(1-strength)*sum(0..n){output*strength^n}</pre>
404+
* 0.1 is likely a sane starting value. Larger values use historical data
405+
* more heavily, with low values weigh newer data. 0 will disable, filtering, and use
406+
* only the most recent value. <br>
407+
* Increasing the filter strength will P and D oscillations, but force larger I
408+
* values and increase I term overshoot.<br>
409+
* Uses an exponential wieghted rolling sum filter, according to a simple <br>
410+
* <pre>output*(1-strength)*sum(0..n){output*strength^n}</pre> algorithm.
337411
* @param output valid between [0..1), meaning [current output only.. historical output only)
338412
*/
339413
public void setOutputFilter(double strength){
@@ -364,9 +438,13 @@ private double constrain(double value, double min, double max){
364438
* @param value to test
365439
* @param min Minimum value of range
366440
* @param max Maximum value of range
367-
* @return
441+
* @return true if value is within range, false otherwise
368442
*/
369443
private boolean bounded(double value, double min, double max){
444+
// Note, this is an inclusive range. This is so tests like
445+
// `bounded(constrain(0,0,1),0,1)` will return false.
446+
// This is more helpful for determining edge-case behaviour
447+
// than <= is.
370448
return (min<value) && (value<max);
371449
}
372450

0 commit comments

Comments
 (0)