InverseKinematicsExample.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. #include "InverseKinematicsExample.h"
  2. #include "../CommonInterfaces/CommonGraphicsAppInterface.h"
  3. #include "Bullet3Common/b3Quaternion.h"
  4. #include "Bullet3Common/b3Transform.h"
  5. #include "Bullet3Common/b3AlignedObjectArray.h"
  6. #include "../CommonInterfaces/CommonRenderInterface.h"
  7. #include "../CommonInterfaces/CommonExampleInterface.h"
  8. #include "../CommonInterfaces/CommonGUIHelperInterface.h"
  9. #include "../OpenGLWindow/OpenGLInclude.h"
  10. #include "BussIK/Node.h"
  11. #include "BussIK/Tree.h"
  12. #include "BussIK/Jacobian.h"
  13. #include "BussIK/VectorRn.h"
  14. #define RADIAN(X) ((X)*RadiansToDegrees)
  15. #define MAX_NUM_NODE 1000
  16. #define MAX_NUM_THETA 1000
  17. #define MAX_NUM_EFFECT 100
  18. double T = 0;
  19. VectorR3 targetaa[MAX_NUM_EFFECT];
  20. // Make slowdown factor larger to make the simulation take larger, less frequent steps
  21. // Make the constant factor in Tstep larger to make time pass more quickly
  22. //const int SlowdownFactor = 40;
  23. const int SlowdownFactor = 0; // Make higher to take larger steps less frequently
  24. const int SleepsPerStep=SlowdownFactor;
  25. int SleepCounter=0;
  26. //const double Tstep = 0.0005*(double)SlowdownFactor; // Time step
  27. int AxesList; /* list to hold the axes */
  28. int AxesOn; /* ON or OFF */
  29. float Scale, Scale2; /* scaling factors */
  30. int JointLimitsOn;
  31. int RestPositionOn;
  32. int UseJacobianTargets1;
  33. int numIteration = 1;
  34. double error = 0.0;
  35. double errorDLS = 0.0;
  36. double errorSDLS = 0.0;
  37. double sumError = 0.0;
  38. double sumErrorDLS = 0.0;
  39. double sumErrorSDLS = 0.0;
  40. #ifdef _DYNAMIC
  41. bool initMaxDist = true;
  42. extern double Excess[];
  43. extern double dsnorm[];
  44. #endif
  45. void Reset(Tree &tree, Jacobian* m_ikJacobian)
  46. {
  47. AxesOn = false;
  48. Scale = 1.0;
  49. Scale2 = 0.0; /* because add 1. to it in Display() */
  50. JointLimitsOn = true;
  51. RestPositionOn = false;
  52. UseJacobianTargets1 = false;
  53. tree.Init();
  54. tree.Compute();
  55. m_ikJacobian->Reset();
  56. }
  57. // Update target positions
  58. void UpdateTargets( double T2, Tree & treeY) {
  59. double T = T2 / 5.;
  60. targetaa[0].Set(0.6*b3Sin(0), 0.6*b3Cos(0), 0.5+0.4*b3Sin(3 * T));
  61. }
  62. // Does a single update (on one kind of tree)
  63. void DoUpdateStep(double Tstep, Tree & treeY, Jacobian *jacob, int ikMethod) {
  64. if ( SleepCounter==0 ) {
  65. T += Tstep;
  66. UpdateTargets( T , treeY);
  67. }
  68. if ( UseJacobianTargets1 ) {
  69. jacob->SetJtargetActive();
  70. }
  71. else {
  72. jacob->SetJendActive();
  73. }
  74. jacob->ComputeJacobian(targetaa); // Set up Jacobian and deltaS vectors
  75. // Calculate the change in theta values
  76. switch (ikMethod) {
  77. case IK_JACOB_TRANS:
  78. jacob->CalcDeltaThetasTranspose(); // Jacobian transpose method
  79. break;
  80. case IK_DLS:
  81. jacob->CalcDeltaThetasDLS(); // Damped least squares method
  82. break;
  83. case IK_DLS_SVD:
  84. jacob->CalcDeltaThetasDLSwithSVD();
  85. break;
  86. case IK_PURE_PSEUDO:
  87. jacob->CalcDeltaThetasPseudoinverse(); // Pure pseudoinverse method
  88. break;
  89. case IK_SDLS:
  90. jacob->CalcDeltaThetasSDLS(); // Selectively damped least squares method
  91. break;
  92. default:
  93. jacob->ZeroDeltaThetas();
  94. break;
  95. }
  96. if ( SleepCounter==0 ) {
  97. jacob->UpdateThetas(); // Apply the change in the theta values
  98. jacob->UpdatedSClampValue(targetaa);
  99. SleepCounter = SleepsPerStep;
  100. }
  101. else {
  102. SleepCounter--;
  103. }
  104. }
  105. ///quick demo showing the right-handed coordinate system and positive rotations around each axis
  106. class InverseKinematicsExample : public CommonExampleInterface
  107. {
  108. CommonGraphicsApp* m_app;
  109. int m_ikMethod;
  110. Tree m_ikTree;
  111. b3AlignedObjectArray<Node*> m_ikNodes;
  112. Jacobian* m_ikJacobian;
  113. float m_x;
  114. float m_y;
  115. float m_z;
  116. b3AlignedObjectArray<int> m_movingInstances;
  117. int m_targetInstance;
  118. enum
  119. {
  120. numCubesX = 20,
  121. numCubesY = 20
  122. };
  123. public:
  124. InverseKinematicsExample(CommonGraphicsApp* app, int option)
  125. :m_app(app),
  126. m_x(0),
  127. m_y(0),
  128. m_z(0),
  129. m_targetInstance(-1),
  130. m_ikMethod(option)
  131. {
  132. m_app->setUpAxis(2);
  133. {
  134. b3Vector3 extents=b3MakeVector3(100,100,100);
  135. extents[m_app->getUpAxis()]=1;
  136. int xres = 20;
  137. int yres = 20;
  138. b3Vector4 color0=b3MakeVector4(0.4, 0.4, 0.4,1);
  139. b3Vector4 color1=b3MakeVector4(0.6, 0.6, 0.6,1);
  140. m_app->registerGrid(xres, yres, color0, color1);
  141. }
  142. ///create some graphics proxy for the tracking target
  143. ///the endeffector tries to track it using Inverse Kinematics
  144. {
  145. int sphereId = m_app->registerGraphicsUnitSphereShape(SPHERE_LOD_MEDIUM);
  146. b3Vector3 pos = b3MakeVector3(1,1,1);
  147. pos[app->getUpAxis()] = 1;
  148. b3Quaternion orn(0, 0, 0, 1);
  149. b3Vector4 color = b3MakeVector4(1., 0.3, 0.3, 1);
  150. b3Vector3 scaling = b3MakeVector3(.02, .02, .02);
  151. m_targetInstance = m_app->m_renderer->registerGraphicsInstance(sphereId, pos, orn, color, scaling);
  152. }
  153. m_app->m_renderer->writeTransforms();
  154. }
  155. virtual ~InverseKinematicsExample()
  156. {
  157. m_app->m_renderer->enableBlend(false);
  158. }
  159. virtual void physicsDebugDraw(int debugDrawMode)
  160. {
  161. }
  162. virtual void initPhysics()
  163. {
  164. BuildKukaIIWAShape();
  165. m_ikJacobian = new Jacobian(&m_ikTree);
  166. Reset(m_ikTree,m_ikJacobian);
  167. }
  168. virtual void exitPhysics()
  169. {
  170. delete m_ikJacobian;
  171. m_ikJacobian = 0;
  172. }
  173. void BuildKukaIIWAShape();
  174. void getLocalTransform(const Node* node, b3Transform& act)
  175. {
  176. b3Vector3 axis = b3MakeVector3(node->v.x, node->v.y, node->v.z);
  177. b3Quaternion rot(0, 0, 0, 1);
  178. if (axis.length())
  179. {
  180. rot = b3Quaternion (axis, node->theta);
  181. }
  182. act.setIdentity();
  183. act.setRotation(rot);
  184. act.setOrigin(b3MakeVector3(node->r.x, node->r.y, node->r.z));
  185. }
  186. void MyDrawTree(Node* node, const b3Transform& tr)
  187. {
  188. b3Vector3 lineColor = b3MakeVector3(0, 0, 0);
  189. int lineWidth = 2;
  190. if (node != 0) {
  191. // glPushMatrix();
  192. b3Vector3 pos = b3MakeVector3(tr.getOrigin().x, tr.getOrigin().y, tr.getOrigin().z);
  193. b3Vector3 color = b3MakeVector3(0, 1, 0);
  194. int pointSize = 10;
  195. m_app->m_renderer->drawPoint(pos, color, pointSize);
  196. m_app->m_renderer->drawLine(pos, pos+ 0.05*tr.getBasis().getColumn(0), b3MakeVector3(1,0,0), lineWidth);
  197. m_app->m_renderer->drawLine(pos, pos + 0.05*tr.getBasis().getColumn(1), b3MakeVector3(0, 1, 0), lineWidth);
  198. m_app->m_renderer->drawLine(pos, pos + 0.05*tr.getBasis().getColumn(2), b3MakeVector3(0, 0, 1), lineWidth);
  199. b3Vector3 axisLocal = b3MakeVector3(node->v.x, node->v.y, node->v.z);
  200. b3Vector3 axisWorld = tr.getBasis()*axisLocal;
  201. m_app->m_renderer->drawLine(pos, pos + 0.1*axisWorld, b3MakeVector3(.2, 0.2, 0.7), 5);
  202. //node->DrawNode(node == root); // Recursively draw node and update ModelView matrix
  203. if (node->left) {
  204. b3Transform act;
  205. getLocalTransform(node->left, act);
  206. b3Transform trl = tr*act;
  207. m_app->m_renderer->drawLine(tr.getOrigin(), trl.getOrigin(), lineColor, lineWidth);
  208. MyDrawTree(node->left, trl); // Draw tree of children recursively
  209. }
  210. // glPopMatrix();
  211. if (node->right) {
  212. b3Transform act;
  213. getLocalTransform(node->right, act);
  214. b3Transform trr = tr*act;
  215. m_app->m_renderer->drawLine(tr.getOrigin(), trr.getOrigin(), lineColor, lineWidth);
  216. MyDrawTree(node->right,trr); // Draw right siblings recursively
  217. }
  218. }
  219. }
  220. virtual void stepSimulation(float deltaTime)
  221. {
  222. DoUpdateStep(deltaTime, m_ikTree, m_ikJacobian, m_ikMethod);
  223. }
  224. virtual void renderScene()
  225. {
  226. b3Transform act;
  227. getLocalTransform(m_ikTree.GetRoot(), act);
  228. MyDrawTree(m_ikTree.GetRoot(), act);
  229. b3Vector3 pos = b3MakeVector3(targetaa[0].x, targetaa[0].y, targetaa[0].z);
  230. b3Quaternion orn(0, 0, 0, 1);
  231. m_app->m_renderer->writeSingleInstanceTransformToCPU(pos, orn, m_targetInstance);
  232. m_app->m_renderer->writeTransforms();
  233. m_app->m_renderer->renderScene();
  234. }
  235. virtual void physicsDebugDraw()
  236. {
  237. }
  238. virtual bool mouseMoveCallback(float x,float y)
  239. {
  240. return false;
  241. }
  242. virtual bool mouseButtonCallback(int button, int state, float x, float y)
  243. {
  244. return false;
  245. }
  246. virtual bool keyboardCallback(int key, int state)
  247. {
  248. return false;
  249. }
  250. virtual void resetCamera()
  251. {
  252. float dist = 1.3;
  253. float pitch = 120;
  254. float yaw = 13;
  255. float targetPos[3]={-0.35,0.14,0.25};
  256. if (m_app->m_renderer && m_app->m_renderer->getActiveCamera())
  257. {
  258. m_app->m_renderer->getActiveCamera()->setCameraDistance(dist);
  259. m_app->m_renderer->getActiveCamera()->setCameraPitch(pitch);
  260. m_app->m_renderer->getActiveCamera()->setCameraYaw(yaw);
  261. m_app->m_renderer->getActiveCamera()->setCameraTargetPosition(targetPos[0],targetPos[1],targetPos[2]);
  262. }
  263. }
  264. };
  265. void InverseKinematicsExample::BuildKukaIIWAShape()
  266. {
  267. const VectorR3& unitx = VectorR3::UnitX;
  268. const VectorR3& unity = VectorR3::UnitY;
  269. const VectorR3& unitz = VectorR3::UnitZ;
  270. const VectorR3 unit1(sqrt(14.0) / 8.0, 1.0 / 8.0, 7.0 / 8.0);
  271. const VectorR3& zero = VectorR3::Zero;
  272. float minTheta = -4 * PI;
  273. float maxTheta = 4 * PI;
  274. m_ikNodes.resize(8);//7DOF+additional endeffector
  275. m_ikNodes[0] = new Node(VectorR3(0.100000, 0.000000, 0.087500), unitz, 0.08, JOINT, -1e30, 1e30, RADIAN(0.));
  276. m_ikTree.InsertRoot(m_ikNodes[0]);
  277. m_ikNodes[1] = new Node(VectorR3(0.100000, -0.000000, 0.290000), unity, 0.08, JOINT, -0.5, 0.4, RADIAN(0.));
  278. m_ikTree.InsertLeftChild(m_ikNodes[0], m_ikNodes[1]);
  279. m_ikNodes[2] = new Node(VectorR3(0.100000, -0.000000, 0.494500), unitz, 0.08, JOINT, minTheta, maxTheta, RADIAN(0.));
  280. m_ikTree.InsertLeftChild(m_ikNodes[1], m_ikNodes[2]);
  281. m_ikNodes[3] = new Node(VectorR3(0.100000, 0.000000, 0.710000), -unity, 0.08, JOINT, minTheta, maxTheta, RADIAN(0.));
  282. m_ikTree.InsertLeftChild(m_ikNodes[2], m_ikNodes[3]);
  283. m_ikNodes[4] = new Node(VectorR3(0.100000, 0.000000, 0.894500), unitz, 0.08, JOINT, minTheta, maxTheta, RADIAN(0.));
  284. m_ikTree.InsertLeftChild(m_ikNodes[3], m_ikNodes[4]);
  285. m_ikNodes[5] = new Node(VectorR3(0.100000, 0.000000, 1.110000), unity, 0.08, JOINT, minTheta, maxTheta, RADIAN(0.));
  286. m_ikTree.InsertLeftChild(m_ikNodes[4], m_ikNodes[5]);
  287. m_ikNodes[6] = new Node(VectorR3(0.100000, 0.000000, 1.191000), unitz, 0.08, JOINT, minTheta, maxTheta, RADIAN(0.));
  288. m_ikTree.InsertLeftChild(m_ikNodes[5], m_ikNodes[6]);
  289. m_ikNodes[7] = new Node(VectorR3(0.100000, 0.000000, 1.20000), zero, 0.08, EFFECTOR);
  290. m_ikTree.InsertLeftChild(m_ikNodes[6], m_ikNodes[7]);
  291. }
  292. class CommonExampleInterface* InverseKinematicsExampleCreateFunc(struct CommonExampleOptions& options)
  293. {
  294. return new InverseKinematicsExample(options.m_guiHelper->getAppInterface(), options.m_option);
  295. }