Who is here? 1 guest(s)
 Print Thread
Easy PID tuning with Ziegler-Nichols
marcov
Hey,
I recently needed to tune the PID for my newly built popper.

After logging an open loop response with Artisan, I did not feel like printing the plot and drawing the Ziegler-Nichols "lines" manually.

So I started playing with Octave (the free version of MATLAB), and in the end I wrote a set of scripts to automatically compute Kp, Ki, Kd from an Artisan CSV log file. You also get a plot with what's need for Ziegler-Nichols (see attached picture).

You can find the code here: https://github.co...ov/pidtune

Have fun and let me know if something needs to be fixed.
marcov attached the following image:
example.jpg
 
renatoa
And some numbers for your machine ?
Better profile following ? Grin

There is a similar thread here:
https://forum.hom...ad_id=5598

... not aware that something changed since then, PID tuning is not easy, and not for a continuous moving target.
 
marcov
I got these for the step response above: : Kp = 12.10 Ki = 0.46 Kd = 79.86

I logged the step response from an empty machine, as I didn't want to "invest" some beans for the tuning.

About profile following, it's acceptable in the end.

I read some of your posts about the inadequacy of a stock PID for following a profile, and now I am curious to try out the proportional on measurement add on.
marcov attached the following image:
tuned.png
 
Wiz Kalita
The heat looks pretty jumpy, that's what I've gotten out of Ziegler-Nichols as well. As far as I understand it's made for quickly reaching a fixed target at the expense of stability in a non-integrating process. Whereas we have a moving target in a somewhat integrating process where stability is more important than responsiveness. I control on ET and use POM, Kp = 0.8, Ki = 0.2 and Kd = 0, and I have decent results on a popper. It's lagging behind the background a bit, but that's what lookahead is for.
By the way, where are your probes placed? My ET probe measures the incoming air, and it's only lower than BT if it has come loose and is touching the wall.
Wiz Kalita attached the following image:
annotation_2019-03-17_183106.png
 
mg512
Oh, nice! I have experimented a little as well with PID tuning on my roaster. See the link that renatoa posted. Admittedly the Arduino sketch is pretty rough around the edges. Since it's running the tuning algorithm on-board, there's not much memory left for more than an absolute minimal command interface, and even then I think there's a few bugs in there.

Still, for me this gave reasonable results. It's not perfect, but I don't know for sure if the remaining instabilities are due to the PID tuning, or noise on the temperature measurements, or other reasons. It's working well enough for me in any case.

More generally, I think it's worth noting that there's a fundamental difference between the dynamics of drum roasters and those of fluid bed roasters. I think difficulties with one don't necessarily correspond to difficulties with the other. Neither of them are purely on one side or the other, but drum roasters are closer to integrating processes, while fluid bed roasters are closer to self-regulating processes, for instance. (As far as I understand it.) I don't know enough about about proportional-on-measurement to say much about it, but it sounds like it is worth trying if regular PID doesn't work well enough. Don't use Ziegler-Nichols or other autotuning methods with POM though, obviously.

Marco, I would absolutely do the PID tuning with beans in the roaster! On my popcorn roaster, the dynamics are completely different if it's empty. It doesn't need to be nice beans, in fact it doesn't even need to be green beans. Any old roasted beans you have lying around? Or get the cheapest ones at the supermarket. Worst case try popcorn. ;)
 
renatoa
chickpeas... almost same roasting characteristics, less the crack, and here 5 times cheaper than coffee.
 
marcov

Quote

Wiz Kalita wrote:
I control on ET and use POM, Kp = 0.8, Ki = 0.2 and Kd = 0, and I have decent results on a popper. It's lagging behind the background a bit, but that's what lookahead is for.


How did you end up with those Kp,i,d values? I have no clue what to use in my case.

And what lookahead value are you using? I am between 5 and 10s.

Quote

Wiz Kalita wrote:
By the way, where are your probes placed? My ET probe measures the incoming air, and it's only lower than BT if it has come loose and is touching the wall.


I drilled a hole in the metal "funnel" connecting the basket to the lower heater and fan holder. My ET rate is a good predictor or the BT derivative in my case, but I don't use it for anything else a.t.m.
 
Wiz Kalita

Quote

marcov wrote:

How did you end up with those Kp,i,d values? I have no clue what to use in my case.

And what lookahead value are you using? I am between 5 and 10s.


