[ODE] motors vs. torques (was: hexapod walking example)

Nate W coding at natew.com
Fri Dec 28 20:41:02 2001


On Fri, 28 Dec 2001, Adam Rotaru wrote:

> First, could someone tell me what is a PD and PID
> controller?

They are basically different types of feedback functions.  The letters
refer to Proportional, Integral, and Differatial terms in the functions.  

A web search on "PID feedback control" will probably turn up some
interesting reading.

> For my hexapod first I tried to use the provided motors, but I
> scrapped them.  I have to admit that I don't understand fully how they
> work, and had some prejudices against the motors. 

I felt exactly the same way myself.  However, I've tried it both ways now
and motors are much easier to tune, the simulation is much more stable,
and I still get the results I want.  Basically, everything Russ said they
would be.  :-)

> For example, to use my bug, even if the bug is standing, some torque
> (force) must be applied so that the leg keeps the body.  What should I
> set my desired velocity?  If I set to 0, will that cause a
> force/torque? If I set to a fixed positive value, I have to oscillate
> as the as the position oscillates around my desired position.

Oscillation is generally a symptom of a feedback system with too much
gain.  If you see oscillation, try scaling your forces down.

My motion system is work well now, so I can share some actual code this
time around...  It's based on a variable called "phase" that cycles from 0
to 2*pi, at a rate of about once every three seconds.  From this I call
sin(phase) to get a number that oscillates smoothly between -1 and
+1.  Then I use that oscillator to compute a desired joint position.  The
code looks about like this:

if (rPhase > (Generic::rPi * 2))
	rPhase -= (Generic::rPi * 2);

// rAmplitude determines the joint's range of motion, e.g. +/- 30 degrees
rDynamicOffset = sin (rPhase) * m_rAmplitude;

// StaticOffset shifts the joint's entire range of motion from the angle
// the joint was at when the simulation started
rDesiredAngle = m_rStaticOffset + rDynamicOffset;

// This is basically a wrapper around dJointGetHingeAngle
rPresentAngle = pRevoluteJoint->rGetAngle ();

// Compute the desired joint velocity
rVelocity = m_rGain * (rDesiredAngle - rPresentAngle);

// Pass that to the motor
pRevoluteJoint->vAddForce (rVelocity, m_rMaxForce);

"AddForce" is a holdover from when I was applying torques to bodies
directly, now it's actually a wrapper for:

dJointSetHingeParam (m_JointID, dParamVel, rVelocity);
dJointSetHingeParam (m_JointID, dParamFMax, rForce);

It works really well.  I have a quadruped walking around another window
right now, the motion is very smooth and a little bit springy, which is
just what I wanted.  

> - if I need to account for the energy (work) used to actuate the
> joint, can I obtain the work consumed of the motors?

Great idea.  Russ, is that feasible?

-- 

Nate Waddoups
Redmond WA USA
http://www.natew.com