piston.cpp 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456
  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/piston.cpp
  27. //
  28. //
  29. ////////////////////////////////////////////////////////////////////////////////
  30. #include <UnitTest++.h>
  31. #include <ode/ode.h>
  32. #include "../../ode/src/config.h"
  33. #include "../../ode/src/joints/piston.h"
  34. SUITE (TestdxJointPiston)
  35. {
  36. // The 2 bodies are positionned at (0, 0, 0), with no rotation
  37. // The joint is a Piston Joint
  38. // Axis is along the X axis
  39. // Anchor at (0, 0, 0)
  40. struct Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X
  41. {
  42. Fixture_dxJointPiston_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 = dJointCreatePiston (wId, 0);
  50. joint = (dxJointPiston*) jId;
  51. dJointAttach (jId, bId1, bId2);
  52. dJointSetPistonAxis (jId, axis[0], axis[1], axis[2]);
  53. }
  54. ~Fixture_dxJointPiston_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. dxJointPiston* joint;
  63. static const dVector3 axis;
  64. static const dReal offset;
  65. };
  66. const dVector3 Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X::axis =
  67. {
  68. 1, 0, 0
  69. };
  70. const dReal Fixture_dxJointPiston_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_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X,
  83. test_dJointSetPistonAxisOffset_B1_3Unit)
  84. {
  85. dJointSetPistonAnchor (jId, 0, 0, 0);
  86. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  87. dBodySetPosition (bId1, offset, 0, 0);
  88. CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
  89. dJointSetPistonAnchorOffset (jId, 0, 0, 0,
  90. offset*axis[0],offset*axis[1],offset*axis[2]);
  91. CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
  92. dBodySetPosition (bId1, 0, 0, 0);
  93. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  94. // Only here to test a deprecated warning
  95. #if 0 // the deprecated warning is not a functional part of the API, no need to test it.
  96. dJointSetPistonAxisDelta (jId, 1, 0, 0, 0, 0, 0);
  97. #endif
  98. }
  99. // Move 1st body offset unit in the opposite X direction
  100. //
  101. // X-------> X---------> Axis -->
  102. // B1 => B1
  103. // B2 B2
  104. //
  105. // Start with a Offset of -offset unit
  106. //
  107. // X-------> X---------> Axis -->
  108. // B1 => B1
  109. // B2 B2
  110. TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X,
  111. test_dJointSetPistonAxisOffset_B1_Minus_3Unit)
  112. {
  113. dJointSetPistonAnchor (jId, 0, 0, 0);
  114. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  115. dBodySetPosition (bId1, -offset, 0, 0);
  116. CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
  117. dJointSetPistonAnchorOffset (jId, 0, 0, 0,
  118. -offset*axis[0],-offset*axis[1],-offset*axis[2]);
  119. CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
  120. dBodySetPosition (bId1, 0, 0, 0);
  121. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  122. }
  123. // Move 2nd body offset unit in the X direction
  124. //
  125. // X-------> X---------> Axis -->
  126. // B1 => B1
  127. // B2 B2
  128. //
  129. // Start with a Offset of offset unit
  130. //
  131. // X-------> X---------> Axis -->
  132. // B1 => B1
  133. // B2 B2
  134. TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X,
  135. test_dJointSetPistonAxisOffset_B2_3Unit)
  136. {
  137. dJointSetPistonAnchor (jId, 0, 0, 0);
  138. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  139. dBodySetPosition (bId2, offset, 0, 0);
  140. CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
  141. dJointSetPistonAnchorOffset (jId, 0, 0, 0,
  142. -offset*axis[0],-offset*axis[1],-offset*axis[2]);
  143. CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
  144. dBodySetPosition (bId2, 0, 0, 0);
  145. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  146. }
  147. // Move 2nd body offset unit in the opposite X direction
  148. //
  149. // X-------> X---------> Axis -->
  150. // B1 => B1
  151. // B2 B2
  152. //
  153. // Start with a Offset of -offset unit
  154. //
  155. // X-------> X---------> Axis -->
  156. // B1 => B1
  157. // B2 B2
  158. TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X,
  159. test_dJointSetPistonAxisOffset_B2_Minus_3Unit)
  160. {
  161. dJointSetPistonAnchor (jId, 0, 0, 0);
  162. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  163. dBodySetPosition (bId2, -offset, 0, 0);
  164. CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
  165. dJointSetPistonAnchorOffset (jId, 0, 0, 0,
  166. offset*axis[0],offset*axis[1],offset*axis[2]);
  167. CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
  168. dBodySetPosition (bId2, 0, 0, 0);
  169. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  170. }
  171. // The 2 bodies are positionned at (0, 0, 0), with no rotation
  172. // The joint is a Piston Joint
  173. // Axis is the opposite of the X axis
  174. // Anchor at (0, 0, 0)
  175. struct Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X
  176. {
  177. Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X()
  178. {
  179. wId = dWorldCreate();
  180. bId1 = dBodyCreate (wId);
  181. dBodySetPosition (bId1, 0, 0, 0);
  182. bId2 = dBodyCreate (wId);
  183. dBodySetPosition (bId2, 0, 0, 0);
  184. jId = dJointCreatePiston (wId, 0);
  185. joint = (dxJointPiston*) jId;
  186. dJointAttach (jId, bId1, bId2);
  187. dJointSetPistonAxis (jId, axis[0], axis[1], axis[2]);
  188. }
  189. ~Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X()
  190. {
  191. dWorldDestroy (wId);
  192. }
  193. dWorldID wId;
  194. dBodyID bId1;
  195. dBodyID bId2;
  196. dJointID jId;
  197. dxJointPiston* joint;
  198. static const dVector3 axis;
  199. static const dReal offset;
  200. };
  201. const dVector3 Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X::axis =
  202. {
  203. -1, 0, 0
  204. };
  205. const dReal Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X::offset = REAL (3.1);
  206. // Move 1st body offset unit in the X direction
  207. //
  208. // X-------> X---------> <-- Axis
  209. // B1 => B1
  210. // B2 B2
  211. //
  212. // Start with a Offset of offset unit
  213. //
  214. // X-------> X---------> <-- Axis
  215. // B1 => B1
  216. // B2 B2
  217. TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X,
  218. test_dJointSetPistonAxisOffset_B1_3Unit)
  219. {
  220. dJointSetPistonAnchor (jId, 0, 0, 0);
  221. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  222. dBodySetPosition (bId1, offset, 0, 0);
  223. CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
  224. dJointSetPistonAnchorOffset (jId, 0, 0, 0,
  225. -offset*axis[0],-offset*axis[1],-offset*axis[2]);
  226. CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
  227. dBodySetPosition (bId1, 0, 0, 0);
  228. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  229. }
  230. // Move 1st body offset unit in the opposite X direction
  231. //
  232. // X-------> X---------> <-- Axis
  233. // B1 => B1
  234. // B2 B2
  235. //
  236. // Start with a Offset of offset unit
  237. //
  238. // X-------> X---------> <-- Axis
  239. // B1 => B1
  240. // B2 B2
  241. TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X,
  242. test_dJointSetPistonAxisOffset_B1_Minus_3Unit)
  243. {
  244. dJointSetPistonAnchor (jId, 0, 0, 0);
  245. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  246. dBodySetPosition (bId1, -offset, 0, 0);
  247. CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
  248. dJointSetPistonAnchorOffset (jId, 0, 0, 0,
  249. offset*axis[0],offset*axis[1],offset*axis[2]);
  250. CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
  251. dBodySetPosition (bId1, 0, 0, 0);
  252. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  253. }
  254. // Move 2nd body offset unit in the X direction
  255. //
  256. // X-------> X---------> <-- Axis
  257. // B1 => B1
  258. // B2 B2
  259. //
  260. // Start with a Offset of offset unit
  261. //
  262. // X-------> X---------> <-- Axis
  263. // B1 => B1
  264. // B2 B2
  265. TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X,
  266. test_dJointSetPistonAxisOffset_B2_3Unit)
  267. {
  268. dJointSetPistonAnchor (jId, 0, 0, 0);
  269. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  270. dBodySetPosition (bId2, offset, 0, 0);
  271. CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
  272. dJointSetPistonAnchorOffset (jId, 0, 0, 0,
  273. offset*axis[0],offset*axis[1],offset*axis[2]);
  274. CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
  275. dBodySetPosition (bId2, 0, 0, 0);
  276. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  277. }
  278. // Move 2nd body offset unit in the opposite X direction
  279. //
  280. // X-------> X---------> <-- Axis
  281. // B1 => B1
  282. // B2 B2
  283. //
  284. // Start with a Offset of -offset unit
  285. //
  286. // X-------> X---------> <-- Axis
  287. // B1 => B1
  288. // B2 B2
  289. TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X,
  290. test_dJointSetPistonAxisOffset_B2_Minus_3Unit)
  291. {
  292. dJointSetPistonAnchor (jId, 0, 0, 0);
  293. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  294. dBodySetPosition (bId2, -offset, 0, 0);
  295. CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
  296. dJointSetPistonAnchorOffset (jId, 0, 0, 0,
  297. -offset*axis[0],-offset*axis[1],-offset*axis[2]);
  298. CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
  299. dBodySetPosition (bId2, 0, 0, 0);
  300. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  301. }
  302. // Only body 1
  303. // The body are positionned at (0, 0, 0), with no rotation
  304. // The joint is a Piston Joint
  305. // Axis is along the X axis
  306. // Anchor at (0, 0, 0)
  307. struct Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X
  308. {
  309. Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X()
  310. {
  311. wId = dWorldCreate();
  312. bId1 = dBodyCreate (wId);
  313. dBodySetPosition (bId1, 0, 0, 0);
  314. jId = dJointCreatePiston (wId, 0);
  315. joint = (dxJointPiston*) jId;
  316. dJointAttach (jId, bId1, NULL);
  317. dJointSetPistonAxis (jId, axis[0], axis[1], axis[2]);
  318. }
  319. ~Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X()
  320. {
  321. dWorldDestroy (wId);
  322. }
  323. dWorldID wId;
  324. dBodyID bId1;
  325. dJointID jId;
  326. dxJointPiston* joint;
  327. static const dVector3 axis;
  328. static const dReal offset;
  329. };
  330. const dVector3 Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X::axis =
  331. {
  332. 1, 0, 0
  333. };
  334. const dReal Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X::offset = REAL (3.1);
  335. // Move 1st body offset unit in the X direction
  336. //
  337. // X-------> X---------> Axis -->
  338. // B1 => B1
  339. //
  340. // Start with a Offset of offset unit
  341. //
  342. // X-------> X---------> Axis -->
  343. // B1 => B1
  344. TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X,
  345. test_dJointSetPistonAxisOffset_B1_OffsetUnit)
  346. {
  347. dJointSetPistonAnchor (jId, 0, 0, 0);
  348. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  349. dBodySetPosition (bId1, offset, 0, 0);
  350. CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
  351. dJointSetPistonAnchorOffset (jId, 0, 0, 0,
  352. offset*axis[0],offset*axis[1],offset*axis[2]);
  353. CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
  354. dBodySetPosition (bId1, 0, 0, 0);
  355. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  356. }
  357. // Move 1st body offset unit in the opposite X direction
  358. //
  359. // X-------> X---------> Axis -->
  360. // B1 => B1
  361. //
  362. // Start with a Offset of -offset unit
  363. //
  364. // X-------> X---------> Axis -->
  365. // B1 => B1
  366. TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X,
  367. test_dJointSetPistonAxisOffset_B1_Minus_OffsetUnit)
  368. {
  369. dJointSetPistonAnchor (jId, 0, 0, 0);
  370. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  371. dBodySetPosition (bId1, -offset, 0, 0);
  372. CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
  373. dJointSetPistonAnchorOffset (jId, 0, 0, 0,
  374. -offset*axis[0],-offset*axis[1],-offset*axis[2]);
  375. CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
  376. dBodySetPosition (bId1, 0, 0, 0);
  377. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  378. }
  379. // Only body 1
  380. // The body are positionned at (0, 0, 0), with no rotation
  381. // The joint is a Piston Joint
  382. // Axis is in the oppsite X axis
  383. // Anchor at (0, 0, 0)
  384. struct Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X
  385. {
  386. Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X()
  387. {
  388. wId = dWorldCreate();
  389. bId1 = dBodyCreate (wId);
  390. dBodySetPosition (bId1, 0, 0, 0);
  391. jId = dJointCreatePiston (wId, 0);
  392. joint = (dxJointPiston*) jId;
  393. dJointAttach (jId, bId1, NULL);
  394. dJointSetPistonAxis (jId, axis[0], axis[1], axis[2]);
  395. }
  396. ~Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X()
  397. {
  398. dWorldDestroy (wId);
  399. }
  400. dWorldID wId;
  401. dBodyID bId1;
  402. dJointID jId;
  403. dxJointPiston* joint;
  404. static const dVector3 axis;
  405. static const dReal offset;
  406. };
  407. const dVector3 Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X::axis =
  408. {
  409. -1, 0, 0
  410. };
  411. const dReal Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X::offset = REAL (3.1);
  412. // Move 1st body offset unit in the X direction
  413. //
  414. // X-------> X---------> <--- Axis
  415. // B1 => B1
  416. //
  417. // Start with a Offset of offset unit
  418. //
  419. // X-------> X---------> <--- Axis
  420. // B1 => B1
  421. TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X,
  422. test_dJointSetPistonAxisOffset_B1_OffsetUnit)
  423. {
  424. dJointSetPistonAnchor (jId, 0, 0, 0);
  425. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  426. dBodySetPosition (bId1, offset, 0, 0);
  427. CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
  428. dJointSetPistonAnchorOffset (jId, 0, 0, 0,
  429. -offset*axis[0],-offset*axis[1],-offset*axis[2]);
  430. CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
  431. dBodySetPosition (bId1, 0, 0, 0);
  432. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  433. }
  434. // Move 1st body offset unit in the opposite X direction
  435. //
  436. // X-------> X---------> <--- Axis
  437. // B1 => B1
  438. //
  439. // Start with a Offset of -offset unit
  440. //
  441. // X-------> X---------> <--- Axis
  442. // B1 => B1
  443. TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X,
  444. test_dJointSetPistonAxisOffset_B1_Minus_OffsetUnit)
  445. {
  446. dJointSetPistonAnchor (jId, 0, 0, 0);
  447. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  448. dBodySetPosition (bId1, -offset, 0, 0);
  449. CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
  450. dJointSetPistonAnchorOffset (jId, 0, 0, 0,
  451. offset*axis[0],offset*axis[1],offset*axis[2]);
  452. CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
  453. dBodySetPosition (bId1, 0, 0, 0);
  454. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  455. }
  456. // Only body 2
  457. // The body are positionned at (0, 0, 0), with no rotation
  458. // The joint is a Piston Joint
  459. // Axis is along the X axis
  460. // Anchor at (0, 0, 0)
  461. struct Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X
  462. {
  463. Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X()
  464. {
  465. wId = dWorldCreate();
  466. bId2 = dBodyCreate (wId);
  467. dBodySetPosition (bId2, 0, 0, 0);
  468. jId = dJointCreatePiston (wId, 0);
  469. joint = (dxJointPiston*) jId;
  470. dJointAttach (jId, NULL, bId2);
  471. dJointSetPistonAxis (jId, axis[0], axis[1], axis[2]);
  472. }
  473. ~Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X()
  474. {
  475. dWorldDestroy (wId);
  476. }
  477. dWorldID wId;
  478. dBodyID bId2;
  479. dJointID jId;
  480. dxJointPiston* joint;
  481. static const dVector3 axis;
  482. static const dReal offset;
  483. };
  484. const dVector3 Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X::axis =
  485. {
  486. 1, 0, 0
  487. };
  488. const dReal Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X::offset = REAL (3.1);
  489. // Move 2nd body offset unit in the X direction
  490. //
  491. // X-------> X---------> Axis -->
  492. // B2 => B2
  493. //
  494. // Start with a Offset of offset unit
  495. //
  496. // X-------> X---------> Axis -->
  497. // B2 => B2
  498. TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X,
  499. test_dJointSetPistonAxisOffset_B2_OffsetUnit)
  500. {
  501. dJointSetPistonAnchor (jId, 0, 0, 0);
  502. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  503. dBodySetPosition (bId2, offset, 0, 0);
  504. CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
  505. dJointSetPistonAnchorOffset (jId, 0, 0, 0,
  506. -offset*axis[0],-offset*axis[1],-offset*axis[2]);
  507. CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
  508. dBodySetPosition (bId2, 0, 0, 0);
  509. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  510. }
  511. // Move 2nd body offset unit in the opposite X direction
  512. //
  513. // X-------> X---------> Axis -->
  514. // B2 => B2
  515. //
  516. // Start with a Offset of -offset unit
  517. //
  518. // X-------> X---------> Axis -->
  519. // B2 => B2
  520. TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X,
  521. test_dJointSetPistonAxisOffset_B2_Minus_OffsetUnit)
  522. {
  523. dJointSetPistonAnchor (jId, 0, 0, 0);
  524. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  525. dBodySetPosition (bId2, -offset, 0, 0);
  526. CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
  527. dJointSetPistonAnchorOffset (jId, 0, 0, 0,
  528. offset*axis[0],offset*axis[1],offset*axis[2]);
  529. CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
  530. dBodySetPosition (bId2, 0, 0, 0);
  531. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  532. }
  533. // Only body 2
  534. // The body are positionned at (0, 0, 0), with no rotation
  535. // The joint is a Piston Joint
  536. // Axis is in the opposite X axis
  537. // Anchor at (0, 0, 0)
  538. struct Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X
  539. {
  540. Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X()
  541. {
  542. wId = dWorldCreate();
  543. bId2 = dBodyCreate (wId);
  544. dBodySetPosition (bId2, 0, 0, 0);
  545. jId = dJointCreatePiston (wId, 0);
  546. joint = (dxJointPiston*) jId;
  547. dJointAttach (jId, NULL, bId2);
  548. dJointSetPistonAxis (jId, axis[0], axis[1], axis[2]);
  549. }
  550. ~Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X()
  551. {
  552. dWorldDestroy (wId);
  553. }
  554. dWorldID wId;
  555. dBodyID bId2;
  556. dJointID jId;
  557. dxJointPiston* joint;
  558. static const dVector3 axis;
  559. static const dReal offset;
  560. };
  561. const dVector3 Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X::axis =
  562. {
  563. -1, 0, 0
  564. };
  565. const dReal Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X::offset = REAL (3.1);
  566. // Move 2nd body offset unit in the X direction
  567. //
  568. // X-------> X---------> <--- Axis
  569. // B2 => B2
  570. //
  571. // Start with a Offset of offset unit
  572. //
  573. // X-------> X---------> <--- Axis
  574. // B2 => B2
  575. TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X,
  576. test_dJointSetPistonAxisOffset_B2_OffsetUnit)
  577. {
  578. dJointSetPistonAnchor (jId, 0, 0, 0);
  579. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  580. dBodySetPosition (bId2, offset, 0, 0);
  581. CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
  582. dJointSetPistonAnchorOffset (jId, 0, 0, 0,
  583. offset*axis[0],offset*axis[1],offset*axis[2]);
  584. CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4);
  585. dBodySetPosition (bId2, 0, 0, 0);
  586. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  587. #if 0 // another deprecated warning test?
  588. dJointSetPistonAxisDelta (jId, 1, 0, 0, 0, 0, 0);
  589. #endif
  590. }
  591. // Move 1st body offset unit in the opposite X direction
  592. //
  593. // X-------> X---------> <--- Axis
  594. // B2 => B2
  595. //
  596. // Start with a Offset of -offset unit
  597. //
  598. // X-------> X---------> <--- Axis
  599. // B2 => B2
  600. TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X,
  601. test_dJointSetPistonAxisOffset_B2_Minus_OffsetUnit)
  602. {
  603. dJointSetPistonAnchor (jId, 0, 0, 0);
  604. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  605. dBodySetPosition (bId2, -offset, 0, 0);
  606. CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
  607. dJointSetPistonAnchorOffset (jId, 0, 0, 0,
  608. -offset*axis[0],-offset*axis[1],-offset*axis[2]);
  609. CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4);
  610. dBodySetPosition (bId2, 0, 0, 0);
  611. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  612. }
  613. // ==========================================================================
  614. // Test Position Rate
  615. // ==========================================================================
  616. // Apply force on 1st body in the X direction also the Axis direction
  617. //
  618. // X-------> X---------> Axis -->
  619. // B1 F-> => B1
  620. // B2 B2
  621. TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X,
  622. test_dJointSetPistonPositionRate_Force_Along_Axis_on_B1)
  623. {
  624. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  625. CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
  626. dBodyAddForce (bId1, 1.0, 0, 0);
  627. dWorldQuickStep (wId, 1.0);
  628. CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4);
  629. }
  630. // Apply force on 1st body in the inverse X direction
  631. //
  632. // X-------> X---------> Axis -->
  633. // B1 <-F => B1
  634. // B2 B2
  635. TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X,
  636. test_dJointSetPistonPositionRate_Force_Inverse_of_Axis_on_B1)
  637. {
  638. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  639. CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
  640. dBodyAddForce (bId1, -1.0, 0, 0);
  641. dWorldQuickStep (wId, 1.0);
  642. CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4);
  643. }
  644. // Apply force on 1st body in the X direction also the Axis direction
  645. //
  646. // X-------> X---------> <-- Axis
  647. // B1 F-> => B1
  648. // B2 B2
  649. TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X,
  650. test_dJointSetPistonPositionRate_Force_Inverse_Axis_on_B1)
  651. {
  652. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  653. CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
  654. dBodyAddForce (bId1, 1.0, 0, 0);
  655. dWorldQuickStep (wId, 1.0);
  656. CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4);
  657. }
  658. // Apply force on 1st body in the inverse X direction
  659. //
  660. // X-------> X---------> <-- Axis
  661. // B1 <-F => B1
  662. // B2 B2
  663. TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X,
  664. test_dJointSetPistonPositionRate_Force_Along_of_Axis_on_B1)
  665. {
  666. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  667. CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
  668. dBodyAddForce (bId1, -1.0, 0, 0);
  669. dWorldQuickStep (wId, 1.0);
  670. CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4);
  671. }
  672. // Apply force on 1st body in the X direction also the Axis direction
  673. //
  674. // X-------> X---------> Axis -->
  675. // B1 => B1
  676. // B2 F-> B2
  677. TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X,
  678. test_dJointSetPistonPositionRate_Force_Along_Axis_on_B2)
  679. {
  680. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  681. CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
  682. dBodyAddForce (bId2, 1.0, 0, 0);
  683. dWorldQuickStep (wId, 1.0);
  684. CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4);
  685. }
  686. // Apply force on 1st body in the inverse X direction
  687. //
  688. // X-------> X---------> Axis -->
  689. // B1 => B1
  690. // B2 <-F B2
  691. TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X,
  692. test_dJointSetPistonPositionRate_Force_Inverse_of_Axis_on_B2)
  693. {
  694. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  695. CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
  696. dBodyAddForce (bId2, -1.0, 0, 0);
  697. dWorldQuickStep (wId, 1.0);
  698. CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4);
  699. }
  700. // Apply force on 1st body in the X direction also the Axis direction
  701. //
  702. // X-------> X---------> <-- Axis
  703. // B1 => B1
  704. // B2 F-> B2
  705. TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X,
  706. test_dJointSetPistonPositionRate_Force_Inverse_Axis_on_B2)
  707. {
  708. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  709. CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
  710. dBodyAddForce (bId2, 1.0, 0, 0);
  711. dWorldQuickStep (wId, 1.0);
  712. CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4);
  713. }
  714. // Apply force on 1st body in the inverse X direction
  715. //
  716. // X-------> X---------> <-- Axis
  717. // B1 => B1
  718. // B2 <-F B2
  719. TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X,
  720. test_dJointSetPistonPositionRate_Force_Along_of_Axis_on_B2)
  721. {
  722. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  723. CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
  724. dBodyAddForce (bId2, -1.0, 0, 0);
  725. dWorldQuickStep (wId, 1.0);
  726. CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4);
  727. }
  728. // Apply force on 1st body in the X direction also the Axis direction
  729. //
  730. // X-------> X---------> Axis -->
  731. // B1 F-> => B1
  732. TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X,
  733. test_dJointSetPistonPositionRate_Force_Along_Axis_on_B1)
  734. {
  735. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  736. CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
  737. dBodyAddForce (bId1, 1.0, 0, 0);
  738. dWorldQuickStep (wId, 1.0);
  739. CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4);
  740. }
  741. // Apply force on 1st body in the inverse X direction
  742. //
  743. // X-------> X---------> Axis -->
  744. // B1 <-F => B1
  745. TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X,
  746. test_dJointSetPistonPositionRate_Force_Inverse_of_Axis_on_B1)
  747. {
  748. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  749. CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
  750. dBodyAddForce (bId1, -1.0, 0, 0);
  751. dWorldQuickStep (wId, 1.0);
  752. CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4);
  753. }
  754. // Apply force on 1st body in the X direction also the Axis direction
  755. //
  756. // X-------> X---------> <-- Axis
  757. // B1 F-> => B1
  758. TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X,
  759. test_dJointSetPistonPositionRate_Force_Inverse_Axis_on_B1)
  760. {
  761. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  762. CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
  763. dBodyAddForce (bId1, 1.0, 0, 0);
  764. dWorldQuickStep (wId, 1.0);
  765. CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4);
  766. }
  767. // Apply force on 1st body in the inverse X direction
  768. //
  769. // X-------> X---------> <-- Axis
  770. // B1 <-F => B1
  771. TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X,
  772. test_dJointSetPistonPositionRate_Force_Along_of_Axis_on_B1)
  773. {
  774. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  775. CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
  776. dBodyAddForce (bId1, -1.0, 0, 0);
  777. dWorldQuickStep (wId, 1.0);
  778. CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4);
  779. }
  780. // Apply force on body 2 in the X direction also the Axis direction
  781. //
  782. // X-------> X---------> Axis -->
  783. // B2 F-> B2
  784. TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X,
  785. test_dJointSetPistonPositionRate_Force_Along_Axis_on_B2)
  786. {
  787. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  788. CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
  789. dBodyAddForce (bId2, 1.0, 0, 0);
  790. dWorldQuickStep (wId, 1.0);
  791. CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4);
  792. }
  793. // Apply force on body 2 in the inverse X direction
  794. //
  795. // X-------> X---------> Axis -->
  796. // B2 <-F B2
  797. TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X,
  798. test_dJointSetPistonPositionRate_Force_Inverse_of_Axis_on_B2)
  799. {
  800. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  801. CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
  802. dBodyAddForce (bId2, -1.0, 0, 0);
  803. dWorldQuickStep (wId, 1.0);
  804. CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4);
  805. }
  806. // Apply force on body 2 in the X direction also the Axis direction
  807. //
  808. // X-------> X---------> <-- Axis
  809. // B2 F-> B2
  810. TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X,
  811. test_dJointSetPistonPositionRate_Force_Inverse_Axis_on_B2)
  812. {
  813. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  814. CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
  815. dBodyAddForce (bId2, 1.0, 0, 0);
  816. dWorldQuickStep (wId, 1.0);
  817. CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4);
  818. }
  819. // Apply force on body 2 in the inverse X direction
  820. //
  821. // X-------> X---------> <-- Axis
  822. // B2 <-F B2
  823. TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X,
  824. test_dJointSetPistonPositionRate_Force_Along_of_Axis_on_B2)
  825. {
  826. CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4);
  827. CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4);
  828. dBodyAddForce (bId2, -1.0, 0, 0);
  829. dWorldQuickStep (wId, 1.0);
  830. CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4);
  831. }
  832. // Create 2 bodies attached by a Piston joint
  833. // Axis is along the X axis (Default value
  834. // Anchor at (0, 0, 0) (Default value)
  835. //
  836. // ^Y
  837. // |
  838. // * Body2
  839. // |
  840. // |
  841. // Body1 |
  842. // * Z-------->
  843. struct dxJointPiston_Test_Initialization
  844. {
  845. dxJointPiston_Test_Initialization()
  846. {
  847. wId = dWorldCreate();
  848. // Remove gravity to have the only force be the force of the joint
  849. dWorldSetGravity(wId, 0,0,0);
  850. for (int j=0; j<2; ++j)
  851. {
  852. bId[j][0] = dBodyCreate (wId);
  853. dBodySetPosition (bId[j][0], -1, -2, -3);
  854. bId[j][1] = dBodyCreate (wId);
  855. dBodySetPosition (bId[j][1], 11, 22, 33);
  856. dMatrix3 R;
  857. dVector3 axis; // Random axis
  858. axis[0] = REAL(0.53);
  859. axis[1] = -REAL(0.71);
  860. axis[2] = REAL(0.43);
  861. dNormalize3(axis);
  862. dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
  863. REAL(0.47123)); // 27deg
  864. dBodySetRotation (bId[j][0], R);
  865. axis[0] = REAL(1.2);
  866. axis[1] = REAL(0.87);
  867. axis[2] = -REAL(0.33);
  868. dNormalize3(axis);
  869. dRFromAxisAndAngle (R, axis[0], axis[1], axis[2],
  870. REAL(0.47123)); // 27deg
  871. dBodySetRotation (bId[j][1], R);
  872. jId[j] = dJointCreatePiston (wId, 0);
  873. dJointAttach (jId[j], bId[j][0], bId[j][1]);
  874. }
  875. }
  876. ~dxJointPiston_Test_Initialization()
  877. {
  878. dWorldDestroy (wId);
  879. }
  880. dWorldID wId;
  881. dBodyID bId[2][2];
  882. dJointID jId[2];
  883. };
  884. // Test if setting a Piston with its default values
  885. // will behave the same as a default Piston joint
  886. TEST_FIXTURE (dxJointPiston_Test_Initialization,
  887. test_Piston_Initialization)
  888. {
  889. using namespace std;
  890. dVector3 axis;
  891. dJointGetPistonAxis(jId[1], axis);
  892. dJointSetPistonAxis(jId[1], axis[0], axis[1], axis[2]);
  893. dVector3 anchor;
  894. dJointGetPistonAnchor(jId[1], anchor);
  895. dJointSetPistonAnchor(jId[1], anchor[0], anchor[1], anchor[2]);
  896. for (int b=0; b<2; ++b)
  897. {
  898. // Compare body b of the first joint with its equivalent on the
  899. // second joint
  900. const dReal *qA = dBodyGetQuaternion(bId[0][b]);
  901. const dReal *qB = dBodyGetQuaternion(bId[1][b]);
  902. CHECK_CLOSE (qA[0], qB[0], 1e-6);
  903. CHECK_CLOSE (qA[1], qB[1], 1e-6);
  904. CHECK_CLOSE (qA[2], qB[2], 1e-6);
  905. CHECK_CLOSE (qA[3], qB[3], 1e-6);
  906. }
  907. dWorldStep (wId,0.5);
  908. dWorldStep (wId,0.5);
  909. dWorldStep (wId,0.5);
  910. dWorldStep (wId,0.5);
  911. for (int b=0; b<2; ++b)
  912. {
  913. // Compare body b of the first joint with its equivalent on the
  914. // second joint
  915. const dReal *qA = dBodyGetQuaternion(bId[0][b]);
  916. const dReal *qB = dBodyGetQuaternion(bId[1][b]);
  917. CHECK_CLOSE (qA[0], qB[0], 1e-6);
  918. CHECK_CLOSE (qA[1], qB[1], 1e-6);
  919. CHECK_CLOSE (qA[2], qB[2], 1e-6);
  920. CHECK_CLOSE (qA[3], qB[3], 1e-6);
  921. const dReal *posA = dBodyGetPosition(bId[0][b]);
  922. const dReal *posB = dBodyGetPosition(bId[1][b]);
  923. CHECK_CLOSE (posA[0], posB[0], 1e-6);
  924. CHECK_CLOSE (posA[1], posB[1], 1e-6);
  925. CHECK_CLOSE (posA[2], posB[2], 1e-6);
  926. CHECK_CLOSE (posA[3], posB[3], 1e-6);
  927. }
  928. }
  929. // Compare only one body to 2 bodies with one fixed.
  930. //
  931. // The body are positionned at (0, 0, 0), with no rotation
  932. // The joint is a Piston Joint
  933. // Axis is along the X axis
  934. // Anchor at (0, 0, 0)
  935. struct Fixture_dxJointPiston_Compare_Body_At_Zero_Axis_Along_X
  936. {
  937. Fixture_dxJointPiston_Compare_Body_At_Zero_Axis_Along_X()
  938. {
  939. wId = dWorldCreate();
  940. bId1_12 = dBodyCreate (wId);
  941. dBodySetPosition (bId1_12, 0, 0, 0);
  942. bId2_12 = dBodyCreate (wId);
  943. dBodySetPosition (bId2_12, 0, 0, 0);
  944. // The force will be added in the function since it is not
  945. // always on the same body
  946. jId_12 = dJointCreatePiston (wId, 0);
  947. dJointAttach(jId_12, bId1_12, bId2_12);
  948. fixed = dJointCreateFixed (wId, 0);
  949. bId = dBodyCreate (wId);
  950. dBodySetPosition (bId, 0, 0, 0);
  951. dBodyAddForce (bId, 4, 0, 0);
  952. jId = dJointCreatePiston (wId, 0);
  953. }
  954. ~Fixture_dxJointPiston_Compare_Body_At_Zero_Axis_Along_X()
  955. {
  956. dWorldDestroy (wId);
  957. }
  958. dWorldID wId;
  959. dBodyID bId1_12;
  960. dBodyID bId2_12;
  961. dJointID jId_12; // Joint with 2 bodies
  962. dJointID fixed;
  963. dBodyID bId;
  964. dJointID jId; // Joint with one body
  965. };
  966. // This test compare the result of a slider with 2 bodies where body body 2 is
  967. // fixed to the world to a slider with only one body at position 1.
  968. //
  969. // Test the limits [-1, 0.25] when only one body at is attached to the joint
  970. // using dJointAttache(jId, bId, 0);
  971. //
  972. TEST_FIXTURE(Fixture_dxJointPiston_Compare_Body_At_Zero_Axis_Along_X,
  973. test_Limit_minus1_025_One_Body_on_left)
  974. {
  975. dBodyAddForce (bId1_12, 4, 0, 0);
  976. dJointAttach(jId_12, bId1_12, bId2_12);
  977. dJointSetPistonParam(jId_12, dParamLoStop, -1);
  978. dJointSetPistonParam(jId_12, dParamHiStop, 0.25);
  979. dJointAttach(fixed, 0, bId2_12);
  980. dJointSetFixed(fixed);
  981. dJointAttach(jId, bId, 0);
  982. dJointSetPistonParam(jId, dParamLoStop, -1);
  983. dJointSetPistonParam(jId, dParamHiStop, 0.25);
  984. for (int i=0; i<50; ++i)
  985. dWorldStep(wId, 1.0);
  986. const dReal *pos1_12 = dBodyGetPosition(bId1_12);
  987. const dReal *pos = dBodyGetPosition(bId);
  988. CHECK_CLOSE (pos1_12[0], pos[0], 1e-2);
  989. CHECK_CLOSE (pos1_12[1], pos[1], 1e-2);
  990. CHECK_CLOSE (pos1_12[2], pos[2], 1e-2);
  991. const dReal *q1_12 = dBodyGetQuaternion(bId1_12);
  992. const dReal *q = dBodyGetQuaternion(bId);
  993. CHECK_CLOSE (q1_12[0], q[0], 1e-4);
  994. CHECK_CLOSE (q1_12[1], q[1], 1e-4);
  995. CHECK_CLOSE (q1_12[2], q[2], 1e-4);
  996. CHECK_CLOSE (q1_12[3], q[3], 1e-4);
  997. }
  998. // This test compare the result of a slider with 2 bodies where body body 1 is
  999. // fixed to the world to a slider with only one body at position 2.
  1000. //
  1001. // Test the limits [-1, 0.25] when only one body at is attached to the joint
  1002. // using dJointAttache(jId, 0, bId);
  1003. //
  1004. TEST_FIXTURE(Fixture_dxJointPiston_Compare_Body_At_Zero_Axis_Along_X,
  1005. test_Limit_minus1_025_One_Body_on_right)
  1006. {
  1007. dBodyAddForce (bId2_12, 4, 0, 0);
  1008. dJointAttach(jId_12, bId1_12, bId2_12);
  1009. dJointSetPistonParam(jId_12, dParamLoStop, -1);
  1010. dJointSetPistonParam(jId_12, dParamHiStop, 0.25);
  1011. dJointAttach(fixed, bId1_12, 0);
  1012. dJointSetFixed(fixed);
  1013. dJointAttach(jId, 0, bId);
  1014. dJointSetPistonParam(jId, dParamLoStop, -1);
  1015. dJointSetPistonParam(jId, dParamHiStop, 0.25);
  1016. for (int i=0; i<50; ++i)
  1017. dWorldStep(wId, 1.0);
  1018. const dReal *pos2_12 = dBodyGetPosition(bId2_12);
  1019. const dReal *pos = dBodyGetPosition(bId);
  1020. CHECK_CLOSE (pos2_12[0], pos[0], 1e-2);
  1021. CHECK_CLOSE (pos2_12[1], pos[1], 1e-2);
  1022. CHECK_CLOSE (pos2_12[2], pos[2], 1e-2);
  1023. const dReal *q2_12 = dBodyGetQuaternion(bId2_12);
  1024. const dReal *q = dBodyGetQuaternion(bId);
  1025. CHECK_CLOSE (q2_12[0], q[0], 1e-4);
  1026. CHECK_CLOSE (q2_12[1], q[1], 1e-4);
  1027. CHECK_CLOSE (q2_12[2], q[2], 1e-4);
  1028. CHECK_CLOSE (q2_12[3], q[3], 1e-4);
  1029. }
  1030. // This test compare the result of a slider with 2 bodies where body body 2 is
  1031. // fixed to the world to a slider with only one body at position 1.
  1032. //
  1033. // Test the limits [0, 0] when only one body at is attached to the joint
  1034. // using dJointAttache(jId, bId, 0);
  1035. //
  1036. // The body should not move since their is no room between the two limits
  1037. //
  1038. TEST_FIXTURE(Fixture_dxJointPiston_Compare_Body_At_Zero_Axis_Along_X,
  1039. test_Limit_0_0_One_Body_on_left)
  1040. {
  1041. dBodyAddForce (bId1_12, 4, 0, 0);
  1042. dJointAttach(jId_12, bId1_12, bId2_12);
  1043. dJointSetPistonParam(jId_12, dParamLoStop, 0);
  1044. dJointSetPistonParam(jId_12, dParamHiStop, 0);
  1045. dJointAttach(fixed, 0, bId2_12);
  1046. dJointSetFixed(fixed);
  1047. dJointAttach(jId, bId, 0);
  1048. dJointSetPistonParam(jId, dParamLoStop, 0);
  1049. dJointSetPistonParam(jId, dParamHiStop, 0);
  1050. for (int i=0; i<500; ++i)
  1051. dWorldStep(wId, 1.0);
  1052. const dReal *pos1_12 = dBodyGetPosition(bId1_12);
  1053. const dReal *pos = dBodyGetPosition(bId);
  1054. CHECK_CLOSE (pos1_12[0], pos[0], 1e-4);
  1055. CHECK_CLOSE (pos1_12[1], pos[1], 1e-4);
  1056. CHECK_CLOSE (pos1_12[2], pos[2], 1e-4);
  1057. CHECK_CLOSE (0, pos[0], 1e-4);
  1058. CHECK_CLOSE (0, pos[1], 1e-4);
  1059. CHECK_CLOSE (0, pos[2], 1e-4);
  1060. const dReal *q1_12 = dBodyGetQuaternion(bId1_12);
  1061. const dReal *q = dBodyGetQuaternion(bId);
  1062. CHECK_CLOSE (q1_12[0], q[0], 1e-4);
  1063. CHECK_CLOSE (q1_12[1], q[1], 1e-4);
  1064. CHECK_CLOSE (q1_12[2], q[2], 1e-4);
  1065. CHECK_CLOSE (q1_12[3], q[3], 1e-4);
  1066. }
  1067. // This test compare the result of a slider with 2 bodies where body body 1 is
  1068. // fixed to the world to a slider with only one body at position 2.
  1069. //
  1070. // Test the limits [0, 0] when only one body at is attached to the joint
  1071. // using dJointAttache(jId, 0, bId);
  1072. //
  1073. // The body should not move since their is no room between the two limits
  1074. //
  1075. TEST_FIXTURE(Fixture_dxJointPiston_Compare_Body_At_Zero_Axis_Along_X,
  1076. test_Limit_0_0_One_Body_on_right)
  1077. {
  1078. dBodyAddForce (bId2_12, 4, 0, 0);
  1079. dJointAttach(jId_12, bId1_12, bId2_12);
  1080. dJointSetPistonParam(jId_12, dParamLoStop, 0);
  1081. dJointSetPistonParam(jId_12, dParamHiStop, 0);
  1082. dJointAttach(fixed, bId1_12, 0);
  1083. dJointSetFixed(fixed);
  1084. dJointAttach(jId, 0, bId);
  1085. dJointSetPistonParam(jId, dParamLoStop, 0);
  1086. dJointSetPistonParam(jId, dParamHiStop, 0);
  1087. for (int i=0; i<500; ++i)
  1088. dWorldStep(wId, 1.0);
  1089. const dReal *pos2_12 = dBodyGetPosition(bId2_12);
  1090. const dReal *pos = dBodyGetPosition(bId);
  1091. CHECK_CLOSE (pos2_12[0], pos[0], 1e-4);
  1092. CHECK_CLOSE (pos2_12[1], pos[1], 1e-4);
  1093. CHECK_CLOSE (pos2_12[2], pos[2], 1e-4);
  1094. CHECK_CLOSE (0, pos[0], 1e-4);
  1095. CHECK_CLOSE (0, pos[1], 1e-4);
  1096. CHECK_CLOSE (0, pos[2], 1e-4);
  1097. const dReal *q2_12 = dBodyGetQuaternion(bId2_12);
  1098. const dReal *q = dBodyGetQuaternion(bId);
  1099. CHECK_CLOSE (q2_12[0], q[0], 1e-4);
  1100. CHECK_CLOSE (q2_12[1], q[1], 1e-4);
  1101. CHECK_CLOSE (q2_12[2], q[2], 1e-4);
  1102. CHECK_CLOSE (q2_12[3], q[3], 1e-4);
  1103. }
  1104. } // End of SUITE TestdxJointPiston