I did some preliminary testing with a load of failed, already roasted beans, using the wild-ass-guess method. Tried to track a curve based on ET and adjusted the parameters based on how much it lagged or how unstable it was until I was satisfied, based on the figures here. ET measured before the beans is relatively independent of the bean load so it translates well to green beans. It's still not perfect and I try to tweak it sometimes. I'm not at home and can't check my laptop, but I think I use a lookahead of 12 seconds.
 
marcov
Thanks for clarifying.
Based on your values, if I understand correctly, your POM is almost like a "I" only regulator: Kp is low, and we know that T moves slowly compared to the sampling time, so the conservative effect of the PoM is very light.

BTW, at the page you linked the proportional term is computed as:
-Kp * (Input[t] - Input[t=0])
while in the PID library code it is computed as:
-Kp * (Input[t] - Input[t-1])

That's quite a big difference, isn't it?
 
renatoa
Moves slowly is relative, and depends equally on resolution, as sample time too.
RoR 10 C/min means one C degree every 6 seconds, so 0.17 C degrees per second.
Guess the sample times should be significantly different for 0.25 C resolution, or for 0.025 C resolution...

Regarding the Brad PoM implementation in his library, already wrote here:
https://forum.hom...post_67882
... that my opinion it is faulty. P term is identical to D term as formula.
 
Wiz Kalita
That's interesting, looks like an ID controller could do the same job then. ;) Still, I'm not sure what more you want from it if it actually tracks the temperature profile. My peak ROR is 60?/minute, which in roasting terms should be quite fast.
 
marcov
That's true.

On my side, I am kind of lost with PID tuning, I can't avoid the oscillations I posted in the picture above with regular PonE.

I tried to play with PonM, but I can't find a correct set of parameters with wild guess only.

I am now kind of lost. I tried 3 different PID implementations, includig the flightgear one, but it's not making things better.

I'll have to stick for some time to the manual mode, but being a engineer it hurts...
 
greencardigan

Quote

marcov wrote:
I can't avoid the oscillations I posted in the picture above with regular PonE.

I feel that all your parameters might be too high for PonE.

On my smaller (350g) air roaster I use P=5, I=0.15 and D=0
On my larger (1.5kg) air roaster I use P=4, I=0.03 and D=0

I would suggest trying something a bit higher than my 350g roaster. Maybe P=6, I=0.3, D=0.

I've never tried any auto tuning, just trial and error. I find something that is useable testing with junk beans. Then just tweak slightly each following roast and compare the resulting profiles.
 
marcov
I did some more testing and ended up using P=2, I=0.11, D=22.
I still have some overshots to fix, what would you suggest to change based on the picture?

I am using the flightgear PID, as suggested by renatoa in some other threads.


About POM, wouldn't make more sense to have a "proportional on setpoint" for our case?
marcov attached the following image:
anotherpid.jpg
 
renatoa
Wondering how you arrived to that big value for derivative term...
It could be good for a machine with preheat, to slow the drop after the charging, but for a profile starting from zero the effect is questionable.
 
renatoa
You can't avoid oscillations with PonE, is the beast nature. At setpoint the P term should be zero, and in order to drive the heater with I term mainly it must exist an error... that led to an overshoot, that clear the I term, lower the power, that led to an undershot, so another error that accumulate and drive the power up, and so on...
Brad explain well the issue in his PonM introduction, only the implementation is not right.

Being an engineer too, after reading marcov post, thought last evening about a personal vision about how a well done PonM should look... will sketch it below if anyone want to try, I don't have a roast scheduled until weekend.
So, reviewing my roasting notes, is somewhat obvious that we should have a continuous power increase proportional with setpoint value (the PonM component), and a fine tune component, the I term.
On my machine the value of this P(onM) term should be 0.40, because I have heater around 80% in the 200 C temperature ballpark of FC.
This term will give me 60% heater when dry phase ends at 150 C, which is close enough to the values I have during real roast, in the 64-66% ballpark.

So I propose to anyone interested to test this approach with a real roast, to access PID_v1.cpp, and change at line 80, from:


output = kp * error;


to


output = *mySetpoint * kp;


so change the P term weight from error to setpoint dependent.

Don't forget to change your actual Kp, from the big value to something computed as above, heater % / temperature at FC, the result should be close to 0.40 value, in the 0.3-0.5 ballpark, if out of these limits there is something wrong with your setup.

I term also can be estimated pretty exact, watching when you have the biggest difference between set value from profile and BT, and what interval this difference has been accumulated.
For example assuming at 150C the BT was spot on the profile, then 20 seconds later you have a 2 degrees difference, then an I term of 0.1 should compensate this and keep BT on track.

PS: this post was been typed in my morning and posted in the evening, some 10 hours later, no idea why it didn't posted first time, not firm enough click on Post perhaps...
 
