pr.cpp 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160
  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/pr.cpp
  27. //
  28. //
  29. ////////////////////////////////////////////////////////////////////////////////
  30. #include <UnitTest++.h>
  31. #include <ode/ode.h>
  32. #include "../../ode/src/config.h"
  33. #include "../../ode/src/joints/pr.h"
  34. SUITE (TestdxJointPR)
  35. {
  36. // The 2 bodies are positionned at (0, 0, 0), with no rotation
  37. // The joint is a PR Joint
  38. // Axis is along the X axis
  39. // Anchor at (0, 0, 0)
  40. struct Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X
  41. {
  42. Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X()
  43. {
  44. wId = dWorldCreate();
  45. bId1 = dBodyCreate (wId);
  46. dBodySetPosition (bId1, 0, 0, 0);
  47. bId2 = dBodyCreate (wId);
  48. dBodySetPosition (bId2, 0, 0, 0);
  49. jId = dJointCreatePR (wId, 0);
  50. joint = (dxJointPR*) jId;
  51. dJointAttach (jId, bId1, bId2);
  52. dJointSetPRAxis1 (jId, axis[0], axis[1], axis[2]);
  53. }
  54. ~Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X()
  55. {
  56. dWorldDestroy (wId);
  57. }
  58. dWorldID wId;
  59. dBodyID bId1;
  60. dBodyID bId2;
  61. dJointID jId;
  62. dxJointPR* joint;
  63. static const dVector3 axis;
  64. static const dReal offset;
  65. };
  66. const dVector3 Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X::axis =
  67. {
  68. 1, 0, 0
  69. };
  70. const dReal Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X::offset = REAL (3.1);
  71. // Move 1st body offset unit in the X direction
  72. //
  73. // X-------> X---------> Axis -->
  74. // B1 => B1
  75. // B2 B2
  76. //
  77. // Start with a Offset of offset unit
  78. //
  79. // X-------> X---------> Axis -->
  80. // B1 => B1
  81. // B2 B2
  82. TEST_FIXTURE (Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X,
  83. test_dJointSetPRAxisOffset_B1_3Unit)
  84. {
  85. dJointSetPRAnchor (jId, 0, 0, 0);
  86. CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  87. dBodySetPosition (bId1, offset, 0, 0);
  88. CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
  89. // dJointSetPRAnchorOffset (jId, 0, 0, 0,
  90. // offset*axis[0],offset*axis[1],offset*axis[2]);
  91. // CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
  92. // dBodySetPosition (bId1, 0, 0, 0);
  93. // CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  94. // // Only here to test a deprecated warning
  95. // dJointSetPRAxisDelta (jId, 1, 0, 0, 0, 0, 0);
  96. }
  97. // Move 1st body offset unit in the opposite X direction
  98. //
  99. // X-------> X---------> Axis -->
  100. // B1 => B1
  101. // B2 B2
  102. //
  103. // Start with a Offset of -offset unit
  104. //
  105. // X-------> X---------> Axis -->
  106. // B1 => B1
  107. // B2 B2
  108. TEST_FIXTURE (Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X,
  109. test_dJointSetPRAxisOffset_B1_Minus_3Unit)
  110. {
  111. dJointSetPRAnchor (jId, 0, 0, 0);
  112. CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  113. dBodySetPosition (bId1, -offset, 0, 0);
  114. CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
  115. // dJointSetPRAnchorOffset (jId, 0, 0, 0,
  116. // -offset*axis[0],-offset*axis[1],-offset*axis[2]);
  117. // CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
  118. // dBodySetPosition (bId1, 0, 0, 0);
  119. // CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  120. }
  121. // Move 2nd body offset unit in the X direction
  122. //
  123. // X-------> X---------> Axis -->
  124. // B1 => B1
  125. // B2 B2
  126. //
  127. // Start with a Offset of offset unit
  128. //
  129. // X-------> X---------> Axis -->
  130. // B1 => B1
  131. // B2 B2
  132. TEST_FIXTURE (Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X,
  133. test_dJointSetPRAxisOffset_B2_3Unit)
  134. {
  135. dJointSetPRAnchor (jId, 0, 0, 0);
  136. CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  137. dBodySetPosition (bId2, offset, 0, 0);
  138. CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
  139. // dJointSetPRAnchorOffset (jId, 0, 0, 0,
  140. // -offset*axis[0],-offset*axis[1],-offset*axis[2]);
  141. // CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
  142. // dBodySetPosition (bId2, 0, 0, 0);
  143. // CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  144. }
  145. // Move 2nd body offset unit in the opposite X direction
  146. //
  147. // X-------> X---------> Axis -->
  148. // B1 => B1
  149. // B2 B2
  150. //
  151. // Start with a Offset of -offset unit
  152. //
  153. // X-------> X---------> Axis -->
  154. // B1 => B1
  155. // B2 B2
  156. TEST_FIXTURE (Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X,
  157. test_dJointSetPRAxisOffset_B2_Minus_3Unit)
  158. {
  159. dJointSetPRAnchor (jId, 0, 0, 0);
  160. CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  161. dBodySetPosition (bId2, -offset, 0, 0);
  162. CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
  163. // dJointSetPRAnchorOffset (jId, 0, 0, 0,
  164. // offset*axis[0],offset*axis[1],offset*axis[2]);
  165. // CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
  166. // dBodySetPosition (bId2, 0, 0, 0);
  167. // CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  168. }
  169. // Only body 1
  170. // The body are positionned at (0, 0, 0), with no rotation
  171. // The joint is a PR Joint
  172. // Axis is along the X axis
  173. // Anchor at (0, 0, 0)
  174. struct Fixture_dxJointPR_B1_At_Zero_Axis_Along_X
  175. {
  176. Fixture_dxJointPR_B1_At_Zero_Axis_Along_X()
  177. {
  178. wId = dWorldCreate();
  179. bId1 = dBodyCreate (wId);
  180. dBodySetPosition (bId1, 0, 0, 0);
  181. jId = dJointCreatePR (wId, 0);
  182. joint = (dxJointPR*) jId;
  183. dJointAttach (jId, bId1, NULL);
  184. dJointSetPRAxis1 (jId, axis[0], axis[1], axis[2]);
  185. }
  186. ~Fixture_dxJointPR_B1_At_Zero_Axis_Along_X()
  187. {
  188. dWorldDestroy (wId);
  189. }
  190. dWorldID wId;
  191. dBodyID bId1;
  192. dJointID jId;
  193. dxJointPR* joint;
  194. static const dVector3 axis;
  195. static const dReal offset;
  196. };
  197. const dVector3 Fixture_dxJointPR_B1_At_Zero_Axis_Along_X::axis =
  198. {
  199. 1, 0, 0
  200. };
  201. const dReal Fixture_dxJointPR_B1_At_Zero_Axis_Along_X::offset = REAL (3.1);
  202. // Move 1st body offset unit in the X direction
  203. //
  204. // X-------> X---------> Axis -->
  205. // B1 => B1
  206. //
  207. // Start with a Offset of offset unit
  208. //
  209. // X-------> X---------> Axis -->
  210. // B1 => B1
  211. TEST_FIXTURE (Fixture_dxJointPR_B1_At_Zero_Axis_Along_X,
  212. test_dJointSetPRAxisOffset_B1_OffsetUnit)
  213. {
  214. dJointSetPRAnchor (jId, 0, 0, 0);
  215. CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  216. dBodySetPosition (bId1, offset, 0, 0);
  217. CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
  218. // dJointSetPRAnchorOffset (jId, 0, 0, 0,
  219. // offset*axis[0],offset*axis[1],offset*axis[2]);
  220. // CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
  221. // dBodySetPosition (bId1, 0, 0, 0);
  222. // CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  223. }
  224. // Move 1st body offset unit in the opposite X direction
  225. //
  226. // X-------> X---------> Axis -->
  227. // B1 => B1
  228. //
  229. // Start with a Offset of -offset unit
  230. //
  231. // X-------> X---------> Axis -->
  232. // B1 => B1
  233. TEST_FIXTURE (Fixture_dxJointPR_B1_At_Zero_Axis_Along_X,
  234. test_dJointSetPRAxisOffset_B1_Minus_OffsetUnit)
  235. {
  236. dJointSetPRAnchor (jId, 0, 0, 0);
  237. CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  238. dBodySetPosition (bId1, -offset, 0, 0);
  239. CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
  240. // dJointSetPRAnchorOffset (jId, 0, 0, 0,
  241. // -offset*axis[0],-offset*axis[1],-offset*axis[2]);
  242. // CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
  243. // dBodySetPosition (bId1, 0, 0, 0);
  244. // CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  245. }
  246. // Only body 1
  247. // The body are positionned at (0, 0, 0), with no rotation
  248. // The joint is a PR Joint
  249. // Axis is in the oppsite X axis
  250. // Anchor at (0, 0, 0)
  251. struct Fixture_dxJointPR_B1_At_Zero_Axis_Inverse_of_X
  252. {
  253. Fixture_dxJointPR_B1_At_Zero_Axis_Inverse_of_X()
  254. {
  255. wId = dWorldCreate();
  256. bId1 = dBodyCreate (wId);
  257. dBodySetPosition (bId1, 0, 0, 0);
  258. jId = dJointCreatePR (wId, 0);
  259. joint = (dxJointPR*) jId;
  260. dJointAttach (jId, bId1, NULL);
  261. dJointSetPRAxis1 (jId, axis[0], axis[1], axis[2]);
  262. }
  263. ~Fixture_dxJointPR_B1_At_Zero_Axis_Inverse_of_X()
  264. {
  265. dWorldDestroy (wId);
  266. }
  267. dWorldID wId;
  268. dBodyID bId1;
  269. dJointID jId;
  270. dxJointPR* joint;
  271. static const dVector3 axis;
  272. static const dReal offset;
  273. };
  274. const dVector3 Fixture_dxJointPR_B1_At_Zero_Axis_Inverse_of_X::axis =
  275. {
  276. -1, 0, 0
  277. };
  278. const dReal Fixture_dxJointPR_B1_At_Zero_Axis_Inverse_of_X::offset = REAL (3.1);
  279. // Move 1st body offset unit in the X direction
  280. //
  281. // X-------> X---------> <--- Axis
  282. // B1 => B1
  283. //
  284. // Start with a Offset of offset unit
  285. //
  286. // X-------> X---------> <--- Axis
  287. // B1 => B1
  288. TEST_FIXTURE (Fixture_dxJointPR_B1_At_Zero_Axis_Inverse_of_X,
  289. test_dJointSetPRAxisOffset_B1_OffsetUnit)
  290. {
  291. dJointSetPRAnchor (jId, 0, 0, 0);
  292. CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  293. dBodySetPosition (bId1, offset, 0, 0);
  294. CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
  295. // dJointSetPRAnchorOffset (jId, 0, 0, 0,
  296. // -offset*axis[0],-offset*axis[1],-offset*axis[2]);
  297. // CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
  298. // dBodySetPosition (bId1, 0, 0, 0);
  299. // CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  300. }
  301. // Move 1st body offset unit in the opposite X direction
  302. //
  303. // X-------> X---------> <--- Axis
  304. // B1 => B1
  305. //
  306. // Start with a Offset of -offset unit
  307. //
  308. // X-------> X---------> <--- Axis
  309. // B1 => B1
  310. TEST_FIXTURE (Fixture_dxJointPR_B1_At_Zero_Axis_Inverse_of_X,
  311. test_dJointSetPRAxisOffset_B1_Minus_OffsetUnit)
  312. {
  313. dJointSetPRAnchor (jId, 0, 0, 0);
  314. CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  315. dBodySetPosition (bId1, -offset, 0, 0);
  316. CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
  317. // dJointSetPRAnchorOffset (jId, 0, 0, 0,
  318. // offset*axis[0],offset*axis[1],offset*axis[2]);
  319. // CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
  320. // dBodySetPosition (bId1, 0, 0, 0);
  321. // CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  322. }
  323. // Compare only one body to 2 bodies with one fixed.
  324. //
  325. // The body are positionned at (0, 0, 0), with no rotation
  326. // The joint is a PR Joint
  327. // Axis is along the X axis
  328. // Anchor at (0, 0, 0)
  329. struct Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y
  330. {
  331. Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y()
  332. {
  333. wId = dWorldCreate();
  334. bId1_12 = dBodyCreate (wId);
  335. dBodySetPosition (bId1_12, 0, 0, 0);
  336. bId2_12 = dBodyCreate (wId);
  337. dBodySetPosition (bId2_12, 0, 0, 0);
  338. // The force will be added in the function since it is not
  339. // always on the same body
  340. jId_12 = dJointCreatePR (wId, 0);
  341. dJointAttach(jId_12, bId1_12, bId2_12);
  342. fixed = dJointCreateFixed (wId, 0);
  343. jId = dJointCreatePR (wId, 0);
  344. bId = dBodyCreate (wId);
  345. dBodySetPosition (bId, 0, 0, 0);
  346. // Linear velocity along the prismatic axis;
  347. dVector3 axis;
  348. dJointGetPRAxis1(jId_12, axis);
  349. dJointSetPRAxis1(jId, axis[0], axis[1], axis[2]);
  350. dBodySetLinearVel (bId, 4*axis[0], 4*axis[1], 4*axis[2]);
  351. }
  352. ~Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y()
  353. {
  354. dWorldDestroy (wId);
  355. }
  356. dWorldID wId;
  357. dBodyID bId1_12;
  358. dBodyID bId2_12;
  359. dJointID jId_12; // Joint with 2 bodies
  360. dJointID fixed;
  361. dBodyID bId;
  362. dJointID jId; // Joint with one body
  363. };
  364. TEST_FIXTURE (Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y,
  365. test_dJointSetPRPositionRate_Only_B1)
  366. {
  367. // Linear velocity along the prismatic axis;
  368. dVector3 axis;
  369. dJointGetPRAxis1(jId_12, axis);
  370. dBodySetLinearVel (bId1_12, 4*axis[0], 4*axis[1], 4*axis[2]);
  371. dJointAttach(jId_12, bId1_12, bId2_12);
  372. dJointAttach(fixed, 0, bId2_12);
  373. dJointSetFixed(fixed);
  374. dJointAttach(jId, bId, 0);
  375. CHECK_CLOSE(dJointGetPRPositionRate(jId_12), dJointGetPRPositionRate(jId), 1e-2);
  376. CHECK_CLOSE(dJointGetPRAngleRate(jId_12), dJointGetPRAngleRate(jId), 1e-2);
  377. }
  378. TEST_FIXTURE (Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y,
  379. test_dJointSetPRPositionRate_Only_B2)
  380. {
  381. // Linear velocity along the prismatic axis;
  382. dVector3 axis;
  383. dJointGetPRAxis1(jId_12, axis);
  384. dBodySetLinearVel (bId2_12, 4*axis[0], 4*axis[1], 4*axis[2]);
  385. dJointAttach(jId_12, bId1_12, bId2_12);
  386. dJointAttach(fixed, bId1_12, 0);
  387. dJointSetFixed(fixed);
  388. dJointAttach(jId, 0, bId);
  389. CHECK_CLOSE(dJointGetPRPositionRate(jId_12), dJointGetPRPositionRate(jId), 1e-2);
  390. CHECK_CLOSE(dJointGetPRAngleRate(jId_12), dJointGetPRAngleRate(jId), 1e-2);
  391. }
  392. // Only body 2
  393. // The body are positionned at (0, 0, 0), with no rotation
  394. // The joint is a PR Joint
  395. // Axis is along the X axis
  396. // Anchor at (0, 0, 0)
  397. struct Fixture_dxJointPR_B2_At_Zero_Axis_Along_X
  398. {
  399. Fixture_dxJointPR_B2_At_Zero_Axis_Along_X()
  400. {
  401. wId = dWorldCreate();
  402. bId2 = dBodyCreate (wId);
  403. dBodySetPosition (bId2, 0, 0, 0);
  404. jId = dJointCreatePR (wId, 0);
  405. joint = (dxJointPR*) jId;
  406. dJointAttach (jId, NULL, bId2);
  407. dJointSetPRAxis1 (jId, axis[0], axis[1], axis[2]);
  408. }
  409. ~Fixture_dxJointPR_B2_At_Zero_Axis_Along_X()
  410. {
  411. dWorldDestroy (wId);
  412. }
  413. dWorldID wId;
  414. dBodyID bId2;
  415. dJointID jId;
  416. dxJointPR* joint;
  417. static const dVector3 axis;
  418. static const dReal offset;
  419. };
  420. const dVector3 Fixture_dxJointPR_B2_At_Zero_Axis_Along_X::axis =
  421. {
  422. 1, 0, 0
  423. };
  424. const dReal Fixture_dxJointPR_B2_At_Zero_Axis_Along_X::offset = REAL (3.1);
  425. // Move 2nd body offset unit in the X direction
  426. //
  427. // X-------> X---------> Axis -->
  428. // B2 => B2
  429. //
  430. // Start with a Offset of offset unit
  431. //
  432. // X-------> X---------> Axis -->
  433. // B2 => B2
  434. TEST_FIXTURE (Fixture_dxJointPR_B2_At_Zero_Axis_Along_X,
  435. test_dJointSetPRAxisOffset_B2_OffsetUnit)
  436. {
  437. dJointSetPRAnchor (jId, 0, 0, 0);
  438. CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  439. dBodySetPosition (bId2, offset, 0, 0);
  440. CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
  441. // dJointSetPRAnchorOffset (jId, 0, 0, 0,
  442. // -offset*axis[0],-offset*axis[1],-offset*axis[2]);
  443. // CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
  444. // dBodySetPosition (bId2, 0, 0, 0);
  445. // CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  446. }
  447. // Move 2nd body offset unit in the opposite X direction
  448. //
  449. // X-------> X---------> Axis -->
  450. // B2 => B2
  451. //
  452. // Start with a Offset of -offset unit
  453. //
  454. // X-------> X---------> Axis -->
  455. // B2 => B2
  456. TEST_FIXTURE (Fixture_dxJointPR_B2_At_Zero_Axis_Along_X,
  457. test_dJointSetPRAxisOffset_B2_Minus_OffsetUnit)
  458. {
  459. dJointSetPRAnchor (jId, 0, 0, 0);
  460. CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  461. dBodySetPosition (bId2, -offset, 0, 0);
  462. CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
  463. // dJointSetPRAnchorOffset (jId, 0, 0, 0,
  464. // offset*axis[0],offset*axis[1],offset*axis[2]);
  465. // CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
  466. // dBodySetPosition (bId2, 0, 0, 0);
  467. // CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  468. }
  469. // Only body 2
  470. // The body are positionned at (0, 0, 0), with no rotation
  471. // The joint is a PR Joint
  472. // Axis is in the opposite X axis
  473. // Anchor at (0, 0, 0)
  474. struct Fixture_dxJointPR_B2_At_Zero_Axis_Inverse_of_X
  475. {
  476. Fixture_dxJointPR_B2_At_Zero_Axis_Inverse_of_X()
  477. {
  478. wId = dWorldCreate();
  479. bId2 = dBodyCreate (wId);
  480. dBodySetPosition (bId2, 0, 0, 0);
  481. jId = dJointCreatePR (wId, 0);
  482. joint = (dxJointPR*) jId;
  483. dJointAttach (jId, NULL, bId2);
  484. dJointSetPRAxis1 (jId, axis[0], axis[1], axis[2]);
  485. }
  486. ~Fixture_dxJointPR_B2_At_Zero_Axis_Inverse_of_X()
  487. {
  488. dWorldDestroy (wId);
  489. }
  490. dWorldID wId;
  491. dBodyID bId2;
  492. dJointID jId;
  493. dxJointPR* joint;
  494. static const dVector3 axis;
  495. static const dReal offset;
  496. };
  497. const dVector3 Fixture_dxJointPR_B2_At_Zero_Axis_Inverse_of_X::axis =
  498. {
  499. -1, 0, 0
  500. };
  501. const dReal Fixture_dxJointPR_B2_At_Zero_Axis_Inverse_of_X::offset = REAL (3.1);
  502. // Move 2nd body offset unit in the X direction
  503. //
  504. // X-------> X---------> <--- Axis
  505. // B2 => B2
  506. //
  507. // Start with a Offset of offset unit
  508. //
  509. // X-------> X---------> <--- Axis
  510. // B2 => B2
  511. TEST_FIXTURE (Fixture_dxJointPR_B2_At_Zero_Axis_Inverse_of_X,
  512. test_dJointSetPRAxisOffset_B2_OffsetUnit)
  513. {
  514. dJointSetPRAnchor (jId, 0, 0, 0);
  515. CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  516. dBodySetPosition (bId2, offset, 0, 0);
  517. CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
  518. // dJointSetPRAnchorOffset (jId, 0, 0, 0,
  519. // offset*axis[0],offset*axis[1],offset*axis[2]);
  520. // CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4);
  521. // dBodySetPosition (bId2, 0, 0, 0);
  522. // CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  523. // dJointSetPRAxisDelta (jId, 1, 0, 0, 0, 0, 0);
  524. }
  525. // Move 1st body offset unit in the opposite X direction
  526. //
  527. // X-------> X---------> <--- Axis
  528. // B2 => B2
  529. //
  530. // Start with a Offset of -offset unit
  531. //
  532. // X-------> X---------> <--- Axis
  533. // B2 => B2
  534. TEST_FIXTURE (Fixture_dxJointPR_B2_At_Zero_Axis_Inverse_of_X,
  535. test_dJointSetPRAxisOffset_B2_Minus_OffsetUnit)
  536. {
  537. dJointSetPRAnchor (jId, 0, 0, 0);
  538. CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  539. dBodySetPosition (bId2, -offset, 0, 0);
  540. CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
  541. // dJointSetPRAnchorOffset (jId, 0, 0, 0,
  542. // -offset*axis[0],-offset*axis[1],-offset*axis[2]);
  543. // CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4);
  544. // dBodySetPosition (bId2, 0, 0, 0);
  545. // CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4);
  546. }
  547. // The 2 bodies are positionned at (0, 0, 0), and (0, 0, 0)
  548. // The bodis have rotation of 27deg around some axis.
  549. // The joint is a PR Joint
  550. // Axis is along the X axis
  551. // Anchor at (0, 0, 0)
  552. struct Fixture_dxJointPR_B1_and_B2_Random_Orientation_At_Zero_Axis_Along_X
  553. {
  554. Fixture_dxJointPR_B1_and_B2_Random_Orientation_At_Zero_Axis_Along_X()
  555. {
  556. wId = dWorldCreate();
  557. bId1 = dBodyCreate (wId);
  558. dBodySetPosition (bId1, 0, 0, 0);
  559. bId2 = dBodyCreate (wId);
  560. dBodySetPosition (bId2, 0, 0, 0);
  561. dMatrix3 R;
  562. dVector3 axis; // Random axis
  563. axis[0] = REAL(0.53);
  564. axis[1] = -REAL(0.71);
  565. axis[2] = REAL(0.43);
  566. dNormalize3(axis);
  567. dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
  568. REAL(0.47123)); // 27deg
  569. dBodySetRotation (bId1, R);
  570. axis[0] = REAL(1.2);
  571. axis[1] = REAL(0.87);
  572. axis[2] = -REAL(0.33);
  573. dNormalize3(axis);
  574. dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
  575. REAL(0.47123)); // 27deg
  576. dBodySetRotation (bId2, R);
  577. jId = dJointCreatePR (wId, 0);
  578. joint = (dxJointPR*) jId;
  579. dJointAttach (jId, bId1, bId2);
  580. }
  581. ~Fixture_dxJointPR_B1_and_B2_Random_Orientation_At_Zero_Axis_Along_X()
  582. {
  583. dWorldDestroy (wId);
  584. }
  585. dWorldID wId;
  586. dBodyID bId1;
  587. dBodyID bId2;
  588. dJointID jId;
  589. dxJointPR* joint;
  590. };
  591. // Test is dJointSetPRAxis and dJointGetPRAxis return same value
  592. TEST_FIXTURE (Fixture_dxJointPR_B1_and_B2_Random_Orientation_At_Zero_Axis_Along_X,
  593. test_dJointSetGetPRAxis)
  594. {
  595. dVector3 axisOrig, axis;
  596. dJointGetPRAxis1 (jId, axisOrig);
  597. dJointGetPRAxis1 (jId, axis);
  598. dJointSetPRAxis1 (jId, axis[0], axis[1], axis[2]);
  599. dJointGetPRAxis1 (jId, axis);
  600. CHECK_CLOSE (axis[0], axisOrig[0] , 1e-4);
  601. CHECK_CLOSE (axis[1], axisOrig[1] , 1e-4);
  602. CHECK_CLOSE (axis[2], axisOrig[2] , 1e-4);
  603. dJointGetPRAxis2 (jId, axisOrig);
  604. dJointGetPRAxis2(jId, axis);
  605. dJointSetPRAxis2 (jId, axis[0], axis[1], axis[2]);
  606. dJointGetPRAxis2 (jId, axis);
  607. CHECK_CLOSE (axis[0], axisOrig[0] , 1e-4);
  608. CHECK_CLOSE (axis[1], axisOrig[1] , 1e-4);
  609. CHECK_CLOSE (axis[2], axisOrig[2] , 1e-4);
  610. }
  611. // Create 2 bodies attached by a PR joint
  612. // Axis is along the X axis (Default value
  613. // Anchor at (0, 0, 0) (Default value)
  614. //
  615. // ^Y
  616. // |
  617. // * Body2
  618. // |
  619. // |
  620. // Body1 |
  621. // * Z-------->
  622. struct dxJointPR_Test_Initialization
  623. {
  624. dxJointPR_Test_Initialization()
  625. {
  626. wId = dWorldCreate();
  627. // Remove gravity to have the only force be the force of the joint
  628. dWorldSetGravity(wId, 0,0,0);
  629. for (int j=0; j<2; ++j)
  630. {
  631. bId[j][0] = dBodyCreate (wId);
  632. dBodySetPosition (bId[j][0], -1, -2, -3);
  633. bId[j][1] = dBodyCreate (wId);
  634. dBodySetPosition (bId[j][1], 11, 22, 33);
  635. dMatrix3 R;
  636. dVector3 axis; // Random axis
  637. axis[0] = REAL(0.53);
  638. axis[1] = -REAL(0.71);
  639. axis[2] = REAL(0.43);
  640. dNormalize3(axis);
  641. dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
  642. REAL(0.47123)); // 27deg
  643. dBodySetRotation (bId[j][0], R);
  644. axis[0] = REAL(1.2);
  645. axis[1] = REAL(0.87);
  646. axis[2] = -REAL(0.33);
  647. dNormalize3(axis);
  648. dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
  649. REAL(0.47123)); // 27deg
  650. dBodySetRotation (bId[j][1], R);
  651. jId[j] = dJointCreatePR (wId, 0);
  652. dJointAttach (jId[j], bId[j][0], bId[j][1]);
  653. }
  654. }
  655. ~dxJointPR_Test_Initialization()
  656. {
  657. dWorldDestroy (wId);
  658. }
  659. dWorldID wId;
  660. dBodyID bId[2][2];
  661. dJointID jId[2];
  662. };
  663. // Test if setting a PR with its default values
  664. // will behave the same as a default PR joint
  665. TEST_FIXTURE (dxJointPR_Test_Initialization,
  666. test_PR_Initialization)
  667. {
  668. using namespace std;
  669. dVector3 axis;
  670. dJointGetPRAxis1(jId[1], axis);
  671. dJointSetPRAxis1(jId[1], axis[0], axis[1], axis[2]);
  672. dJointGetPRAxis2(jId[1], axis);
  673. dJointSetPRAxis2(jId[1], axis[0], axis[1], axis[2]);
  674. dVector3 anchor;
  675. dJointGetPRAnchor(jId[1], anchor);
  676. dJointSetPRAnchor(jId[1], anchor[0], anchor[1], anchor[2]);
  677. for (int b=0; b<2; ++b)
  678. {
  679. // Compare body b of the first joint with its equivalent on the
  680. // second joint
  681. const dReal *qA = dBodyGetQuaternion(bId[0][b]);
  682. const dReal *qB = dBodyGetQuaternion(bId[1][b]);
  683. CHECK_CLOSE (qA[0], qB[0], 1e-4);
  684. CHECK_CLOSE (qA[1], qB[1], 1e-4);
  685. CHECK_CLOSE (qA[2], qB[2], 1e-4);
  686. CHECK_CLOSE (qA[3], qB[3], 1e-4);
  687. }
  688. dWorldStep (wId,0.5);
  689. dWorldStep (wId,0.5);
  690. dWorldStep (wId,0.5);
  691. dWorldStep (wId,0.5);
  692. for (int b=0; b<2; ++b)
  693. {
  694. // Compare body b of the first joint with its equivalent on the
  695. // second joint
  696. const dReal *qA = dBodyGetQuaternion(bId[0][b]);
  697. const dReal *qB = dBodyGetQuaternion(bId[1][b]);
  698. CHECK_CLOSE (qA[0], qB[0], 1e-4);
  699. CHECK_CLOSE (qA[1], qB[1], 1e-4);
  700. CHECK_CLOSE (qA[2], qB[2], 1e-4);
  701. CHECK_CLOSE (qA[3], qB[3], 1e-4);
  702. const dReal *posA = dBodyGetPosition(bId[0][b]);
  703. const dReal *posB = dBodyGetPosition(bId[1][b]);
  704. CHECK_CLOSE (posA[0], posB[0], 1e-4);
  705. CHECK_CLOSE (posA[1], posB[1], 1e-4);
  706. CHECK_CLOSE (posA[2], posB[2], 1e-4);
  707. CHECK_CLOSE (posA[3], posB[3], 1e-4);
  708. }
  709. }
  710. // This test compare the result of a slider with 2 bodies where body body 2 is
  711. // fixed to the world to a slider with only one body at position 1.
  712. //
  713. // Test the limits [-1, 0.25] when only one body at is attached to the joint
  714. // using dJointAttache(jId, bId, 0);
  715. //
  716. TEST_FIXTURE(Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y,
  717. test_Limit_minus1_025_One_Body_on_left)
  718. {
  719. // Linear velocity along the prismatic axis;
  720. dVector3 axis;
  721. dJointGetPRAxis1(jId_12, axis);
  722. dBodySetLinearVel (bId1_12, 4*axis[0], 4*axis[1], 4*axis[2]);
  723. dJointAttach(jId_12, bId1_12, bId2_12);
  724. dJointSetPRParam(jId_12, dParamLoStop, -1);
  725. dJointSetPRParam(jId_12, dParamHiStop, 0.25);
  726. dJointAttach(fixed, 0, bId2_12);
  727. dJointSetFixed(fixed);
  728. dJointAttach(jId, bId, 0);
  729. dJointSetPRParam(jId, dParamLoStop, -1);
  730. dJointSetPRParam(jId, dParamHiStop, 0.25);
  731. for (int i=0; i<50; ++i)
  732. dWorldStep(wId, 1.0);
  733. const dReal *pos1_12 = dBodyGetPosition(bId1_12);
  734. const dReal *pos = dBodyGetPosition(bId);
  735. CHECK_CLOSE (pos1_12[0], pos[0], 1e-2);
  736. CHECK_CLOSE (pos1_12[1], pos[1], 1e-2);
  737. CHECK_CLOSE (pos1_12[2], pos[2], 1e-2);
  738. const dReal *q1_12 = dBodyGetQuaternion(bId1_12);
  739. const dReal *q = dBodyGetQuaternion(bId);
  740. CHECK_CLOSE (q1_12[0], q[0], 1e-4);
  741. CHECK_CLOSE (q1_12[1], q[1], 1e-4);
  742. CHECK_CLOSE (q1_12[2], q[2], 1e-4);
  743. CHECK_CLOSE (q1_12[3], q[3], 1e-4);
  744. }
  745. // This test compare the result of a slider with 2 bodies where body body 1 is
  746. // fixed to the world to a slider with only one body at position 2.
  747. //
  748. // Test the limits [-1, 0.25] when only one body at is attached to the joint
  749. // using dJointAttache(jId, 0, bId);
  750. //
  751. TEST_FIXTURE(Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y,
  752. test_Limit_minus1_025_One_Body_on_right)
  753. {
  754. // Linear velocity along the prismatic axis;
  755. dVector3 axis;
  756. dJointGetPRAxis1(jId_12, axis);
  757. dBodySetLinearVel (bId2_12, 4*axis[0], 4*axis[1], 4*axis[2]);
  758. dJointAttach(jId_12, bId1_12, bId2_12);
  759. dJointSetPRParam(jId_12, dParamLoStop, -1);
  760. dJointSetPRParam(jId_12, dParamHiStop, 0.25);
  761. dJointAttach(fixed, bId1_12, 0);
  762. dJointSetFixed(fixed);
  763. dJointAttach(jId, 0, bId);
  764. dJointSetPRParam(jId, dParamLoStop, -1);
  765. dJointSetPRParam(jId, dParamHiStop, 0.25);
  766. for (int i=0; i<50; ++i)
  767. dWorldStep(wId, 1.0);
  768. const dReal *pos2_12 = dBodyGetPosition(bId2_12);
  769. const dReal *pos = dBodyGetPosition(bId);
  770. CHECK_CLOSE (pos2_12[0], pos[0], 1e-2);
  771. CHECK_CLOSE (pos2_12[1], pos[1], 1e-2);
  772. CHECK_CLOSE (pos2_12[2], pos[2], 1e-2);
  773. const dReal *q2_12 = dBodyGetQuaternion(bId2_12);
  774. const dReal *q = dBodyGetQuaternion(bId);
  775. CHECK_CLOSE (q2_12[0], q[0], 1e-4);
  776. CHECK_CLOSE (q2_12[1], q[1], 1e-4);
  777. CHECK_CLOSE (q2_12[2], q[2], 1e-4);
  778. CHECK_CLOSE (q2_12[3], q[3], 1e-4);
  779. }
  780. // This test compare the result of a slider with 2 bodies where body body 2 is
  781. // fixed to the world to a slider with only one body at position 1.
  782. //
  783. // Test the limits [0, 0] when only one body at is attached to the joint
  784. // using dJointAttache(jId, bId, 0);
  785. //
  786. // The body should not move since their is no room between the two limits
  787. //
  788. TEST_FIXTURE(Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y,
  789. test_Limit_0_0_One_Body_on_left)
  790. {
  791. // Linear velocity along the prismatic axis;
  792. dVector3 axis;
  793. dJointGetPRAxis1(jId_12, axis);
  794. dBodySetLinearVel (bId1_12, 4*axis[0], 4*axis[1], 4*axis[2]);
  795. dJointAttach(jId_12, bId1_12, bId2_12);
  796. dJointSetPRParam(jId_12, dParamLoStop, 0);
  797. dJointSetPRParam(jId_12, dParamHiStop, 0);
  798. dJointAttach(fixed, 0, bId2_12);
  799. dJointSetFixed(fixed);
  800. dJointAttach(jId, bId, 0);
  801. dJointSetPRParam(jId, dParamLoStop, 0);
  802. dJointSetPRParam(jId, dParamHiStop, 0);
  803. for (int i=0; i<50; ++i)
  804. dWorldStep(wId, 1.0);
  805. const dReal *pos1_12 = dBodyGetPosition(bId1_12);
  806. const dReal *pos = dBodyGetPosition(bId);
  807. CHECK_CLOSE (pos1_12[0], pos[0], 1e-4);
  808. CHECK_CLOSE (pos1_12[1], pos[1], 1e-4);
  809. CHECK_CLOSE (pos1_12[2], pos[2], 1e-4);
  810. CHECK_CLOSE (0, pos[0], 1e-4);
  811. CHECK_CLOSE (0, pos[1], 1e-4);
  812. CHECK_CLOSE (0, pos[2], 1e-4);
  813. const dReal *q1_12 = dBodyGetQuaternion(bId1_12);
  814. const dReal *q = dBodyGetQuaternion(bId);
  815. CHECK_CLOSE (q1_12[0], q[0], 1e-4);
  816. CHECK_CLOSE (q1_12[1], q[1], 1e-4);
  817. CHECK_CLOSE (q1_12[2], q[2], 1e-4);
  818. CHECK_CLOSE (q1_12[3], q[3], 1e-4);
  819. }
  820. // This test compare the result of a slider with 2 bodies where body body 1 is
  821. // fixed to the world to a slider with only one body at position 2.
  822. //
  823. // Test the limits [0, 0] when only one body at is attached to the joint
  824. // using dJointAttache(jId, 0, bId);
  825. //
  826. // The body should not move since their is no room between the two limits
  827. //
  828. TEST_FIXTURE(Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y,
  829. test_Limit_0_0_One_Body_on_right)
  830. {
  831. // Linear velocity along the prismatic axis;
  832. dVector3 axis;
  833. dJointGetPRAxis1(jId_12, axis);
  834. dBodySetLinearVel (bId2_12, 4*axis[0], 4*axis[1], 4*axis[2]);
  835. dJointAttach(jId_12, bId1_12, bId2_12);
  836. dJointSetPRParam(jId_12, dParamLoStop, 0);
  837. dJointSetPRParam(jId_12, dParamHiStop, 0);
  838. dJointAttach(fixed, bId1_12, 0);
  839. dJointSetFixed(fixed);
  840. dJointAttach(jId, 0, bId);
  841. dJointSetPRParam(jId, dParamLoStop, 0);
  842. dJointSetPRParam(jId, dParamHiStop, 0);
  843. for (int i=0; i<50; ++i)
  844. {
  845. dWorldStep(wId, 1.0);
  846. }
  847. const dReal *pos2_12 = dBodyGetPosition(bId2_12);
  848. const dReal *pos = dBodyGetPosition(bId);
  849. CHECK_CLOSE (pos2_12[0], pos[0], 1e-4);
  850. CHECK_CLOSE (pos2_12[1], pos[1], 1e-4);
  851. CHECK_CLOSE (pos2_12[2], pos[2], 1e-4);
  852. CHECK_CLOSE (0, pos[0], 1e-4);
  853. CHECK_CLOSE (0, pos[1], 1e-4);
  854. CHECK_CLOSE (0, pos[2], 1e-4);
  855. const dReal *q2_12 = dBodyGetQuaternion(bId2_12);
  856. const dReal *q = dBodyGetQuaternion(bId);
  857. CHECK_CLOSE (q2_12[0], q[0], 1e-4);
  858. CHECK_CLOSE (q2_12[1], q[1], 1e-4);
  859. CHECK_CLOSE (q2_12[2], q[2], 1e-4);
  860. CHECK_CLOSE (q2_12[3], q[3], 1e-4);
  861. }
  862. } // End of SUITE TestdxJointPR