[ODE] Servo to reach a target position

Royce Mitchell III Royce Mitchell III <royce3 at ev1.net>
Thu Apr 10 22:49:02 2003


Thursday, April 10, 2003, 11:37:41 PM, you wrote:

> 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.

As long as you "constrain" ( sorry couldn't resist ) yourself to
modeling simple systems this will remain true. When you start to get
into multiple levels of abstraction, you may find that P isn't enough.
For example, say you wanted to control speed in an AI race car driver
by controlling whether he's pressing gas or brake, and how much force
to apply to each ( and modelling how long it takes foot to react to
request, etc ), and I think you could easily end up needing more than
just the P term.

Basically, if you ever find that you can't get something to "settle
down" control-wise, you have found a situation that needs more than
just P. I don't pretend to know all those situations.

> 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.

This isn't a P problem, it is a torque problem, as you stated. The I
and D terms are used to stabilize tricky systems. Raw power is
delivered through P only.

> 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.

When dealing with floating point, even inside the clean CPU, things
never work out to 0 in control situations :)  Just look at the silly
example I sent with the source.

Besides, in a speed control, your output doesn't converge on 0, it
stabilizes at an output that gives you your desired speed.

> 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.

You have to think about what D is for. D back-compensates fluctuations.
Say you're running along nicely and suddenly hit an ice patch that
causes your engine to rev up due to lack of friction. D-term would
help greatly minimize that by responding to the sudden change in
error. Please forgive my arrogance but I think you misunderstood what
I was trying to say about D needing dT. D is a very temporary, very
small adjustment. Too much D makes things go crazy. If you want I can
create a simple app that let's you play with the #'s and see their
effect.

> 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).

In a position controller, we calculate E which tells us how far away
from our target we are. We then generate a command that tells the
system how fast we need to be going *at the moment*. Think about this:
If you're on a highway, and you're 2 miles from your exit, how fast
are you gonna go? Does it matter how often you think about how fast
you should be going? No, until you get close, you are going to go your
maximum comfortable speed. As you approach, let's say you're 100 ft
from your exit. You should probably be going appx 45 mph at this
point. Does it matter how often we check the speed to determine that
we need to be going about 45 when 100 ft from the exit? Generally
speaking, your control algo will be *way faster* than the system's
response time, and that's why dT has never come up before. I was
trying to figure out what was mathematically correct. However, I don't
think it's a real-life issue, unless you run into a *very* responsive
system with respect to it's controller. That probably boils down to
too much Kp anyways. This is probably a dead horse we're kickin'... ;)

> 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).

I haven't had a chance to do anything with ODE yet, but you definitely
want to cap the speed off in certain situations. I can't think of any,
but I can imagine there would be situations where you wouldn't. Of
course, in RL, there's always a limit to what we can send. My analog
card can't put out any more than 10 volts, for example. Your gas petal
only goes so far until it's "to the metal".

--
Royce3