As indicated in the begining of the text, it is not the appropriate place to
learn about Laplace Transforms or Steady State Stability, but it is a very
well written introductory text on PID control.
I didn't check the algorithm, but one note I'd make is to better display the
code, using identation. Being really nitpick, different color for comments,
but that's already too much.
One issue I have with heavily math based explanations is that the authors
(And I have tended to be one as well) think that the math does most of the
description. It is true, of course, that it does, but I find that if I am
not "in deep" into the math of a specific problem, or have not used my
"math skills" recently, it takes a lot of focus and thinking really
understand and visualize it. More often than not, I'll find myself
PID is fundamentally simple math but with really complex behavior. (Isn't
that always the way?) I wanted to be able to explain PID to a "highschool
kid." This was my attempt.
I'll consider it, but I'm not sure I agree. If a few more people have the
same aesthetic comment I probably will. It is just that I find colored text
difficult to read.
As for the algorithm, it works pretty well. It does a fairly good job
compensating for variability of sample intervals and the robot goes
basically straight. I don't see any position error in the wheels, as I have
run them for a couple hours and a couple chalk lines on the wheels kept in
sync. It certainly works well within the margins of error inherent in a
: Padu wrote:
: > the code, using identation. Being really nitpick, different color for
: > comments, but that's already too much.
: I'll consider it, but I'm not sure I agree. If a few more people have the
: same aesthetic comment I probably will. It is just that I find colored text
: difficult to read.
Since I generally print things to read, color doesn't make a different to
me. On the other hand, a version to print without the sidebar would be
appreciated. :-) Otherwise, it's lynx -dump and a pure-ascii version.
Chris Candreva -- email@example.com -- (914) 967-7816
Now that's an idea I'll consider. While I want to keep the ads and such so
maybe I can get some money out of it, I can easily add a "Printer Friendly"
(That url will probably change if I add the printer friendly version.)
It's always good to see somebody adding robotics information
to the web. I hope you'll continue.
I did have a suggestion. While I would not encourage you to
go overboard on the math, I do think that a few simple, well-chosen
equations might do a lot to clarify what you're doing, perhaps
even more so than the code examples. Believe it or not, there are
people who find syntax like "virtual ~PIDControl();" more opaque than
a partial differential equation (well, maybe not a partial differential
So I don't think that you need to be any more reluctant about
posting equations than you are about posting code.
Anyway, to see what I mean about using equations,
consider the image at
Now the equation uses calculus notation which I think that you
could reasonably avoid. But if you look at the equation for a
minute or so you might find yourself asking something like
"why is the derivative term positive instead of negative".
Well, the article I referenced does something a little non-standard.
But the point is that the relationship between the P, I, and D
terms is more apparent in the equation than it would be in code.
That positive/negative sign issue would be totally swallowed up
in code. In the equation it is available for inspection.
Finally I don't know who persuaded the software community
that using a leading "m_" for all member variables
was a good idea, but I've never cared for that convention. Reading
code is hard enough without extra clutter thrown in. Of course, that's
just my personal taste (not everyone likes Reggae music either).
But just as an experiment some time, I propose that you do the
following. Take a moderately dense, non-trivial class and
do a global search and replace to remove the prefix. Then ask
yourself which is easier to read.
Again, thank you for making your helpful addition to our
collective robotics knowledge base.
For those people there are plenty of treatments of PID. I'm focusing on
programmers that may or may not know the math, but are certainly more
comfortable with abstract concepts.
I'm not reluctant to post the equations, it is just that there are so many
PID descriptions heavily steeped in math that I wanted this one based only
on the abstract concepts. I guess my feelings were that if you needed or
wanted more math, you can back it up with something else, but if you are
put off by the math, then you would be ale to read it.
Does that make sense?
Interestingly, for me at least, maybe I'm strange, I don't know, but I need
more conceptual information. An equation does not impart the concepts as
much as a graph or description.
For me, it is concepts first, reinforced with theory. Many people claim to
learn with theory first, but my brain doesn't seem to work that way.
I think it is a great convention (obviously, I use it) because I know,
without looking anywhere else, that any variable that starts with "m_" is
part of my current object. If used consistently, it is a fantastic tool to
avoid many coding problems, especially if you intend other people to read
and use your code.
Perhaps C++ should have required "this->var" syntax, which does work, but
there should be a way, either enforced by compiler or convention, to
differentiate between "member" variables and local/global variables.
I also have some useful habits left over from my Windows programming days,
namely incorporating the variable type into the variable name, like szName
is a zero terminated string, pVar is a pointer to a var, etc. Not all of
the "hungarian" notation, but a small subset of it.
Sorry, I have written and read too much code in my life to even bother. Do
code reviews, QA code audits, and manage a several large software projects,
you'll take back everything you said. The "m_" like "sz" or "p" or "n" or
any naming convention for that matter does take time to get used too, but I
find that variable names without this information are confusing because
they don't carry enough information about themselves.
Take, for instance:
m_szId = 0;
What is that? Easy.. It is a zero terminated string that is a member
variable of my current object. I'm setting it to zero so I know that it has
no value. (A string set to 0 or NULL has no value). A simple naming
convention makes that variable self documenting.
Now how about this:
id = 0;
What is it? Where is it? Why am I setting it to zero? Is "0" the "id?" Is
"0" an uninitialized state?
My gripe with open source is that they tend not to use naming conventions
and it is hard to get familiar with other people's code.
What's really funny is that I don't know if any of my text books are still
in print! (or where they are after the last couple moves) I wrote my first
PID algorithm in the late 70s and while I learn something new every time I
write a new one, I haven't needed a book or reference to do so in over 20
If I knew I was going to live this long I would have take better care of my
My commenting on a coding convention was a mistake because it
diverted attention from the real intention of my post which was
to thank you for your work and make a suggestion about adding a
few equations to your text. Based on your reaction, perhaps I did
not make my point clearly. I was not arguing for a mathematical
treatment of PID... Those have their place but I, at least, am more
comfortable with the non-mathematical treatment of a subject
especially when I'm just getting started. I doubt many people
would feel otherwise. So let me make one last
attempt to clarify what I was saying. I'll do so with an example.
The Classical Greeks didn't have algebra. So everything they did in
geometry was stated in sentence form. You really have to admire how
much they were able to accomplish with what must often have been
an awkward way of expressing mathematical concepts. Consider the
following statement: "the sum of the squares of the sides of a right
triangle is equal to the sum of the hypotenuse." Now consider the
"a^2 + b^2 = c^2".
Now the algebraic statement makes no sense at all without the
plain-text statement. But once you have the plain text in mind, it
sure does make it easier to remember (and use).
Equations do not take the place of a good explanation. Actually,
don't explain anything. What they do accomplish is to give us an exact
formulation of an idea. They can also be manipulated and put into
alternate forms that reveal nuances that might otherwise be non-obvious
in a textual form. A non-calculus statement of the PID
PID = A * ProportionalError + B * IntegralError - C * DerivativeError
instantly reveals that there is a role for arbitrary coefficients mixed
in with real-world measurements. Seeing that, your reader might ask
"Hmmm, I wonder where they come from?" In your article, it might
have served as a seque to a discussion of tuning parameters.
So, the essence of my suggestion was simply that you consider
two or three well-placed equations to clarify the relationships you
describe in your text. I did not mean to suggest that you fundamentally
alter your approach. Only to suggest that there were ways to reinforce
Perhaps, but "computer science" is a topic I really take seriously. My first
teacher in the 70s was an ex-navy programmer, and she approached the
subject as a math and a science. A math in that concepts are provable, and
a science in that it is something you need to study and learn. Even back
then, she as adamant that a "good" program is one that works, works
efficiently, and can be understood by someone else.
I don't necessarily propose that everyone use the naming convention that I
use, quite the contrary, but there should be some effort in the open source
community to use one. <rant>a lot of the Open Source guys are very very
bright but lack the discipline to make "good" (see above) code.</rant>
Actually, I like the verbal description better :-)
The PID initials are not quite enough, my implementation is basically this:
POW = (((E*E_GAIN) + (I*I_GAIN) + (D*D_GAIN)) * SCALE) + BIAS
POW = The calculated output power
E = The current positional error
D = The differential of the last error
I = The integration of the error
PE = The previous error
SCALE = The "scale" of the calculation based on elapsed time since last
BIAS = The offset to "zero" for POW plus acceleration
The actual algorithm is sort of an amalgam of PID and other control stuff.
The SCALE factor is used to adjust the output calculation for a variable or
indeterminate sample period. As long as it samples fast enough, it works.
The BIAS allows for two things, first, systems that "stop" or zero output
is not numerically zero, second, if you are accelerating, You can tweek the
output power up or down in anticipation of a change in speed for the next
However, this is all described clearly in the code :-)
Seems to be some difference of opinion here as to the
common PID capabilities of mobile robots, and specifically
as to the performance of hobby mobile robots.
Here's a few hobby robots that can accomplish the trivial
PID tasks of maintaining constant velocity while moving from
a low to high friction surface, responding smoothly to abrupt
changes in the control stream, as well as abrupt changes in the
This is a video of the six-wheel robot posted previously.
Here's its homepage:
This one's a standard two-wheel differential drive with a
This one's a LEGO robot.
Even the LEGO robot has all the capabilities that have been
referred to in this thread as precision capabilites that
are supposedly outside the realm of hobby robot builders.
I politely and respectfully disagree.
enjoy your Sunday,
You seem to be confused as to what was said in another part of this thread.
The "PID" algorithm is only part of a much larger system, like PLL on an FM
receiver, it only provides the closed loop feedback control for a larger
The $500 robot's PID control system maintains pretty good velocity control
over a wide range of loads within the capabilities of drive system. On a
clean regular surface, it drives straight, rotates 90 degrees when
programmed opposing 45 degrees on each wheel. Just like any other dual
wheel system would. Drive it on rugs and hard wood floors, its kind of
funny to watch.
The problem is that, even though it is as precise as the encoders make it,
the wheels are not, the floor isn't, and the contact between wheel and
surface is not always assured. Wheels slip and drift, this is a common
problem in all mobile robots.
When a wheel encounters a run on the floor, if you push too hard, it just
spins in place, if you push more slowly you maintain friction and travel
over the run. Remember, the robot weighs about 50 lbs, this is not a
trivial control application like mindstorms or other microbots.
One can move a wheel exactly one revolution, but that does not mean that you
will move PI*R distance.
PID is one of those "mystery things" that really isn't all that mysterious.
I think it is somewhat related to the necessity to look at the granularity
of a problem that is being solved. It seems the smaller the time granules,
the harder it is for a lot of people to understand.
The one thing that I see that MLW has done that obfusicates things is
polling the error asynchronously. This is ok in a PID loop, but greatly
complicates other transfer functions. Generally, PID is performed
synchronously. In the least, it allows easy graphing of the results, in the
worst, it makes implementing other transder functions easier.
I still haven't had the time to filter through all these threads and
determine why there is no limit term on the integration. If I had the choice
of implementing either an integral limit, or simple feedforward, I would
have chosen the limit.
On a side note, gains are generally referred to as Kp, Ki, Kd.
I have seen MLW direct a lot of hostility towards DPA. Unfortunately, DPA is
a robotics God, up there with the likes of Alex G. Dan M. and Gordon M. , he
just doesn't show his face here that often. I doon't care how long anyon has
been doing this as a profession blah blah blah, there is a lot to learn from
the masters of the craft. I hope that this doesn't dissuade DPA from
interjecting his wisdom into this otherwise wilted corner of Usenet.
What is the advantage of a cheap laser with a line making lens over a cheap
laser with just the usual dot output? Isn't this going to be used as a
rangefinder by finding the dot on a video frame? Or something more
Polytechforum.com is a website by engineers for engineers. It is not affiliated with any of manufacturers or vendors discussed here.
All logos and trade names are the property of their respective owners.