[ODE] Ball and Socket or (Universal +Hinge)

Brian Dexter Allen chokma at gmail.com
Tue Apr 11 11:13:00 MST 2006


On 4/10/06, Jaap Stolk <jwstolk at gmail.com> wrote:
> On 4/11/06, Brian Dexter Allen <chokma at gmail.com> wrote:
> > Right, I don't believe the Angular Velocity info is (easily) available
> > from the API.  For my AMotors (I'm also doing controlled humanoids) I
> > just settle for comparing the current angle to the previous, which
> > works fine for small time-steps and smooth motion.  That said,
> > retrieving the current angle works fine for Euler-mode AMotors.  FWIW,
> > I'd be happy to send you my setup for ball-and-socket joints with
> > Euler AMotor drivers if you might find it useful.
>
> yes that would help me a lot.

Here's a code snippet from my project, hope it can help.  It's been
working alright in practice, but I'm no expert.  Assumes +y up, +z
forward and a right-handed system.

	myJointGroupID = 0; //dJointGroupCreate( 0 );
	dJointID spine = dJointCreateBall( myWorldID, myJointGroupID );
	myJoints[Spine] = spine;
	dJointAttach( spine, myBodies[Trunk], myBodies[Waist] );
	dJointSetBallAnchor( spine, 0, .582 * ht, 0 );
	dJointID spineMotor = dJointCreateAMotor( myWorldID, myJointGroupID );
	myMotors[Spine] = spineMotor;
	dJointAttach( spineMotor, myBodies[Trunk], myBodies[Waist] );
	dJointSetAMotorNumAxes( spineMotor, 2 );
	// zeroth axis is y and anchored to the trunk
	dJointSetAMotorAxis( spineMotor, 0, 1, -1, 0, 0 );
	// second axis is z and anchored to the waist
	dJointSetAMotorAxis( spineMotor, 2, 2, 0, 0, 1 );

	// zeroth axis (Y) stops  (shoulder-to-shoulder rotation axis)
	dJointSetAMotorParam( spineMotor, dParamLoStop, M_PI / -16.0 );
	dJointSetAMotorParam( spineMotor, dParamHiStop, M_PI / 16. );
	dJointSetAMotorParam( spineMotor, dParamFudgeFactor, myJointFudgeFactor );

	// Transverse Axis
	double transverseSpineMin = theConfig->getFloat(
"SpineTransverseMinRange", M_PI / -16.0 );
	double transverseSpineMax = theConfig->getFloat(
"SpineTransverseMaxRange", M_PI /  16.0 );

	dJointSetAMotorParam( spineMotor, dParamLoStop2, transverseSpineMin );
	dJointSetAMotorParam( spineMotor, dParamHiStop2, transverseSpineMax );
	dJointSetAMotorParam( spineMotor, dParamFudgeFactor, myJointFudgeFactor );
	// second axis (Z) stops (twist axis)
	dJointSetAMotorParam( spineMotor, dParamLoStop3, M_PI / -16.0 );
	dJointSetAMotorParam( spineMotor, dParamHiStop3, M_PI / 16.0 );
	dJointSetAMotorParam( spineMotor, dParamFudgeFactor, myJointFudgeFactor );

	dJointSetAMotorMode( spineMotor, dAMotorEuler );

	dJointSetAMotorParam( spineMotor, dParamFMax,   spineResistanceForce );
	dJointSetAMotorParam( spineMotor, dParamBounce, 0.01 );  // 1 is max bounce.
	dJointSetAMotorParam( spineMotor, dParamVel,    0.0 );  // initial
	dJointSetAMotorParam( spineMotor, dParamFMax2,   spine2ResistanceForce );
	dJointSetAMotorParam( spineMotor, dParamBounce2, 0.01 );  // 1 is max bounce.
	dJointSetAMotorParam( spineMotor, dParamVel2,    0.0 );  // initial
	dJointSetAMotorParam( spineMotor, dParamFMax3,   spine3ResistanceForce );
	dJointSetAMotorParam( spineMotor, dParamBounce3, 0.010 );  // 1 is
max bounce.
	dJointSetAMotorParam( spineMotor, dParamVel3,    0.0 );  // initial

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

Also, I haven't had any problems with ODE's recomputing of the euler
axes each step; they seem to change smoothly and reasonably.


>
> > So, how are you
> > planning to do the motor control?
>
> in short, i simulate (torsional) springs, and set the position and
> stiffness before each simulation step. like on the bottom of this
> page:
> http://www.ai.mit.edu/projects/humanoid-robotics-group/cog/hardware.html
>
> the code is on the bottom of this page:
> http://jwstolk.xs4all.nl/wisse/?M=A
> (this was still without the amotors)
>
> jaap.
>



More information about the ODE mailing list