[ODE] Servo to reach a target position

Gary R. Van Sickle g.r.vansickle at worldnet.att.net
Thu Apr 10 05:34:02 2003


PID controllers (or as Royce3 indicates some subset thereof) are definitely the
way to go here.  I use them for this very thing and they work well, controlling
into the velocity term while sensing the position.  I tried to control torque
first, but that didn't work well, probably because I never took the time to try
to actually tune the PID parameters.  Using velocity instead, while not as
physically correct in my application, has the advantage of taking an integral
out of the loop and therefore making the system much more tolerant of sloppy
tuning.  Definitely fix the stops though; moving them around can't be a good
thing.

PID (Proportional-Integral-Derivative) controllers are the workhorse of control
theory (which is the field you're getting into here).  The site Royce3 mentions
is a pretty good intro, and there will be no shortage of similar sites Google
will come up with.

--
Gary R. Van Sickle
Brewer.  Patriot.

> This is basically the first term of a PID equation. I have written
> controls for various real-world servos, and I use PID loops exclusively.
>
> The would obviously work very well here, also.
>
> Here's a URL I found for you in a quick search on Google:
>
> http://www.jashaw.com/pid/tutorial/
>
> If anybody's interested, I wrote a generic PID algorithm in C++ a
> while back. I could dig it up and send it to the list.
>
> Royce3
>
> >
> >Subject: Re: [ODE] Servo to reach a target position
> >   From: <david@csworkbench.com>
> >   Date: Wed, 9 Apr 2003 13:24:12 -0500 (CDT)
> >     To: <ode@q12.org>
> >
> >Setting both velocity and stops is rarely a good idea, and since your code
> >is basically replacing the functionality of stops anyway, I recommend you
> >don't use them.  Something like this (before each step):
> >
> >fmax = constant_fmax
> >if (scale_factor * fabs(target_pos - current_pos) < constant_velocity) {
> >  velocity = scale_factor * (target_pos - current_pos)  //for a smooth stop
> >}
> >else if (target_pos > current_pos) {
> >  velocity = constant_velocity
> >}
> >else {
> >  velocity = -constant_velocity
> >}
> >
> >The first if statement lowers the velocity when you get close to the stop,
> >and the scale_factor determines how close you have to be relative to the
> >velocity.  We make it relative to the velocity so it will have a smooth
> >transition from the constant_velocity to the first calculated velocity.
> >You might even want to use a more complex function (like squaring the
> >calculated velocity) to "round off" the slowing down segment of the
> >stop... just remember that whatever you put to the right of velocity =
> >(well, in the third parameter of dJointSetParam), put the absolute value
> >of that to the left of < constant_velocity in the if statement.
> >
> >This method keeps you from getting to constant_velocity*timestep/2
> >distance from the target one step, then jumping to the other side on the
> >next step and oscillating back and forth.  I would also assume that real
> >servo controllers use similar techniques since they can't physically set
> >the servo velocity to 0 and expect the structure to react instantaneously.
> > It also means that loads placed on the system arent handled by a
> >full-power push back towards the target, but a slight nudge (which is all
> >you needed to start with).
> >
> >
> >Your other (simpler) option is to keep velocity at 0, set fmax to a
> >reasonably low value, and set both the low and high stop to the target
> >position.  ODE will add up to FMax force at the correct angles to both
> >satisfy the joint and move it towards the stops.  But you lose control
> >over velocity in this method.  And I'm not exactly sure how it would
> >handle loads.... You could always try both methods and see which one you
> >like better.
> >
> >David
> >
> >> Hello,
> >>
> >> I have a servo motor and I want it to reach a target position.
> >>
> >> The servo is implemented as a hinge and it seems to me that in ODE
> >> hinges are controlable either by applying a torque on the body (tricky
> >> and dangerous according to the ODE manual), or by specifying a target
> >> velocity (dParamVel) and a maximum torque (dParamFMax).
> >>
> >> Since I just want to achieve a target position, I was considering
> >> setting the following:
> >>
> >> dParamFMax: to define the maximum acceleration.
> >> dParamVel: to define the target speed.
> >> dParamHiStop or dParamLoStop: to define the target position.
> >>
> >> My control program should read the current position of the servo and
> >> compute the following:
> >>
> >> // set dParamFMax to a constant value
> >> if (target_position > current_position) {
> >>   // set dParamVel to a constant positive value
> >>   // set dParamHiStop to target_position
> >>   // possibly set dParamLoStop to current_position
> >>   // run until target_position is reached
> >> }else {
> >>   // set dParamVel to a constant negative value
> >>   // set dParamLoStop to target_position
> >>   // possibly set dPareamHiStop to current_position
> >>   // run until target_position is reached
> >> }
> >>
> >> Does this sound to be the right way to do position control on servos ?
> >> Are these any issues I should be aware of ?
> >>
> >> -Olivier
> >>
> >>
> >> _______________________________________________
> >> ODE mailing list
> >> ODE@q12.org
> >> http://q12.org/mailman/listinfo/ode
> >
> >
> >
> >_______________________________________________
> >ODE mailing list
> >ODE@q12.org
> >http://q12.org/mailman/listinfo/ode
>
> _______________________________________________
> ODE mailing list
> ODE@q12.org
> http://q12.org/mailman/listinfo/ode