PID Without a PhD, Finally

OOps just spotted a terminology blunder

Page 2 The "PID" in "PID Control" stands for "Proportional, Integral, Derivative".

Page 19

Section Title is "Differential" Should be "Derivative"

From there on you interchange differential and derivavtive all over the place.

--
Paul Carpenter          | paul@pcserviceselectronics.co.uk 
    PC Services 
  Raspberry Pi Add-ons 
 Timing Diagram Font 
 For those web sites you hate
Reply to
Paul
Loading thread data ...

See "A Meeting with Medusa" by Arthur Clarke. (Really a good story.)

Cheers

Phil Hobbs (who's not qualified to comment on Tim's magnum opus.) ;)

--
Dr Philip C D Hobbs 
Principal Consultant 
ElectroOptical Innovations LLC 
Optics, Electro-optics, Photonics, Analog Electronics 

160 North State Road #203 
Briarcliff Manor NY 10510 

hobbs at electrooptical dot net 
http://electrooptical.net
Reply to
Phil Hobbs

I would not have said it was obfuscated - but it certainly could be a little better (as could the code on page 22). So far, I have only looked at the style of the code - I haven't actually looked at the details to see what it does, nor have I had time to read the whole paper. Hopefully I will do so some time - but perhaps by then there will be a second version from feedback from others in this thread!

As this code is for embedded systems, it should be written in a manner close to that used in common embedded coding standards such as MISRA. Here are some points here that I think would make the code clearer, as well as more compatible with things like MISRA, and more suitable for flexible use in embedded systems:

  1. MISRA does not approve of native types such as "double", because the precision is implementation defined and can vary between C compilers and targets. I agree with that regarding integers (so use types rather than "int" or "short"), but the use of 32-bit and 64-bit IEEE formats for "float" and "double" is so close to universal that I think it is unnecessary. However, many people using code like this will want to use "float" for speed, while others will want "double" for precision. I would recommend starting the code with:

typedef double real_t; // Use "float" or "double" as desired

Then use "real_t" throughout, instead of "double".

(It may be interesting to have a small section discussing the merits of these options - on something like a Cortex-M4F with hardware single-precision floating point, the speed difference could easily be a factor of 100. It may even be worth mentioning things like compiler flags - while most people know about basic optimisation flags, they may not know the huge difference "-ffast-math" can have on code like this. You may also want to discuss using integers instead of floating point, especially considering errors, scaling, rounding, and overflows.)

  1. Do not give identifiers names such as "dState" and "iState". There are, unfortunately, a good many programmers who have totally misunderstood the point of "Hungarian notation" and will think that these mean a variable "state" with type "double", and another variable "state" with type "int".

  1. Do not give identifiers names that are almost the same. Do not abbreviate the important part of the name (the "differential" or "integrator" part) to a single letter. It's fine to have shorter names for local variables within a function, but names that are visible over a wider range (such as the struct fields) should be self-explanatory.

  2. If you need a comment to tell you what an identifier is, then the identifier name is bad. It is the identifier's name that says what it is - a comment may be used to add extra information such as scaling, or when it is used.

  1. Always use the "one true brace" style. Every "if" and "else" should have brackets.

  2. Do not declare more than one identifier in the same declaration.

  1. Even the most conservative and backwards development companies have heard of C99. Declare your variables when you need them, in the smallest reasonable scope.

Full marks for good character spacing!

typedef double real_t; // Use "float" or "double" as desired

typedef struct { real_t lastPosition; real_t integrator; real_t integratorLimitMax; real_t integratorLimitMin; real_t integralGain; real_t proportionalGain; real_t derivativeGain; } pid_s;

