[ODE] Servo to reach a target position

David Whittaker david at csworkbench.com
Thu Apr 10 21:41:02 2003


Truthfully, my thoughts are that once we get back to ODE, and away from a
general PID algorithm, I and D both lose all value.  In fact, I would say
that Ki and Kd are replaced by fmax, and the fact that we change velocity
(a time *derivative* of position) to arrive at an end position.  All that
is needed is the Proportional part of the algorithm, and the limit on
force (fmax) keeps it smooth.  Since the joints are implemented as
constraints, and the entire purpose of the solver (dWorldStep) is to find
a configuration that satisfies all the constraints, you really do have a
"perfect" system to work with from the outside.

With that said, there are a few cases where a P-only algorithm would fail:
a) there is not enough force (fmax) to get past friction, gravity, etc.
b) there is another object in the way
There are two possible solutions to either one of these problems:
a) increase fmax (for b, this would push the object out of the way)
b) it was physically impossible to start with... you can't improve a
process that there is not enough power to do with better control.

The point is, any function that converges on 0 when error is 0 will work
and the velocity/fmax combo will do the job of smoothing things out.

So, there's my justification for thinking that you'll never use the ID
part of the PID algorithm.... fmax provides all the rest of
customizability you'll need, unless you want to get into varying both fmax
and velocity dynamically, but that's a whole other discussion.  However,
with a bit more thought, here's what I've come up with as far as using Dt
in the I and D functions:

I = you do need to multiply in Dt here for the reasons you stated.
D = uses the change in error.  If you used half the timestep last step,
then your error would have changed by half as much.  Which is what you
want... no Dt here.
How about P???  In a simplified direct feedback loop (PV = OP), Kp can be
thought of as the percentage of error to fix next step.  i.e. if Kp = 0.5,
you'll go half the distance to the setpoint each step under a P-only
controller.  Now let's take the CPU A: timestep = 0.01, CPU B: timestep =
0.02 example.  Say you reach a negligible amount of error in 100 steps on
CPU A.  To get to the same amount of error on CPU B, it will take.... 100
steps.  However, on CPU A, 100 steps takes 1 second, but on CPU B, 100
steps takes 2 seconds.  So you need to multiply by Dt for P and I (which
both use the Error directly) and not for D (which uses the change in
Error, where Dt is implicit).

A final note: the more I think about it, the more I realize that a
(non-powered) joint with stops is already a pretty decent controller.  You
can set the Low and High stops to the same setpoint, then adjust StopERP
to act (exactly) like a Kp parameter.  FMax keeps things from happening
way too fast.  You just don't get the advantage of being able to cap the
speed off before it gets sent on to the joint.  Only the acceleration
(through fmax).

David

> Hello David,
>
> You're welcome!
>
> However, I think I owe you an apology. You've gotten me to really
> think about exactly how PID works, and I think I was wrong in
> dismissing your use of dT. In the argument I presented, I only dealt
> with the P term.
>
> I think, to be perfectly technically correct, you need to incorporate dT
> for I and D ( multiplying for I and dividing for D ). I will caveat all
> this with the fact that a well-tuned process running at a decent update
> rate will have no need for dT, we're only talking about being perfectly
> "correct". However, when talking about game development, there is a
> wider range of update times the code will see, as opposed to industrial
> equipment where the update rate is solid. So, if you happen to want to
> model a system that is very sensitive, you could run into an issue where
> it works fine on one computer, but not on the
> next.
>
> To present an example:
>
> We have to CPUs, running at different speeds. CPU A's dT is .01 and CPU
> B's dT is .02.
>
> without dT, CPU A's I term will react faster, causing a need for less
> Ki, which is not what we want. Multiplying E by dT would cause A's I to
> accumulate at the same rate in real-time.
>
> Dividing by dT for D is a little more tricky, tho. The only thing I can
> think of is this: a system that updates more often can afford to throw
> out more D to compensate for change in E because it will be back sooner
> to take it out as E stabilizes. On the flip side, a slower
> system can't afford to have D too high, because if it reacts hard, it
> won't be back as soon to fix the problem, leading to instability.
> However, I'm not quite convinced of this argument. The only reason I'm
> leaning more towards it than against it is b/c it doesn't make sense to
> apply dT to I but not D.
>
> If it's any consolation, PID looks simple on the surface, but I've seen
> it as a source of heated debates. People can't even agree on the math to
> use. One of the links you can find doing a search on PID will explain
> that there are at least 3 different *common* ways to code PID. It's
> further complicated because the way hardware PID algos work
> doesn't match mathematical PID algos, at least as far as the I term
> goes.
>
> Any thoughts?
>
> --
> Royce3
>
> _______________________________________________
> ODE mailing list
> ODE@q12.org
> http://q12.org/mailman/listinfo/ode