1
0

CartFreeDrag.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. #include "CartFreeDrag.h"
  2. void CartFreeDrag::Init()
  3. {
  4. isDrag = false;
  5. // 导纳控制参数 K=0
  6. M.diagonal() << 0.01, 0.01, 0.01, 0.001, 0.001, 0.001;
  7. B.diagonal() << 10.0, 10.0, 10.0, 0.8, 0.8, 0.8;
  8. K.diagonal() << 0.0, 0.0, 0.0, 0.0, 0.0, 0.0;
  9. Md = M.toDenseMatrix();
  10. Bd = B.toDenseMatrix();
  11. Kd = K.toDenseMatrix();
  12. deltaFkminus1.setZero();
  13. deltaFkminus2.setZero();
  14. Vkminus1.setZero();
  15. Vkminus2.setZero();
  16. tool2Basekminus1 = Eigen::Matrix4d::Identity();
  17. Y = 0;
  18. N = 0;
  19. // 启动力阈值
  20. //dragFThr << 1.0, 2.0, 2.0, 0.2, 0.2, 0.1; // RoundProde
  21. dragFThr << 1.0, 2.0, 3.0, 0.3, 0.1, 0.1; // S16Pv
  22. }
  23. void CartFreeDrag::LoadData(WayPoint curWayPt, FTData curForce, WayPoint refWayPt)
  24. {
  25. //拖动模式下只需要当前的笛卡尔力和当前的笛卡尔位姿
  26. _curCart = curWayPt.cartPos;
  27. _curForce = curForce.CartFT;
  28. }
  29. void CartFreeDrag::GetActualTarget(WayPoint& wayPoint)
  30. {
  31. try
  32. {
  33. CartDragFunction(wayPoint);
  34. }
  35. catch (const std::exception&)
  36. {
  37. }
  38. }
  39. void CartFreeDrag::RefreshAdmittancePara()
  40. {
  41. deltaFkminus1.setZero();
  42. deltaFkminus2.setZero();
  43. Vkminus1.setZero();
  44. Vkminus2.setZero();
  45. tool2Basekminus1 = Eigen::Matrix4d::Identity();
  46. M.setZero();
  47. B.setZero();
  48. K.setZero();
  49. Md.setZero();
  50. Bd.setZero();
  51. Kd.setZero();
  52. dragFThr.setZero();
  53. isDrag = false;
  54. Y = 0;
  55. N = 0;
  56. }
  57. /**
  58. * \brief 笛卡尔拖动回调函数
  59. * \param robotState 机器人实时状态
  60. */
  61. void CartFreeDrag::CartDragFunction(WayPoint& wayPoint)
  62. {
  63. // 获取当前机器人位置
  64. Eigen::Matrix4d tool2BaseNow = Eigen::Map<Eigen::Matrix4d>(_curCart.position).transpose();
  65. // 传输六维力信息
  66. Sophus::Vector6d toolFk = Eigen::Map<Sophus::Vector6d>(_curForce.GenForce);
  67. //The transformation of force/torques in different coordinate systems
  68. Sophus::SE3d tool2BaseT(tool2BaseNow);
  69. Sophus::Matrix6d AdjTool2Base = tool2BaseT.Adj();
  70. Sophus::Vector6d baseFk = AdjTool2Base * toolFk;
  71. // 期望力为0
  72. // deltaF
  73. Sophus::Vector6d deltaFk = baseFk;
  74. // 拖了吗
  75. if (!isDrag)
  76. {
  77. for (size_t i = 0; i < 6; i++)
  78. {
  79. if (abs(toolFk(i)) >= dragFThr(i))
  80. {
  81. Y++;
  82. break;
  83. }
  84. else
  85. {
  86. Y = 0;
  87. }
  88. }
  89. if (Y >= 50)
  90. {
  91. isDrag = true;
  92. Y = 0;
  93. N = 0;
  94. deltaFkminus1.setZero();
  95. deltaFkminus2.setZero();
  96. Vkminus1.setZero();
  97. Vkminus2.setZero();
  98. tool2Basekminus1 = tool2BaseNow;
  99. }
  100. }
  101. else
  102. {
  103. for (size_t i = 0; i < 6; i++)
  104. {
  105. if (abs(toolFk(i)) < dragFThr(i))
  106. {
  107. N++;
  108. }
  109. else
  110. {
  111. N = 0;
  112. }
  113. if (N >= 50)
  114. {
  115. isDrag = false;
  116. N = 0;
  117. Y = 0;
  118. deltaFkminus1.setZero();
  119. deltaFkminus2.setZero();
  120. Vkminus1.setZero();
  121. Vkminus2.setZero();
  122. tool2Basekminus1 = tool2BaseNow;
  123. }
  124. }
  125. }
  126. // deltaF -> deltaT
  127. Eigen::Matrix4d deltaT = Eigen::Matrix4d::Identity(4, 4);
  128. if (isDrag)
  129. {
  130. #if false //方法一
  131. Sophus::Matrix6d P = 2 * Md + Bd * Ts;
  132. Sophus::Matrix6d Q = 2 * Md - Bd * Ts;
  133. Sophus::Vector6d Vk = P.inverse() * ((deltaFk + deltaFkminus1) * Ts + Q * Vkminus1);
  134. deltaT = Sophus::SE3d::exp((Vk + Vkminus1) / 2 * Ts).matrix();
  135. #else //方法二
  136. Sophus::Matrix6d Q = 4 * Md + 2 * Bd * Ts + Kd * Ts * Ts;
  137. Sophus::Matrix6d beta0 = Ts * Ts * Q.inverse();
  138. Sophus::Matrix6d beta1 = 2 * Ts * Ts * Q.inverse();
  139. Sophus::Matrix6d beta2 = -(2 * Kd * Ts * Ts - 8 * Md) * Q.inverse();
  140. Sophus::Matrix6d beta3 = -(4 * Md - 2 * Bd * Ts + Kd * Ts * Ts) * Q.inverse();
  141. Sophus::Vector6d Vk = beta0 * deltaFk + beta1 * deltaFkminus1 + beta0 * deltaFkminus2 + beta2 * Vkminus1 + beta3 * Vkminus2;
  142. deltaT = Sophus::SE3d::exp(Vk - Vkminus1).matrix();
  143. #endif //两种方法结果一样
  144. deltaFkminus2 = deltaFkminus1;
  145. deltaFkminus1 = deltaFk;
  146. Vkminus2 = Vkminus1;
  147. //将真实位移加入算法过程
  148. if (false)
  149. {
  150. Eigen::Matrix4d deltaTkminus1 = tool2BaseNow * tool2Basekminus1.inverse();
  151. Sophus::SE3d tmp(deltaTkminus1);
  152. Vkminus1 = tmp.log() + Vkminus2;
  153. }
  154. else
  155. {
  156. Vkminus1 = Vk;
  157. }
  158. tool2Basekminus1 = tool2BaseNow;
  159. }
  160. // X = XRefer + XDelta
  161. Eigen::Matrix4d tool2BaseTarget = deltaT * tool2BaseNow;
  162. Eigen::Map<Eigen::Matrix<double, 4, 4, Eigen::RowMajor>>(wayPoint.cartPos.position) = tool2BaseTarget;
  163. #if true
  164. //欧拉角是多少
  165. Eigen::Vector3d eulerNow = tool2BaseNow.block<3, 3>(0, 0).eulerAngles(2, 1, 0);
  166. Eigen::Vector3d eulerDelta = deltaT.block<3, 3>(0, 0).eulerAngles(2, 1, 0);
  167. Eigen::Vector3d eulerTarget = tool2BaseTarget.block<3, 3>(0, 0).eulerAngles(2, 1, 0);
  168. LogInfo((
  169. std::to_string(toolFk(0)) + " " +
  170. std::to_string(toolFk(1)) + " " +
  171. std::to_string(toolFk(2)) + " " +
  172. //std::to_string(toolFk(3)) + " " +
  173. //std::to_string(toolFk(4)) + " " +
  174. //std::to_string(toolFk(5)) + " " +
  175. std::to_string(baseFk(0)) + " " +
  176. std::to_string(baseFk(1)) + " " +
  177. std::to_string(baseFk(2)) + " " +
  178. //std::to_string(baseFk(3)) + " " +
  179. //std::to_string(baseFk(4)) + " " +
  180. //std::to_string(baseFk(5)) + " " +
  181. std::to_string(tool2BaseNow(0, 3)) + " " +
  182. std::to_string(tool2BaseNow(1, 3)) + " " +
  183. std::to_string(tool2BaseNow(2, 3)) + " " +
  184. //std::to_string(eulerNow(0)) + " " +
  185. //std::to_string(eulerNow(1)) + " " +
  186. //std::to_string(eulerNow(2)) + " " +
  187. std::to_string(tool2BaseTarget(0, 3)) + " " +
  188. std::to_string(tool2BaseTarget(1, 3)) + " " +
  189. std::to_string(tool2BaseTarget(2, 3)) + " " +
  190. //std::to_string(eulerTarget(0)) + " " +
  191. //std::to_string(eulerTarget(1)) + " " +
  192. //std::to_string(eulerTarget(2)) + " " +
  193. std::to_string(deltaT(0, 3)) + " " +
  194. std::to_string(deltaT(1, 3)) + " " +
  195. std::to_string(deltaT(2, 3)) + " " +
  196. //std::to_string(eulerDelta(0)) + " " +
  197. //std::to_string(eulerDelta(1)) + " " +
  198. //std::to_string(eulerDelta(2)) + " " +
  199. std::to_string((int)isDrag) + "\n").c_str());
  200. #endif
  201. }