www.pudn.com > RCApp-src.zip > mod_buggy.cpp
/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001 Russell L. Smith. * * 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 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. * * * * 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 GNU * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with this library (see the file LICENSE.TXT); if not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307 USA. * * * *************************************************************************/ /* buggy with suspension. this also shows you how to use geom groups. */ #include#include #include "SDL.h" #include #include #ifdef MSVC #pragma warning(disable:4244 4305) // for VC++, no precision loss complaints #endif // select correct drawing functions #ifdef dDOUBLE #define dsDrawBox dsDrawBoxD #define dsDrawSphere dsDrawSphereD #define dsDrawCylinder dsDrawCylinderD #define dsDrawCappedCylinder dsDrawCappedCylinderD #endif // some constants #define LENGTH 1.05 // chassis length #define WIDTH .6 // chassis width #define HEIGHT .45 // chassis height #define RADIUS 0.18 // wheeldInfinity radius #define STARTZ 1.0 // starting height of chassis #define CMASS 1.5 // chassis mass #define WMASS 1.0 // wheel mass #define MU .6 #define SUSPHEIGHT .08 #define SUSPERP .8 #define SUSPCFM .4 #define VCONS 1.5 #define MAXV 60.0 #define MAXF .12 // .125 was good too #define ETUVETO #define TAKAVETO // dynamics and collision objects (chassis, 3 wheels, environment) static dWorldID world; static dSpaceID space; static dBodyID body[5]; static dJointID joint[4]; // joint[0] is the front wheel static dJointGroupID contactgroup; static dGeomID ground,geom_group; static dGeomID box[1]; static dGeomID sphere[4]; static dGeomID ground_box; // things that the user controls static dReal speed=0,steer=0; // user commands extern SDL_Joystick *joystick; short xax, yax; float kaasu, kaanto; // this is called by dSpaceCollide when two objects in space are // potentially colliding. static void nearCallback (void *data, dGeomID o1, dGeomID o2) { int i,n; // only collide things with the ground int g1 = (o1 == ground || o1 == ground_box); int g2 = (o2 == ground || o2 == ground_box); if (!(g1 ^ g2)) return; const int N = 11; dContact contact[N]; n = dCollide (o1,o2,N,&contact[0].geom,sizeof(dContact)); if (n > 0) { for (i=0; i MAXF?MAXF:tv1; maxvee = butt ? -kaasu*MAXV : kaasu*MAXV; // printf("maxvee: %f\tvauhti: %f\n", maxvee, vauhti); // kaanto = vauhti<-4.0 ? kaanto/(vauhti/(-4.0)) : kaanto; if (kaanto>0) { dJointSetHinge2Param (joint[3],dParamVel,kaanto); dJointSetHinge2Param (joint[3],dParamFMax,.5); dJointSetHinge2Param (joint[3],dParamLoStop,kaanto); dJointSetHinge2Param (joint[3],dParamHiStop,kaanto); dJointSetHinge2Param (joint[3],dParamFudgeFactor,0.1); r1 = LENGTH/tan((double)kaanto); beeta = atan(LENGTH/(r1+WIDTH)); dJointSetHinge2Param (joint[0],dParamVel,beeta); dJointSetHinge2Param (joint[0],dParamFMax,.5); dJointSetHinge2Param (joint[0],dParamLoStop,beeta); dJointSetHinge2Param (joint[0],dParamHiStop,beeta); dJointSetHinge2Param (joint[0],dParamFudgeFactor,0.1); v2 = tv1*(r1+WIDTH)/r1; v2 = VCONS*v2/vauhti; v2 = v2>MAXF?MAXF:v2; #ifdef TAKAVETO dJointSetHinge2Param (joint[1],dParamVel2, maxvee); dJointSetHinge2Param (joint[1],dParamFMax2, tv1); dJointSetHinge2Param (joint[2],dParamVel2, maxvee); dJointSetHinge2Param (joint[2],dParamFMax2, v2); #endif #ifdef ETUVETO dJointSetHinge2Param (joint[3],dParamVel2, maxvee); dJointSetHinge2Param (joint[3],dParamFMax2, tv1); dJointSetHinge2Param (joint[0],dParamVel2, maxvee); dJointSetHinge2Param (joint[0],dParamFMax2, v2); #endif } else { dJointSetHinge2Param (joint[0],dParamVel,kaanto); dJointSetHinge2Param (joint[0],dParamFMax,.5); dJointSetHinge2Param (joint[0],dParamLoStop,kaanto); dJointSetHinge2Param (joint[0],dParamHiStop,kaanto); dJointSetHinge2Param (joint[0],dParamFudgeFactor,0.1); r1 = LENGTH/tan((double)kaanto); beeta = -atan(LENGTH/(-r1+WIDTH)); dJointSetHinge2Param (joint[3],dParamVel,beeta); dJointSetHinge2Param (joint[3],dParamFMax,.5); dJointSetHinge2Param (joint[3],dParamLoStop,beeta); dJointSetHinge2Param (joint[3],dParamHiStop,beeta); dJointSetHinge2Param (joint[3],dParamFudgeFactor,0.1); v2 = tv1*(-r1+WIDTH)/r1; v2 = VCONS*v2/vauhti; v2 = v2>MAXF?MAXF:v2; #ifdef TAKAVETO dJointSetHinge2Param (joint[1],dParamVel2, maxvee); dJointSetHinge2Param (joint[1],dParamFMax2, v2); dJointSetHinge2Param (joint[2],dParamVel2, maxvee); dJointSetHinge2Param (joint[2],dParamFMax2, tv1); #endif #ifdef ETUVETO dJointSetHinge2Param (joint[0],dParamVel2, maxvee); dJointSetHinge2Param (joint[0],dParamFMax2, v2); dJointSetHinge2Param (joint[3],dParamVel2, maxvee); dJointSetHinge2Param (joint[3],dParamFMax2, tv1); #endif } // disable braking in front wheels #ifndef ETUVETO dJointSetHinge2Param (joint[3],dParamVel2, .0); dJointSetHinge2Param (joint[3],dParamFMax2, .0); dJointSetHinge2Param (joint[0],dParamVel2, .0); dJointSetHinge2Param (joint[0],dParamFMax2, .0); #endif } else { //jarrutys kaasu /= 6.0; if (kaanto>0) { dJointSetHinge2Param (joint[3],dParamVel,kaanto); dJointSetHinge2Param (joint[3],dParamFMax,.5); dJointSetHinge2Param (joint[3],dParamLoStop,kaanto); dJointSetHinge2Param (joint[3],dParamHiStop,kaanto); dJointSetHinge2Param (joint[3],dParamFudgeFactor,0.1); r1 = LENGTH/tan((double)kaanto); beeta = atan(LENGTH/(r1+WIDTH)); dJointSetHinge2Param (joint[0],dParamVel,beeta); dJointSetHinge2Param (joint[0],dParamFMax,.5); dJointSetHinge2Param (joint[0],dParamLoStop,beeta); dJointSetHinge2Param (joint[0],dParamHiStop,beeta); dJointSetHinge2Param (joint[0],dParamFudgeFactor,0.1); dJointSetHinge2Param (joint[2],dParamVel2, .0); dJointSetHinge2Param (joint[2],dParamFMax2, kaasu); dJointSetHinge2Param (joint[1],dParamVel2, .0); dJointSetHinge2Param (joint[1],dParamFMax2, kaasu); dJointSetHinge2Param (joint[3],dParamVel2, .0); dJointSetHinge2Param (joint[3],dParamFMax2, kaasu); dJointSetHinge2Param (joint[0],dParamVel2, .0); dJointSetHinge2Param (joint[0],dParamFMax2, kaasu); } else { dJointSetHinge2Param (joint[0],dParamVel,kaanto); dJointSetHinge2Param (joint[0],dParamFMax,.5); dJointSetHinge2Param (joint[0],dParamLoStop,kaanto); dJointSetHinge2Param (joint[0],dParamHiStop,kaanto); dJointSetHinge2Param (joint[0],dParamFudgeFactor,0.1); r1 = LENGTH/tan((double)kaanto); beeta = -atan(LENGTH/(-r1+WIDTH)); dJointSetHinge2Param (joint[3],dParamVel,beeta); dJointSetHinge2Param (joint[3],dParamFMax,.5); dJointSetHinge2Param (joint[3],dParamLoStop,beeta); dJointSetHinge2Param (joint[3],dParamHiStop,beeta); dJointSetHinge2Param (joint[3],dParamFudgeFactor,0.1); dJointSetHinge2Param (joint[2],dParamVel2, .0); dJointSetHinge2Param (joint[2],dParamFMax2, kaasu); dJointSetHinge2Param (joint[1],dParamVel2, .0); dJointSetHinge2Param (joint[1],dParamFMax2, kaasu); dJointSetHinge2Param (joint[3],dParamVel2, .0); dJointSetHinge2Param (joint[3],dParamFMax2, kaasu); dJointSetHinge2Param (joint[0],dParamVel2, .0); dJointSetHinge2Param (joint[0],dParamFMax2, kaasu); } } dSpaceCollide (space,0,&nearCallback); dWorldStep (world,0.05); // remove all contact joints dJointGroupEmpty (contactgroup); // } 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<=4; i++) dsDrawCylinder (dBodyGetPosition(body[i]), dBodyGetRotation(body[i]),0.04f,RADIUS); dVector3 ss; dGeomBoxGetLengths (ground_box,ss); dsDrawBox (dGeomGetPosition(ground_box),dGeomGetRotation(ground_box),ss); /* printf ("%.10f %.10f %.10f %.10f\n", dJointGetHingeAngle (joint[1]), dJointGetHingeAngle (joint[2]), dJointGetHingeAngleRate (joint[1]), dJointGetHingeAngleRate (joint[2])); */ } int main (int argc, char **argv) { int i; dMass m; // 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/textures"; // create world world = dWorldCreate(); space = dHashSpaceCreate(); contactgroup = dJointGroupCreate (0); dWorldSetGravity (world,0,0,-0.5); ground = dCreatePlane (space,0,0,1,0); // chassis body body[0] = dBodyCreate (world); dBodySetPosition (body[0],0,0,STARTZ-RADIUS+SUSPHEIGHT); dMassSetBox (&m,1,LENGTH,WIDTH,HEIGHT); dMassAdjust (&m,CMASS); dBodySetMass (body[0],&m); box[0] = dCreateBox (0,LENGTH,WIDTH,HEIGHT); dGeomSetBody (box[0],body[0]); // wheel bodies for (i=1; i<=4; i++) { body[i] = dBodyCreate (world); 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]); } dBodySetPosition (body[1],0.5*LENGTH, WIDTH*.5,STARTZ-HEIGHT*0.5); dBodySetPosition (body[4],0.5*LENGTH,-WIDTH*.5,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 wheel hinge /* joint[0] = dJointCreateHinge2 (world,0); dJointAttach (joint[0],body[0],body[1]); const dReal *a = dBodyGetPosition (body[1]); dJointSetHinge2Anchor (joint[0],a[0],a[1],a[2]); dJointSetHinge2Axis1 (joint[0],0,0,1); dJointSetHinge2Axis2 (joint[0],0,1,0); */ // front and back wheel hinges for (i=0; i<4; i++) { joint[i] = dJointCreateHinge2 (world,0); dJointAttach (joint[i],body[0],body[i+1]); const dReal *a = dBodyGetPosition (body[i+1]); dJointSetHinge2Anchor (joint[i],a[0],a[1],a[2]); dJointSetHinge2Axis1 (joint[i],0,0,1); dJointSetHinge2Axis2 (joint[i],0,1,0); } // set joint suspension for (i=0; i<4; i++) { dJointSetHinge2Param (joint[i],dParamSuspensionERP,SUSPERP); // .4 dJointSetHinge2Param (joint[i],dParamSuspensionCFM,SUSPCFM); // .8 } // lock back wheels along the steering axis 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); // the following alternative method is no good as the wheels may get out // of alignment: // dJointSetHinge2Param (joint[i],dParamVel,0); // dJointSetHinge2Param (joint[i],dParamFMax,dInfinity); } // create geometry group and add it to the space geom_group = dCreateGeomGroup (space); dGeomGroupAdd (geom_group,box[0]); dGeomGroupAdd (geom_group,sphere[0]); dGeomGroupAdd (geom_group,sphere[1]); dGeomGroupAdd (geom_group,sphere[2]); dGeomGroupAdd (geom_group,sphere[3]); // environment ground_box = dCreateBox (space,6,2,.8); dMatrix3 R; dRFromAxisAndAngle (R,0,3,0,-0.45); dGeomSetPosition (ground_box,2,0,-.3); dGeomSetRotation (ground_box,R); // run simulation dsSimulationLoop (argc,argv,560,440,&fn); dJointGroupDestroy (contactgroup); dSpaceDestroy (space); dWorldDestroy (world); dGeomDestroy (box[0]); dGeomDestroy (sphere[0]); dGeomDestroy (sphere[1]); dGeomDestroy (sphere[2]); dGeomDestroy (sphere[3]); SDL_Quit(); return 0; }