greencardigan

Quote

renatoa wrote:
Regarding the Brad PoM implementation in his library, already wrote here:
https://forum.hom...post_67882
... that my opinion it is faulty. P term is identical to D term as formula.

You should raise this with Brett as an issue on the Github page? https://github.co...ID-Library

I do notice that the Artisan PonM code has the following. Note dtinput used when calculating D rather than dinput.



dinput = i - self.lastInput
dtinput = dinput / dt
...
self.Pterm = self.Pterm -self.Kp * dinput
...
D = - self.Kd * dtinput


If PID cycle time is 1 second, does this mean that Brett's code (TC4 implementation) works ok in that case?
 
Wiz Kalita

Quote

marcov wrote:

Thanks for clarifying.
Based on your values, if I understand correctly, your POM is almost like a "I" only regulator: Kp is low, and we know that T moves slowly compared to the sampling time, so the conservative effect of the PoM is very light.

BTW, at the page you linked the proportional term is computed as:
-Kp * (Input[t] - Input[t=0])
while in the PID library code it is computed as:
-Kp * (Input[t] - Input[t-1])

That's quite a big difference, isn't it?


After looking at the code, I disagree with this. The reason is that output (not outputSum) is reset each loop. outputSum is not reset unless it clips, so any values added to it are integrated. In both PonE and PonM, ki * error is added to outputSum each loop and so adds up.

In PonM, output is set to 0 each loop and -kp * dInput is added to outputSum. kd * dInput is added directly to output and is not stored in the running outputSum variable. So the difference between the two is that in PonM the proportional term is given by the integral of the derivative, and this builds in t=0.

So for the two cases, the loop boils down to the following:

PonE:


outputSum+= (ki * error);
output = kp * error;
output += outputSum - kd * dInput;


PonM:


outputSum+= (ki * error);
outputSum-= kp * dInput;
output = 0;
output += outputSum - kd * dInput;
 
renatoa
The result of continuously integrating (sum) dInput values is, at every moment, input(t) - input(0).
Please check below how all intermediate inputs does not matter, because they clear each other:
outputSum = -(i1-i0)-(i2-i1)-(i3-i2)-...(in-1-in-2)-(in-in-1) = -(in-i0)
 
Wiz Kalita
Yes, that's what I mean.
 
renatoa
The problem is how this approach (Brad PnM) would give us better results for our specific needs.

Based on collective wisdom roasting experience, I see the power driven by 4 components:

- a component proportional with setpoint; this should be the most important driving factor of output, not something error based.

- a component proportional with error, not integrating, but instant. There are events during the roast that are fast and short as duration, flicks, crashes... until the integrator move the heat to compensate, they are gone.

- an integral component, that resolve the small differences between the first proportional term and actual profile power needs. This I term should be small enough, probably less than 10% of power range used during roast, to make the inherent oscillations negligible.

- the derivative, whose role I see only in machines with preheat and fast charge, to provide some power during the charge abrupt temperature drop. There aren't other moments in a roast with a fast enough temperature change, I mean RoR bigger than 100, to make the D-term relevant in the output. I remind for those not familiar with PID innards, that a value of 1 of D term will move power output with 1% only if there is a temperature change of 1 degree per second, which equates to RoR 60deg/min.
The derivative component can be replaced by a well thought MIN_OT1 value, probably a safer approach than using a derivative, that amplifies the noise, making RoR looking ugly.

Does the above make any sense ?
 
Wiz Kalita
Yes, that makes a lot of sense. I still think PonM is an improvement on PonE, but what you are describing could be even better. I see your point about fast events as the hardest thing to handle with a traditional PID due to stability. But maybe decoupling the main driving term from the error would help.
 
marcov

Quote


Based on collective wisdom roasting experience, I see the power driven by 4 components:
...



Makes a lot of sense, to sum it up: P1 * setpoint + P2 * error + I * sumOf(errors).

About derivative, I think it would be interesting to try a term based on the derivative of RoR error, to avoid RoR oscillations.
 
marcov
I'm back with my latest tuning attempt.

This time I took a different route. I loaded my step response data in MATLAB, I estimated the transfer function of my system and the used the PID tune function to auto-guess the PID parameters.

This resulted in a PI regulator with: PRO = 0.7939f, INT = 0.1188f

I am attaching a plot of a test roast, again done with PID ported from the Flight Gear project.

I'm calling it a day and going back to more coffe-oriented topics.
marcov attached the following image:
costarica-2203-pi-51galog.jpg
 
Jump to Forum: