amotor.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  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. //234567890123456789012345678901234567890123456789012345678901234567890123456789
  23. // 1 2 3 4 5 6 7
  24. ////////////////////////////////////////////////////////////////////////////////
  25. // This file create unit test for some of the functions found in:
  26. // ode/src/joinst/fixed.cpp
  27. //
  28. //
  29. ////////////////////////////////////////////////////////////////////////////////
  30. #include <UnitTest++.h>
  31. #include <ode/ode.h>
  32. #include "config.h"
  33. #include "../../ode/src/joints/amotor.h"
  34. const dReal tol = 1e-5;
  35. SUITE (TestdxJointAMotor)
  36. {
  37. struct FixtureBase {
  38. dWorldID world;
  39. dBodyID body;
  40. dJointID joint;
  41. FixtureBase()
  42. {
  43. world = dWorldCreate();
  44. body = dBodyCreate(world);
  45. joint = dJointCreateAMotor(world, 0);
  46. }
  47. ~FixtureBase()
  48. {
  49. dJointDestroy(joint);
  50. dBodyDestroy(body);
  51. dWorldDestroy(world);
  52. }
  53. };
  54. struct FixtureXUser: FixtureBase {
  55. FixtureXUser()
  56. {
  57. // body only allowed to rotate around X axis
  58. dBodySetFiniteRotationMode(body, 1);
  59. dBodySetFiniteRotationAxis(body, 1, 0, 0);
  60. dJointAttach(joint, body, 0);
  61. dJointSetAMotorNumAxes(joint, 2);
  62. dJointSetAMotorAxis(joint, 0, 2, 0, 1, 0);
  63. dJointSetAMotorAxis(joint, 1, 2, 0, 0, 1);
  64. dJointSetAMotorParam(joint, dParamVel, 0);
  65. dJointSetAMotorParam(joint, dParamFMax, dInfinity);
  66. dJointSetAMotorParam(joint, dParamVel2, 0);
  67. dJointSetAMotorParam(joint, dParamFMax2, dInfinity);
  68. }
  69. };
  70. TEST_FIXTURE(FixtureXUser, rotate_x)
  71. {
  72. const dReal h = 1;
  73. const dReal v = 1;
  74. dMatrix3 identity = {1, 0, 0, 0,
  75. 0, 1, 0, 0,
  76. 0, 0, 1, 0};
  77. dBodySetRotation(body, identity);
  78. dBodySetAngularVel(body, v, 0, 0);
  79. dWorldQuickStep(world, h);
  80. const dReal* rot = dBodyGetRotation(body);
  81. CHECK_CLOSE(1, rot[0], tol);
  82. CHECK_CLOSE(0, rot[4], tol);
  83. CHECK_CLOSE(0, rot[8], tol);
  84. CHECK_CLOSE(0, rot[1], tol);
  85. CHECK_CLOSE(dCos(v*h), rot[5], tol);
  86. CHECK_CLOSE(dSin(v*h), rot[9], tol);
  87. CHECK_CLOSE(0, rot[2], tol);
  88. CHECK_CLOSE(-dSin(v*h), rot[6], tol);
  89. CHECK_CLOSE( dCos(v*h), rot[10], tol);
  90. }
  91. TEST_FIXTURE(FixtureXUser, rotate_yz)
  92. {
  93. const dReal h = 1;
  94. const dReal v = 1;
  95. dMatrix3 identity = {1, 0, 0, 0,
  96. 0, 1, 0, 0,
  97. 0, 0, 1, 0};
  98. dBodySetRotation(body, identity);
  99. dVector3 axis_y;
  100. dJointGetAMotorAxis(joint, 0, axis_y);
  101. CHECK_CLOSE(0, axis_y[0], tol);
  102. CHECK_CLOSE(1, axis_y[1], tol);
  103. CHECK_CLOSE(0, axis_y[2], tol);
  104. dVector3 axis_z;
  105. dJointGetAMotorAxis(joint, 1, axis_z);
  106. CHECK_CLOSE(0, axis_z[0], tol);
  107. CHECK_CLOSE(0, axis_z[1], tol);
  108. CHECK_CLOSE(1, axis_z[2], tol);
  109. dBodySetAngularVel(body, 0, v, v);
  110. dWorldStep(world, h);
  111. const dReal* rot = dBodyGetRotation(body);
  112. CHECK_CLOSE(1, rot[0], tol);
  113. CHECK_CLOSE(0, rot[4], tol);
  114. CHECK_CLOSE(0, rot[8], tol);
  115. CHECK_CLOSE(0, rot[1], tol);
  116. CHECK_CLOSE(1, rot[5], tol);
  117. CHECK_CLOSE(0, rot[9], tol);
  118. CHECK_CLOSE(0, rot[2], tol);
  119. CHECK_CLOSE(0, rot[6], tol);
  120. CHECK_CLOSE(1, rot[10], tol);
  121. }
  122. TEST_FIXTURE(FixtureBase, sanity_check)
  123. {
  124. dMatrix3 R;
  125. dRFromAxisAndAngle(R, 1, 1, 1, 10*M_PI/180);
  126. dBodySetRotation(body, R);
  127. dVector3 res;
  128. dJointAttach(joint, body, 0);
  129. dJointSetAMotorNumAxes(joint, 3);
  130. CHECK_EQUAL(3, dJointGetAMotorNumAxes(joint));
  131. // axes relative to world
  132. dJointSetAMotorAxis(joint, 0, 0, 1, 0, 0);
  133. dJointGetAMotorAxis(joint, 0, res);
  134. CHECK_EQUAL(0, dJointGetAMotorAxisRel(joint, 0));
  135. CHECK_CLOSE(1, res[0], tol);
  136. CHECK_CLOSE(0, res[1], tol);
  137. CHECK_CLOSE(0, res[2], tol);
  138. dJointSetAMotorAxis(joint, 1, 0, 0, 1, 0);
  139. dJointGetAMotorAxis(joint, 1, res);
  140. CHECK_EQUAL(0, dJointGetAMotorAxisRel(joint, 1));
  141. CHECK_CLOSE(0, res[0], tol);
  142. CHECK_CLOSE(1, res[1], tol);
  143. CHECK_CLOSE(0, res[2], tol);
  144. dJointSetAMotorAxis(joint, 2, 0, 0, 0, 1);
  145. dJointGetAMotorAxis(joint, 2, res);
  146. CHECK_EQUAL(0, dJointGetAMotorAxisRel(joint, 2));
  147. CHECK_CLOSE(0, res[0], tol);
  148. CHECK_CLOSE(0, res[1], tol);
  149. CHECK_CLOSE(1, res[2], tol);
  150. // axes relative to body1
  151. dJointSetAMotorAxis(joint, 0, 1, 1, 0, 0);
  152. dJointGetAMotorAxis(joint, 0, res);
  153. CHECK_EQUAL(1, dJointGetAMotorAxisRel(joint, 0));
  154. CHECK_CLOSE(1, res[0], tol);
  155. CHECK_CLOSE(0, res[1], tol);
  156. CHECK_CLOSE(0, res[2], tol);
  157. dJointSetAMotorAxis(joint, 1, 1, 0, 1, 0);
  158. dJointGetAMotorAxis(joint, 1, res);
  159. CHECK_EQUAL(1, dJointGetAMotorAxisRel(joint, 1));
  160. CHECK_CLOSE(0, res[0], tol);
  161. CHECK_CLOSE(1, res[1], tol);
  162. CHECK_CLOSE(0, res[2], tol);
  163. dJointSetAMotorAxis(joint, 2, 1, 0, 0, 1);
  164. dJointGetAMotorAxis(joint, 2, res);
  165. CHECK_EQUAL(1, dJointGetAMotorAxisRel(joint, 2));
  166. CHECK_CLOSE(0, res[0], tol);
  167. CHECK_CLOSE(0, res[1], tol);
  168. CHECK_CLOSE(1, res[2], tol);
  169. // axes relative to body2
  170. dJointSetAMotorAxis(joint, 0, 2, 1, 0, 0);
  171. dJointGetAMotorAxis(joint, 0, res);
  172. CHECK_EQUAL(2, dJointGetAMotorAxisRel(joint, 0));
  173. CHECK_CLOSE(1, res[0], tol);
  174. CHECK_CLOSE(0, res[1], tol);
  175. CHECK_CLOSE(0, res[2], tol);
  176. dJointSetAMotorAxis(joint, 1, 2, 0, 1, 0);
  177. dJointGetAMotorAxis(joint, 1, res);
  178. CHECK_EQUAL(2, dJointGetAMotorAxisRel(joint, 1));
  179. CHECK_CLOSE(0, res[0], tol);
  180. CHECK_CLOSE(1, res[1], tol);
  181. CHECK_CLOSE(0, res[2], tol);
  182. dJointSetAMotorAxis(joint, 2, 2, 0, 0, 1);
  183. dJointGetAMotorAxis(joint, 2, res);
  184. CHECK_EQUAL(2, dJointGetAMotorAxisRel(joint, 2));
  185. CHECK_CLOSE(0, res[0], tol);
  186. CHECK_CLOSE(0, res[1], tol);
  187. CHECK_CLOSE(1, res[2], tol);
  188. // reverse attachment to force internal reversal
  189. dJointAttach(joint, 0, body);
  190. // axes relative to world
  191. dJointSetAMotorAxis(joint, 0, 0, 1, 0, 0);
  192. dJointGetAMotorAxis(joint, 0, res);
  193. CHECK_EQUAL(0, dJointGetAMotorAxisRel(joint, 0));
  194. CHECK_CLOSE(1, res[0], tol);
  195. CHECK_CLOSE(0, res[1], tol);
  196. CHECK_CLOSE(0, res[2], tol);
  197. dJointSetAMotorAxis(joint, 1, 0, 0, 1, 0);
  198. dJointGetAMotorAxis(joint, 1, res);
  199. CHECK_EQUAL(0, dJointGetAMotorAxisRel(joint, 1));
  200. CHECK_CLOSE(0, res[0], tol);
  201. CHECK_CLOSE(1, res[1], tol);
  202. CHECK_CLOSE(0, res[2], tol);
  203. dJointSetAMotorAxis(joint, 2, 0, 0, 0, 1);
  204. dJointGetAMotorAxis(joint, 2, res);
  205. CHECK_EQUAL(0, dJointGetAMotorAxisRel(joint, 2));
  206. CHECK_CLOSE(0, res[0], tol);
  207. CHECK_CLOSE(0, res[1], tol);
  208. CHECK_CLOSE(1, res[2], tol);
  209. // axes relative to body1
  210. dJointSetAMotorAxis(joint, 0, 1, 1, 0, 0);
  211. dJointGetAMotorAxis(joint, 0, res);
  212. CHECK_EQUAL(1, dJointGetAMotorAxisRel(joint, 0));
  213. CHECK_CLOSE(1, res[0], tol);
  214. CHECK_CLOSE(0, res[1], tol);
  215. CHECK_CLOSE(0, res[2], tol);
  216. dJointSetAMotorAxis(joint, 1, 1, 0, 1, 0);
  217. dJointGetAMotorAxis(joint, 1, res);
  218. CHECK_EQUAL(1, dJointGetAMotorAxisRel(joint, 1));
  219. CHECK_CLOSE(0, res[0], tol);
  220. CHECK_CLOSE(1, res[1], tol);
  221. CHECK_CLOSE(0, res[2], tol);
  222. dJointSetAMotorAxis(joint, 2, 1, 0, 0, 1);
  223. dJointGetAMotorAxis(joint, 2, res);
  224. CHECK_EQUAL(1, dJointGetAMotorAxisRel(joint, 2));
  225. CHECK_CLOSE(0, res[0], tol);
  226. CHECK_CLOSE(0, res[1], tol);
  227. CHECK_CLOSE(1, res[2], tol);
  228. // axes relative to body2
  229. dJointSetAMotorAxis(joint, 0, 2, 1, 0, 0);
  230. dJointGetAMotorAxis(joint, 0, res);
  231. CHECK_EQUAL(2, dJointGetAMotorAxisRel(joint, 0));
  232. CHECK_CLOSE(1, res[0], tol);
  233. CHECK_CLOSE(0, res[1], tol);
  234. CHECK_CLOSE(0, res[2], tol);
  235. dJointSetAMotorAxis(joint, 1, 2, 0, 1, 0);
  236. dJointGetAMotorAxis(joint, 1, res);
  237. CHECK_EQUAL(2, dJointGetAMotorAxisRel(joint, 1));
  238. CHECK_CLOSE(0, res[0], tol);
  239. CHECK_CLOSE(1, res[1], tol);
  240. CHECK_CLOSE(0, res[2], tol);
  241. dJointSetAMotorAxis(joint, 2, 2, 0, 0, 1);
  242. dJointGetAMotorAxis(joint, 2, res);
  243. CHECK_EQUAL(2, dJointGetAMotorAxisRel(joint, 2));
  244. CHECK_CLOSE(0, res[0], tol);
  245. CHECK_CLOSE(0, res[1], tol);
  246. CHECK_CLOSE(1, res[2], tol);
  247. }
  248. struct FixtureXEuler : FixtureBase {
  249. FixtureXEuler()
  250. {
  251. // body only allowed to rotate around X axis
  252. dJointAttach(joint, 0, body);
  253. dJointSetAMotorMode(joint, dAMotorEuler);
  254. dJointSetAMotorAxis(joint, 0, 0, 1, 0, 0);
  255. dJointSetAMotorAxis(joint, 2, 0, 0, 0, 1);
  256. }
  257. };
  258. TEST_FIXTURE(FixtureXEuler, check_axes)
  259. {
  260. // test patch #181 bug fix
  261. dVector3 axis_x;
  262. dJointGetAMotorAxis(joint, 0, axis_x);
  263. CHECK_CLOSE(1, axis_x[0], tol);
  264. CHECK_CLOSE(0, axis_x[1], tol);
  265. CHECK_CLOSE(0, axis_x[2], tol);
  266. dVector3 axis_y;
  267. dJointGetAMotorAxis(joint, 1, axis_y);
  268. CHECK_CLOSE(0, axis_y[0], tol);
  269. CHECK_CLOSE(1, axis_y[1], tol);
  270. CHECK_CLOSE(0, axis_y[2], tol);
  271. dVector3 axis_z;
  272. dJointGetAMotorAxis(joint, 2, axis_z);
  273. CHECK_CLOSE(0, axis_z[0], tol);
  274. CHECK_CLOSE(0, axis_z[1], tol);
  275. CHECK_CLOSE(1, axis_z[2], tol);
  276. }
  277. } // End of SUITE TestdxJointAMotor