[ODE] motor wierdness
Darken, Chris
cjdarken at nps.navy.mil
Mon Feb 25 11:57:01 2002
I was playing around with Gene's biped code this weekend and noticed
something strange. I don't know that this is a serious issue in any way,
but I thought I would mention it in case anyone is interested.
This wierdness happens when driving motors into their stops when the joint
is set fairly soft. ODE moves the joint past the stop (as it should, since
the motor is trying to maintain a set velocity with a large max force and
the joint is soft). The wierd thing is that when the stop is hit, the
angular velocity *increases*. This looks very strange, to say the least,
and maybe something needs improvement. Hacked-up example code below.
Chris
#include <ode/ode.h>
#include <drawstuff/drawstuff.h>
#define Pi 3.14159
#ifdef MSVC
#pragma warning(disable:4244 4305) // for VC++, no precision loss
complaints
#endif
// select correct drawing functions
#ifdef dDOUBLE
#define dsDrawBox dsDrawBoxD
#define dsDrawSphere dsDrawSphereD
#define dsDrawCylinder dsDrawCylinderD
#define dsDrawCappedCylinder dsDrawCappedCylinderD
#endif
// global constants
//const dReal ERP = 0.2;
//const dReal CFM = 0.05;
const dReal ERP = 0.2;
const dReal CFM = 0.05;
const dReal HEAD = 0.12;
const dReal TORSO[3] = {0.1,0.1,.80}; //0.7 // length, width height
const dReal STARTZ = 5.0;
// environment setup
static dWorldID world;
static dGeomID ground, geom_group;
static dJointGroupID contactgroup;
static dSpaceID space;
static dBodyID body[11],head; // 11 body parts + head
static dGeomID box[11]; // 11 geometries for body parts
//static dGeomID ground_box[10];
static dJointID joint[10],headj; // 10 joints + fixed joint for head
static dJointID lmotor[2];
static dJointID amotor[2];
static dJointID head_ball;
static dJointID head_motor;
static dJointID hook;
// Collision call back function here
static void nearCallback (void *data, dGeomID o1, dGeomID o2)
{
}
// start simulation - set viewpoint
static void start()
{
static float xyz[3] = {0.8317f,-0.9817f,4.8000f};
static float hpr[3] = {121.0000f,-27.5000f,0.0000f};
dsSetViewpoint (xyz,hpr);
}
// called when a key pressed
static void command (int cmd)
{
}
// run Simulation
static void simLoop(int pause)
{
static int itime = 0;
static int vsign = 1;
dSpaceCollide (space,0,&nearCallback);
dWorldStep (world,0.005);
// remove all contact joints
dJointGroupEmpty (contactgroup);
dsSetColor (0,1,1);
dsSetTexture (DS_WOOD); // DS_WOOD
// draw components
dsDrawSphere(dBodyGetPosition(head),dBodyGetRotation(head),HEAD);
dsSetColor (1,0,1);
dsDrawBox(dBodyGetPosition(body[0]),dBodyGetRotation(body[0]),TORSO);
/*
if ( (itime++) % 40 == 0 ) {
vsign *= -1;
dJointSetAMotorParam(head_motor,dParamVel3,vsign*10);
printf("Change!\n");
}
*/
}
static void init(void)
{
dMass m;
for (int i=0;i<11;i++)
body[i] = dBodyCreate(world);
head = dBodyCreate(world);
dBodySetPosition (head,0,0,STARTZ+TORSO[2]/2+HEAD);
dBodySetPosition (body[0],0,0,STARTZ); // torso
// head
dMassSetSphere(&m,1,HEAD);
dBodySetMass(head, &m);
// torso
dMassSetBox (&m,1,TORSO[0],TORSO[1],TORSO[2]); // torso
dMassAdjust (&m,1); // torso weight
dBodySetMass (body[0],&m);
box[0] = dCreateBox (space,TORSO[0],TORSO[1],TORSO[2]);
dGeomSetBody (box[0],body[0]);
// Create Joints
// hook
hook = dJointCreateFixed (world, 0);
dJointAttach (hook, 0, head);
dJointSetFixed (hook);
// head joint
head_ball = dJointCreateBall(world,0);
dJointAttach(head_ball,body[0],head);
dJointSetBallAnchor(head_ball,0,0,STARTZ+TORSO[2]/2);
head_motor = dJointCreateAMotor(world,0);
dJointAttach(head_motor,body[0],head);
const float stop = Pi/2;
// const float stop_cfm = 0.01;
// const float stop_erp = 0.8;
const float stop_cfm = 0.05;
const float stop_erp = 0.2;
dJointSetAMotorMode(head_motor,dAMotorEuler);
dJointSetAMotorAxis(head_motor,0,1,0,0,1);
dJointSetAMotorAxis(head_motor,2,2,0,1,0);
dJointSetAMotorParam(head_motor,dParamLoStop,-stop); // twist
dJointSetAMotorParam(head_motor,dParamHiStop,stop);
dJointSetAMotorParam(head_motor,dParamVel,0);
dJointSetAMotorParam(head_motor,dParamFMax,0);
dJointSetAMotorParam(head_motor,dParamLoStop2,-stop); // back
dJointSetAMotorParam(head_motor,dParamHiStop2,stop); // front
dJointSetAMotorParam(head_motor,dParamVel2,0);
dJointSetAMotorParam(head_motor,dParamFMax2,0);
dJointSetAMotorParam(head_motor,dParamLoStop3,-stop); // back
dJointSetAMotorParam(head_motor,dParamHiStop3,stop); // front
dJointSetAMotorParam(head_motor,dParamVel3,1);
dJointSetAMotorParam(head_motor,dParamFMax3,1000);
dJointSetAMotorParam(head_motor,dParamStopERP,stop_erp);
dJointSetAMotorParam(head_motor,dParamStopCFM,stop_cfm);
dJointSetAMotorParam(head_motor,dParamStopERP2,stop_erp);
dJointSetAMotorParam(head_motor,dParamStopCFM2,stop_cfm);
dJointSetAMotorParam(head_motor,dParamStopERP3,stop_erp);
dJointSetAMotorParam(head_motor,dParamStopCFM3,stop_cfm);
dJointSetAMotorParam(head_motor,dParamBounce,0);
dJointSetAMotorParam(head_motor,dParamBounce2,0);
dJointSetAMotorParam(head_motor,dParamBounce3,0);
}
// main program
int main(int argc, char **argv) {
// setup pointers to drawstuff callback functions
dsFunctions fn;
fn.version = DS_VERSION;
fn.start = &start;
fn.step = &simLoop;
fn.command = &command;
fn.stop = 0;
fn.path_to_textures = "../../drawstuff/textures";
// create world (setup environment)
world = dWorldCreate(); // create ODE world
space = dHashSpaceCreate();
contactgroup = dJointGroupCreate (0);
dWorldSetGravity (world,0,0,-1.50); // set gravity (x,y,z)
dWorldSetERP (world,ERP); // global ERP
dWorldSetCFM (world,CFM); // global CFM
ground = dCreatePlane(space,0,0,1,0);
init();
// Start Simulation
dsSimulationLoop (argc,argv,640,480,&fn); // 640 x 480 OpenGL
display
// Destroy World (end program)
dJointGroupDestroy (contactgroup);
dSpaceDestroy (space);
dWorldDestroy(world);
return 0;
}