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_TEXTURE_PATH; if (argc >= 2 ) { for (int i=1; i < argc; ++i) { if ( 0 == strcmp ("-h", argv[i]) || 0 == strcmp ("--help", argv[i]) ) Help (argv); if ( 0 == strcmp ("-p", argv[i]) || 0 == strcmp ("--PRJoint", argv[i]) ) type = dJointTypePR; if (0 == strcmp ("-t", argv[i]) || 0 == strcmp ("--texture-path", argv[i]) ) { int j = i+1; if ( j+1 > argc || // Check if we have enough arguments argv[j] == '\0' || // We should have a path here argv[j][0] == '-' ) // We should have a path not a command line Help (argv); else fn.path_to_textures = argv[++i]; // Increase i since we use this argument } } } dInitODE2(0); world.setERP (0.8); space = dSimpleSpaceCreate (0); contactgroup = dJointGroupCreate (0); geom[GROUND] = dCreatePlane (space, 0,0,1,0); dGeomSetCategoryBits (geom[GROUND], catBits[GROUND]); dGeomSetCollideBits (geom[GROUND], catBits[ALL]); dMass m; // Create the body attached to the World body[W].create (world); // Main axis of cylinder is along X=1 m.setBox (1, boxDim[X], boxDim[Y], boxDim[Z]); m.adjust (Mass1); geom[W] = dCreateBox (space, boxDim[X], boxDim[Y], boxDim[Z]); dGeomSetBody (geom[W], body[W]); dGeomSetCategoryBits (geom[W], catBits[W]); dGeomSetCollideBits (geom[W], catBits[ALL] & (~catBits[W]) & (~catBits[JOINT]) ); body[W].setMass(m); // Create the dandling body body[D].create(world); // Main axis of capsule is along X=1 m.setBox (1, boxDim[X], boxDim[Y], boxDim[Z]); m.adjust (Mass1); geom[D] = dCreateBox (space, boxDim[X], boxDim[Y], boxDim[Z]); dGeomSetBody (geom[D], body[D]); dGeomSetCategoryBits (geom[D], catBits[D]); dGeomSetCollideBits (geom[D], catBits[ALL] & (~catBits[D]) & (~catBits[JOINT]) ); body[D].setMass(&m); // Create the external part of the slider joint geom[EXT] = dCreateBox (space, extDim[X], extDim[Y], extDim[Z]); dGeomSetCategoryBits (geom[EXT], catBits[EXT]); dGeomSetCollideBits (geom[EXT], catBits[ALL] & (~catBits[JOINT]) & (~catBits[W]) & (~catBits[D]) ); // Create the internal part of the slider joint geom[INT] = dCreateBox (space, INT_EXT_RATIO*extDim[X], INT_EXT_RATIO*extDim[Y], INT_EXT_RATIO*extDim[Z]); dGeomSetCategoryBits (geom[INT], catBits[INT]); dGeomSetCollideBits (geom[INT], catBits[ALL] & (~catBits[JOINT]) & (~catBits[W]) & (~catBits[D]) ); dMatrix3 R; dGeomID id; // Create the first axis of the universal joi9nt geom[AXIS1] = dCreateGeomTransform (space); //Rotation of 90deg around y dRFromAxisAndAngle (R, 0,1,0, 0.5*PI); dGeomSetRotation (geom[AXIS1], R); dGeomSetCategoryBits (geom[AXIS1], catBits[AXIS1]); dGeomSetCollideBits (geom[AXIS1], catBits[ALL] & ~catBits[JOINT] & ~catBits[W] & ~catBits[D]); id = geom[AXIS1]; dGeomTransformSetGeom (geom[AXIS1], dCreateCylinder (0, axDim[RADIUS], axDim[LENGTH]) ); // Create the second axis of the universal joint geom[AXIS2] = dCreateGeomTransform (space); //Rotation of 90deg around y dRFromAxisAndAngle (R, 1,0,0, 0.5*PI); dGeomSetRotation (geom[AXIS2], R); dGeomSetCategoryBits (geom[AXIS2], catBits[AXIS2]); dGeomSetCollideBits (geom[AXIS2], catBits[ALL] & ~catBits[JOINT] & ~catBits[W] & ~catBits[D]); id = geom[AXIS2]; dGeomTransformSetGeom (geom[AXIS2], dCreateCylinder (0, axDim[RADIUS], axDim[LENGTH]) ); // Create the anchor geom[ANCHOR] = dCreateBox (space, ancDim[X], ancDim[Y], ancDim[Z]); dGeomSetCategoryBits (geom[ANCHOR], catBits[ANCHOR]); dGeomSetCollideBits (geom[ANCHOR], catBits[ALL] & (~catBits[JOINT]) & (~catBits[W]) & (~catBits[D]) ); if (body[W]) { body[W].setPosition(0, 0, 5); } if (geom[EXT]) { dGeomSetPosition (geom[EXT], 0,0,3.8); } if (geom[INT]) { dGeomSetPosition (geom[INT], 0,0,2.6); } if (geom[AXIS1]) { dGeomSetPosition (geom[AXIS1], 0,0,2.5); } if (geom[AXIS2]) { dGeomSetPosition (geom[AXIS2], 0,0,2.5); } if (geom[ANCHOR]) { dGeomSetPosition (geom[ANCHOR], 0,0,2.25); } if (body[D]) { body[D].setPosition(0,0,1.5); } // Attache the upper box to the world dJointID fixed = dJointCreateFixed (world,0); dJointAttach (fixed , NULL, body[W]); dJointSetFixed (fixed ); if (type == dJointTypePR) { dPRJoint *pr = new dPRJoint (world, 0); pr->attach (body[W], body[D]); pr->setAxis1 (0, 0, -1); pr->setAxis2 (1, 0, 0); joint = pr; dJointSetPRAnchor (pr->id(), 0, 0, 2.5); } else { dPUJoint *pu = new dPUJoint (world, 0); pu->attach (body[W], body[D]); pu->setAxis1 (1, 0, 0); pu->setAxis2 (0, 1, 0); pu->setAxisP (0, 0, -1); joint = pu; dJointSetPUAnchor (pu->id(), 0, 0, 2.5); } // run simulation dsSimulationLoop (argc,argv,400,300,&fn); delete joint; dJointGroupDestroy (contactgroup); dSpaceDestroy (space); dWorldDestroy (world); dCloseODE(); return 0; }
int setupTest (int n) { switch (n) { // ********** fixed joint case 0: { // 2 body constructWorldForTest (0,2, 0.5*SIDE,0.5*SIDE,1, -0.5*SIDE,-0.5*SIDE,1, 1,1,0, 1,1,0, 0.25*M_PI,0.25*M_PI); joint = dJointCreateFixed (world,0); dJointAttach (joint,body[0],body[1]); dJointSetFixed (joint); return 1; } case 1: { // 1 body to static env constructWorldForTest (0,1, 0.5*SIDE,0.5*SIDE,1, 0,0,0, 1,0,0, 1,0,0, 0,0); joint = dJointCreateFixed (world,0); dJointAttach (joint,body[0],0); dJointSetFixed (joint); return 1; } case 2: { // 2 body with relative rotation constructWorldForTest (0,2, 0.5*SIDE,0.5*SIDE,1, -0.5*SIDE,-0.5*SIDE,1, 1,1,0, 1,1,0, 0.25*M_PI,-0.25*M_PI); joint = dJointCreateFixed (world,0); dJointAttach (joint,body[0],body[1]); dJointSetFixed (joint); return 1; } case 3: { // 1 body to static env with relative rotation constructWorldForTest (0,1, 0.5*SIDE,0.5*SIDE,1, 0,0,0, 1,0,0, 1,0,0, 0.25*M_PI,0); joint = dJointCreateFixed (world,0); dJointAttach (joint,body[0],0); dJointSetFixed (joint); return 1; } // ********** hinge joint case 200: // 2 body constructWorldForTest (0,2, 0.5*SIDE,0.5*SIDE,1, -0.5*SIDE,-0.5*SIDE,1, 1,1,0, 1,1,0, 0.25*M_PI,0.25*M_PI); joint = dJointCreateHinge (world,0); dJointAttach (joint,body[0],body[1]); dJointSetHingeAnchor (joint,0,0,1); dJointSetHingeAxis (joint,1,-1,1.41421356); return 1; case 220: // hinge angle polarity test case 221: // hinge angle rate test constructWorldForTest (0,2, 0.5*SIDE,0.5*SIDE,1, -0.5*SIDE,-0.5*SIDE,1, 1,0,0, 1,0,0, 0,0); joint = dJointCreateHinge (world,0); dJointAttach (joint,body[0],body[1]); dJointSetHingeAnchor (joint,0,0,1); dJointSetHingeAxis (joint,0,0,1); max_iterations = 50; return 1; case 230: // hinge motor rate (and polarity) test case 231: // ...with stops constructWorldForTest (0,2, 0.5*SIDE,0.5*SIDE,1, -0.5*SIDE,-0.5*SIDE,1, 1,0,0, 1,0,0, 0,0); joint = dJointCreateHinge (world,0); dJointAttach (joint,body[0],body[1]); dJointSetHingeAnchor (joint,0,0,1); dJointSetHingeAxis (joint,0,0,1); dJointSetHingeParam (joint,dParamFMax,1); if (n==231) { dJointSetHingeParam (joint,dParamLoStop,-0.5); dJointSetHingeParam (joint,dParamHiStop,0.5); } return 1; case 250: // limit bounce test (gravity down) case 251: { // ...gravity up constructWorldForTest ((n==251) ? 0.1 : -0.1, 2, 0.5*SIDE,0,1+0.5*SIDE, -0.5*SIDE,0,1-0.5*SIDE, 1,0,0, 1,0,0, 0,0); joint = dJointCreateHinge (world,0); dJointAttach (joint,body[0],body[1]); dJointSetHingeAnchor (joint,0,0,1); dJointSetHingeAxis (joint,0,1,0); dJointSetHingeParam (joint,dParamLoStop,-0.9); dJointSetHingeParam (joint,dParamHiStop,0.7854); dJointSetHingeParam (joint,dParamBounce,0.5); // anchor 2nd body with a fixed joint dJointID j = dJointCreateFixed (world,0); dJointAttach (j,body[1],0); dJointSetFixed (j); return 1; } // ********** slider case 300: // 2 body constructWorldForTest (0,2, 0,0,1, 0.2,0.2,1.2, 0,0,1, -1,1,0, 0,0.25*M_PI); joint = dJointCreateSlider (world,0); dJointAttach (joint,body[0],body[1]); dJointSetSliderAxis (joint,1,1,1); return 1; case 320: // slider angle polarity test case 321: // slider angle rate test constructWorldForTest (0,2, 0,0,1, 0,0,1.2, 1,0,0, 1,0,0, 0,0); joint = dJointCreateSlider (world,0); dJointAttach (joint,body[0],body[1]); dJointSetSliderAxis (joint,0,0,1); max_iterations = 50; return 1; case 330: // slider motor rate (and polarity) test case 331: // ...with stops constructWorldForTest (0, 2, 0,0,1, 0,0,1.2, 1,0,0, 1,0,0, 0,0); joint = dJointCreateSlider (world,0); dJointAttach (joint,body[0],body[1]); dJointSetSliderAxis (joint,0,0,1); dJointSetSliderParam (joint,dParamFMax,100); if (n==331) { dJointSetSliderParam (joint,dParamLoStop,-0.4); dJointSetSliderParam (joint,dParamHiStop,0.4); } return 1; case 350: // limit bounce tests case 351: { constructWorldForTest ((n==351) ? 0.1 : -0.1, 2, 0,0,1, 0,0,1.2, 1,0,0, 1,0,0, 0,0); joint = dJointCreateSlider (world,0); dJointAttach (joint,body[0],body[1]); dJointSetSliderAxis (joint,0,0,1); dJointSetSliderParam (joint,dParamLoStop,-0.5); dJointSetSliderParam (joint,dParamHiStop,0.5); dJointSetSliderParam (joint,dParamBounce,0.5); // anchor 2nd body with a fixed joint dJointID j = dJointCreateFixed (world,0); dJointAttach (j,body[1],0); dJointSetFixed (j); return 1; } // ********** hinge-2 joint case 420: // hinge-2 steering angle polarity test case 421: // hinge-2 steering angle rate test constructWorldForTest (0,2, 0.5*SIDE,0,1, -0.5*SIDE,0,1, 1,0,0, 1,0,0, 0,0); joint = dJointCreateHinge2 (world,0); dJointAttach (joint,body[0],body[1]); dJointSetHinge2Anchor (joint,-0.5*SIDE,0,1); dJointSetHinge2Axis1 (joint,0,0,1); dJointSetHinge2Axis2 (joint,1,0,0); max_iterations = 50; return 1; case 430: // hinge 2 steering motor rate (+polarity) test case 431: // ...with stops case 432: // hinge 2 wheel motor rate (+polarity) test constructWorldForTest (0,2, 0.5*SIDE,0,1, -0.5*SIDE,0,1, 1,0,0, 1,0,0, 0,0); joint = dJointCreateHinge2 (world,0); dJointAttach (joint,body[0],body[1]); dJointSetHinge2Anchor (joint,-0.5*SIDE,0,1); dJointSetHinge2Axis1 (joint,0,0,1); dJointSetHinge2Axis2 (joint,1,0,0); dJointSetHinge2Param (joint,dParamFMax,1); dJointSetHinge2Param (joint,dParamFMax2,1); if (n==431) { dJointSetHinge2Param (joint,dParamLoStop,-0.5); dJointSetHinge2Param (joint,dParamHiStop,0.5); } return 1; // ********** angular motor joint case 600: // test euler angle calculations constructWorldForTest (0,2, -SIDE*0.5,0,1, SIDE*0.5,0,1, 0,0,1, 0,0,1, 0,0); joint = dJointCreateAMotor (world,0); dJointAttach (joint,body[0],body[1]); dJointSetAMotorNumAxes (joint,3); dJointSetAMotorAxis (joint,0,1, 0,0,1); dJointSetAMotorAxis (joint,2,2, 1,0,0); dJointSetAMotorMode (joint,dAMotorEuler); max_iterations = 200; return 1; // ********** universal joint case 700: // 2 body case 701: case 702: constructWorldForTest (0,2, 0.5*SIDE,0.5*SIDE,1, -0.5*SIDE,-0.5*SIDE,1, 1,1,0, 1,1,0, 0.25*M_PI,0.25*M_PI); joint = dJointCreateUniversal (world,0); dJointAttach (joint,body[0],body[1]); dJointSetUniversalAnchor (joint,0,0,1); dJointSetUniversalAxis1 (joint, 1, -1, 1.41421356); dJointSetUniversalAxis2 (joint, 1, -1, -1.41421356); return 1; case 720: // universal transmit torque test case 721: case 722: case 730: // universal torque about axis 1 case 731: case 732: case 740: // universal torque about axis 2 case 741: case 742: constructWorldForTest (0,2, 0.5*SIDE,0.5*SIDE,1, -0.5*SIDE,-0.5*SIDE,1, 1,0,0, 1,0,0, 0,0); joint = dJointCreateUniversal (world,0); dJointAttach (joint,body[0],body[1]); dJointSetUniversalAnchor (joint,0,0,1); dJointSetUniversalAxis1 (joint,0,0,1); dJointSetUniversalAxis2 (joint, 1, -1,0); max_iterations = 100; return 1; // Joint PR (Prismatic and Rotoide) case 800: // 2 body case 801: // 2 bodies with spring force and prismatic fixed case 802: // 2 bodies with torque on body1 and prismatic fixed constructWorldForTest (0, 2, -1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1,0,0, 1,0,0, 0, 0); joint = dJointCreatePR (world, 0); dJointAttach (joint, body[0], body[1]); dJointSetPRAnchor (joint,-0.5, 0.0, 1.0); dJointSetPRAxis1 (joint, 0, 1, 0); dJointSetPRAxis2 (joint, 1, 0, 0); dJointSetPRParam (joint,dParamLoStop,-0.5); dJointSetPRParam (joint,dParamHiStop,0.5); dJointSetPRParam (joint,dParamLoStop2,0); dJointSetPRParam (joint,dParamHiStop2,0); return 1; case 803: // 2 bodies with spring force and prismatic NOT fixed case 804: // 2 bodies with torque force and prismatic NOT fixed case 805: // 2 bodies with force only on first body constructWorldForTest (0, 2, -1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1,0,0, 1,0,0, 0, 0); joint = dJointCreatePR (world, 0); dJointAttach (joint, body[0], body[1]); dJointSetPRAnchor (joint,-0.5, 0.0, 1.0); dJointSetPRAxis1 (joint, 0, 1, 0); dJointSetPRAxis2 (joint, 1, 0, 0); dJointSetPRParam (joint,dParamLoStop,-0.5); dJointSetPRParam (joint,dParamHiStop,0.5); dJointSetPRParam (joint,dParamLoStop2,-0.5); dJointSetPRParam (joint,dParamHiStop2,0.5); return 1; } return 0; }