ODE仿真引擎使用(七)
在我们周围有许多关节,例如,手机的铰链,门的铰链,等等。一个接头连接两个物体。换句话说,关节是约束两个物体运动的约束。ODE使用与约束含义相同的关节。
How to use a joint
1、Create a joint
dJointCreate***()
2、connect bodies with the joint
dJointAttach ()
3、Set an anchor of the joint
dJointSet***Anchor()
4、Set an axis of the joint
dJointSet***Axis()
How to set parameters of the joint
5、Set range of motion
dJointSetHingeParam (dJointID, dParamLoStop, the minimum range of motion);
dJointSetHingeParam (dJointID, dParamHiStop, the maximum range of motion);
6、Set angular velocity and maximum torque
dJointSetHingeParam (dJointID, dParamVel, target angular velocity);
dJointSetHingeParam (dJointID, dParamFMax, maximum torque);
你可以设置关节的参数,dParamLoStop是远动最小范围,dParamHiStop是运动最大范围。dParamVel是期望速度,dParamFMax是关节上的最大力矩,下面的例子展示了一个跳跃机器人。
1 // Joint —— a hopping robot 2 #ifdef dDOUBLE 3 #define dsDrawSphere dsDrawSphereD 4 #define dsDrawCapsule dsDrawCapsuleD 5 #endif 6 7 typedef struct { 8 dBodyID body; // a body 9 dGeomID geom; // a geometry 10 dReal radius, length, mass; // radius[m], length[m], mass[kg] 11 } myLink; 12 13 myLink ball, pole; 14 15 static void simLoop (int pause) 16 { 17 const dReal *pos1,*R1,*pos2,*R2; 18 dSpaceCollide(space,0,&nearCallback); // Collision detection 19 dWorldStep(world,0.01); // Step a world for 0.01 [sec] 20 dJointGroupEmpty(contactgroup); // Empty the joint group 21 22 // Draw a ball 23 dsSetColor(1.0,0.0,0.0); // Set red color 24 pos1 = dBodyGetPosition(ball.body); // Get a position 25 R1 = dBodyGetRotation(ball.body); // Get an orientation 26 dsDrawSphere(pos1,R1,ball.radius); // Draw a sphere 27 28 // Draw a capsule 29 pos2 = dBodyGetPosition(pole.body); // Get a position 30 R2 = dBodyGetRotation(pole.body); // Get an orientation 31 dsDrawCapsule(pos2,R2,pole.length,pole.radius); // Draw a capsule 32 } 33 34 // Create an object 35 void createBallPole() 36 { 37 dMass m1, m2; 38 dReal x0 = 0.0, y0 = 0.0, z0 = 2.5; // a ball 39 ball.radius = 0.2; 40 ball.mass = 1.0; 41 ball.body = dBodyCreate(world); 42 dMassSetZero(&m1); 43 dMassSetSphereTotal(&m1,ball.mass,ball.radius); 44 dBodySetMass(ball.body,&m1); 45 dBodySetPosition(ball.body, x0, y0, z0); 46 ball.geom = dCreateSphere(space,ball.radius); 47 dGeomSetBody(ball.geom,ball.body); 48 49 // a capsule 50 pole.radius = 0.025; 51 pole.length = 1.0; 52 pole.mass = 1.0; 53 pole.body = dBodyCreate(world); 54 dMassSetZero(&m2); 55 dMassSetCapsuleTotal(&m2,pole.mass,3,pole.radius,pole.length); 56 dBodySetMass(pole.body,&m2); 57 dBodySetPosition(pole.body, x0, y0, z0 - 0.5 * pole.length); 58 pole.geom = dCreateCapsule(space,pole.radius,pole.length); 59 dGeomSetBody(pole.geom,pole.body); 60 61 // hinge joint 62 joint = dJointCreateHinge(world, 0); // Create a hinge joint 63 dJointAttach(joint, ball.body,pole.body); // Attach joint to bodies 64 dJointSetHingeAnchor(joint, x0, y0, z0 - ball.radius); // Set a joint anchor 65 dJointSetHingeAxis(joint, 1, 0, 0); // Set a hinge axis(1,0,0) 66 } 67 68 int main (int argc, char **argv) 69 { 70 setDrawStuff(); // Set a draw function 71 dInitODE(); // Initialize ODE 72 world = dWorldCreate(); // Create a world 73 space = dHashSpaceCreate(0); // Create a collision space 74 contactgroup = dJointGroupCreate(0); // Create a joint group 75 dWorldSetGravity(world,0,0,-9.8); // Set gravity 76 ground = dCreatePlane(space,0,0,1,0); // Create a ground 77 createBallPole(); // Create ball and capsule 78 79 dsSimulationLoop (argc,argv,352,288,&fn); // Simulation loop 80 81 dWorldDestroy (world); // Destroy the world 82 dCloseODE(); // Close ODE 83 return 0; 84 }
在本例中,机器人由连接躯干和腿的铰链关节组成。让我们阅读源代码。createBallandPole函数是为躯干创建一个球,为腿创建一个圆柱体,并通过dJointCreateHinge()创建一个关节。主体通过dJointAttach()与接头连接。然后,dSetHingeAnchor()设置关节的锚点,dJointSetHingeAxis()设置铰节点的轴。在本例中,旋转轴向量设置为(1,0,0),即,轴向量是x轴。我没有设置关节的参数来简化源代码。通常,您可以设置关于关节的许多参数。请详细查看ODE用户手册。