demo_transmission.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  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 dDOUBLE
  26. #define dsDrawCylinder dsDrawCylinderD
  27. #define dsDrawLine dsDrawLineD
  28. #define dsDrawSphere dsDrawSphereD
  29. #endif
  30. dReal theta = M_PI / 4;
  31. dReal ratio = 1, speed = 5, rho_1 = 1, rho_2 = 1, backlash = 0.1;
  32. int mode = 0;
  33. dWorldID world;
  34. dSpaceID space;
  35. dBodyID body1, body2;
  36. dGeomID geom1, geom2;
  37. dJointID hinge1, hinge2, transmission;
  38. dJointFeedback feedback;
  39. void setup() {
  40. dMatrix3 R;
  41. switch (mode) {
  42. case 0:
  43. // Parallel axes.
  44. dBodySetPosition(body1, 1, 0, 1);
  45. dBodySetPosition(body2, -1, 0, 1);
  46. dRSetIdentity (R);
  47. dBodySetRotation (body1, R);
  48. dBodySetRotation (body2, R);
  49. dJointSetHingeAnchor(hinge2, -1, 0, 1);
  50. dJointSetHingeAxis(hinge2, 0, 0, 1);
  51. dJointSetHingeAnchor(hinge1, 1, 0, 1);
  52. dJointSetHingeAxis(hinge1, 0, 0, 1);
  53. dJointSetTransmissionMode(transmission, dTransmissionParallelAxes);
  54. dJointSetTransmissionRatio(transmission, ratio);
  55. dJointSetTransmissionAnchor1(transmission, 1, 0, 1);
  56. dJointSetTransmissionAnchor2(transmission, -1, 0, 1);
  57. dJointSetTransmissionAxis(transmission, 0, 0, 1);
  58. break;
  59. case 1:
  60. // Intersecting axes.
  61. dBodySetPosition(body1, 1, 0, 1);
  62. dBodySetPosition(body2, -1, 0, 2);
  63. dRSetIdentity (R);
  64. dBodySetRotation (body1, R);
  65. dRFromZAxis (R, cos(theta), 0, sin(theta));
  66. dBodySetRotation (body2, R);
  67. dJointSetHingeAnchor(hinge2, -1, 0, 2);
  68. dJointSetHingeAxis(hinge2, cos(theta), 0, sin(theta));
  69. dJointSetHingeAnchor(hinge1, 1, 0, 1);
  70. dJointSetHingeAxis(hinge1, 0, 0, 1);
  71. dJointSetTransmissionMode(transmission, dTransmissionIntersectingAxes);
  72. dJointSetTransmissionAnchor1(transmission, 1, 0, 1);
  73. dJointSetTransmissionAnchor2(transmission, -1, 0, 2);
  74. dJointSetTransmissionAxis1(transmission, 0, 0, -1);
  75. dJointSetTransmissionAxis2(transmission, cos(theta), 0, sin(theta));
  76. break;
  77. case 2:
  78. // Chain.
  79. dBodySetPosition(body1, 2, 0, 1);
  80. dBodySetPosition(body2, -2, 0, 1);
  81. dRSetIdentity (R);
  82. dBodySetRotation (body1, R);
  83. dBodySetRotation (body2, R);
  84. dJointSetHingeAnchor(hinge2, -2, 0, 1);
  85. dJointSetHingeAxis(hinge2, 0, 0, 1);
  86. dJointSetHingeAnchor(hinge1, 2, 0, 1);
  87. dJointSetHingeAxis(hinge1, 0, 0, 1);
  88. dJointSetTransmissionMode(transmission, dTransmissionChainDrive);
  89. dJointSetTransmissionAnchor1(transmission, 2, 0, 1);
  90. dJointSetTransmissionAnchor2(transmission, -2, 0, 1);
  91. dJointSetTransmissionRadius1(transmission, rho_1);
  92. dJointSetTransmissionRadius2(transmission, rho_2);
  93. dJointSetTransmissionAxis(transmission, 0, 0, 1);
  94. break;
  95. }
  96. dJointSetTransmissionBacklash(transmission, backlash);
  97. dJointSetHingeParam(hinge2, dParamVel, speed);
  98. dJointSetHingeParam(hinge2, dParamFMax, 50);
  99. dJointSetHingeParam(hinge1, dParamVel, 0);
  100. dJointSetHingeParam(hinge1, dParamFMax, 2);
  101. dBodySetLinearVel(body1, 0, 0, 0);
  102. dBodySetLinearVel(body2, 0, 0, 0);
  103. dBodySetAngularVel(body1, 0, 0, 0);
  104. dBodySetAngularVel(body2, 0, 0, 0);
  105. }
  106. void start()
  107. {
  108. dMass mass;
  109. world = dWorldCreate();
  110. dWorldSetGravity (world,0,0,-9.8);
  111. dWorldSetERP(world, 0.2);
  112. space = dSimpleSpaceCreate (0);
  113. body1 = dBodyCreate(world);
  114. body2 = dBodyCreate(world);
  115. dBodySetFiniteRotationMode(body1, 1);
  116. dBodySetFiniteRotationMode(body2, 1);
  117. geom1 = dCreateCylinder(space, 0.2, 0.5);
  118. dGeomSetBody(geom1, body1);
  119. dMassSetCylinder(&mass, 100, 3, 0.2, 0.5);
  120. dBodySetMass(body1, &mass);
  121. geom2 = dCreateCylinder(space, 0.2, 0.5);
  122. dGeomSetBody(geom2, body2);
  123. dMassSetCylinder(&mass, 100, 3, 0.2, 0.5);
  124. dBodySetMass(body2, &mass);
  125. hinge1 = dJointCreateHinge(world, 0);
  126. dJointAttach(hinge1, body1, 0);
  127. hinge2 = dJointCreateHinge(world, 0);
  128. dJointAttach(hinge2, body2, 0);
  129. transmission = dJointCreateTransmission(world, 0);
  130. dJointAttach(transmission, body1, body2);
  131. dJointSetFeedback(transmission, &feedback);
  132. setup();
  133. // initial camera position
  134. static float xyz[3] = {1.15,-2.78,4.1};
  135. static float hpr[3] = {105,-45.5,0};
  136. dsSetViewpoint (xyz,hpr);
  137. fprintf (stderr,
  138. "The green wheel is driving the red one. To control it use the following:\n"
  139. " '[' : decrease wheel ratio\n"
  140. " ']' : increase wheel ratio\n"
  141. " ',' : decrease driving wheel speed\n"
  142. " '.' : increase driving wheel speed\n"
  143. " '-' : decrease backlash\n"
  144. " '=' : increase backlash\n"
  145. " '1' : switch to parallel axes gears mode\n"
  146. " '2' : switch to intersecting axes gears mode\n"
  147. " '3' : switch to chain (or belt) mode\n"
  148. );
  149. }
  150. void stop()
  151. {
  152. dSpaceDestroy(space);
  153. dWorldDestroy(world);
  154. }
  155. void drawGeom(dGeomID g)
  156. {
  157. int gclass = dGeomGetClass(g);
  158. const dReal *pos = dGeomGetPosition(g);
  159. const dReal *rot = dGeomGetRotation(g);
  160. switch (gclass) {
  161. case dCylinderClass:
  162. {
  163. dReal length, radius;
  164. if (g == geom1) {
  165. dsSetColorAlpha(1, 0, 0, 1);
  166. } else {
  167. dsSetColorAlpha(0, 1, 0, 1);
  168. }
  169. dsSetTexture (DS_WOOD);
  170. dGeomCylinderGetParams(g, &radius, &length);
  171. dsDrawCylinder(pos, rot, length, radius);
  172. break;
  173. }
  174. default:
  175. {
  176. abort();
  177. }
  178. }
  179. }
  180. void simLoop(int pause)
  181. {
  182. if (!pause) {
  183. const dReal step = 0.003;
  184. const unsigned nsteps = 4;
  185. for (unsigned i=0; i<nsteps; ++i) {
  186. dWorldQuickStep(world, step);
  187. }
  188. }
  189. #if 0
  190. {
  191. const dReal *omega_1, *omega_2;
  192. omega_1 = dBodyGetAngularVel(body1);
  193. omega_2 = dBodyGetAngularVel(body2);
  194. printf ("T1: %f, %f, %f\n",
  195. feedback.t1[0], feedback.t1[1], feedback.t1[2]);
  196. printf ("T2: %f, %f, %f\n",
  197. feedback.t2[0], feedback.t2[1], feedback.t2[2]);
  198. printf ("F1: %f, %f, %f\n",
  199. feedback.f1[0], feedback.f1[1], feedback.f1[2]);
  200. printf ("F2: %f, %f, %f\n",
  201. feedback.f2[0], feedback.f2[1], feedback.f2[2]);
  202. }
  203. #endif
  204. // now we draw everything
  205. unsigned ngeoms = dSpaceGetNumGeoms(space);
  206. for (unsigned i=0; i<ngeoms; ++i) {
  207. dGeomID g = dSpaceGetGeom(space, i);
  208. drawGeom(g);
  209. }
  210. const dReal *R_1 = dGeomGetRotation(geom1);
  211. const dReal *R_2 = dGeomGetRotation(geom2);
  212. dVector3 c_1, c_2, a_1, a_2;
  213. dJointGetTransmissionContactPoint1(transmission, c_1);
  214. dJointGetTransmissionContactPoint2(transmission, c_2);
  215. dJointGetTransmissionAnchor1(transmission, a_1);
  216. dJointGetTransmissionAnchor2(transmission, a_2);
  217. dsSetColorAlpha(1, 0, 0, 0.5);
  218. dsDrawCylinder(a_1, R_1, 0.05, dCalcPointsDistance3(c_1, a_1));
  219. dsSetColorAlpha(0, 1, 0, 0.5);
  220. dsDrawCylinder(a_2, R_2, 0.05, dCalcPointsDistance3(c_2, a_2));
  221. dsSetColorAlpha(1, 0, 0, 0.5);
  222. dsDrawSphere (c_1, R_1, 0.05);
  223. dsDrawSphere (c_2, R_1, 0.05);
  224. dsSetColorAlpha(1, 1, 0, 0.5);
  225. if (mode == dTransmissionChainDrive) {
  226. dsDrawLine(c_1, c_2);
  227. }
  228. }
  229. static void command (int cmd)
  230. {
  231. if (cmd == '[') {
  232. switch(mode) {
  233. case dTransmissionParallelAxes:
  234. if (ratio > 0.125) {
  235. ratio *= 0.5;
  236. fprintf (stderr, "Gear ratio set to %.3f.\n", ratio);
  237. }
  238. break;
  239. case dTransmissionIntersectingAxes:
  240. if (theta > 0.1) {
  241. theta -= 0.1;
  242. fprintf (stderr, "Gear angle set to %.3f deg.\n",
  243. theta / M_PI * 180);
  244. }
  245. break;
  246. case dTransmissionChainDrive:
  247. if (rho_2 > 0.125) {
  248. rho_2 /= 2;
  249. fprintf (stderr, "Sprocket ratio set to %.3f.\n", rho_2 / rho_1);
  250. }
  251. break;
  252. }
  253. setup();
  254. } else if (cmd == ']') {
  255. switch(mode) {
  256. case dTransmissionParallelAxes:
  257. if (ratio < 8) {
  258. ratio *= 2;
  259. fprintf (stderr, "Gear ratio set to %.3f.\n", ratio);
  260. }
  261. break;
  262. case dTransmissionIntersectingAxes:
  263. if (theta < 0.9) {
  264. theta += 0.1;
  265. fprintf (stderr, "Gear angle set to %.3f deg.\n",
  266. theta / M_PI * 180);
  267. }
  268. break;
  269. case dTransmissionChainDrive:
  270. if (rho_2 < 2) {
  271. rho_2 *= 2;
  272. fprintf (stderr, "Sprocket ratio set to %.3f.\n", rho_2 / rho_1);
  273. }
  274. break;
  275. }
  276. setup();
  277. } else if (cmd == '.') {
  278. speed += 5;
  279. fprintf (stderr, "Driving wheel speed set to %g rad/s.\n", speed);
  280. dJointSetHingeParam(hinge2, dParamVel, speed);
  281. } else if (cmd == ',') {
  282. speed -= 5;
  283. fprintf (stderr, "Driving wheel speed set to %g rad/s.\n", speed);
  284. dJointSetHingeParam(hinge2, dParamVel, speed);
  285. } else if (cmd == '/') {
  286. if (dJointGetHingeParam(hinge2, dParamFMax) > 0) {
  287. dJointSetHingeParam(hinge2, dParamFMax, 0);
  288. } else {
  289. dJointSetHingeParam(hinge2, dParamFMax, 50);
  290. }
  291. } else if (cmd == '-') {
  292. backlash -= 0.1;
  293. fprintf (stderr, "Backlash set to %g m.\n", backlash);
  294. dJointSetTransmissionBacklash(transmission, backlash);
  295. } else if (cmd == '=') {
  296. backlash += 0.1;
  297. fprintf (stderr, "Backlash set to %g m.\n", backlash);
  298. dJointSetTransmissionBacklash(transmission, backlash);
  299. } else if (cmd == '1') {
  300. mode = dTransmissionParallelAxes;
  301. setup();
  302. } else if (cmd == '2') {
  303. mode = dTransmissionIntersectingAxes;
  304. setup();
  305. } else if (cmd == '3') {
  306. mode = dTransmissionChainDrive;
  307. setup();
  308. }
  309. }
  310. int main(int argc, char **argv)
  311. {
  312. // setup pointers to drawstuff callback functions
  313. dsFunctions fn;
  314. fn.version = DS_VERSION;
  315. fn.start = &start;
  316. fn.step = &simLoop;
  317. fn.command = &command;
  318. fn.stop = stop;
  319. fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH;
  320. // create world
  321. dInitODE();
  322. // run demo
  323. dsSimulationLoop (argc, argv, 800, 600, &fn);
  324. dCloseODE();
  325. return 0;
  326. }