[ODE] Simulating a Human Leg

Adam Rotaru adam_rotaru at yahoo.com
Sun Feb 10 16:32:01 2002


--- Gene Ruebsamen <gene@erachampion.com> wrote:
> I am trying
> to model a simple bipedal humanoid in ODE. My
> question is, is using a
> Ball & Socket joint the way to go to simulate where
> the upper leg
> connects to the Torso??
> 
> I am using a hinge joint with stops to simulate the
> knee, and where the
> torso connects to the leg, I am using a ball &
> socket joint. The problem
> with the ball & socket is it seems like there is
> nothing to constrain
> its degrees of freedom. I tried using an AMotor with
> the ball & socket
> joint, but is that the way to go?


I was thinking about the same problem: a limb joint
such as the
pelvis-thigh joint needs to allow bending
forward/backward 
(flexion/extension), bending outwards and invards
(abduction/adduction),
but limit rotation.  It would be good if it allows
some rotation,
but definitely not too far.
Here are the approaches I came up with:

1) Two hinge joints with perpendicular axes, with a
small, 
dummy object in between.
This works, but requires two joints and an extra body,
which
might be relevant for performance.  Also, the dummy
part 
needs to have a small, but non-zero mass (0 doesn't
work).

2) A hinge2 joint.  A hinge two joint is supposed to
be two 
hinge joints connected in serial (similar to the above
setup),
but implemented more optimally.  Unfortunatelly, I
found that
hinge2 is not entirely general, but it is optimised
for setups
used in wheel suspensions, namely that one axis does
limited 
rotation and the other does more.  Some functions are
not available
for the second axis (such as getting the current
angle), which make
the use of this joint type somewhat limited.

3) A ball-and-socket joint (for the position) plus an
AMotor
joint between the same parts.  I found out about 
the AMotor joint only recently, and it seems
promising.
As for the axes, I tried out two combinations.
3a) user mode, using two axes: the Z axis of one part,
and
the Z axis of the second part.
3b) Euler mode, axis 0 is axis X of body 1, axis 2 is
axis
Y of body 2.  I control this last axis.

Of all these, I'm still not sure which is the best. 
Currently
I lean towards 3b.

Below is some code snippet for 3a and 3b.
Any thoughts welcome!
I have a small but complete test program, i cans end
it/post it
if you or somebody else wants it.

cheers, 
  Adam

----------------------------------------

    {
      arm->joint[1] = dJointCreateBall(world, 0);
      dJointAttach(arm->joint[1], arm->body[0],
arm->body[1]);
      dJointSetBallAnchor(arm->joint[1], x, y, z);

      dJointID j2 = dJointCreateAMotor(world, 0);
      dJointAttach(j2, arm->body[0], arm->body[1]);

      dJointSetAMotorMode(j2, dAMotorUser);
      dJointSetAMotorNumAxes(j2, 2);
      dJointSetAMotorAxis(j2, 0, 1, 0, 0, 1);
      dJointSetAMotorAxis(j2, 1, 2, 0, 0, 1);
      float FMax = 0.001;
      float jStop = 0.2;
      dJointSetAMotorParam(j2, dParamLoStop,  -jStop);
      dJointSetAMotorParam(j2, dParamHiStop,   jStop);
      dJointSetAMotorParam(j2, dParamFMax,     FMax);
      dJointSetAMotorParam(j2, dParamBounce,   0.0);
      dJointSetAMotorParam(j2, dParamVel,      0.0);
      dJointSetAMotorParam(j2, dParamLoStop2, -jStop);
      dJointSetAMotorParam(j2, dParamHiStop2,  jStop);
      dJointSetAMotorParam(j2, dParamFMax2,    FMax);
      dJointSetAMotorParam(j2, dParamBounce2,  0.0);
      dJointSetAMotorParam(j2, dParamVel2,     0.0);
    }

----------------------------------------

      arm->joint[1] = dJointCreateBall(world, 0);
      dJointAttach(arm->joint[1], arm->body[0],
arm->body[1]);
      dJointSetBallAnchor(arm->joint[1], x, y, z);

      dJointID j2 = dJointCreateAMotor(world, 0);
      dJointAttach(j2, arm->body[0], arm->body[1]);
      dJointSetAMotorMode(j2, dAMotorEuler);
      dJointSetAMotorAxis(j2, 0, 1, 0, 1, 0);
      dJointSetAMotorAxis(j2, 2, 2, 0, 0, 1);
      float FMax = 0.001;
      float jStop = 0.2;
      dJointSetAMotorParam(j2, dParamLoStop3, -jStop);
      dJointSetAMotorParam(j2, dParamHiStop3,  jStop);
      dJointSetAMotorParam(j2, dParamFMax3,    FMax);
      dJointSetAMotorParam(j2, dParamBounce3,  0.0);
      dJointSetAMotorParam(j2, dParamVel3,     0.0);

----------------------------------------



__________________________________________________
Do You Yahoo!?
Send FREE Valentine eCards with Yahoo! Greetings!
http://greetings.yahoo.com