diff options
Diffstat (limited to 'libraries/ode-0.9/ode/demo/demo_feedback.cpp')
-rw-r--r-- | libraries/ode-0.9/ode/demo/demo_feedback.cpp | 314 |
1 files changed, 314 insertions, 0 deletions
diff --git a/libraries/ode-0.9/ode/demo/demo_feedback.cpp b/libraries/ode-0.9/ode/demo/demo_feedback.cpp new file mode 100644 index 0000000..fd49278 --- /dev/null +++ b/libraries/ode-0.9/ode/demo/demo_feedback.cpp | |||
@@ -0,0 +1,314 @@ | |||
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 | // Test for breaking joints, by Bram Stolk | ||
24 | |||
25 | #include <ode/config.h> | ||
26 | #include <assert.h> | ||
27 | #ifdef HAVE_UNISTD_H | ||
28 | #include <unistd.h> | ||
29 | #endif | ||
30 | #include <ode/ode.h> | ||
31 | #include <drawstuff/drawstuff.h> | ||
32 | |||
33 | |||
34 | #ifdef _MSC_VER | ||
35 | #pragma warning(disable:4244 4305) // for VC++, no precision loss complaints | ||
36 | #endif | ||
37 | |||
38 | #ifdef dDOUBLE | ||
39 | #define dsDrawBox dsDrawBoxD | ||
40 | #define dsDrawCylinder dsDrawCylinderD | ||
41 | #endif | ||
42 | |||
43 | |||
44 | // dynamics and collision objects (chassis, 3 wheels, environment) | ||
45 | |||
46 | static dWorldID world; | ||
47 | static dSpaceID space; | ||
48 | |||
49 | static const int STACKCNT=10; // nr of weights on bridge | ||
50 | static const int SEGMCNT=16; // nr of segments in bridge | ||
51 | static const float SEGMDIM[3] = { 0.9, 4, 0.1 }; | ||
52 | |||
53 | static dGeomID groundgeom; | ||
54 | static dBodyID segbodies[SEGMCNT]; | ||
55 | static dGeomID seggeoms[SEGMCNT]; | ||
56 | static dBodyID stackbodies[STACKCNT]; | ||
57 | static dGeomID stackgeoms[STACKCNT]; | ||
58 | static dJointID hinges[SEGMCNT-1]; | ||
59 | static dJointID sliders[2]; | ||
60 | static dJointFeedback jfeedbacks[SEGMCNT-1]; | ||
61 | static dReal colours[SEGMCNT]; | ||
62 | static int stress[SEGMCNT-1]; | ||
63 | |||
64 | static dJointGroupID contactgroup; | ||
65 | |||
66 | |||
67 | // this is called by dSpaceCollide when two objects in space are | ||
68 | // potentially colliding. | ||
69 | |||
70 | static void nearCallback (void *data, dGeomID o1, dGeomID o2) | ||
71 | { | ||
72 | assert(o1); | ||
73 | assert(o2); | ||
74 | |||
75 | if (dGeomIsSpace(o1) || dGeomIsSpace(o2)) | ||
76 | { | ||
77 | fprintf(stderr,"testing space %p %p\n", o1,o2); | ||
78 | // colliding a space with something | ||
79 | dSpaceCollide2(o1,o2,data,&nearCallback); | ||
80 | // Note we do not want to test intersections within a space, | ||
81 | // only between spaces. | ||
82 | return; | ||
83 | } | ||
84 | |||
85 | const int N = 32; | ||
86 | dContact contact[N]; | ||
87 | int n = dCollide (o1,o2,N,&(contact[0].geom),sizeof(dContact)); | ||
88 | if (n > 0) | ||
89 | { | ||
90 | for (int i=0; i<n; i++) | ||
91 | { | ||
92 | contact[i].surface.mode = dContactSoftERP | dContactSoftCFM | dContactApprox1; | ||
93 | contact[i].surface.mu = 100.0; | ||
94 | contact[i].surface.soft_erp = 0.96; | ||
95 | contact[i].surface.soft_cfm = 0.02; | ||
96 | dJointID c = dJointCreateContact (world,contactgroup,&contact[i]); | ||
97 | dJointAttach (c, | ||
98 | dGeomGetBody(contact[i].geom.g1), | ||
99 | dGeomGetBody(contact[i].geom.g2)); | ||
100 | } | ||
101 | } | ||
102 | } | ||
103 | |||
104 | |||
105 | // start simulation - set viewpoint | ||
106 | |||
107 | static void start() | ||
108 | { | ||
109 | static float xyz[3] = { -6, 8, 6}; | ||
110 | static float hpr[3] = { -65.0f, -27.0f, 0.0f}; | ||
111 | dsSetViewpoint (xyz,hpr); | ||
112 | } | ||
113 | |||
114 | |||
115 | |||
116 | // called when a key pressed | ||
117 | |||
118 | static void command (int cmd) | ||
119 | { | ||
120 | } | ||
121 | |||
122 | |||
123 | |||
124 | void drawGeom (dGeomID g) | ||
125 | { | ||
126 | const dReal *pos = dGeomGetPosition(g); | ||
127 | const dReal *R = dGeomGetRotation(g); | ||
128 | |||
129 | int type = dGeomGetClass (g); | ||
130 | if (type == dBoxClass) | ||
131 | { | ||
132 | dVector3 sides; | ||
133 | dGeomBoxGetLengths (g, sides); | ||
134 | dsDrawBox (pos,R,sides); | ||
135 | } | ||
136 | if (type == dCylinderClass) | ||
137 | { | ||
138 | dReal r,l; | ||
139 | dGeomCylinderGetParams(g, &r, &l); | ||
140 | dsDrawCylinder (pos, R, l, r); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | |||
145 | static void inspectJoints(void) | ||
146 | { | ||
147 | const dReal forcelimit = 2000.0; | ||
148 | int i; | ||
149 | for (i=0; i<SEGMCNT-1; i++) | ||
150 | { | ||
151 | if (dJointGetBody(hinges[i], 0)) | ||
152 | { | ||
153 | // This joint has not snapped already... inspect it. | ||
154 | dReal l0 = dLENGTH(jfeedbacks[i].f1); | ||
155 | dReal l1 = dLENGTH(jfeedbacks[i].f2); | ||
156 | colours[i+0] = 0.95*colours[i+0] + 0.05 * l0/forcelimit; | ||
157 | colours[i+1] = 0.95*colours[i+1] + 0.05 * l1/forcelimit; | ||
158 | if (l0 > forcelimit || l1 > forcelimit) | ||
159 | stress[i]++; | ||
160 | else | ||
161 | stress[i]=0; | ||
162 | if (stress[i]>4) | ||
163 | { | ||
164 | // Low-pass filter the noisy feedback data. | ||
165 | // Only after 4 consecutive timesteps with excessive load, snap. | ||
166 | fprintf(stderr,"SNAP! (that was the sound of joint %d breaking)\n", i); | ||
167 | dJointAttach (hinges[i], 0, 0); | ||
168 | } | ||
169 | } | ||
170 | } | ||
171 | } | ||
172 | |||
173 | |||
174 | // simulation loop | ||
175 | |||
176 | static void simLoop (int pause) | ||
177 | { | ||
178 | int i; | ||
179 | |||
180 | double simstep = 0.005; // 5ms simulation steps | ||
181 | double dt = dsElapsedTime(); | ||
182 | int nrofsteps = (int) ceilf(dt/simstep); | ||
183 | for (i=0; i<nrofsteps && !pause; i++) | ||
184 | { | ||
185 | dSpaceCollide (space,0,&nearCallback); | ||
186 | dWorldQuickStep (world, simstep); | ||
187 | dJointGroupEmpty (contactgroup); | ||
188 | inspectJoints(); | ||
189 | } | ||
190 | |||
191 | for (i=0; i<SEGMCNT; i++) | ||
192 | { | ||
193 | float r=0,g=0,b=0.2; | ||
194 | float v = colours[i]; | ||
195 | if (v>1.0) v=1.0; | ||
196 | if (v<0.5) | ||
197 | { | ||
198 | r=2*v; | ||
199 | g=1.0; | ||
200 | } | ||
201 | else | ||
202 | { | ||
203 | r=1.0; | ||
204 | g=2*(1.0-v); | ||
205 | } | ||
206 | dsSetColor (r,g,b); | ||
207 | drawGeom(seggeoms[i]); | ||
208 | } | ||
209 | dsSetColor (1,1,1); | ||
210 | for (i=0; i<STACKCNT; i++) | ||
211 | drawGeom(stackgeoms[i]); | ||
212 | } | ||
213 | |||
214 | |||
215 | |||
216 | int main (int argc, char **argv) | ||
217 | { | ||
218 | dMass m; | ||
219 | |||
220 | // setup pointers to drawstuff callback functions | ||
221 | dsFunctions fn; | ||
222 | fn.version = DS_VERSION; | ||
223 | fn.start = &start; | ||
224 | fn.step = &simLoop; | ||
225 | fn.command = &command; | ||
226 | fn.stop = 0; | ||
227 | fn.path_to_textures = "../../drawstuff/textures"; | ||
228 | if(argc==2) | ||
229 | { | ||
230 | fn.path_to_textures = argv[1]; | ||
231 | } | ||
232 | |||
233 | // create world | ||
234 | dInitODE(); | ||
235 | world = dWorldCreate(); | ||
236 | space = dHashSpaceCreate (0); | ||
237 | contactgroup = dJointGroupCreate (0); | ||
238 | dWorldSetGravity (world,0,0,-9.8); | ||
239 | dWorldSetQuickStepNumIterations (world, 20); | ||
240 | |||
241 | int i; | ||
242 | for (i=0; i<SEGMCNT; i++) | ||
243 | { | ||
244 | segbodies[i] = dBodyCreate (world); | ||
245 | dBodySetPosition(segbodies[i], i - SEGMCNT/2.0, 0, 5); | ||
246 | dMassSetBox (&m, 1, SEGMDIM[0], SEGMDIM[1], SEGMDIM[2]); | ||
247 | dBodySetMass (segbodies[i], &m); | ||
248 | seggeoms[i] = dCreateBox (0, SEGMDIM[0], SEGMDIM[1], SEGMDIM[2]); | ||
249 | dGeomSetBody (seggeoms[i], segbodies[i]); | ||
250 | dSpaceAdd (space, seggeoms[i]); | ||
251 | } | ||
252 | |||
253 | for (i=0; i<SEGMCNT-1; i++) | ||
254 | { | ||
255 | hinges[i] = dJointCreateHinge (world,0); | ||
256 | dJointAttach (hinges[i], segbodies[i],segbodies[i+1]); | ||
257 | dJointSetHingeAnchor (hinges[i], i + 0.5 - SEGMCNT/2.0, 0, 5); | ||
258 | dJointSetHingeAxis (hinges[i], 0,1,0); | ||
259 | dJointSetHingeParam (hinges[i],dParamFMax, 8000.0); | ||
260 | // NOTE: | ||
261 | // Here we tell ODE where to put the feedback on the forces for this hinge | ||
262 | dJointSetFeedback (hinges[i], jfeedbacks+i); | ||
263 | stress[i]=0; | ||
264 | } | ||
265 | |||
266 | for (i=0; i<STACKCNT; i++) | ||
267 | { | ||
268 | stackbodies[i] = dBodyCreate(world); | ||
269 | dMassSetBox (&m, 2.0, 2, 2, 0.6); | ||
270 | dBodySetMass(stackbodies[i],&m); | ||
271 | |||
272 | stackgeoms[i] = dCreateBox(0, 2, 2, 0.6); | ||
273 | dGeomSetBody(stackgeoms[i], stackbodies[i]); | ||
274 | dBodySetPosition(stackbodies[i], 0,0,8+2*i); | ||
275 | dSpaceAdd(space, stackgeoms[i]); | ||
276 | } | ||
277 | |||
278 | sliders[0] = dJointCreateSlider (world,0); | ||
279 | dJointAttach(sliders[0], segbodies[0], 0); | ||
280 | dJointSetSliderAxis (sliders[0], 1,0,0); | ||
281 | dJointSetSliderParam (sliders[0],dParamFMax, 4000.0); | ||
282 | dJointSetSliderParam (sliders[0],dParamLoStop, 0.0); | ||
283 | dJointSetSliderParam (sliders[0],dParamHiStop, 0.2); | ||
284 | |||
285 | sliders[1] = dJointCreateSlider (world,0); | ||
286 | dJointAttach(sliders[1], segbodies[SEGMCNT-1], 0); | ||
287 | dJointSetSliderAxis (sliders[1], 1,0,0); | ||
288 | dJointSetSliderParam (sliders[1],dParamFMax, 4000.0); | ||
289 | dJointSetSliderParam (sliders[1],dParamLoStop, 0.0); | ||
290 | dJointSetSliderParam (sliders[1],dParamHiStop, -0.2); | ||
291 | |||
292 | groundgeom = dCreatePlane(space, 0,0,1,0); | ||
293 | |||
294 | for (i=0; i<SEGMCNT; i++) | ||
295 | colours[i]=0.0; | ||
296 | |||
297 | // run simulation | ||
298 | dsSimulationLoop (argc,argv,352,288,&fn); | ||
299 | |||
300 | dJointGroupEmpty (contactgroup); | ||
301 | dJointGroupDestroy (contactgroup); | ||
302 | |||
303 | // First destroy seggeoms, then space, then the world. | ||
304 | for (i=0; i<SEGMCNT; i++) | ||
305 | dGeomDestroy (seggeoms[i]); | ||
306 | for (i=0; i<STACKCNT; i++) | ||
307 | dGeomDestroy (stackgeoms[i]); | ||
308 | |||
309 | dSpaceDestroy(space); | ||
310 | dWorldDestroy (world); | ||
311 | dCloseODE(); | ||
312 | return 0; | ||
313 | } | ||
314 | |||