天天看點

ODE仿真引擎使用(七)

Joint——在不同物體間加入關節

  在我們周圍有許多關節,例如,手機的鉸鍊,門的鉸鍊,等等。一個接頭連接配接兩個物體。換句話說,關節是限制兩個物體運動的限制。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使用者手冊。