/************************************************************************* * * * 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. * * * *************************************************************************/ /* test the Coulomb friction approximation. a 10x10 array of boxes is made, each of which rests on the ground. a horizantal force is applied to each box to try and get it to slide. box[i][j] has a mass (i+1)*MASS and a force (j+1)*FORCE. by the Coloumb friction model, the box should only slide if the force is greater than MU times the contact normal force, i.e. f > MU * body_mass * GRAVITY (j+1)*FORCE > MU * (i+1)*MASS * GRAVITY (j+1) > (i+1) * (MU*MASS*GRAVITY/FORCE) (j+1) > (i+1) * k this should be independent of the number of contact points, as N contact points will each have 1/N'th the normal force but the pushing force will have to overcome N contacts. the constants are chosen so that k=1. thus you should see a triangle made of half the bodies in the array start to slide. */ #include #include #ifdef _MSC_VER #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 dsDrawCapsule dsDrawCapsuleD #endif // some constants #define LENGTH 0.2 // box length & width #define HEIGHT 0.05 // box height #define MASS 0.2 // mass of box[i][j] = (i+1) * MASS #define FORCE 0.05 // force applied to box[i][j] = (j+1) * FORCE #define MU 0.5 // the global mu to use #define GRAVITY 0.5 // the global gravity to use #define N1 10 // number of different forces to try #define N2 10 // number of different masses to try // dynamics and collision objects static dWorldID world; static dSpaceID space; static dBodyID body[N1][N2]; static dJointGroupID contactgroup; static dGeomID ground; static dGeomID box[N1][N2]; // this is called by dSpaceCollide when two objects in space are // potentially colliding. static void nearCallback (void *data, dGeomID o1, dGeomID o2) { int i; // only collide things with the ground int g1 = (o1 == ground); int g2 = (o2 == ground); if (!(g1 ^ g2)) return; dBodyID b1 = dGeomGetBody(o1); dBodyID b2 = dGeomGetBody(o2); dContact contact[3]; // up to 3 contacts per box for (i=0; i<3; i++) { contact[i].surface.mode = dContactSoftCFM | dContactApprox1; contact[i].surface.mu = MU; contact[i].surface.soft_cfm = 0.01; } if (int numc = dCollide (o1,o2,3,&contact[0].geom,sizeof(dContact))) { for (i=0; i