kinematics.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2 * Copyright 2018 ROBOTIS CO., LTD.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *******************************************************************************/
16 
17 /* Authors: Darby Lim, Hye-Jong KIM, Ryan Shim, Yong-Ho Na */
18 
19 #include "../include/open_manipulator_libs/kinematics.h"
20 
21 using namespace robotis_manipulator;
22 using namespace kinematics;
23 
24 
25 /*****************************************************************************
26 ** Kinematics Solver Using Chain Rule and Jacobian
27 *****************************************************************************/
28 void SolverUsingCRAndJacobian::setOption(const void *arg){}
29 
30 Eigen::MatrixXd SolverUsingCRAndJacobian::jacobian(Manipulator *manipulator, Name tool_name)
31 {
32  Eigen::MatrixXd jacobian = Eigen::MatrixXd::Identity(6, manipulator->getDOF());
33 
34  Eigen::Vector3d joint_axis = Eigen::Vector3d::Zero(3);
35 
36  Eigen::Vector3d position_changed = Eigen::Vector3d::Zero(3);
37  Eigen::Vector3d orientation_changed = Eigen::Vector3d::Zero(3);
38  Eigen::VectorXd pose_changed = Eigen::VectorXd::Zero(6);
39 
41 
42  int8_t index = 0;
43  Name my_name = manipulator->getWorldChildName();
44 
45  for (int8_t size = 0; size < manipulator->getDOF(); size++)
46  {
47  Name parent_name = manipulator->getComponentParentName(my_name);
48  if (parent_name == manipulator->getWorldName())
49  {
50  joint_axis = manipulator->getWorldOrientation() * manipulator->getAxis(my_name);
51  }
52  else
53  {
54  joint_axis = manipulator->getComponentOrientationFromWorld(parent_name) * manipulator->getAxis(my_name);
55  }
56 
57  position_changed = math::skewSymmetricMatrix(joint_axis) *
58  (manipulator->getComponentPositionFromWorld(tool_name) - manipulator->getComponentPositionFromWorld(my_name));
59  orientation_changed = joint_axis;
60 
61  pose_changed << position_changed(0),
62  position_changed(1),
63  position_changed(2),
64  orientation_changed(0),
65  orientation_changed(1),
66  orientation_changed(2);
67 
68  jacobian.col(index) = pose_changed;
69  index++;
70  my_name = manipulator->getComponentChildName(my_name).at(0); // Get Child name which has active joint
71  }
72  return jacobian;
73 }
74 
75 void SolverUsingCRAndJacobian::solveForwardKinematics(Manipulator *manipulator)
76 {
77  forwardSolverUsingChainRule(manipulator, manipulator->getWorldChildName());
78 }
79 
80 bool SolverUsingCRAndJacobian::solveInverseKinematics(Manipulator *manipulator, Name tool_name, Pose target_pose, std::vector<JointValue> *goal_joint_value)
81 {
82  return inverseSolverUsingJacobian(manipulator, tool_name, target_pose, goal_joint_value);
83 }
84 
85 
86 //private
87 void SolverUsingCRAndJacobian::forwardSolverUsingChainRule(Manipulator *manipulator, Name component_name)
88 {
89  Name my_name = component_name;
90  Name parent_name = manipulator->getComponentParentName(my_name);
91  int8_t number_of_child = manipulator->getComponentChildName(my_name).size();
92 
93  Pose parent_pose_value;
94  Pose my_pose_value;
95 
96  //Get Parent Pose
97  if (parent_name == manipulator->getWorldName())
98  {
99  parent_pose_value = manipulator->getWorldPose();
100  }
101  else
102  {
103  parent_pose_value = manipulator->getComponentPoseFromWorld(parent_name);
104  }
105 
106  //position
107  my_pose_value.kinematic.position = parent_pose_value.kinematic.position
108  + (parent_pose_value.kinematic.orientation * manipulator->getComponentRelativePositionFromParent(my_name));
109  //orientation
110  my_pose_value.kinematic.orientation = parent_pose_value.kinematic.orientation * math::rodriguesRotationMatrix(manipulator->getAxis(my_name), manipulator->getJointPosition(my_name));
111  //linear velocity
112  my_pose_value.dynamic.linear.velocity = math::vector3(0.0, 0.0, 0.0);
113  //angular velocity
114  my_pose_value.dynamic.angular.velocity = math::vector3(0.0, 0.0, 0.0);
115  //linear acceleration
116  my_pose_value.dynamic.linear.acceleration = math::vector3(0.0, 0.0, 0.0);
117  //angular acceleration
118  my_pose_value.dynamic.angular.acceleration = math::vector3(0.0, 0.0, 0.0);
119 
120  manipulator->setComponentPoseFromWorld(my_name, my_pose_value);
121 
122  for (int8_t index = 0; index < number_of_child; index++)
123  {
124  Name child_name = manipulator->getComponentChildName(my_name).at(index);
125  forwardSolverUsingChainRule(manipulator, child_name);
126  }
127 }
128 
129 bool SolverUsingCRAndJacobian::inverseSolverUsingJacobian(Manipulator *manipulator, Name tool_name, Pose target_pose, std::vector<JointValue> *goal_joint_value)
130 {
131  const double lambda = 0.7;
132  const int8_t iteration = 10;
133 
134  Manipulator _manipulator = *manipulator;
135 
136  Eigen::MatrixXd jacobian = Eigen::MatrixXd::Identity(6, _manipulator.getDOF());
137 
138  Eigen::VectorXd pose_changed = Eigen::VectorXd::Zero(6);
139  Eigen::VectorXd delta_angle = Eigen::VectorXd::Zero(_manipulator.getDOF());
140 
141  for (int8_t count = 0; count < iteration; count++)
142  {
143  //Forward kinematics solve
144  solveForwardKinematics(&_manipulator);
145  //Get jacobian
146  jacobian = this->jacobian(&_manipulator, tool_name);
147 
148  //Pose Difference
149  pose_changed = math::poseDifference(target_pose.kinematic.position, _manipulator.getComponentPositionFromWorld(tool_name),
150  target_pose.kinematic.orientation, _manipulator.getComponentOrientationFromWorld(tool_name));
151 
152  //pose sovler success
153  if (pose_changed.norm() < 1E-6)
154  {
155  *goal_joint_value = _manipulator.getAllActiveJointValue();
156  for(int8_t index = 0; index < _manipulator.getDOF(); index++)
157  {
158  goal_joint_value->at(index).velocity = 0.0;
159  goal_joint_value->at(index).acceleration = 0.0;
160  goal_joint_value->at(index).effort = 0.0;
161  }
162  return true;
163  }
164 
165  //get delta angle
166  ColPivHouseholderQR<MatrixXd> dec(jacobian);
167  delta_angle = lambda * dec.solve(pose_changed);
168 
169  //set changed angle
170  std::vector<double> changed_angle;
171  for(int8_t index = 0; index < _manipulator.getDOF(); index++)
172  changed_angle.push_back(_manipulator.getAllActiveJointPosition().at(index) + delta_angle(index));
173  _manipulator.setAllActiveJointPosition(changed_angle);
174  }
175  *goal_joint_value = {};
176  return false;
177 }
178 
179 
180 /*****************************************************************************
181 ** Kinematics Solver Using Chain Rule and Singularity Robust Jacobian
182 *****************************************************************************/
183 void SolverUsingCRAndSRJacobian::setOption(const void *arg){}
184 
185 Eigen::MatrixXd SolverUsingCRAndSRJacobian::jacobian(Manipulator *manipulator, Name tool_name)
186 {
187  Eigen::MatrixXd jacobian = Eigen::MatrixXd::Identity(6, manipulator->getDOF());
188 
189  Eigen::Vector3d joint_axis = Eigen::Vector3d::Zero(3);
190 
191  Eigen::Vector3d position_changed = Eigen::Vector3d::Zero(3);
192  Eigen::Vector3d orientation_changed = Eigen::Vector3d::Zero(3);
193  Eigen::VectorXd pose_changed = Eigen::VectorXd::Zero(6);
194 
196 
197  int8_t index = 0;
198  Name my_name = manipulator->getWorldChildName();
199 
200  for (int8_t size = 0; size < manipulator->getDOF(); size++)
201  {
202  Name parent_name = manipulator->getComponentParentName(my_name);
203  if (parent_name == manipulator->getWorldName())
204  {
205  joint_axis = manipulator->getWorldOrientation() * manipulator->getAxis(my_name);
206  }
207  else
208  {
209  joint_axis = manipulator->getComponentOrientationFromWorld(parent_name) * manipulator->getAxis(my_name);
210  }
211 
212  position_changed = math::skewSymmetricMatrix(joint_axis) *
213  (manipulator->getComponentPositionFromWorld(tool_name) - manipulator->getComponentPositionFromWorld(my_name));
214  orientation_changed = joint_axis;
215 
216  pose_changed << position_changed(0),
217  position_changed(1),
218  position_changed(2),
219  orientation_changed(0),
220  orientation_changed(1),
221  orientation_changed(2);
222 
223  jacobian.col(index) = pose_changed;
224  index++;
225  my_name = manipulator->getComponentChildName(my_name).at(0); // Get Child name which has active joint
226  }
227  return jacobian;
228 }
229 
230 void SolverUsingCRAndSRJacobian::solveForwardKinematics(Manipulator *manipulator)
231 {
232  forwardSolverUsingChainRule(manipulator, manipulator->getWorldChildName());
233 }
234 
235 bool SolverUsingCRAndSRJacobian::solveInverseKinematics(Manipulator *manipulator, Name tool_name, Pose target_pose, std::vector<JointValue> *goal_joint_value)
236 {
237  return inverseSolverUsingSRJacobian(manipulator, tool_name, target_pose, goal_joint_value);
238 }
239 
240 
241 //private
242 void SolverUsingCRAndSRJacobian::forwardSolverUsingChainRule(Manipulator *manipulator, Name component_name)
243 {
244  Name my_name = component_name;
245  Name parent_name = manipulator->getComponentParentName(my_name);
246  int8_t number_of_child = manipulator->getComponentChildName(my_name).size();
247 
248  Pose parent_pose_value;
249  Pose my_pose_value;
250 
251  //Get Parent Pose
252  if (parent_name == manipulator->getWorldName())
253  {
254  parent_pose_value = manipulator->getWorldPose();
255  }
256  else
257  {
258  parent_pose_value = manipulator->getComponentPoseFromWorld(parent_name);
259  }
260 
261  //position
262  my_pose_value.kinematic.position = parent_pose_value.kinematic.position
263  + (parent_pose_value.kinematic.orientation * manipulator->getComponentRelativePositionFromParent(my_name));
264  //orientation
265  my_pose_value.kinematic.orientation = parent_pose_value.kinematic.orientation * math::rodriguesRotationMatrix(manipulator->getAxis(my_name), manipulator->getJointPosition(my_name));
266  //linear velocity
267  my_pose_value.dynamic.linear.velocity = math::vector3(0.0, 0.0, 0.0);
268  //angular velocity
269  my_pose_value.dynamic.angular.velocity = math::vector3(0.0, 0.0, 0.0);
270  //linear acceleration
271  my_pose_value.dynamic.linear.acceleration = math::vector3(0.0, 0.0, 0.0);
272  //angular acceleration
273  my_pose_value.dynamic.angular.acceleration = math::vector3(0.0, 0.0, 0.0);
274 
275  manipulator->setComponentPoseFromWorld(my_name, my_pose_value);
276 
277  for (int8_t index = 0; index < number_of_child; index++)
278  {
279  Name child_name = manipulator->getComponentChildName(my_name).at(index);
280  forwardSolverUsingChainRule(manipulator, child_name);
281  }
282 }
283 
284 bool SolverUsingCRAndSRJacobian::inverseSolverUsingSRJacobian(Manipulator *manipulator, Name tool_name, Pose target_pose, std::vector<JointValue> *goal_joint_value)
285 {
286  //manipulator
287  Manipulator _manipulator = *manipulator;
288 
289  //solver parameter
290  double lambda = 0.0;
291  const double param = 0.002;
292  const int8_t iteration = 10;
293 
294  const double gamma = 0.5; //rollback delta
295 
296  //sr sovler parameter
297  double wn_pos = 1 / 0.3;
298  double wn_ang = 1 / (2 * M_PI);
299  double pre_Ek = 0.0;
300  double new_Ek = 0.0;
301 
302  Eigen::MatrixXd We(6, 6);
303  We << wn_pos, 0, 0, 0, 0, 0,
304  0, wn_pos, 0, 0, 0, 0,
305  0, 0, wn_pos, 0, 0, 0,
306  0, 0, 0, wn_ang, 0, 0,
307  0, 0, 0, 0, wn_ang, 0,
308  0, 0, 0, 0, 0, wn_ang;
309 
310  Eigen::MatrixXd Wn = Eigen::MatrixXd::Identity(_manipulator.getDOF(), _manipulator.getDOF());
311 
312  //jacobian
313  Eigen::MatrixXd jacobian = Eigen::MatrixXd::Identity(6, _manipulator.getDOF());
314  Eigen::MatrixXd sr_jacobian = Eigen::MatrixXd::Identity(_manipulator.getDOF(), _manipulator.getDOF());
315 
316  //delta parameter
317  Eigen::VectorXd pose_changed = Eigen::VectorXd::Zero(6);
318  Eigen::VectorXd angle_changed = Eigen::VectorXd::Zero(_manipulator.getDOF()); //delta angle (dq)
319  Eigen::VectorXd gerr(_manipulator.getDOF());
320 
321  //angle parameter
322  std::vector<double> present_angle; //angle (q)
323  std::vector<double> set_angle; //set angle (q + dq)
324 
326 
327  solveForwardKinematics(&_manipulator);
329  pose_changed = math::poseDifference(target_pose.kinematic.position, _manipulator.getComponentPositionFromWorld(tool_name), target_pose.kinematic.orientation, _manipulator.getComponentOrientationFromWorld(tool_name));
330  pre_Ek = pose_changed.transpose() * We * pose_changed;
332 
334  #if defined(KINEMATICS_DEBUG)
335  Eigen::Vector3d target_orientation_rpy = math::convertRotationToRPY(target_pose.orientation);
336  Eigen::VectorXd debug_target_pose(6);
337  for(int t=0; t<3; t++)
338  debug_target_pose(t) = target_pose.position(t);
339  for(int t=0; t<3; t++)
340  debug_target_pose(t+3) = target_orientation_rpy(t);
341 
342  Eigen::Vector3d present_position = _manipulator.getComponentPositionFromWorld(tool_name);
343  Eigen::MatrixXd present_orientation = _manipulator.getComponentOrientationFromWorld(tool_name);
344  Eigen::Vector3d present_orientation_rpy = math::convertRotationToRPY(present_orientation);
345  Eigen::VectorXd debug_present_pose(6);
346  for(int t=0; t<3; t++)
347  debug_present_pose(t) = present_position(t);
348  for(int t=0; t<3; t++)
349  debug_present_pose(t+3) = present_orientation_rpy(t);
350 
351  log::println("------------------------------------");
352  log::warn("iter : first");
353  log::warn("Ek : ", pre_Ek*1000000000000);
354  log::println("tar_pose");
355  log::println_VECTOR(debug_target_pose,16);
356  log::println("pre_pose");
357  log::println_VECTOR(debug_present_pose,16);
358  log::println("delta_pose");
359  log::println_VECTOR(debug_target_pose-debug_present_pose,16);
360  #endif
361 
364  for (int8_t count = 0; count < iteration; count++)
365  {
367  jacobian = this->jacobian(&_manipulator, tool_name);
368  lambda = pre_Ek + param;
369 
370  sr_jacobian = (jacobian.transpose() * We * jacobian) + (lambda * Wn); //calculate sr_jacobian (J^T*we*J + lamda*Wn)
371  gerr = jacobian.transpose() * We * pose_changed; //calculate gerr (J^T*we) dx
372 
373  ColPivHouseholderQR<Eigen::MatrixXd> dec(sr_jacobian); //solving (get dq)
374  angle_changed = dec.solve(gerr); //(J^T*we) * dx = (J^T*we*J + lamda*Wn) * dq
375 
376  present_angle = _manipulator.getAllActiveJointPosition();
377  set_angle.clear();
378  for (int8_t index = 0; index < _manipulator.getDOF(); index++)
379  set_angle.push_back(present_angle.at(index) + angle_changed(index));
380  _manipulator.setAllActiveJointPosition(set_angle);
381  solveForwardKinematics(&_manipulator);
383 
385  pose_changed = math::poseDifference(target_pose.kinematic.position, _manipulator.getComponentPositionFromWorld(tool_name), target_pose.kinematic.orientation, _manipulator.getComponentOrientationFromWorld(tool_name));
386  new_Ek = pose_changed.transpose() * We * pose_changed;
388 
390  #if defined(KINEMATICS_DEBUG)
391  present_position = _manipulator.getComponentPositionFromWorld(tool_name);
392  present_orientation = _manipulator.getComponentOrientationFromWorld(tool_name);
393  present_orientation_rpy = math::convertRotationToRPY(present_orientation);
394  for(int t=0; t<3; t++)
395  debug_present_pose(t) = present_position(t);
396  for(int t=0; t<3; t++)
397  debug_present_pose(t+3) = present_orientation_rpy(t);
398  log::warn("iter : ", count,0);
399  log::warn("Ek : ", new_Ek*1000000000000);
400  log::println("tar_pose");
401  log::println_VECTOR(debug_target_pose,16);
402  log::println("pre_pose");
403  log::println_VECTOR(debug_present_pose,16);
404  log::println("delta_pose");
405  log::println_VECTOR(debug_target_pose-debug_present_pose,16);
406  #endif
407 
409  if (new_Ek < 1E-12)
410  {
412  #if defined(KINEMATICS_DEBUG)
413  log::warn("iter : ", count,0);
414  log::warn("Ek : ", new_Ek*1000000000000);
415  log::error("Success");
416  log::println("------------------------------------");
417  #endif
418  *goal_joint_value = _manipulator.getAllActiveJointValue();
420  for(int8_t index = 0; index < _manipulator.getDOF(); index++)
421  {
422  goal_joint_value->at(index).velocity = 0.0;
423  goal_joint_value->at(index).acceleration = 0.0;
424  goal_joint_value->at(index).effort = 0.0;
425  }
426  return true;
427  }
428  else if (new_Ek < pre_Ek)
429  {
430  pre_Ek = new_Ek;
431  }
432  else
433  {
434  present_angle = _manipulator.getAllActiveJointPosition();
435  for (int8_t index = 0; index < _manipulator.getDOF(); index++)
436  set_angle.push_back(present_angle.at(index) - (gamma * angle_changed(index)));
437  _manipulator.setAllActiveJointPosition(set_angle);
438 
439  solveForwardKinematics(&_manipulator);
440  }
441  }
442  log::error("[sr]fail to solve inverse kinematics (please change the solver)");
443  *goal_joint_value = {};
444  return false;
445 }
446 
447 
448 /*****************************************************************************
449 ** Kinematics Solver Using Chain Rule and Singularity Robust Position Only Jacobian
450 *****************************************************************************/
451 void SolverUsingCRAndSRPositionOnlyJacobian::setOption(const void *arg){}
452 
453 Eigen::MatrixXd SolverUsingCRAndSRPositionOnlyJacobian::jacobian(Manipulator *manipulator, Name tool_name)
454 {
455  Eigen::MatrixXd jacobian = Eigen::MatrixXd::Identity(6, manipulator->getDOF());
456 
457  Eigen::Vector3d joint_axis = Eigen::Vector3d::Zero(3);
458 
459  Eigen::Vector3d position_changed = Eigen::Vector3d::Zero(3);
460  Eigen::Vector3d orientation_changed = Eigen::Vector3d::Zero(3);
461  Eigen::VectorXd pose_changed = Eigen::VectorXd::Zero(6);
462 
464 
465  int8_t index = 0;
466  Name my_name = manipulator->getWorldChildName();
467 
468  for (int8_t size = 0; size < manipulator->getDOF(); size++)
469  {
470  Name parent_name = manipulator->getComponentParentName(my_name);
471  if (parent_name == manipulator->getWorldName())
472  {
473  joint_axis = manipulator->getWorldOrientation() * manipulator->getAxis(my_name);
474  }
475  else
476  {
477  joint_axis = manipulator->getComponentOrientationFromWorld(parent_name) * manipulator->getAxis(my_name);
478  }
479 
480  position_changed = math::skewSymmetricMatrix(joint_axis) *
481  (manipulator->getComponentPositionFromWorld(tool_name) - manipulator->getComponentPositionFromWorld(my_name));
482  orientation_changed = joint_axis;
483 
484  pose_changed << position_changed(0),
485  position_changed(1),
486  position_changed(2),
487  orientation_changed(0),
488  orientation_changed(1),
489  orientation_changed(2);
490 
491  jacobian.col(index) = pose_changed;
492  index++;
493  my_name = manipulator->getComponentChildName(my_name).at(0); // Get Child name which has active joint
494  }
495  return jacobian;
496 }
497 
498 void SolverUsingCRAndSRPositionOnlyJacobian::solveForwardKinematics(Manipulator *manipulator)
499 {
500  forwardSolverUsingChainRule(manipulator, manipulator->getWorldChildName());
501 }
502 
503 bool SolverUsingCRAndSRPositionOnlyJacobian::solveInverseKinematics(Manipulator *manipulator, Name tool_name, Pose target_pose, std::vector<JointValue> *goal_joint_value)
504 {
505  return inverseSolverUsingPositionOnlySRJacobian(manipulator, tool_name, target_pose, goal_joint_value);
506 }
507 
508 
509 //private
510 void SolverUsingCRAndSRPositionOnlyJacobian::forwardSolverUsingChainRule(Manipulator *manipulator, Name component_name)
511 {
512  Name my_name = component_name;
513  Name parent_name = manipulator->getComponentParentName(my_name);
514  int8_t number_of_child = manipulator->getComponentChildName(my_name).size();
515 
516  Pose parent_pose_value;
517  Pose my_pose_value;
518 
519  //Get Parent Pose
520  if (parent_name == manipulator->getWorldName())
521  {
522  parent_pose_value = manipulator->getWorldPose();
523  }
524  else
525  {
526  parent_pose_value = manipulator->getComponentPoseFromWorld(parent_name);
527  }
528 
529  //position
530  my_pose_value.kinematic.position = parent_pose_value.kinematic.position
531  + (parent_pose_value.kinematic.orientation * manipulator->getComponentRelativePositionFromParent(my_name));
532  //orientation
533  my_pose_value.kinematic.orientation = parent_pose_value.kinematic.orientation * math::rodriguesRotationMatrix(manipulator->getAxis(my_name), manipulator->getJointPosition(my_name));
534  //linear velocity
535  my_pose_value.dynamic.linear.velocity = math::vector3(0.0, 0.0, 0.0);
536  //angular velocity
537  my_pose_value.dynamic.angular.velocity = math::vector3(0.0, 0.0, 0.0);
538  //linear acceleration
539  my_pose_value.dynamic.linear.acceleration = math::vector3(0.0, 0.0, 0.0);
540  //angular acceleration
541  my_pose_value.dynamic.angular.acceleration = math::vector3(0.0, 0.0, 0.0);
542 
543  manipulator->setComponentPoseFromWorld(my_name, my_pose_value);
544 
545  for (int8_t index = 0; index < number_of_child; index++)
546  {
547  Name child_name = manipulator->getComponentChildName(my_name).at(index);
548  forwardSolverUsingChainRule(manipulator, child_name);
549  }
550 }
551 
552 bool SolverUsingCRAndSRPositionOnlyJacobian::inverseSolverUsingPositionOnlySRJacobian(Manipulator *manipulator, Name tool_name, Pose target_pose, std::vector<JointValue> *goal_joint_value)
553 {
554  //manipulator
555  Manipulator _manipulator = *manipulator;
556 
557  //solver parameter
558  double lambda = 0.0;
559  const double param = 0.002;
560  const int8_t iteration = 10;
561 
562  const double gamma = 0.5; //rollback delta
563 
564  //jacobian
565  Eigen::MatrixXd jacobian = Eigen::MatrixXd::Identity(6, _manipulator.getDOF());
566  Eigen::MatrixXd position_jacobian = Eigen::MatrixXd::Identity(3, _manipulator.getDOF());
567  Eigen::MatrixXd sr_jacobian = Eigen::MatrixXd::Identity(_manipulator.getDOF(), _manipulator.getDOF());
568 
569  //delta parameter
570  Eigen::Vector3d position_changed = Eigen::VectorXd::Zero(3);
571  Eigen::VectorXd angle_changed = Eigen::VectorXd::Zero(_manipulator.getDOF()); //delta angle (dq)
572  Eigen::VectorXd gerr(_manipulator.getDOF());
573 
574  //sr sovler parameter
575  double wn_pos = 1 / 0.3;
576  double pre_Ek = 0.0;
577  double new_Ek = 0.0;
578 
579  Eigen::MatrixXd We(3, 3);
580  We << wn_pos, 0, 0,
581  0, wn_pos, 0,
582  0, 0, wn_pos;
583 
584  Eigen::MatrixXd Wn = Eigen::MatrixXd::Identity(_manipulator.getDOF(), _manipulator.getDOF());
585 
586  //angle parameter
587  std::vector<double> present_angle; //angle (q)
588  std::vector<double> set_angle; //set angle (q + dq)
589 
591 
592  solveForwardKinematics(&_manipulator);
594  position_changed = math::positionDifference(target_pose.kinematic.position, _manipulator.getComponentPositionFromWorld(tool_name));
595  pre_Ek = position_changed.transpose() * We * position_changed;
597 
599  #if defined(KINEMATICS_DEBUG)
600  Eigen::Vector3d target_orientation_rpy = math::convertRotationToRPY(target_pose.orientation);
601  Eigen::VectorXd debug_target_pose(6);
602  for(int t=0; t<3; t++)
603  debug_target_pose(t) = target_pose.position(t);
604  for(int t=0; t<3; t++)
605  debug_target_pose(t+3) = target_orientation_rpy(t);
606 
607  Eigen::Vector3d present_position = _manipulator.getComponentPositionFromWorld(tool_name);
608  Eigen::MatrixXd present_orientation = _manipulator.getComponentOrientationFromWorld(tool_name);
609  Eigen::Vector3d present_orientation_rpy = math::convertRotationToRPY(present_orientation);
610  Eigen::VectorXd debug_present_pose(6);
611  for(int t=0; t<3; t++)
612  debug_present_pose(t) = present_position(t);
613  for(int t=0; t<3; t++)
614  debug_present_pose(t+3) = present_orientation_rpy(t);
615 
616  log::println("------------------------------------");
617  log::warn("iter : first");
618  log::warn("Ek : ", pre_Ek*1000000000000);
619  log::println("tar_pose");
620  log::println_VECTOR(debug_target_pose,16);
621  log::println("pre_pose");
622  log::println_VECTOR(debug_present_pose,16);
623  log::println("delta_pose");
624  log::println_VECTOR(debug_target_pose-debug_present_pose,16);
625  #endif
626 
629  for (int8_t count = 0; count < iteration; count++)
630  {
632  jacobian = this->jacobian(&_manipulator, tool_name);
633  position_jacobian.row(0) = jacobian.row(0);
634  position_jacobian.row(1) = jacobian.row(1);
635  position_jacobian.row(2) = jacobian.row(2);
636  lambda = pre_Ek + param;
637 
638  sr_jacobian = (position_jacobian.transpose() * We * position_jacobian) + (lambda * Wn); //calculate sr_jacobian (J^T*we*J + lamda*Wn)
639  gerr = position_jacobian.transpose() * We * position_changed; //calculate gerr (J^T*we) dx
640 
641  ColPivHouseholderQR<Eigen::MatrixXd> dec(sr_jacobian); //solving (get dq)
642  angle_changed = dec.solve(gerr); //(J^T*we) * dx = (J^T*we*J + lamda*Wn) * dq
643 
644  present_angle = _manipulator.getAllActiveJointPosition();
645  set_angle.clear();
646  for (int8_t index = 0; index < _manipulator.getDOF(); index++)
647  set_angle.push_back(_manipulator.getAllActiveJointPosition().at(index) + angle_changed(index));
648  _manipulator.setAllActiveJointPosition(set_angle);
649  solveForwardKinematics(&_manipulator);
651 
653  position_changed = math::positionDifference(target_pose.kinematic.position, _manipulator.getComponentPositionFromWorld(tool_name));
654  new_Ek = position_changed.transpose() * We * position_changed;
656 
658  #if defined(KINEMATICS_DEBUG)
659  present_position = _manipulator.getComponentPositionFromWorld(tool_name);
660  present_orientation = _manipulator.getComponentOrientationFromWorld(tool_name);
661  present_orientation_rpy = math::convertRotationToRPY(present_orientation);
662  for(int t=0; t<3; t++)
663  debug_present_pose(t) = present_position(t);
664  for(int t=0; t<3; t++)
665  debug_present_pose(t+3) = present_orientation_rpy(t);
666  log::warn("iter : ", count,0);
667  log::warn("Ek : ", new_Ek*1000000000000);
668  log::println("tar_pose");
669  log::println_VECTOR(debug_target_pose,16);
670  log::println("pre_pose");
671  log::println_VECTOR(debug_present_pose,16);
672  log::println("delta_pose");
673  log::println_VECTOR(debug_target_pose-debug_present_pose,16);
674  #endif
675 
677  if (new_Ek < 1E-12)
678  {
680  #if defined(KINEMATICS_DEBUG)
681  log::warn("iter : ", count,0);
682  log::warn("Ek : ", new_Ek*1000000000000);
683  log::error("IK Success");
684  log::println("------------------------------------");
685  #endif
686  *goal_joint_value = _manipulator.getAllActiveJointValue();
688  for(int8_t index = 0; index < _manipulator.getDOF(); index++)
689  {
690  goal_joint_value->at(index).velocity = 0.0;
691  goal_joint_value->at(index).acceleration = 0.0;
692  goal_joint_value->at(index).effort = 0.0;
693  }
694  return true;
695  }
696  else if (new_Ek < pre_Ek)
697  {
698  pre_Ek = new_Ek;
699  }
700  else
701  {
702  present_angle = _manipulator.getAllActiveJointPosition();
703  for (int8_t index = 0; index < _manipulator.getDOF(); index++)
704  set_angle.push_back(_manipulator.getAllActiveJointPosition().at(index) - (gamma * angle_changed(index)));
705  _manipulator.setAllActiveJointPosition(set_angle);
706 
707  solveForwardKinematics(&_manipulator);
708  }
709  }
710  log::error("[position_only]fail to solve inverse kinematics (please change the solver)");
711  *goal_joint_value = {};
712  return false;
713 }
714 
715 
716 /*****************************************************************************
717 ** Kinematics Solver Customized for OpenManipulator Chain
718 *****************************************************************************/
719 void SolverCustomizedforOMChain::setOption(const void *arg){}
720 
721 Eigen::MatrixXd SolverCustomizedforOMChain::jacobian(Manipulator *manipulator, Name tool_name)
722 {
723  Eigen::MatrixXd jacobian = Eigen::MatrixXd::Identity(6, manipulator->getDOF());
724 
725  Eigen::Vector3d joint_axis = Eigen::Vector3d::Zero(3);
726 
727  Eigen::Vector3d position_changed = Eigen::Vector3d::Zero(3);
728  Eigen::Vector3d orientation_changed = Eigen::Vector3d::Zero(3);
729  Eigen::VectorXd pose_changed = Eigen::VectorXd::Zero(6);
730 
732 
733  int8_t index = 0;
734  Name my_name = manipulator->getWorldChildName();
735 
736  for (int8_t size = 0; size < manipulator->getDOF(); size++)
737  {
738  Name parent_name = manipulator->getComponentParentName(my_name);
739  if (parent_name == manipulator->getWorldName())
740  {
741  joint_axis = manipulator->getWorldOrientation() * manipulator->getAxis(my_name);
742  }
743  else
744  {
745  joint_axis = manipulator->getComponentOrientationFromWorld(parent_name) * manipulator->getAxis(my_name);
746  }
747 
748  position_changed = math::skewSymmetricMatrix(joint_axis) *
749  (manipulator->getComponentPositionFromWorld(tool_name) - manipulator->getComponentPositionFromWorld(my_name));
750  orientation_changed = joint_axis;
751 
752  pose_changed << position_changed(0),
753  position_changed(1),
754  position_changed(2),
755  orientation_changed(0),
756  orientation_changed(1),
757  orientation_changed(2);
758 
759  jacobian.col(index) = pose_changed;
760  index++;
761  my_name = manipulator->getComponentChildName(my_name).at(0); // Get Child name which has active joint
762  }
763  return jacobian;
764 }
765 
766 void SolverCustomizedforOMChain::solveForwardKinematics(Manipulator *manipulator)
767 {
768  forwardSolverUsingChainRule(manipulator, manipulator->getWorldChildName());
769 }
770 
771 bool SolverCustomizedforOMChain::solveInverseKinematics(Manipulator *manipulator, Name tool_name, Pose target_pose, std::vector<JointValue> *goal_joint_value)
772 {
773  return chainCustomInverseKinematics(manipulator, tool_name, target_pose, goal_joint_value);
774 }
775 
776 
777 //private
778 void SolverCustomizedforOMChain::forwardSolverUsingChainRule(Manipulator *manipulator, Name component_name)
779 {
780  Name my_name = component_name;
781  Name parent_name = manipulator->getComponentParentName(my_name);
782  int8_t number_of_child = manipulator->getComponentChildName(my_name).size();
783 
784  Pose parent_pose_value;
785  Pose my_pose_value;
786 
787  //Get Parent Pose
788  if (parent_name == manipulator->getWorldName())
789  {
790  parent_pose_value = manipulator->getWorldPose();
791  }
792  else
793  {
794  parent_pose_value = manipulator->getComponentPoseFromWorld(parent_name);
795  }
796 
797  //position
798  my_pose_value.kinematic.position = parent_pose_value.kinematic.position
799  + (parent_pose_value.kinematic.orientation * manipulator->getComponentRelativePositionFromParent(my_name));
800  //orientation
801  my_pose_value.kinematic.orientation = parent_pose_value.kinematic.orientation * math::rodriguesRotationMatrix(manipulator->getAxis(my_name), manipulator->getJointPosition(my_name));
802  //linear velocity
803  my_pose_value.dynamic.linear.velocity = math::vector3(0.0, 0.0, 0.0);
804  //angular velocity
805  my_pose_value.dynamic.angular.velocity = math::vector3(0.0, 0.0, 0.0);
806  //linear acceleration
807  my_pose_value.dynamic.linear.acceleration = math::vector3(0.0, 0.0, 0.0);
808  //angular acceleration
809  my_pose_value.dynamic.angular.acceleration = math::vector3(0.0, 0.0, 0.0);
810 
811  manipulator->setComponentPoseFromWorld(my_name, my_pose_value);
812 
813  for (int8_t index = 0; index < number_of_child; index++)
814  {
815  Name child_name = manipulator->getComponentChildName(my_name).at(index);
816  forwardSolverUsingChainRule(manipulator, child_name);
817  }
818 }
819 bool SolverCustomizedforOMChain::chainCustomInverseKinematics(Manipulator *manipulator, Name tool_name, Pose target_pose, std::vector<JointValue> *goal_joint_value)
820 {
821  //manipulator
822  Manipulator _manipulator = *manipulator;
823 
824  //solver parameter
825  double lambda = 0.0;
826  const double param = 0.002;
827  const int8_t iteration = 10;
828 
829  const double gamma = 0.5; //rollback delta
830 
831  //sr sovler parameter
832  double wn_pos = 1 / 0.3;
833  double wn_ang = 1 / (2 * M_PI);
834  double pre_Ek = 0.0;
835  double new_Ek = 0.0;
836 
837  Eigen::MatrixXd We(6, 6);
838  We << wn_pos, 0, 0, 0, 0, 0,
839  0, wn_pos, 0, 0, 0, 0,
840  0, 0, wn_pos, 0, 0, 0,
841  0, 0, 0, wn_ang, 0, 0,
842  0, 0, 0, 0, wn_ang, 0,
843  0, 0, 0, 0, 0, wn_ang;
844 
845  Eigen::MatrixXd Wn = Eigen::MatrixXd::Identity(_manipulator.getDOF(), _manipulator.getDOF());
846 
847  //jacobian
848  Eigen::MatrixXd jacobian = Eigen::MatrixXd::Identity(6, _manipulator.getDOF());
849  Eigen::MatrixXd sr_jacobian = Eigen::MatrixXd::Identity(_manipulator.getDOF(), _manipulator.getDOF());
850 
851  //delta parameter
852  Eigen::VectorXd pose_changed = Eigen::VectorXd::Zero(6);
853  Eigen::VectorXd angle_changed = Eigen::VectorXd::Zero(_manipulator.getDOF()); //delta angle (dq)
854  Eigen::VectorXd gerr(_manipulator.getDOF());
855 
856  //angle parameter
857  std::vector<double> present_angle; //angle (q)
858  std::vector<double> set_angle; //set angle (q + dq)
859 
861 
862  solveForwardKinematics(&_manipulator);
863 
865  Eigen::Matrix3d present_orientation = _manipulator.getComponentOrientationFromWorld(tool_name);
866  Eigen::Vector3d present_orientation_rpy = math::convertRotationMatrixToRPYVector(present_orientation);
867  Eigen::Matrix3d target_orientation = target_pose.kinematic.orientation;
868  Eigen::Vector3d target_orientation_rpy = math::convertRotationMatrixToRPYVector(target_orientation);
869 
870  Eigen::Vector3d joint1_rlative_position = _manipulator.getComponentRelativePositionFromParent(_manipulator.getWorldChildName());
871  Eigen::Vector3d target_position_from_joint1 = target_pose.kinematic.position - joint1_rlative_position;
872 
873  target_orientation_rpy(0) = present_orientation_rpy(0);
874  target_orientation_rpy(1) = target_orientation_rpy(1);
875  target_orientation_rpy(2) = atan2(target_position_from_joint1(1) ,target_position_from_joint1(0));
876 
877  target_pose.kinematic.orientation = math::convertRPYToRotationMatrix(target_orientation_rpy(0), target_orientation_rpy(1), target_orientation_rpy(2));
879 
881  pose_changed = math::poseDifference(target_pose.kinematic.position, _manipulator.getComponentPositionFromWorld(tool_name), target_pose.kinematic.orientation, _manipulator.getComponentOrientationFromWorld(tool_name));
882  pre_Ek = pose_changed.transpose() * We * pose_changed;
884 
886  #if defined(KINEMATICS_DEBUG)
887  Eigen::VectorXd debug_target_pose(6);
888  for(int t=0; t<3; t++)
889  debug_target_pose(t) = target_pose.position(t);
890  for(int t=0; t<3; t++)
891  debug_target_pose(t+3) = target_orientation_rpy(t);
892 
893  Eigen::Vector3d present_position = _manipulator.getComponentPositionFromWorld(tool_name);
894  Eigen::VectorXd debug_present_pose(6);
895  for(int t=0; t<3; t++)
896  debug_present_pose(t) = present_position(t);
897  for(int t=0; t<3; t++)
898  debug_present_pose(t+3) = present_orientation_rpy(t);
899 
900  log::println("------------------------------------");
901  log::warn("iter : first");
902  log::warn("Ek : ", pre_Ek*1000000000000);
903  log::println("tar_pose");
904  log::println_VECTOR(debug_target_pose,16);
905  log::println("pre_pose");
906  log::println_VECTOR(debug_present_pose,16);
907  log::println("delta_pose");
908  log::println_VECTOR(debug_target_pose-debug_present_pose,16);
909  #endif
910 
913  for (int8_t count = 0; count < iteration; count++)
914  {
916  jacobian = this->jacobian(&_manipulator, tool_name);
917  lambda = pre_Ek + param;
918 
919  sr_jacobian = (jacobian.transpose() * We * jacobian) + (lambda * Wn); //calculate sr_jacobian (J^T*we*J + lamda*Wn)
920  gerr = jacobian.transpose() * We * pose_changed; //calculate gerr (J^T*we) dx
921 
922  ColPivHouseholderQR<Eigen::MatrixXd> dec(sr_jacobian); //solving (get dq)
923  angle_changed = dec.solve(gerr); //(J^T*we) * dx = (J^T*we*J + lamda*Wn) * dq
924 
925  present_angle = _manipulator.getAllActiveJointPosition();
926  set_angle.clear();
927  for (int8_t index = 0; index < _manipulator.getDOF(); index++)
928  set_angle.push_back(present_angle.at(index) + angle_changed(index));
929  _manipulator.setAllActiveJointPosition(set_angle);
930  solveForwardKinematics(&_manipulator);
932 
934  pose_changed = math::poseDifference(target_pose.kinematic.position, _manipulator.getComponentPositionFromWorld(tool_name), target_pose.kinematic.orientation, _manipulator.getComponentOrientationFromWorld(tool_name));
935  new_Ek = pose_changed.transpose() * We * pose_changed;
937 
939  #if defined(KINEMATICS_DEBUG)
940  present_position = _manipulator.getComponentPositionFromWorld(tool_name);
941  present_orientation = _manipulator.getComponentOrientationFromWorld(tool_name);
942  present_orientation_rpy = math::convertRotationToRPY(present_orientation);
943  for(int t=0; t<3; t++)
944  debug_present_pose(t) = present_position(t);
945  for(int t=0; t<3; t++)
946  debug_present_pose(t+3) = present_orientation_rpy(t);
947  log::warn("iter : ", count,0);
948  log::warn("Ek : ", new_Ek*1000000000000);
949  log::println("tar_pose");
950  log::println_VECTOR(debug_target_pose,16);
951  log::println("pre_pose");
952  log::println_VECTOR(debug_present_pose,16);
953  log::println("delta_pose");
954  log::println_VECTOR(debug_target_pose-debug_present_pose,16);
955  #endif
956 
958  if (new_Ek < 1E-12)
959  {
961  #if defined(KINEMATICS_DEBUG)
962  log::warn("iter : ", count,0);
963  log::warn("Ek : ", new_Ek*1000000000000);
964  log::error("Success");
965  log::println("------------------------------------");
966  #endif
967  *goal_joint_value = _manipulator.getAllActiveJointValue();
969  for(int8_t index = 0; index < _manipulator.getDOF(); index++)
970  {
971  goal_joint_value->at(index).velocity = 0.0;
972  goal_joint_value->at(index).acceleration = 0.0;
973  goal_joint_value->at(index).effort = 0.0;
974  }
975  return true;
976  }
977  else if (new_Ek < pre_Ek)
978  {
979  pre_Ek = new_Ek;
980  }
981  else
982  {
983  present_angle = _manipulator.getAllActiveJointPosition();
984  for (int8_t index = 0; index < _manipulator.getDOF(); index++)
985  set_angle.push_back(present_angle.at(index) - (gamma * angle_changed(index)));
986  _manipulator.setAllActiveJointPosition(set_angle);
987 
988  solveForwardKinematics(&_manipulator);
989  }
990  }
991  log::error("[OpenManipulator Chain Custom]fail to solve inverse kinematics");
992  *goal_joint_value = {};
993  return false;
994 }
995 
996 
997 
998 
999 
1000 
1001 
1002 
1003 
1004 
1005 
1006 
1007 
1008 
1009 
1010 
1011 
1012 
1013 
1014 
1015 
1016 
1017 
1018 
1019 
1020 
1021 
1022 
1023 
1024 
1025 
1026 
1027 
1028 
1029 
1030 
1031 
1032 
1033 
1034 
1035 
1036 
1037 
1038 
1039 
1040 
1041 
double getJointPosition(Name component_name)
bool param(const std::string &param_name, T &param_val, const T &default_val)
STRING Name
Pose getComponentPoseFromWorld(Name component_name)
void setAllActiveJointPosition(std::vector< double > joint_position_vector)
Eigen::Matrix3d getComponentOrientationFromWorld(Name component_name)
std::vector< double > getAllActiveJointPosition()
Eigen::Vector3d getAxis(Name component_name)
Eigen::Vector3d getComponentRelativePositionFromParent(Name component_name)
Eigen::VectorXd poseDifference(Eigen::Vector3d desired_position, Eigen::Vector3d present_position, Eigen::Matrix3d desired_orientation, Eigen::Matrix3d present_orientation)
Name getComponentParentName(Name component_name)
void println(STRING str, STRING color="DEFAULT")
std::vector< JointValue > getAllActiveJointValue()
Eigen::Vector3d vector3(double v1, double v2, double v3)
Eigen::Matrix3d skewSymmetricMatrix(Eigen::Vector3d v)
Eigen::Vector3d positionDifference(Eigen::Vector3d desired_position, Eigen::Vector3d present_position)
void setComponentPoseFromWorld(Name component_name, Pose pose_to_world)
Eigen::Matrix3d rodriguesRotationMatrix(Eigen::Vector3d axis, double angle)
std::vector< Name > getComponentChildName(Name component_name)
void error(STRING str)
Eigen::Matrix3d getWorldOrientation()
void warn(STRING str)
Eigen::Vector3d convertRotationMatrixToRPYVector(const Eigen::Matrix3d &rotation_matrix)
Eigen::Vector3d getComponentPositionFromWorld(Name component_name)
Eigen::Matrix3d convertRPYToRotationMatrix(double roll, double pitch, double yaw)


open_manipulator_libs
Author(s): Darby Lim , Hye-Jong KIM , Ryan Shim , Yong-Ho Na
autogenerated on Mon Jun 10 2019 14:12:00