aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ode-0.9/ode/demo/demo_friction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ode-0.9/ode/demo/demo_friction.cpp')
-rw-r--r--libraries/ode-0.9/ode/demo/demo_friction.cpp206
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 100644
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
25test the Coulomb friction approximation.
26
27a 10x10 array of boxes is made, each of which rests on the ground.
28a horizantal force is applied to each box to try and get it to slide.
29box[i][j] has a mass (i+1)*MASS and a force (j+1)*FORCE. by the Coloumb
30friction model, the box should only slide if the force is greater than MU
31times 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
38this should be independent of the number of contact points, as N contact
39points will each have 1/N'th the normal force but the pushing force will
40have to overcome N contacts. the constants are chosen so that k=1.
41thus you should see a triangle made of half the bodies in the array start to
42slide.
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
78static dWorldID world;
79static dSpaceID space;
80static dBodyID body[N1][N2];
81static dJointGroupID contactgroup;
82static dGeomID ground;
83static dGeomID box[N1][N2];
84
85
86
87// this is called by dSpaceCollide when two objects in space are
88// potentially colliding.
89
90static 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
119static 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
129static 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
158int 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}