博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ODE的buggy例程分析
阅读量:6950 次
发布时间:2019-06-27

本文共 7893 字,大约阅读时间需要 26 分钟。

        ODE (Open Dynamic Engine) 是一个免费的具有工业品质的刚体动力学的库,一款优秀的开源物理引擎。它能很好地仿真现实环境中的可移动物体,而且它有内建的碰撞检测系统。

        最近从网上看到了ODE,不禁有一种跃跃欲试的冲动,于是这两天就小试了一下。虽然ODE这个库已经使用了十几年了,但是资料还是比较少,中文的更是寥寥可数,只有几篇官网教程的翻译,也只有前几章的,不是很全。貌似这种日本做的东西,文档做的都不是很好呀。以下是几篇教程的链接:

       ODE文档的部分翻译: 

                                           

       ODE 教程:

                          

                                            

            没办法,就开始看官方源码中的demo,今天花了一下午时间看了buggy的例程,对照着在线手册了解了程序中的API,简单做了一下中文注释。

       

/************************************************************************* *                                                                       * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       * * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          * *                                                                       * * This library is free software; you can redistribute it and/or         * * modify it under the terms of EITHER:                                  * *   (1) The GNU Lesser General Public License as published by the Free  * *       Software Foundation; either version 2.1 of the License, or (at  * *       your option) any later version. The text of the GNU Lesser      * *       General Public License is included with this library in the     * *       file LICENSE.TXT.                                               * *   (2) The BSD-style license that is included with this library in     * *       the file LICENSE-BSD.TXT.                                       * *                                                                       * * This library is distributed in the hope that it will be useful,       * * but WITHOUT ANY WARRANTY; without even the implied warranty of        * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    * * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     * *                                                                       * *************************************************************************//*   buggy with suspension.   this also shows you how to use geom groups.*/#define  dSINGLE    //定义为单精度#include 
#include
#define DRAWSTUFF_TEXTURE_PATH "textures" //纹理文件的路径// select correct drawing functions#ifdef dDOUBLE#define dsDrawBox dsDrawBoxD#define dsDrawSphere dsDrawSphereD#define dsDrawCylinder dsDrawCylinderD#define dsDrawCapsule dsDrawCapsuleD#endif// some constants#define LENGTH 0.7 // 车壳长度#define WIDTH 0.5 // 车壳宽度#define HEIGHT 0.2 // 车壳高度#define RADIUS 0.18 // 轮子半径#define STARTZ 0.5 // 开始车壳的位置#define CMASS 1 // 车壳的质量#define WMASS 0.2 // 轮子的质量// dynamics and collision objects (chassis, 3 wheels, environment)static dWorldID world; //动力学计算使用的worldstatic dSpaceID space; //检测碰撞使用的spacestatic dBodyID body[4]; //设置车体的ID(三个轮子,一个车体)static dJointID joint[3]; // joint[0]是前轮static dJointGroupID contactgroup;static dGeomID ground; //大地static dSpaceID car_space;static dGeomID box[1]; //车体geom的IDstatic dGeomID sphere[3]; //车轮geom的IDstatic dGeomID ground_box; //障碍物geom的ID// things that the user controlsstatic dReal speed=0,steer=0; // 用户命令// 碰撞检测的callback函数static void nearCallback (void *data, dGeomID o1, dGeomID o2){ int i,n; // 选择碰撞检测中的2个中的一个作为标志; // 如果有一个碰撞物为ground或者障碍物则把标志位g1\g2置为1 int g1 = (o1 == ground || o1 == ground_box); int g2 = (o2 == ground || o2 == ground_box); if (!(g1 ^ g2)) return; const int N = 10; //接触点的上限是10个 dContact contact[N]; n = dCollide (o1,o2,N,&contact[0].geom,sizeof(dContact)); //n是碰撞的次数 if (n > 0) { for (i=0; i
0.1) v = 0.1; if (v < -0.1) v = -0.1; v *= 10.0; dJointSetHinge2Param (joint[0],dParamVel,v); dJointSetHinge2Param (joint[0],dParamFMax,0.2); dJointSetHinge2Param (joint[0],dParamLoStop,-0.75); //最小停止角度 dJointSetHinge2Param (joint[0],dParamHiStop,0.75); //最大停止角度 dJointSetHinge2Param (joint[0],dParamFudgeFactor,0.1); //防止启动跳动 dSpaceCollide (space,0,&nearCallback); //碰撞检测,最初写入的值 dWorldStep (world,0.05); //决定simulation的stepsize // remove all contact joints dJointGroupEmpty (contactgroup); //将contactgroup置空 } //DrawStuff绘制 dsSetColor (0,1,1); //颜色切换 dsSetTexture (DS_WOOD); //纹理切换 dReal sides[3] = {LENGTH,WIDTH,HEIGHT}; //车壳的尺寸 dsDrawBox (dBodyGetPosition(body[0]),dBodyGetRotation(body[0]),sides); //绘制车壳 dsSetColor (1,1,1); for (i=1; i<=3; i++) dsDrawCylinder (dBodyGetPosition(body[i]), dBodyGetRotation(body[i]),0.02f,RADIUS); //绘制车轮 dVector3 ss; dGeomBoxGetLengths (ground_box,ss); dsDrawBox (dGeomGetPosition(ground_box),dGeomGetRotation(ground_box),ss); //绘制障碍}int main (int argc, char **argv){ int i; dMass m; // setup pointers to drawstuff callback functions dsFunctions fn; // drawstuff结构体 fn.version = DS_VERSION; // drawstuff的版本 fn.start = &start; // 仿真的前处理函数 fn.step = &simLoop; // 仿真的每一步被调用的函数 fn.command = &command; // 键盘输入 fn.stop = 0; // 没有函数,因此设定为NULL指针 fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; // 纹理文件的路径 // create world dInitODE2(0); //初始化ODE环境 world = dWorldCreate(); //创建世界 space = dHashSpaceCreate (0); //创建碰撞检测用space,返回它的ID。 contactgroup = dJointGroupCreate (0); //生成jointGroup dWorldSetGravity (world,0,0,-0.5); //重力加速度 ground = dCreatePlane (space,0,0,1,0); //创建一个ground // 创建车体 body[0] = dBodyCreate (world); dBodySetPosition (body[0],0,0,STARTZ); //设置初始位置 dMassSetBox (&m,1,LENGTH,WIDTH,HEIGHT); dMassAdjust (&m,CMASS); dBodySetMass (body[0],&m); //设置质量 box[0] = dCreateBox (0,LENGTH,WIDTH,HEIGHT); //生成车体的geom dGeomSetBody (box[0],body[0]); //设置车体中的geom,给物体的两个属性形状geom和刚体body添加关联。 // wheel bodies for (i=1; i<=3; i++) { body[i] = dBodyCreate (world); //创建车轮的body dQuaternion q; dQFromAxisAndAngle (q,1,0,0,M_PI*0.5); //计算车轮的旋转角度 dBodySetQuaternion (body[i],q); //设置车轮的旋转角度 dMassSetSphere (&m,1,RADIUS); dMassAdjust (&m,WMASS); dBodySetMass (body[i],&m); //设置质量 sphere[i-1] = dCreateSphere (0,RADIUS); dGeomSetBody (sphere[i-1],body[i]); //设置geom } dBodySetPosition (body[1],0.5*LENGTH,0,STARTZ-HEIGHT*0.5); //设置初始位置 dBodySetPosition (body[2],-0.5*LENGTH, WIDTH*0.5,STARTZ-HEIGHT*0.5); dBodySetPosition (body[3],-0.5*LENGTH,-WIDTH*0.5,STARTZ-HEIGHT*0.5); // front and back wheel hinges for (i=0; i<3; i++) { joint[i] = dJointCreateHinge2 (world,0); //创建joint dJointAttach (joint[i],body[0],body[i+1]); //设置joint的连接体 const dReal *a = dBodyGetPosition (body[i+1]); //获取位置 dJointSetHinge2Anchor (joint[i],a[0],a[1],a[2]); //设置joint的位置 dJointSetHinge2Axis1 (joint[i],0,0,1); //设置旋转轴 dJointSetHinge2Axis2 (joint[i],0,1,0); } // 设置joint的悬挂参数 // 如果不需要悬挂可以将参数设置为0 for (i=0; i<3; i++) { dJointSetHinge2Param (joint[i],dParamSuspensionERP,0.4); dJointSetHinge2Param (joint[i],dParamSuspensionCFM,0.8); } // 固定后面两个轮子 for (i=1; i<3; i++) { // set stops to make sure wheels always stay in alignment dJointSetHinge2Param (joint[i],dParamLoStop,0); dJointSetHinge2Param (joint[i],dParamHiStop,0); } // 创建car的space,并且包含在总的space中 car_space = dSimpleSpaceCreate (space); dSpaceSetCleanup (car_space,0); dSpaceAdd (car_space,box[0]); dSpaceAdd (car_space,sphere[0]); dSpaceAdd (car_space,sphere[1]); dSpaceAdd (car_space,sphere[2]); // 设置障碍 ground_box = dCreateBox (space,2,1.5,1); dMatrix3 R; dRFromAxisAndAngle (R,0,1,0,-0.15); dGeomSetPosition (ground_box,2,0,-0.34); dGeomSetRotation (ground_box,R); // run simulation dsSimulationLoop (argc,argv,352,288,&fn); dGeomDestroy (box[0]); dGeomDestroy (sphere[0]); dGeomDestroy (sphere[1]); dGeomDestroy (sphere[2]); dJointGroupDestroy (contactgroup); dSpaceDestroy (space); dWorldDestroy (world); dCloseODE(); return 0;}

               运行效果:            

               程序中比较难理解的是一些参数的设置和API的使用。

         当发生碰撞时,调用回调函数nearCallback,其中需要设置一些碰撞点的参数,具体的参数可以参考用户手册中的说明:

        joint的配置中也有一些参数的设置:

 

        以上均参考在线文档:

        API手册:

            用户手册:            

 

转载地址:http://lgkil.baihongyu.com/

你可能感兴趣的文章
通过php 执行git pull 自动部署
查看>>
个人笔记--------错误解决记录-------Servlet.init() for servlet rest threw exception
查看>>
搭建kubernetes时容易遇到的问题
查看>>
css 视图结构
查看>>
Windows版本redis高可用方案探究
查看>>
centos7安装python3 以及tab补全功能
查看>>
leetcode539
查看>>
[leetcode]Two Sum @ Python
查看>>
[翻译] Canvas 不用写代码的动画
查看>>
POJ 3468 A Simple Problem with Integers (成端更新)
查看>>
ArcGIS案例学习笔记4_2_水文分析批处理地理建模
查看>>
POJ 1226 Substrings(后缀数组)
查看>>
一步一步写一个简单通用的makefile(一)
查看>>
docker学习3-虚拟网络模式
查看>>
Silverlight socket组件
查看>>
go语言中的map
查看>>
如何让您的应用程序进入苹果App Store?(上)
查看>>
[ERROR]-Error: failure: repodata/filelists.xml.gz from addons: [Errno 256] No more mirrors to try.
查看>>
css3ps—ps直接生成css3 使用方法
查看>>
hdu1002——A + B Problem II
查看>>