real_t updatePID(pid_s * pid, real_t error, real_t position) { // The "P" part real_t pTerm = pid->proportionalGain * error;

// The "I" part pid->integrator += error; if (pid->integrator > pid->integratorLimitMax) { pid->integrator = pid->integratorLimitMax; } else if (pid->integrator < pid->integratorLimitMin) { pid->integrator = pid->integratorLimitMin; } real_t iTerm = pid->integratorGain * pid->integrator;

// The "D" part real_t dTerm = pid->derivativeGain * (pid->lastPosition - position); pid->lastPosition = position;

// Combined PID result return pTerm + iTerm + dTerm; }

Note that almost no comments are needed - the functionality is clear from the names used in the code.

Regarding the typesetting, I recommend using the "listings" package rather than just a verbatim environment:

The setup I use for C code is something like this:

\lstset{ language=C, formfeed=\newpage, tabsize=4, basicstyle=\small, numbers=left, numberstyle=\tiny, firstnumber=1, numberfirstline=true, stepnumber=5, numbersep=5pt, extendedchars=true, showstringspaces=false, breakatwhitespace=false, identifierstyle=\color{Black}\itshape, commentstyle=\color{Gray}\itshape, stringstyle=\color{Green} }

(I vary it a little according to the document in question, but this is probably fine to get you started.)

Reply to
David Brown

Ok, that all makes sense and is what is being described in the paper. The drive is current rather than voltage and will produce the result shown in the diagram until the max voltage of the supply is reached. Thanks.

I still don't get equation 3. I searched a bit and could not find anything similar. All the other references I found on the web use the Laplace transform to perform the math and don't produce a similar equation.

Trying to find info on the web for control theory really opens a rabbit hole, lol.

--

Rick
Reply to
rickman

Thermal systems are generally far more complex than equation 3 implies. That one really should be taken just add the equation used to generate the plant model, nothing more.

Pragmatically, if you need to wrap a control loop around a thermal plant, you should probably close your eyes to the theory and either tune it up by the seat of your pants (as in that paper), or you should use measured responses (which I cover briefly in another paper, and at length in my book).

--
www.wescottdesign.com 


----Android NewsGroup Reader---- 
http://usenet.sinaapp.com/
Reply to
Tim Wescott

Yes. It was published in Embedded Systems Design magazine back in 2000 or something. For years I've just pointed to their version in my website, but they keep moving it around as their priorities change.

Textbooks make things easy to understand. Practitioners make things work well. (Snarkity-snark).

I kind of allude to this in the text -- I could add a section. Basically, if you feed the entire error signal to the PID controller then when you have a step-change in the input you just hammer the output driver of the controller. Sometimes this is a good thing, because you get snappier response from the plant. Sometimes this is a bad thing, because if you've got a lot of extraneous changes in the command you can heat up (or wear out, or whatever) your output driver.

--

Tim Wescott 
Wescott Design Services 
http://www.wescottdesign.com
Reply to
Tim Wescott

Argh! yes. Thank you.

--

Tim Wescott 
Wescott Design Services 
http://www.wescottdesign.com
Reply to
Tim Wescott

Hi David:

Thank you for your pertinent comments. I think I'll apply most of them. The only scary part of your comments are the "if someone uses the code"

-- I originally meant this code to be for illustrative purposes only, not for use in production systems. My assumption was that people would read the article, grok the material, then go off and write code from scratch.

Thus, the first time I got feedback along the lines of "we copied your code into our production software and it works GREAT!" my response was

"WHAT!?! NOOOO!"

So I would be tempted to take your real_t and change it to do_not_use_this_for_real_t.

I have a question, since you brought it up and since I'm lazy. In many control systems, 32-bit IEEE floating point is inadequate, because a 24 bit significand just doesn't cut it. So the choice of double, with its bigger significand, is usually necessary.

Is there a better way to express the "you damned well need 'double' here, bub" in code than just using "double", or a comment to that effect?

--

Tim Wescott 
Wescott Design Services 
http://www.wescottdesign.com
Reply to
Tim Wescott

That calls for clarification. "Derivative" is the correct term if you're doing the work with continuous-time hardware (i.e. op-amps, resistors and capacitors). "Differential" is the correct term if you're doing the work in sampled time.

So I need to figure out how to work that in.

--

Tim Wescott 
Wescott Design Services 
http://www.wescottdesign.com
Reply to
Tim Wescott

I double-checked, and I kind of allude to this but I need to SAY this in the text. Thermal systems are generally sluggish with lots of high- frequency roll-off. The model chosen is sluggish with lots of high- frequency roll-off. That's about the extent of the accuracy of the model, in general. On a good day the chosen model may actually match a real thermal system well enough to work with -- but it's not to be taken as a generally accurate model, where equations 1 and 2 are generally much more applicable.

--

Tim Wescott 
Wescott Design Services 
http://www.wescottdesign.com
Reply to
Tim Wescott

That is why papers often use pseudo code rather than real code that can be copied.

How about a comment that you shouldn't be doing this unless you actually understand what is happening?

--

Rick
Reply to
rickman

I was going to make that comment, but then I recalled the term my professor actually used was "difference equations". "Differential equations" means something else, no? I couldn't find any sources on this, so I didn't make the comment. It's been far too long to trust my memory.

--

Rick
Reply to
rickman

Yes, I understand a real system may be more complicated. But as I've said before, if I can't understand what an equation means, I have a very hard time understanding how to use it. I just need to "get" the equations you use as examples. This one eludes me and you seem to be saying you sort of made it up without a physical basis. You said you invented not one, but two time constants.

--

Rick
Reply to
rickman

Here's how you use that equation within the intended context of the paper:

  • Look at it.
  • Say "oh, it's math".
  • move on.

Seriously. If you're not trying to duplicate the examples, you _do not need the math_. That's the point of the paper.

--

Tim Wescott 
Wescott Design Services 
http://www.wescottdesign.com
Reply to
Tim Wescott

Because then you would never start. Possibly 90% of the control loops in the world are implemented by people who have no greater understanding of control theory than what's presented in that paper. I'm not trying to turn people into control engineers, I'm trying to supply a pragmatic solution to a large class of real-world problems.

--

Tim Wescott 
Wescott Design Services 
http://www.wescottdesign.com
Reply to
Tim Wescott

"Differential equations" are what you need to describe things in a continuous-time world (the three equations in the paper are differential equations).

"Difference equations" are what you need to describe things in a discrete- time world.

--

Tim Wescott 
Wescott Design Services 
http://www.wescottdesign.com
Reply to
Tim Wescott

Lots of high frequency rolloff and even more high frequency phase shift. In thermal diffusion, you get another radian for every 1/e amplitude decay, which makes PID kind of disappointing IME.

My TC loops are always pretty simple--diode lasers on TECs, or resonators with a heater--but after the nonlinearity is taken out, I can usually get away with a plant model of a time delay followed by an integrator. You can read the parameters right off the scope trace. I'm perfectly sure that was invented a very long time ago, but it works great for smallish stuff.

Cheers

Phil Hobbs

--
Dr Philip C D Hobbs 
Principal Consultant 
ElectroOptical Innovations LLC 
Optics, Electro-optics, Photonics, Analog Electronics 

160 North State Road #203 
Briarcliff Manor NY 10510 

hobbs at electrooptical dot net 
http://electrooptical.net
Reply to
Phil Hobbs

I may change my model.

Probably the most important temperature loop I've ever closed (the temperature of a focal plane array, cooled by a split-cycle Stirling cooler) had a simple 1st-order dominant pole, with no discernible excess phase shift or attenuation until well past the practical loop closing frequency. I was happily astonished.

--

Tim Wescott 
Wescott Design Services 
http://www.wescottdesign.com
Reply to
Tim Wescott

ChuckE2009

formatting link
mig welding
formatting link
stick welding
formatting link
tig welding

Reply to
DJ Delorie

Plus you were a hero. It's nice when things work out that way.

One time when I was a post-doc, a colleague needed a notch filter to get rid of a 30-kHz resonance in the piezo tube actuator of the STM he was building. I reached into my bench drawer, pulled out a largish Pulse Engineering transformer, and parallel-resonated both sides with a 0.1 uF cap on it, just as a first try.

Stuck a sweep generator and scope on it, and what came out was a nearly symmetrical two-bump notch exactly at 30 kHz, with a Q of about 30.

Then of course I just quietly handed it to him, smiled, and went back to work. Never did let slip that it was a total fluke. ;)

I still don't know where the beautiful two-bump notch shape came from--leakage inductance and capacitor tolerance, I suppose.

Cheers

Phil Hobbs

--
Dr Philip C D Hobbs 
Principal Consultant 
ElectroOptical Innovations LLC 
Optics, Electro-optics, Photonics, Analog Electronics 

160 North State Road #203 
Briarcliff Manor NY 10510 

hobbs at electrooptical dot net 
http://electrooptical.net
Reply to
Phil Hobbs

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.