moveit2
The MoveIt Motion Planning Framework for ROS 2.
pr2_arm_ik.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2011, Willow Garage, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of Willow Garage nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 
35 /* Author: Sachin Chitta, E. Gil Jones */
36 
37 #include <angles/angles.h>
38 #include <moveit/utils/logger.hpp>
39 #include "pr2_arm_ik.h"
40 
41 /**** List of angles (for reference) *******
42  th1 = shoulder/turret pan
43  th2 = shoulder/turret lift/pitch
44  th3 = shoulder/turret roll
45  th4 = elbow pitch
46  th5 = elbow roll
47  th6 = wrist pitch
48  th7 = wrist roll
49 *****/
50 using namespace angles;
52 {
53 namespace
54 {
55 rclcpp::Logger getLogger()
56 {
57  return moveit::getLogger("moveit_constaint_samplers.test.pr2_arm_ik");
58 }
59 } // namespace
60 
61 PR2ArmIK::PR2ArmIK()
62 {
63 }
64 
65 bool PR2ArmIK::init(const urdf::ModelInterface& robot_model, const std::string& root_name, const std::string& tip_name)
66 {
67  std::vector<urdf::Pose> link_offset;
68  int num_joints = 0;
69  urdf::LinkConstSharedPtr link = robot_model.getLink(tip_name);
70  while (link && num_joints < 7)
71  {
72  urdf::JointConstSharedPtr joint;
73  if (link->parent_joint)
74  joint = robot_model.getJoint(link->parent_joint->name);
75  if (!joint)
76  {
77  if (link->parent_joint)
78  {
79  RCLCPP_ERROR(getLogger(), "Could not find joint: %s", link->parent_joint->name.c_str());
80  }
81  else
82  {
83  RCLCPP_ERROR(getLogger(), "Link %s has no parent joint", link->name.c_str());
84  }
85  return false;
86  }
87  if (joint->type != urdf::Joint::UNKNOWN && joint->type != urdf::Joint::FIXED)
88  {
89  link_offset.push_back(link->parent_joint->parent_to_joint_origin_transform);
90  angle_multipliers_.push_back(joint->axis.x * fabs(joint->axis.x) + joint->axis.y * fabs(joint->axis.y) +
91  joint->axis.z * fabs(joint->axis.z));
92  RCLCPP_DEBUG(getLogger(), "Joint axis: %d, %f, %f, %f", 6 - num_joints, joint->axis.x, joint->axis.y,
93  joint->axis.z);
94  if (joint->type != urdf::Joint::CONTINUOUS)
95  {
96  if (joint->safety)
97  {
98  min_angles_.push_back(joint->safety->soft_lower_limit);
99  max_angles_.push_back(joint->safety->soft_upper_limit);
100  }
101  else
102  {
103  if (joint->limits)
104  {
105  min_angles_.push_back(joint->limits->lower);
106  max_angles_.push_back(joint->limits->upper);
107  }
108  else
109  {
110  min_angles_.push_back(0.0);
111  max_angles_.push_back(0.0);
112  RCLCPP_WARN(getLogger(), "No joint limits or joint '%s'", joint->name.c_str());
113  }
114  }
115  continuous_joint_.push_back(false);
116  }
117  else
118  {
119  min_angles_.push_back(-M_PI);
120  max_angles_.push_back(M_PI);
121  continuous_joint_.push_back(true);
122  }
123  addJointToChainInfo(link->parent_joint, solver_info_);
124  num_joints++;
125  }
126  link = robot_model.getLink(link->getParent()->name);
127  }
128 
129  solver_info_.link_names.push_back(tip_name);
130 
131  // solver_info_.link_names.push_back(tip_name);
132  // We expect order from root to tip, so reverse the order
133  std::reverse(angle_multipliers_.begin(), angle_multipliers_.end());
134  std::reverse(min_angles_.begin(), min_angles_.end());
135  std::reverse(max_angles_.begin(), max_angles_.end());
136  std::reverse(link_offset.begin(), link_offset.end());
137  std::reverse(solver_info_.limits.begin(), solver_info_.limits.end());
138  std::reverse(solver_info_.joint_names.begin(), solver_info_.joint_names.end());
139  std::reverse(solver_info_.link_names.begin(), solver_info_.link_names.end());
140  std::reverse(continuous_joint_.begin(), continuous_joint_.end());
141 
142  if (num_joints != 7)
143  {
144  RCLCPP_ERROR(getLogger(), "PR2ArmIK:: Chain from %s to %s does not have 7 joints", root_name.c_str(),
145  tip_name.c_str());
146  return false;
147  }
148 
149  torso_shoulder_offset_x_ = link_offset[0].position.x;
150  torso_shoulder_offset_y_ = link_offset[0].position.y;
151  torso_shoulder_offset_z_ = link_offset[0].position.z;
152  shoulder_upperarm_offset_ = distance(link_offset[1]);
153  upperarm_elbow_offset_ = distance(link_offset[3]);
154  elbow_wrist_offset_ = distance(link_offset[5]);
155  shoulder_elbow_offset_ = shoulder_upperarm_offset_ + upperarm_elbow_offset_;
156  shoulder_wrist_offset_ = shoulder_upperarm_offset_ + upperarm_elbow_offset_ + elbow_wrist_offset_;
157 
158  Eigen::Isometry3f home = Eigen::Isometry3f::Identity();
159  home(0, 3) = shoulder_upperarm_offset_ + upperarm_elbow_offset_ + elbow_wrist_offset_;
160  home_inv_ = home.inverse();
161  grhs_ = home;
162  gf_ = home_inv_;
163  solution_.resize(NUM_JOINTS_ARM7DOF);
164  return true;
165 }
166 
167 void PR2ArmIK::addJointToChainInfo(const urdf::JointConstSharedPtr& joint, moveit_msgs::msg::KinematicSolverInfo& info)
168 {
169  moveit_msgs::msg::JointLimits limit;
170  info.joint_names.push_back(joint->name); // Joints are coming in reverse order
171 
172  if (joint->type != urdf::Joint::CONTINUOUS)
173  {
174  if (joint->safety)
175  {
176  limit.min_position = joint->safety->soft_lower_limit;
177  limit.max_position = joint->safety->soft_upper_limit;
178  limit.has_position_limits = true;
179  }
180  else if (joint->limits)
181  {
182  limit.min_position = joint->limits->lower;
183  limit.max_position = joint->limits->upper;
184  limit.has_position_limits = true;
185  }
186  else
187  limit.has_position_limits = false;
188  }
189  else
190  {
191  limit.min_position = -M_PI;
192  limit.max_position = M_PI;
193  limit.has_position_limits = false;
194  }
195  if (joint->limits)
196  {
197  limit.max_velocity = joint->limits->velocity;
198  limit.has_velocity_limits = 1;
199  }
200  else
201  limit.has_velocity_limits = 0;
202  info.limits.push_back(limit);
203 }
204 
205 void PR2ArmIK::getSolverInfo(moveit_msgs::msg::KinematicSolverInfo& info)
206 {
207  info = solver_info_;
208 }
209 
210 void PR2ArmIK::computeIKShoulderPan(const Eigen::Isometry3f& g_in, double t1_in,
211  std::vector<std::vector<double> >& solution) const
212 {
213  // t1 = shoulder/turret pan is specified
214  // solution_ik_.resize(0);
215  std::vector<double> solution_ik(NUM_JOINTS_ARM7DOF, 0.0);
216  Eigen::Isometry3f g = g_in;
217  Eigen::Isometry3f gf_local = home_inv_;
218  Eigen::Isometry3f grhs_local = home_inv_;
219  // First bring everything into the arm frame
220  g(0, 3) = g_in(0, 3) - torso_shoulder_offset_x_;
221  g(1, 3) = g_in(1, 3) - torso_shoulder_offset_y_;
222  g(2, 3) = g_in(2, 3) - torso_shoulder_offset_z_;
223 
224  double t1 = angles::normalize_angle(t1_in);
225  if (!checkJointLimits(t1, 0))
226  return;
227 
228  double cost1, cost2, cost3, cost4;
229  double sint1, sint2, sint3, sint4;
230 
231  gf_local = g * home_inv_;
232 
233  cost1 = cos(t1);
234  sint1 = sin(t1);
235 
236  double t2(0), t3(0), t4(0), t5(0), t6(0), t7(0);
237 
238  double at(0), bt(0), ct(0);
239 
240  double theta2[2], theta3[2], theta4[2], theta5[2], theta6[4], theta7[2];
241 
242  double sopx = shoulder_upperarm_offset_ * cost1;
243  double sopy = shoulder_upperarm_offset_ * sint1;
244  double sopz = 0;
245 
246  double x = g(0, 3);
247  double y = g(1, 3);
248  double z = g(2, 3);
249 
250  double dx = x - sopx;
251  double dy = y - sopy;
252  double dz = z - sopz;
253 
254  double dd = dx * dx + dy * dy + dz * dz;
255 
256  double numerator =
257  dd - shoulder_upperarm_offset_ * shoulder_upperarm_offset_ +
258  2 * shoulder_upperarm_offset_ * shoulder_elbow_offset_ - 2 * shoulder_elbow_offset_ * shoulder_elbow_offset_ +
259  2 * shoulder_elbow_offset_ * shoulder_wrist_offset_ - shoulder_wrist_offset_ * shoulder_wrist_offset_;
260  double denominator =
261  2 * (shoulder_upperarm_offset_ - shoulder_elbow_offset_) * (shoulder_elbow_offset_ - shoulder_wrist_offset_);
262 
263  double acos_term = numerator / denominator;
264 
265  if (acos_term > 1.0 || acos_term < -1.0)
266  return;
267 
268  double acos_angle = acos(acos_term);
269 
270  theta4[0] = acos_angle;
271  theta4[1] = -acos_angle;
272 
273 #ifdef DEBUG
274  std::cout << "ComputeIK::theta3:" << numerator << ',' << denominator << ",\n" << theta4[0] << '\n';
275 #endif
276 
277  for (double theta : theta4)
278  {
279  t4 = theta;
280  cost4 = cos(t4);
281  sint4 = sin(t4);
282 
283 #ifdef DEBUG
284  std::cout << "t4 " << t4 << '\n';
285 #endif
286  if (std::isnan(t4))
287  continue;
288 
289  if (!checkJointLimits(t4, 3))
290  continue;
291 
292  at = x * cost1 + y * sint1 - shoulder_upperarm_offset_;
293  bt = -z;
294  ct = -shoulder_upperarm_offset_ + shoulder_elbow_offset_ +
295  (shoulder_wrist_offset_ - shoulder_elbow_offset_) * cos(t4);
296 
297  if (!solveCosineEqn(at, bt, ct, theta2[0], theta2[1]))
298  continue;
299 
300  for (double theta : theta2)
301  {
302  t2 = theta;
303  if (!checkJointLimits(t2, 1))
304  continue;
305 
306 #ifdef DEBUG
307  std::cout << "t2 " << t2 << '\n';
308 #endif
309  sint2 = sin(t2);
310  cost2 = cos(t2);
311 
312  at = sint1 * (shoulder_elbow_offset_ - shoulder_wrist_offset_) * sint2 * sint4;
313  bt = (-shoulder_elbow_offset_ + shoulder_wrist_offset_) * cost1 * sint4;
314  ct = y - (shoulder_upperarm_offset_ + cost2 * (-shoulder_upperarm_offset_ + shoulder_elbow_offset_ +
315  (-shoulder_elbow_offset_ + shoulder_wrist_offset_) * cos(t4))) *
316  sint1;
317  if (!solveCosineEqn(at, bt, ct, theta3[0], theta3[1]))
318  continue;
319 
320  for (double theta : theta3)
321  {
322  t3 = theta;
323 
324  if (!checkJointLimits(angles::normalize_angle(t3), 2))
325  continue;
326 
327  sint3 = sin(t3);
328  cost3 = cos(t3);
329 #ifdef DEBUG
330  std::cout << "t3 " << t3 << '\n';
331 #endif
332  if (fabs((shoulder_upperarm_offset_ - shoulder_elbow_offset_ +
333  (shoulder_elbow_offset_ - shoulder_wrist_offset_) * cost4) *
334  sint2 +
335  (shoulder_elbow_offset_ - shoulder_wrist_offset_) * cost2 * cost3 * sint4 - z) > IK_EPS)
336  continue;
337 
338  if (fabs((shoulder_elbow_offset_ - shoulder_wrist_offset_) * sint1 * sint3 * sint4 +
339  cost1 * (shoulder_upperarm_offset_ +
340  cost2 * (-shoulder_upperarm_offset_ + shoulder_elbow_offset_ +
341  (-shoulder_elbow_offset_ + shoulder_wrist_offset_) * cost4) +
342  (shoulder_elbow_offset_ - shoulder_wrist_offset_) * cost3 * sint2 * sint4) -
343  x) > IK_EPS)
344  continue;
345 
346  grhs_local(0, 0) =
347  cost4 * (gf_local(0, 0) * cost1 * cost2 + gf_local(1, 0) * cost2 * sint1 - gf_local(2, 0) * sint2) -
348  (gf_local(2, 0) * cost2 * cost3 + cost3 * (gf_local(0, 0) * cost1 + gf_local(1, 0) * sint1) * sint2 +
349  (-(gf_local(1, 0) * cost1) + gf_local(0, 0) * sint1) * sint3) *
350  sint4;
351 
352  grhs_local(0, 1) =
353  cost4 * (gf_local(0, 1) * cost1 * cost2 + gf_local(1, 1) * cost2 * sint1 - gf_local(2, 1) * sint2) -
354  (gf_local(2, 1) * cost2 * cost3 + cost3 * (gf_local(0, 1) * cost1 + gf_local(1, 1) * sint1) * sint2 +
355  (-(gf_local(1, 1) * cost1) + gf_local(0, 1) * sint1) * sint3) *
356  sint4;
357 
358  grhs_local(0, 2) =
359  cost4 * (gf_local(0, 2) * cost1 * cost2 + gf_local(1, 2) * cost2 * sint1 - gf_local(2, 2) * sint2) -
360  (gf_local(2, 2) * cost2 * cost3 + cost3 * (gf_local(0, 2) * cost1 + gf_local(1, 2) * sint1) * sint2 +
361  (-(gf_local(1, 2) * cost1) + gf_local(0, 2) * sint1) * sint3) *
362  sint4;
363 
364  grhs_local(1, 0) = cost3 * (gf_local(1, 0) * cost1 - gf_local(0, 0) * sint1) + gf_local(2, 0) * cost2 * sint3 +
365  (gf_local(0, 0) * cost1 + gf_local(1, 0) * sint1) * sint2 * sint3;
366 
367  grhs_local(1, 1) = cost3 * (gf_local(1, 1) * cost1 - gf_local(0, 1) * sint1) + gf_local(2, 1) * cost2 * sint3 +
368  (gf_local(0, 1) * cost1 + gf_local(1, 1) * sint1) * sint2 * sint3;
369 
370  grhs_local(1, 2) = cost3 * (gf_local(1, 2) * cost1 - gf_local(0, 2) * sint1) + gf_local(2, 2) * cost2 * sint3 +
371  (gf_local(0, 2) * cost1 + gf_local(1, 2) * sint1) * sint2 * sint3;
372 
373  grhs_local(2, 0) =
374  cost4 *
375  (gf_local(2, 0) * cost2 * cost3 + cost3 * (gf_local(0, 0) * cost1 + gf_local(1, 0) * sint1) * sint2 +
376  (-(gf_local(1, 0) * cost1) + gf_local(0, 0) * sint1) * sint3) +
377  (gf_local(0, 0) * cost1 * cost2 + gf_local(1, 0) * cost2 * sint1 - gf_local(2, 0) * sint2) * sint4;
378 
379  grhs_local(2, 1) =
380  cost4 *
381  (gf_local(2, 1) * cost2 * cost3 + cost3 * (gf_local(0, 1) * cost1 + gf_local(1, 1) * sint1) * sint2 +
382  (-(gf_local(1, 1) * cost1) + gf_local(0, 1) * sint1) * sint3) +
383  (gf_local(0, 1) * cost1 * cost2 + gf_local(1, 1) * cost2 * sint1 - gf_local(2, 1) * sint2) * sint4;
384 
385  grhs_local(2, 2) =
386  cost4 *
387  (gf_local(2, 2) * cost2 * cost3 + cost3 * (gf_local(0, 2) * cost1 + gf_local(1, 2) * sint1) * sint2 +
388  (-(gf_local(1, 2) * cost1) + gf_local(0, 2) * sint1) * sint3) +
389  (gf_local(0, 2) * cost1 * cost2 + gf_local(1, 2) * cost2 * sint1 - gf_local(2, 2) * sint2) * sint4;
390 
391  double val1 = sqrt(grhs_local(0, 1) * grhs_local(0, 1) + grhs_local(0, 2) * grhs_local(0, 2));
392  double val2 = grhs_local(0, 0);
393 
394  theta6[0] = atan2(val1, val2);
395  theta6[1] = atan2(-val1, val2);
396 
397  // theta6[3] = M_PI + theta6[0];
398  // theta6[4] = M_PI + theta6[1];
399 
400  for (int mm = 0; mm < 2; ++mm)
401  {
402  t6 = theta6[mm];
403  if (!checkJointLimits(angles::normalize_angle(t6), 5))
404  continue;
405 
406 #ifdef DEBUG
407  std::cout << "t6 " << t6 << '\n';
408 #endif
409  if (fabs(cos(t6) - grhs_local(0, 0)) > IK_EPS)
410  continue;
411 
412  if (fabs(sin(t6)) < IK_EPS)
413  {
414  // std::cout << "Singularity" << '\n';
415  theta5[0] = acos(grhs_local(1, 1)) / 2.0;
416  theta7[0] = theta7[0];
417  theta7[1] = M_PI + theta7[0];
418  theta5[1] = theta7[1];
419  }
420  else
421  {
422  theta7[0] = atan2(grhs_local(0, 1), grhs_local(0, 2));
423  theta5[0] = atan2(grhs_local(1, 0), -grhs_local(2, 0));
424  theta7[1] = M_PI + theta7[0];
425  theta5[1] = M_PI + theta5[0];
426  }
427 #ifdef DEBUG
428  std::cout << "theta1: " << t1 << '\n';
429  std::cout << "theta2: " << t2 << '\n';
430  std::cout << "theta3: " << t3 << '\n';
431  std::cout << "theta4: " << t4 << '\n';
432  std::cout << "theta5: " << t5 << '\n';
433  std::cout << "theta6: " << t6 << '\n';
434  std::cout << "theta7: " << t7 << '\n' << '\n' << '\n';
435 #endif
436  for (int lll = 0; lll < 2; ++lll)
437  {
438  t5 = theta5[lll];
439  t7 = theta7[lll];
440  if (!checkJointLimits(t5, 4))
441  continue;
442  if (!checkJointLimits(t7, 6))
443  continue;
444 
445 #ifdef DEBUG
446  std::cout << "t5" << t5 << '\n';
447  std::cout << "t7" << t7 << '\n';
448 #endif
449  if (fabs(sin(t6) * sin(t7) - grhs_local(0, 1)) > IK_EPS ||
450  fabs(cos(t7) * sin(t6) - grhs_local(0, 2)) > IK_EPS)
451  continue;
452 
453  solution_ik[0] = normalize_angle(t1) * angle_multipliers_[0];
454  solution_ik[1] = normalize_angle(t2) * angle_multipliers_[1];
455  solution_ik[2] = normalize_angle(t3) * angle_multipliers_[2];
456  solution_ik[3] = normalize_angle(t4) * angle_multipliers_[3];
457  solution_ik[4] = normalize_angle(t5) * angle_multipliers_[4];
458  solution_ik[5] = normalize_angle(t6) * angle_multipliers_[5];
459  solution_ik[6] = normalize_angle(t7) * angle_multipliers_[6];
460  solution.push_back(solution_ik);
461 
462 #ifdef DEBUG
463  std::cout << "SOLN " << solution_ik[0] << ' ' << solution_ik[1] << ' ' << solution_ik[2] << ' '
464  << solution_ik[3] << ' ' << solution_ik[4] << ' ' << solution_ik[5] << ' ' << solution_ik[6]
465  << '\n'
466  << '\n';
467 #endif
468  }
469  }
470  }
471  }
472  }
473 }
474 
475 void PR2ArmIK::computeIKShoulderRoll(const Eigen::Isometry3f& g_in, const double t3,
476  std::vector<std::vector<double> >& solution) const
477 {
478  std::vector<double> solution_ik(NUM_JOINTS_ARM7DOF, 0.0);
479  // ROS_INFO(" ");
480  // solution_ik_.clear();
481  // ROS_INFO("Solution IK size: %d",solution_ik_.size());
482  // for(unsigned int i=0; i < solution_ik_.size(); ++i)
483  // {
484  // solution_ik_[i].clear();
485  // }
486  // if(!solution_ik_.empty())
487  // solution_ik_.resize(0);
488  // t3 = shoulder/turret roll is specified
489  Eigen::Isometry3f g = g_in;
490  Eigen::Isometry3f gf_local = home_inv_;
491  Eigen::Isometry3f grhs_local = home_inv_;
492  // First bring everything into the arm frame
493  g(0, 3) = g_in(0, 3) - torso_shoulder_offset_x_;
494  g(1, 3) = g_in(1, 3) - torso_shoulder_offset_y_;
495  g(2, 3) = g_in(2, 3) - torso_shoulder_offset_z_;
496 
497  if (!checkJointLimits(t3, 2))
498  {
499  return;
500  }
501  double x = g(0, 3);
502  double y = g(1, 3);
503  double z = g(2, 3);
504  double cost1, cost2, cost3, cost4;
505  double sint1, sint2, sint3, sint4;
506 
507  gf_local = g * home_inv_;
508 
509  cost3 = cos(t3);
510  sint3 = sin(t3);
511 
512  double t1(0), t2(0), t4(0), t5(0), t6(0), t7(0);
513 
514  double at(0), bt(0), ct(0);
515 
516  double theta1[2], theta2[2], theta4[4], theta5[2], theta6[4], theta7[2];
517 
518  double c0 = -sin(-t3) * elbow_wrist_offset_;
519  double c1 = -cos(-t3) * elbow_wrist_offset_;
520 
521  double d0 = 4 * shoulder_upperarm_offset_ * shoulder_upperarm_offset_ *
522  (upperarm_elbow_offset_ * upperarm_elbow_offset_ + c1 * c1 - z * z);
523  double d1 = 8 * shoulder_upperarm_offset_ * shoulder_upperarm_offset_ * upperarm_elbow_offset_ * elbow_wrist_offset_;
524  double d2 =
525  4 * shoulder_upperarm_offset_ * shoulder_upperarm_offset_ * (elbow_wrist_offset_ * elbow_wrist_offset_ - c1 * c1);
526 
527  double b0 = x * x + y * y + z * z - shoulder_upperarm_offset_ * shoulder_upperarm_offset_ -
528  upperarm_elbow_offset_ * upperarm_elbow_offset_ - c0 * c0 - c1 * c1;
529  double b1 = -2 * upperarm_elbow_offset_ * elbow_wrist_offset_;
530 
531  if (!solveQuadratic(b1 * b1 - d2, 2 * b0 * b1 - d1, b0 * b0 - d0, &theta4[0], &theta4[1]))
532  {
533 #ifdef DEBUG
534  printf("No solution to quadratic eqn\n");
535 #endif
536  return;
537  }
538  theta4[0] = acos(theta4[0]);
539  theta4[2] = acos(theta4[1]);
540  theta4[1] = -theta4[0];
541  theta4[3] = -theta4[2];
542 
543  for (double theta : theta4)
544  {
545  t4 = theta;
546 
547  if (!checkJointLimits(t4, 3))
548  {
549  continue;
550  }
551  cost4 = cos(t4);
552  sint4 = sin(t4);
553 #ifdef DEBUG
554  std::cout << "t4 " << t4 << '\n';
555 #endif
556  if (std::isnan(t4))
557  continue;
558  at = cos(t3) * sin(t4) * (shoulder_elbow_offset_ - shoulder_wrist_offset_);
559  bt = (shoulder_upperarm_offset_ - shoulder_elbow_offset_ +
560  (shoulder_elbow_offset_ - shoulder_wrist_offset_) * cos(t4));
561  ct = z;
562 
563  if (!solveCosineEqn(at, bt, ct, theta2[0], theta2[1]))
564  continue;
565 
566  for (double theta : theta2)
567  {
568  t2 = theta;
569 #ifdef DEBUG
570  std::cout << "t2 " << t2 << '\n';
571 #endif
572  if (!checkJointLimits(t2, 1))
573  {
574  continue;
575  }
576 
577  sint2 = sin(t2);
578  cost2 = cos(t2);
579 
580  at = -y;
581  bt = x;
582  ct = (shoulder_elbow_offset_ - shoulder_wrist_offset_) * sin(t3) * sin(t4);
583  if (!solveCosineEqn(at, bt, ct, theta1[0], theta1[1]))
584  {
585 #ifdef DEBUG
586  std::cout << "could not solve cosine equation for t1" << '\n';
587 #endif
588  continue;
589  }
590 
591  for (double theta : theta1)
592  {
593  t1 = theta;
594 #ifdef DEBUG
595  std::cout << "t1 " << t1 << '\n';
596 #endif
597  if (!checkJointLimits(t1, 0))
598  {
599  continue;
600  }
601  sint1 = sin(t1);
602  cost1 = cos(t1);
603  if (fabs((shoulder_upperarm_offset_ - shoulder_elbow_offset_ +
604  (shoulder_elbow_offset_ - shoulder_wrist_offset_) * cost4) *
605  sint2 +
606  (shoulder_elbow_offset_ - shoulder_wrist_offset_) * cost2 * cost3 * sint4 - z) > IK_EPS)
607  {
608 #ifdef DEBUG
609  printf("z value not matched %f\n",
610  fabs((shoulder_upperarm_offset_ - shoulder_elbow_offset_ +
611  (shoulder_elbow_offset_ - shoulder_wrist_offset_) * cost4) *
612  sint2 +
613  (shoulder_elbow_offset_ - shoulder_wrist_offset_) * cost2 * cost3 * sint4 - z));
614 #endif
615  continue;
616  }
617  if (fabs((shoulder_elbow_offset_ - shoulder_wrist_offset_) * sint1 * sint3 * sint4 +
618  cost1 * (shoulder_upperarm_offset_ +
619  cost2 * (-shoulder_upperarm_offset_ + shoulder_elbow_offset_ +
620  (-shoulder_elbow_offset_ + shoulder_wrist_offset_) * cost4) +
621  (shoulder_elbow_offset_ - shoulder_wrist_offset_) * cost3 * sint2 * sint4) -
622  x) > IK_EPS)
623  {
624 #ifdef DEBUG
625  printf("x value not matched by %f\n",
626  fabs((shoulder_elbow_offset_ - shoulder_wrist_offset_) * sint1 * sint3 * sint4 +
627  cost1 * (shoulder_upperarm_offset_ +
628  cost2 * (-shoulder_upperarm_offset_ + shoulder_elbow_offset_ +
629  (-shoulder_elbow_offset_ + shoulder_wrist_offset_) * cost4) +
630  (shoulder_elbow_offset_ - shoulder_wrist_offset_) * cost3 * sint2 * sint4) -
631  x));
632 #endif
633  continue;
634  }
635  if (fabs(-(shoulder_elbow_offset_ - shoulder_wrist_offset_) * cost1 * sint3 * sint4 +
636  sint1 * (shoulder_upperarm_offset_ +
637  cost2 * (-shoulder_upperarm_offset_ + shoulder_elbow_offset_ +
638  (-shoulder_elbow_offset_ + shoulder_wrist_offset_) * cost4) +
639  (shoulder_elbow_offset_ - shoulder_wrist_offset_) * cost3 * sint2 * sint4) -
640  y) > IK_EPS)
641  {
642 #ifdef DEBUG
643  printf("y value not matched\n");
644 #endif
645  continue;
646  }
647  grhs_local(0, 0) =
648  cost4 * (gf_local(0, 0) * cost1 * cost2 + gf_local(1, 0) * cost2 * sint1 - gf_local(2, 0) * sint2) -
649  (gf_local(2, 0) * cost2 * cost3 + cost3 * (gf_local(0, 0) * cost1 + gf_local(1, 0) * sint1) * sint2 +
650  (-(gf_local(1, 0) * cost1) + gf_local(0, 0) * sint1) * sint3) *
651  sint4;
652 
653  grhs_local(0, 1) =
654  cost4 * (gf_local(0, 1) * cost1 * cost2 + gf_local(1, 1) * cost2 * sint1 - gf_local(2, 1) * sint2) -
655  (gf_local(2, 1) * cost2 * cost3 + cost3 * (gf_local(0, 1) * cost1 + gf_local(1, 1) * sint1) * sint2 +
656  (-(gf_local(1, 1) * cost1) + gf_local(0, 1) * sint1) * sint3) *
657  sint4;
658 
659  grhs_local(0, 2) =
660  cost4 * (gf_local(0, 2) * cost1 * cost2 + gf_local(1, 2) * cost2 * sint1 - gf_local(2, 2) * sint2) -
661  (gf_local(2, 2) * cost2 * cost3 + cost3 * (gf_local(0, 2) * cost1 + gf_local(1, 2) * sint1) * sint2 +
662  (-(gf_local(1, 2) * cost1) + gf_local(0, 2) * sint1) * sint3) *
663  sint4;
664 
665  grhs_local(1, 0) = cost3 * (gf_local(1, 0) * cost1 - gf_local(0, 0) * sint1) + gf_local(2, 0) * cost2 * sint3 +
666  (gf_local(0, 0) * cost1 + gf_local(1, 0) * sint1) * sint2 * sint3;
667 
668  grhs_local(1, 1) = cost3 * (gf_local(1, 1) * cost1 - gf_local(0, 1) * sint1) + gf_local(2, 1) * cost2 * sint3 +
669  (gf_local(0, 1) * cost1 + gf_local(1, 1) * sint1) * sint2 * sint3;
670 
671  grhs_local(1, 2) = cost3 * (gf_local(1, 2) * cost1 - gf_local(0, 2) * sint1) + gf_local(2, 2) * cost2 * sint3 +
672  (gf_local(0, 2) * cost1 + gf_local(1, 2) * sint1) * sint2 * sint3;
673 
674  grhs_local(2, 0) =
675  cost4 *
676  (gf_local(2, 0) * cost2 * cost3 + cost3 * (gf_local(0, 0) * cost1 + gf_local(1, 0) * sint1) * sint2 +
677  (-(gf_local(1, 0) * cost1) + gf_local(0, 0) * sint1) * sint3) +
678  (gf_local(0, 0) * cost1 * cost2 + gf_local(1, 0) * cost2 * sint1 - gf_local(2, 0) * sint2) * sint4;
679 
680  grhs_local(2, 1) =
681  cost4 *
682  (gf_local(2, 1) * cost2 * cost3 + cost3 * (gf_local(0, 1) * cost1 + gf_local(1, 1) * sint1) * sint2 +
683  (-(gf_local(1, 1) * cost1) + gf_local(0, 1) * sint1) * sint3) +
684  (gf_local(0, 1) * cost1 * cost2 + gf_local(1, 1) * cost2 * sint1 - gf_local(2, 1) * sint2) * sint4;
685 
686  grhs_local(2, 2) =
687  cost4 *
688  (gf_local(2, 2) * cost2 * cost3 + cost3 * (gf_local(0, 2) * cost1 + gf_local(1, 2) * sint1) * sint2 +
689  (-(gf_local(1, 2) * cost1) + gf_local(0, 2) * sint1) * sint3) +
690  (gf_local(0, 2) * cost1 * cost2 + gf_local(1, 2) * cost2 * sint1 - gf_local(2, 2) * sint2) * sint4;
691 
692  double val1 = sqrt(grhs_local(0, 1) * grhs_local(0, 1) + grhs_local(0, 2) * grhs_local(0, 2));
693  double val2 = grhs_local(0, 0);
694 
695  theta6[0] = atan2(val1, val2);
696  theta6[1] = atan2(-val1, val2);
697 
698  for (int mm = 0; mm < 2; ++mm)
699  {
700  t6 = theta6[mm];
701 #ifdef DEBUG
702  std::cout << "t6 " << t6 << '\n';
703 #endif
704  if (!checkJointLimits(t6, 5))
705  {
706  continue;
707  }
708 
709  if (fabs(cos(t6) - grhs_local(0, 0)) > IK_EPS)
710  continue;
711 
712  if (fabs(sin(t6)) < IK_EPS)
713  {
714  // std::cout << "Singularity" << '\n';
715  theta5[0] = acos(grhs_local(1, 1)) / 2.0;
716  theta7[0] = theta5[0];
717  // theta7[1] = M_PI+theta7[0];
718  // theta5[1] = theta7[1];
719  }
720  else
721  {
722  theta7[0] = atan2(grhs_local(0, 1) / sin(t6), grhs_local(0, 2) / sin(t6));
723  theta5[0] = atan2(grhs_local(1, 0) / sin(t6), -grhs_local(2, 0) / sin(t6));
724  // theta7[1] = M_PI+theta7[0];
725  // theta5[1] = M_PI+theta5[0];
726  }
727  for (int lll = 0; lll < 1; ++lll)
728  {
729  t5 = theta5[lll];
730  t7 = theta7[lll];
731 
732  if (!checkJointLimits(t5, 4))
733  {
734  continue;
735  }
736  if (!checkJointLimits(t7, 6))
737  {
738  continue;
739  }
740 
741 #ifdef DEBUG
742  std::cout << "t5 " << t5 << '\n';
743  std::cout << "t7 " << t7 << '\n';
744 #endif
745  // if(fabs(sin(t6)*sin(t7)-grhs_local(0,1)) > IK_EPS || fabs(cos(t7)*sin(t6)-grhs_local(0,2)) > IK_EPS)
746  // continue;
747 
748 #ifdef DEBUG
749  std::cout << "theta1: " << t1 << '\n';
750  std::cout << "theta2: " << t2 << '\n';
751  std::cout << "theta3: " << t3 << '\n';
752  std::cout << "theta4: " << t4 << '\n';
753  std::cout << "theta5: " << t5 << '\n';
754  std::cout << "theta6: " << t6 << '\n';
755  std::cout << "theta7: " << t7 << '\n' << '\n' << '\n';
756 #endif
757 
758  solution_ik[0] = normalize_angle(t1 * angle_multipliers_[0]);
759  solution_ik[1] = normalize_angle(t2 * angle_multipliers_[1]);
760  solution_ik[2] = t3 * angle_multipliers_[2];
761  solution_ik[3] = normalize_angle(t4 * angle_multipliers_[3]);
762  solution_ik[4] = normalize_angle(t5 * angle_multipliers_[4]);
763  solution_ik[5] = normalize_angle(t6 * angle_multipliers_[5]);
764  solution_ik[6] = normalize_angle(t7 * angle_multipliers_[6]);
765  solution.push_back(solution_ik);
766 #ifdef DEBUG
767  std::cout << "SOLN " << solution_ik[0] << ' ' << solution_ik[1] << ' ' << solution_ik[2] << ' '
768  << solution_ik[3] << ' ' << solution_ik[4] << ' ' << solution_ik[5] << ' ' << solution_ik[6]
769  << '\n'
770  << '\n';
771 #endif
772  }
773  }
774  }
775  }
776  }
777 }
778 
779 bool PR2ArmIK::checkJointLimits(const std::vector<double>& joint_values) const
780 {
781  for (int i = 0; i < NUM_JOINTS_ARM7DOF; ++i)
782  {
783  if (!checkJointLimits(angles::normalize_angle(joint_values[i] * angle_multipliers_[i]), i))
784  {
785  return false;
786  }
787  }
788  return true;
789 }
790 
791 bool PR2ArmIK::checkJointLimits(const double joint_value, const int joint_num) const
792 {
793  double jv;
794  if (continuous_joint_[joint_num])
795  {
796  jv = angles::normalize_angle(joint_value * angle_multipliers_[joint_num]);
797  }
798  else if (joint_num == 2)
799  {
800  jv = joint_value * angle_multipliers_[joint_num];
801  }
802  else
803  {
804  jv = angles::normalize_angle(joint_value * angle_multipliers_[joint_num]);
805  }
806 
807  return !(jv < min_angles_[joint_num] || jv > max_angles_[joint_num]);
808 }
809 } // namespace pr2_arm_kinematics
rclcpp::Logger getLogger(const std::string &name)
Creates a namespaced logger.
Definition: logger.cpp:79
double distance(const urdf::Pose &transform)
Definition: pr2_arm_ik.h:55
bool solveQuadratic(double a, double b, double c, double *x1, double *x2)
Definition: pr2_arm_ik.h:61
bool solveCosineEqn(double a, double b, double c, double &soln1, double &soln2)
Definition: pr2_arm_ik.h:91