ODE仿真引擎使用(五)
在ODE仿真中,有许多种类的对象可以创建:
• dWorld - 一个动态的世界,包含了所有的模拟数据。
• dBody - 一个刚体;它没有任何形状:它需要一个或多个dGeoms。
• dJoint – 一个关节。
• dJointGroup - 一组关节,使它很容易一次摧毁所有的关节。
• dSpace - 一个冲突空间,用来组织和加速冲突测试。
• dGeom - 用来检测碰撞的形状。
ODE creates a World for the dynamics calculation and create a Space for the collision detection . An object has two attributes, that is, a body (rigid body) for dynamics and a geometry for collision detection.
1、World
世界对象是刚体和关节的容器。不同世界的物体不能相互作用,例如来自两个不同世界的刚体不能碰撞。世界中的所有对象都存在于同一时间点,因此使用不同世界的一个原因是以不同的速率模拟系统。大多数应用程序只需要一个世界。
··dWorldID dWorldCreate();
创建一个新的、空的世界并返回它的ID号。
··void dWorldDestroy (dWorldID);
dJointGroupEmpty摧毁一个世界和其中的一切。这包括所有的身体,和所有的关节,不属于一个关节组。属于joint group的关节将被停用,并且可以通过调用,例如,dJointGroupEmpty来销毁它们。
··void dWorldSetGravity (dWorldID, dReal x, dReal y, dReal z);
··void dWorldGetGravity (dWorldID, dVector3 gravity);
设置并得到全局重力矢量。在SI单位中,地球的重力向量是(0,0,-9.81),假设+z向上。默认是没有重力,即(0,0,0)。
2、Space
一个空间是一个不可替换的geom,它可以容纳其他geom。它类似于“世界”的刚体概念,只是它适用于碰撞而不是动力学。
空间物体的存在使碰撞检测变得更快。如果没有spaces,您可能通过调用dcollision来为每一对geoms获取接触点,从而在模拟中生成接触点。对于N个geoms,这是O(N2)测试,如果您的环境有许多对象,这在计算上太昂贵了。
更好的方法是将geoms插入一个空间,并调用dSpaceCollide。然后空间将执行碰撞剔除,这意味着它将快速识别哪些geoms可能相交。这些对将被传递给一个回调函数,这个回调函数反过来可以在它们上调用dcollision。这节省了大量在无用的dcollision测试中花费的时间,因为传递给回调函数的对的数量只是每个可能的对象-对象对的一小部分。
空间可以包含其他空间。这对于将冲突环境划分为几个层次结构以进一步优化冲突检测速度非常有用。下面将对此进行更详细的描述。
3、Body
·· dBodyID dBodyCreate (dWorldID);
Create a body in the given world with default mass parameters at position (0,0,0). Return its ID.
·· void dBodyDestroy (dBodyID);
Destroy a body. 所有连接到这个身体上的关节都将被放入地狱边缘(即不连接,不影响模拟,但不会被删除)。
·· void dBodySetPosition (dBodyID, dReal x, dReal y, dReal z);
·· void dBodySetRotation (dBodyID, const dMatrix3 R);
·· void dBodySetQuaternion (dBodyID, const dQuaternion q);
·· void dBodySetLinearVel (dBodyID, dReal x, dReal y, dReal z);
·· void dBodySetAngularVel (dBodyID, dReal x, dReal y, dReal z);
·· const dReal * dBodyGetPosition (dBodyID);
·· const dReal * dBodyGetRotation (dBodyID);
·· const dReal * dBodyGetQuaternion (dBodyID);
·· const dReal * dBodyGetLinearVel (dBodyID);
·· const dReal * dBodyGetAngularVel (dBodyID);
这些函数设置并得到物体的位置、旋转、线速度和角速度。在设置了一组物体后,如果新配置与现有的关节/约束不一致,则模拟的结果是不确定的。在获取时,返回的值是指向内部数据结构的指针,因此在对刚体系统结构进行任何更改之前,这些向量都是有效的。
·· void dBodySetMass (dBodyID, const dMass *mass);
·· void dBodyGetMass (dBodyID, dMass *mass);
Set/get the mass of the body (see the mass functions). 设置和获得body的质量
·· void dBodyAddForce (dBodyID, dReal fx, dReal fy, dReal fz);
·· void dBodyAddTorque (dBodyID, dReal fx, dReal fy, dReal fz);
·· void dBodyAddRelForce (dBodyID, dReal fx, dReal fy, dReal fz);
·· void dBodyAddRelTorque (dBodyID, dReal fx, dReal fy, dReal fz);
·· void dBodyAddForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz);
·· void dBodyAddForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz);
·· void dBodyAddRelForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz);
·· void dBodyAddRelForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz);
3、Geom
几何对象(简称geoms)是碰撞系统中的基本对象。一个geom可以表示一个单一的刚性形状(如球体或盒子),也可以表示一组其他geom—这是一种特殊的geom,称为“空间”。
任何geom都可以与任何其他geom相撞,从而产生零个或多个接触点。空间具有额外的能力,能够碰撞其包含的geoms在一起,以产生内部接触点。
Geoms可以是可替换的,也可以是不可替换的。可替换的geom和刚体一样,具有位置向量和3*3的旋转矩阵,可以在仿真过程中改变。不可替换的geom不具备此功能—例如,它可能代表无法移动的环境的某些静态特性。空间是不可替换的空间,因为每个包含的空间可能有自己的位置和方向,但是空间本身有位置和方向是没有意义的。
为了在刚体模拟中使用碰撞引擎,可替换的geoms与刚体物体相关联。这使得碰撞引擎能够从物体上获得geoms的位置和方向。注意geom与刚体的区别在于geom具有几何特性(尺寸、形状、位置和方向),但没有动力学特性(如速度或质量)。一个body和一个geom一起代表了被模拟物体的所有属性。
每个geom都是一个类的实例,比如sphere、plane或box。有许多内置类,如下所述,您也可以定义自己的类。
可换系统的参考点是由其位置矢量控制的参考点。标准类的参考点通常与geom的质心相对应。这个特性使得标准类可以很容易地连接到动态体。如果需要其他参考点,可以使用转换对象来封装geom。
程序见 (三)中创建世界和实物。