demo_gyroscopic.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /*************************************************************************
  2. * *
  3. * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
  4. * All rights reserved. Email: [email protected] 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. #include <ode/ode.h>
  23. #include <drawstuff/drawstuff.h>
  24. #include "texturepath.h"
  25. #ifdef _MSC_VER
  26. #pragma warning(disable:4244 4305) // for VC++, no precision loss complaints
  27. #endif
  28. // select correct drawing functions
  29. #ifdef dDOUBLE
  30. #define dsDrawBox dsDrawBoxD
  31. #define dsDrawSphere dsDrawSphereD
  32. #define dsDrawCylinder dsDrawCylinderD
  33. #define dsDrawCapsule dsDrawCapsuleD
  34. #define dsDrawConvex dsDrawConvexD
  35. #endif
  36. bool write_world = false;
  37. bool show_contacts = false;
  38. dWorld * world;
  39. dBody *top1, *top2;
  40. dSpace *space;
  41. dJointGroup contactgroup;
  42. const dReal pinradius = 0.05f;
  43. const dReal pinlength = 1.5f;
  44. const dReal topradius = 1.0f;
  45. const dReal toplength = 0.25f;
  46. const dReal topmass = 1.0f;
  47. #define MAX_CONTACTS 4
  48. static void nearCallback (void *, dGeomID o1, dGeomID o2)
  49. {
  50. // for drawing the contact points
  51. dMatrix3 RI;
  52. dRSetIdentity (RI);
  53. const dReal ss[3] = {0.02,0.02,0.02};
  54. int i;
  55. dBodyID b1 = dGeomGetBody(o1);
  56. dBodyID b2 = dGeomGetBody(o2);
  57. dContact contact[MAX_CONTACTS];
  58. int numc = dCollide (o1,o2,MAX_CONTACTS,&contact[0].geom,
  59. sizeof(dContact));
  60. for (i=0; i<numc; i++) {
  61. contact[i].surface.mode = dContactApprox1;
  62. contact[i].surface.mu = 2;
  63. dJointID c = dJointCreateContact (*world,contactgroup,contact+i);
  64. dJointAttach (c,b1,b2);
  65. if (show_contacts)
  66. dsDrawBox (contact[i].geom.pos, RI, ss);
  67. }
  68. }
  69. // start simulation - set viewpoint
  70. static void start()
  71. {
  72. static float xyz[3] = {4.777f, -2.084f, 2.18f};
  73. static float hpr[3] = {153.0f, -14.5f, 0.0f};
  74. dsSetViewpoint (xyz,hpr);
  75. printf ("Orange top approximates conservation of angular momentum\n");
  76. printf ("Green top uses conservation of angular velocity\n");
  77. printf ("---\n");
  78. printf ("SPACE to reset\n");
  79. printf ("A to tilt the tops.\n");
  80. printf ("T to toggle showing the contact points.\n");
  81. printf ("1 to save the current state to 'state.dif'.\n");
  82. }
  83. char locase (char c)
  84. {
  85. if (c >= 'A' && c <= 'Z') return c - ('a'-'A');
  86. else return c;
  87. }
  88. // called when a key pressed
  89. static void reset();
  90. static void tilt();
  91. static void command (int cmd)
  92. {
  93. cmd = locase (cmd);
  94. if (cmd == ' ')
  95. {
  96. reset();
  97. }
  98. else if (cmd == 'a') {
  99. tilt();
  100. }
  101. else if (cmd == 't') {
  102. show_contacts = !show_contacts;
  103. }
  104. else if (cmd == '1') {
  105. write_world = true;
  106. }
  107. }
  108. // simulation loop
  109. static void simLoop (int pause)
  110. {
  111. dsSetColor (0,0,2);
  112. space->collide(0,&nearCallback);
  113. if (!pause)
  114. //world->quickStep(0.02);
  115. world->step(0.02);
  116. if (write_world) {
  117. FILE *f = fopen ("state.dif","wt");
  118. if (f) {
  119. dWorldExportDIF (*world,f,"X");
  120. fclose (f);
  121. }
  122. write_world = false;
  123. }
  124. // remove all contact joints
  125. dJointGroupEmpty (contactgroup);
  126. dsSetTexture (DS_WOOD);
  127. dsSetColor (1,0.5f,0);
  128. dsDrawCylinder(top1->getPosition(),
  129. top1->getRotation(),
  130. toplength, topradius);
  131. dsDrawCapsule(top1->getPosition(),
  132. top1->getRotation(),
  133. pinlength, pinradius);
  134. dsSetColor (0.5f,1,0);
  135. dsDrawCylinder(top2->getPosition(),
  136. top2->getRotation(),
  137. toplength, topradius);
  138. dsDrawCapsule(top2->getPosition(),
  139. top2->getRotation(),
  140. pinlength, pinradius);
  141. }
  142. static void reset()
  143. {
  144. dMatrix3 R;
  145. dRSetIdentity(R);
  146. top1->setRotation(R);
  147. top2->setRotation(R);
  148. top1->setPosition(0.8f, -2, 2);
  149. top2->setPosition(0.8f, 2, 2);
  150. top1->setAngularVel(1,0,7);
  151. top2->setAngularVel(1,0,7);
  152. top1->setLinearVel(0,0.2f,0);
  153. top2->setLinearVel(0,0.2f,0);
  154. }
  155. static void tilt()
  156. {
  157. top1->addTorque(0, 10, 0);
  158. top2->addTorque(0, 10, 0);
  159. }
  160. int main (int argc, char **argv)
  161. {
  162. // setup pointers to drawstuff callback functions
  163. dsFunctions fn;
  164. fn.version = DS_VERSION;
  165. fn.start = &start;
  166. fn.step = &simLoop;
  167. fn.command = &command;
  168. fn.stop = 0;
  169. fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH;
  170. // create world
  171. dInitODE();
  172. world = new dWorld();
  173. world->setGravity(0,0,-0.5f);
  174. world->setCFM(1e-5f);
  175. world->setLinearDamping(0.00001f);
  176. world->setAngularDamping(0.0001f);
  177. space = new dSimpleSpace(0);
  178. dPlane *floor = new dPlane(*space, 0,0,1,0);
  179. top1 = new dBody(*world);
  180. top2 = new dBody(*world);
  181. dMass m;
  182. m.setCylinderTotal(1, 3, topradius, toplength);
  183. top1->setMass(m);
  184. top2->setMass(m);
  185. dGeom *g1, *g2, *pin1, *pin2;
  186. g1 = new dCylinder(*space, topradius, toplength);
  187. g1->setBody(*top1);
  188. g2 = new dCylinder(*space, topradius, toplength);
  189. g2->setBody(*top2);
  190. pin1 = new dCapsule(*space, pinradius, pinlength);
  191. pin1->setBody(*top1);
  192. pin2 = new dCapsule(*space, pinradius, pinlength);
  193. pin2->setBody(*top2);
  194. top2->setGyroscopicMode(false);
  195. reset();
  196. // run simulation
  197. dsSimulationLoop (argc,argv,512,384,&fn);
  198. delete g1;
  199. delete g2;
  200. delete pin1;
  201. delete pin2;
  202. delete floor;
  203. contactgroup.empty();
  204. delete top1;
  205. delete top2;
  206. delete space;
  207. delete world;
  208. dCloseODE();
  209. }