diff options
Diffstat (limited to 'libraries/ode-0.9\/ode/demo/demo_friction.cpp')
-rwxr-xr-x | libraries/ode-0.9\/ode/demo/demo_friction.cpp | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/libraries/ode-0.9\/ode/demo/demo_friction.cpp b/libraries/ode-0.9\/ode/demo/demo_friction.cpp new file mode 100755 index 0000000..36ba2d4 --- /dev/null +++ b/libraries/ode-0.9\/ode/demo/demo_friction.cpp | |||
@@ -0,0 +1,206 @@ | |||
1 | /************************************************************************* | ||
2 | * * | ||
3 | * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * | ||
4 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * | ||
5 | * * | ||
6 | * This library is free software; you can redistribute it and/or * | ||
7 | * modify it under the terms of EITHER: * | ||
8 | * (1) The GNU Lesser General Public License as published by the Free * | ||
9 | * Software Foundation; either version 2.1 of the License, or (at * | ||
10 | * your option) any later version. The text of the GNU Lesser * | ||
11 | * General Public License is included with this library in the * | ||
12 | * file LICENSE.TXT. * | ||
13 | * (2) The BSD-style license that is included with this library in * | ||
14 | * the file LICENSE-BSD.TXT. * | ||
15 | * * | ||
16 | * This library is distributed in the hope that it will be useful, * | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * | ||
19 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * | ||
20 | * * | ||
21 | *************************************************************************/ | ||
22 | |||
23 | /* | ||
24 | |||
25 | test the Coulomb friction approximation. | ||
26 | |||
27 | a 10x10 array of boxes is made, each of which rests on the ground. | ||
28 | a horizantal force is applied to each box to try and get it to slide. | ||
29 | box[i][j] has a mass (i+1)*MASS and a force (j+1)*FORCE. by the Coloumb | ||
30 | friction model, the box should only slide if the force is greater than MU | ||
31 | times the contact normal force, i.e. | ||
32 | |||
33 | f > MU * body_mass * GRAVITY | ||
34 | (j+1)*FORCE > MU * (i+1)*MASS * GRAVITY | ||
35 | (j+1) > (i+1) * (MU*MASS*GRAVITY/FORCE) | ||
36 | (j+1) > (i+1) * k | ||
37 | |||
38 | this should be independent of the number of contact points, as N contact | ||
39 | points will each have 1/N'th the normal force but the pushing force will | ||
40 | have to overcome N contacts. the constants are chosen so that k=1. | ||
41 | thus you should see a triangle made of half the bodies in the array start to | ||
42 | slide. | ||
43 | |||
44 | */ | ||
45 | |||
46 | |||
47 | #include <ode/ode.h> | ||
48 | #include <drawstuff/drawstuff.h> | ||
49 | |||
50 | #ifdef _MSC_VER | ||
51 | #pragma warning(disable:4244 4305) // for VC++, no precision loss complaints | ||
52 | #endif | ||
53 | |||
54 | // select correct drawing functions | ||
55 | |||
56 | #ifdef dDOUBLE | ||
57 | #define dsDrawBox dsDrawBoxD | ||
58 | #define dsDrawSphere dsDrawSphereD | ||
59 | #define dsDrawCylinder dsDrawCylinderD | ||
60 | #define dsDrawCapsule dsDrawCapsuleD | ||
61 | #endif | ||
62 | |||
63 | |||
64 | // some constants | ||
65 | |||
66 | #define LENGTH 0.2 // box length & width | ||
67 | #define HEIGHT 0.05 // box height | ||
68 | #define MASS 0.2 // mass of box[i][j] = (i+1) * MASS | ||
69 | #define FORCE 0.05 // force applied to box[i][j] = (j+1) * FORCE | ||
70 | #define MU 0.5 // the global mu to use | ||
71 | #define GRAVITY 0.5 // the global gravity to use | ||
72 | #define N1 10 // number of different forces to try | ||
73 | #define N2 10 // number of different masses to try | ||
74 | |||
75 | |||
76 | // dynamics and collision objects | ||
77 | |||
78 | static dWorldID world; | ||
79 | static dSpaceID space; | ||
80 | static dBodyID body[N1][N2]; | ||
81 | static dJointGroupID contactgroup; | ||
82 | static dGeomID ground; | ||
83 | static dGeomID box[N1][N2]; | ||
84 | |||
85 | |||
86 | |||
87 | // this is called by dSpaceCollide when two objects in space are | ||
88 | // potentially colliding. | ||
89 | |||
90 | static void nearCallback (void *data, dGeomID o1, dGeomID o2) | ||
91 | { | ||
92 | int i; | ||
93 | |||
94 | // only collide things with the ground | ||
95 | int g1 = (o1 == ground); | ||
96 | int g2 = (o2 == ground); | ||
97 | if (!(g1 ^ g2)) return; | ||
98 | |||
99 | dBodyID b1 = dGeomGetBody(o1); | ||
100 | dBodyID b2 = dGeomGetBody(o2); | ||
101 | |||
102 | dContact contact[3]; // up to 3 contacts per box | ||
103 | for (i=0; i<3; i++) { | ||
104 | contact[i].surface.mode = dContactSoftCFM | dContactApprox1; | ||
105 | contact[i].surface.mu = MU; | ||
106 | contact[i].surface.soft_cfm = 0.01; | ||
107 | } | ||
108 | if (int numc = dCollide (o1,o2,3,&contact[0].geom,sizeof(dContact))) { | ||
109 | for (i=0; i<numc; i++) { | ||
110 | dJointID c = dJointCreateContact (world,contactgroup,contact+i); | ||
111 | dJointAttach (c,b1,b2); | ||
112 | } | ||
113 | } | ||
114 | } | ||
115 | |||
116 | |||
117 | // start simulation - set viewpoint | ||
118 | |||
119 | static void start() | ||
120 | { | ||
121 | static float xyz[3] = {1.7772,-0.7924,2.7600}; | ||
122 | static float hpr[3] = {90.0000,-54.0000,0.0000}; | ||
123 | dsSetViewpoint (xyz,hpr); | ||
124 | } | ||
125 | |||
126 | |||
127 | // simulation loop | ||
128 | |||
129 | static void simLoop (int pause) | ||
130 | { | ||
131 | int i; | ||
132 | if (!pause) { | ||
133 | // apply forces to all bodies | ||
134 | for (i=0; i<N1; i++) { | ||
135 | for (int j=0; j<N2; j++) { | ||
136 | dBodyAddForce (body[i][j],FORCE*(i+1),0,0); | ||
137 | } | ||
138 | } | ||
139 | |||
140 | dSpaceCollide (space,0,&nearCallback); | ||
141 | dWorldStep (world,0.05); | ||
142 | |||
143 | // remove all contact joints | ||
144 | dJointGroupEmpty (contactgroup); | ||
145 | } | ||
146 | |||
147 | dsSetColor (1,0,1); | ||
148 | dReal sides[3] = {LENGTH,LENGTH,HEIGHT}; | ||
149 | for (i=0; i<N1; i++) { | ||
150 | for (int j=0; j<N2; j++) { | ||
151 | dsDrawBox (dGeomGetPosition(box[i][j]),dGeomGetRotation(box[i][j]), | ||
152 | sides); | ||
153 | } | ||
154 | } | ||
155 | } | ||
156 | |||
157 | |||
158 | int main (int argc, char **argv) | ||
159 | { | ||
160 | int i,j; | ||
161 | dMass m; | ||
162 | |||
163 | // setup pointers to drawstuff callback functions | ||
164 | dsFunctions fn; | ||
165 | fn.version = DS_VERSION; | ||
166 | fn.start = &start; | ||
167 | fn.step = &simLoop; | ||
168 | fn.command = 0; | ||
169 | fn.stop = 0; | ||
170 | fn.path_to_textures = "../../drawstuff/textures"; | ||
171 | if(argc==2) | ||
172 | { | ||
173 | fn.path_to_textures = argv[1]; | ||
174 | } | ||
175 | |||
176 | // create world | ||
177 | dInitODE(); | ||
178 | world = dWorldCreate(); | ||
179 | space = dHashSpaceCreate (0); | ||
180 | contactgroup = dJointGroupCreate (0); | ||
181 | dWorldSetGravity (world,0,0,-GRAVITY); | ||
182 | ground = dCreatePlane (space,0,0,1,0); | ||
183 | |||
184 | // bodies | ||
185 | for (i=0; i<N1; i++) { | ||
186 | for (j=0; j<N2; j++) { | ||
187 | body[i][j] = dBodyCreate (world); | ||
188 | dMassSetBox (&m,1,LENGTH,LENGTH,HEIGHT); | ||
189 | dMassAdjust (&m,MASS*(j+1)); | ||
190 | dBodySetMass (body[i][j],&m); | ||
191 | dBodySetPosition (body[i][j],i*2*LENGTH,j*2*LENGTH,HEIGHT*0.5); | ||
192 | |||
193 | box[i][j] = dCreateBox (space,LENGTH,LENGTH,HEIGHT); | ||
194 | dGeomSetBody (box[i][j],body[i][j]); | ||
195 | } | ||
196 | } | ||
197 | |||
198 | // run simulation | ||
199 | dsSimulationLoop (argc,argv,352,288,&fn); | ||
200 | |||
201 | dJointGroupDestroy (contactgroup); | ||
202 | dSpaceDestroy (space); | ||
203 | dWorldDestroy (world); | ||
204 | dCloseODE(); | ||
205 | return 0; | ||
206 | } | ||