[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