IKTrajectoryHelper.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #include "IKTrajectoryHelper.h"
  2. #include "BussIK/Node.h"
  3. #include "BussIK/Tree.h"
  4. #include "BussIK/Jacobian.h"
  5. #include "BussIK/VectorRn.h"
  6. #include "BussIK/MatrixRmn.h"
  7. #include "Bullet3Common/b3AlignedObjectArray.h"
  8. #include "BulletDynamics/Featherstone/btMultiBody.h"
  9. #define RADIAN(X) ((X)*RadiansToDegrees)
  10. //use BussIK and Reflexxes to convert from Cartesian endeffector future target to
  11. //joint space positions at each real-time (simulation) step
  12. struct IKTrajectoryHelperInternalData
  13. {
  14. VectorR3 m_endEffectorTargetPosition;
  15. VectorRn m_nullSpaceVelocity;
  16. b3AlignedObjectArray<Node*> m_ikNodes;
  17. Jacobian* m_ikJacobian;
  18. IKTrajectoryHelperInternalData()
  19. {
  20. m_endEffectorTargetPosition.SetZero();
  21. m_nullSpaceVelocity.SetZero();
  22. }
  23. };
  24. IKTrajectoryHelper::IKTrajectoryHelper()
  25. {
  26. m_data = new IKTrajectoryHelperInternalData;
  27. }
  28. IKTrajectoryHelper::~IKTrajectoryHelper()
  29. {
  30. delete m_data;
  31. }
  32. bool IKTrajectoryHelper::computeIK(const double endEffectorTargetPosition[3],
  33. const double endEffectorTargetOrientation[4],
  34. const double endEffectorWorldPosition[3],
  35. const double endEffectorWorldOrientation[4],
  36. const double* q_current, int numQ,int endEffectorIndex,
  37. double* q_new, int ikMethod, const double* linear_jacobian, const double* angular_jacobian, int jacobian_size, const double dampIk[6])
  38. {
  39. bool useAngularPart = (ikMethod==IK2_VEL_DLS_WITH_ORIENTATION || ikMethod==IK2_VEL_DLS_WITH_ORIENTATION_NULLSPACE) ? true : false;
  40. m_data->m_ikJacobian = new Jacobian(useAngularPart,numQ);
  41. // Reset(m_ikTree,m_ikJacobian);
  42. m_data->m_ikJacobian->Reset();
  43. bool UseJacobianTargets1 = false;
  44. if ( UseJacobianTargets1 ) {
  45. m_data->m_ikJacobian->SetJtargetActive();
  46. }
  47. else {
  48. m_data->m_ikJacobian->SetJendActive();
  49. }
  50. VectorR3 targets;
  51. targets.Set(endEffectorTargetPosition[0],endEffectorTargetPosition[1],endEffectorTargetPosition[2]);
  52. m_data->m_ikJacobian->ComputeJacobian(&targets); // Set up Jacobian and deltaS vectors
  53. // Set one end effector world position from Bullet
  54. VectorRn deltaS(3);
  55. for (int i = 0; i < 3; ++i)
  56. {
  57. deltaS.Set(i,dampIk[i]*(endEffectorTargetPosition[i]-endEffectorWorldPosition[i]));
  58. }
  59. // Set one end effector world orientation from Bullet
  60. VectorRn deltaR(3);
  61. if (useAngularPart)
  62. {
  63. btQuaternion startQ(endEffectorWorldOrientation[0],endEffectorWorldOrientation[1],endEffectorWorldOrientation[2],endEffectorWorldOrientation[3]);
  64. btQuaternion endQ(endEffectorTargetOrientation[0],endEffectorTargetOrientation[1],endEffectorTargetOrientation[2],endEffectorTargetOrientation[3]);
  65. btQuaternion deltaQ = endQ*startQ.inverse();
  66. float angle = deltaQ.getAngle();
  67. btVector3 axis = deltaQ.getAxis();
  68. if (angle > PI) {
  69. angle -= 2.0*PI;
  70. }
  71. else if (angle < -PI) {
  72. angle += 2.0*PI;
  73. }
  74. float angleDot = angle;
  75. btVector3 angularVel = angleDot*axis.normalize();
  76. for (int i = 0; i < 3; ++i)
  77. {
  78. deltaR.Set(i,dampIk[i+3]*angularVel[i]);
  79. }
  80. }
  81. {
  82. if (useAngularPart)
  83. {
  84. VectorRn deltaC(6);
  85. MatrixRmn completeJacobian(6,numQ);
  86. for (int i = 0; i < 3; ++i)
  87. {
  88. deltaC.Set(i,deltaS[i]);
  89. deltaC.Set(i+3,deltaR[i]);
  90. for (int j = 0; j < numQ; ++j)
  91. {
  92. completeJacobian.Set(i,j,linear_jacobian[i*numQ+j]);
  93. completeJacobian.Set(i+3,j,angular_jacobian[i*numQ+j]);
  94. }
  95. }
  96. m_data->m_ikJacobian->SetDeltaS(deltaC);
  97. m_data->m_ikJacobian->SetJendTrans(completeJacobian);
  98. } else
  99. {
  100. VectorRn deltaC(3);
  101. MatrixRmn completeJacobian(3,numQ);
  102. for (int i = 0; i < 3; ++i)
  103. {
  104. deltaC.Set(i,deltaS[i]);
  105. for (int j = 0; j < numQ; ++j)
  106. {
  107. completeJacobian.Set(i,j,linear_jacobian[i*numQ+j]);
  108. }
  109. }
  110. m_data->m_ikJacobian->SetDeltaS(deltaC);
  111. m_data->m_ikJacobian->SetJendTrans(completeJacobian);
  112. }
  113. }
  114. // Calculate the change in theta values
  115. switch (ikMethod) {
  116. case IK2_JACOB_TRANS:
  117. m_data->m_ikJacobian->CalcDeltaThetasTranspose(); // Jacobian transpose method
  118. break;
  119. case IK2_DLS:
  120. case IK2_VEL_DLS:
  121. case IK2_VEL_DLS_WITH_ORIENTATION:
  122. m_data->m_ikJacobian->CalcDeltaThetasDLS(); // Damped least squares method
  123. break;
  124. case IK2_VEL_DLS_WITH_NULLSPACE:
  125. case IK2_VEL_DLS_WITH_ORIENTATION_NULLSPACE:
  126. assert(m_data->m_nullSpaceVelocity.GetLength()==numQ);
  127. m_data->m_ikJacobian->CalcDeltaThetasDLSwithNullspace(m_data->m_nullSpaceVelocity);
  128. break;
  129. case IK2_DLS_SVD:
  130. m_data->m_ikJacobian->CalcDeltaThetasDLSwithSVD();
  131. break;
  132. case IK2_PURE_PSEUDO:
  133. m_data->m_ikJacobian->CalcDeltaThetasPseudoinverse(); // Pure pseudoinverse method
  134. break;
  135. case IK2_SDLS:
  136. m_data->m_ikJacobian->CalcDeltaThetasSDLS(); // Selectively damped least squares method
  137. break;
  138. default:
  139. m_data->m_ikJacobian->ZeroDeltaThetas();
  140. break;
  141. }
  142. // Use for velocity IK, update theta dot
  143. //m_data->m_ikJacobian->UpdateThetaDot();
  144. // Use for position IK, incrementally update theta
  145. //m_data->m_ikJacobian->UpdateThetas();
  146. // Apply the change in the theta values
  147. //m_data->m_ikJacobian->UpdatedSClampValue(&targets);
  148. for (int i=0;i<numQ;i++)
  149. {
  150. // Use for velocity IK
  151. q_new[i] = m_data->m_ikJacobian->dTheta[i] + q_current[i];
  152. // Use for position IK
  153. //q_new[i] = m_data->m_ikNodes[i]->GetTheta();
  154. }
  155. return true;
  156. }
  157. bool IKTrajectoryHelper::computeNullspaceVel(int numQ, const double* q_current, const double* lower_limit, const double* upper_limit, const double* joint_range, const double* rest_pose)
  158. {
  159. m_data->m_nullSpaceVelocity.SetLength(numQ);
  160. m_data->m_nullSpaceVelocity.SetZero();
  161. double stayCloseToZeroGain = 0.1;
  162. double stayAwayFromLimitsGain = 10.0;
  163. // Stay close to zero
  164. for (int i = 0; i < numQ; ++i)
  165. {
  166. m_data->m_nullSpaceVelocity[i] = stayCloseToZeroGain * (rest_pose[i]-q_current[i]);
  167. }
  168. // Stay away from joint limits
  169. for (int i = 0; i < numQ; ++i) {
  170. if (q_current[i] > upper_limit[i]) {
  171. m_data->m_nullSpaceVelocity[i] += stayAwayFromLimitsGain * (upper_limit[i] - q_current[i]) / joint_range[i];
  172. }
  173. if (q_current[i] < lower_limit[i]) {
  174. m_data->m_nullSpaceVelocity[i] += stayAwayFromLimitsGain * (lower_limit[i] - q_current[i]) / joint_range[i];
  175. }
  176. }
  177. return true;
  178. }