moveit_opw_kinematics_plugin.cpp
Go to the documentation of this file.
3 
6 
7 // abs
8 #include <cstdlib>
9 
10 // Eigen
11 #include <Eigen/Core>
12 #include <Eigen/Geometry>
14 
15 // OPW kinematics
16 #include "opw_kinematics/opw_io.h"
19 
20 // register OPWKinematics as a KinematicsBase implementation
22 
24 {
25 constexpr char LOGNAME[] = "opw";
27 
29 {
30 }
31 
32 bool MoveItOPWKinematicsPlugin::initialize(const moveit::core::RobotModel& robot_model, const std::string& group_name,
33  const std::string& base_frame, const std::vector<std::string>& tip_frames,
34  double search_discretization)
35 {
36  bool debug = false;
37 
38  ROS_INFO_STREAM_NAMED(LOGNAME, "MoveItOPWKinematicsPlugin initializing");
39 
40  storeValues(robot_model, group_name, base_frame, tip_frames, search_discretization);
41 
42  joint_model_group_ = robot_model_->getJointModelGroup(group_name);
43  if (!joint_model_group_)
44  return false;
45 
46  if (debug)
47  {
48  std::cout << std::endl
49  << "Joint Model Variable Names: "
50  "------------------------------------------- "
51  << std::endl;
52  const std::vector<std::string> jm_names = joint_model_group_->getVariableNames();
53  std::copy(jm_names.begin(), jm_names.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
54  std::cout << std::endl;
55  }
56 
57  // Get the dimension of the planning group
58  dimension_ = joint_model_group_->getVariableCount();
59  ROS_INFO_STREAM_NAMED(LOGNAME, "Dimension planning group '"
60  << group_name << "': " << dimension_
61  << ". Active Joints Models: " << joint_model_group_->getActiveJointModels().size()
62  << ". Mimic Joint Models: " << joint_model_group_->getMimicJointModels().size());
63 
64  // Copy joint names
65  for (std::size_t i = 0; i < joint_model_group_->getActiveJointModels().size(); ++i)
66  {
67  ik_group_info_.joint_names.push_back(joint_model_group_->getActiveJointModelNames()[i]);
68  }
69 
70  if (debug)
71  {
72  ROS_ERROR_STREAM_NAMED(LOGNAME, "tip links available:");
73  std::copy(tip_frames_.begin(), tip_frames_.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
74  }
75 
76  // Make sure all the tip links are in the link_names vector
77  for (std::size_t i = 0; i < tip_frames_.size(); ++i)
78  {
79  if (!joint_model_group_->hasLinkModel(tip_frames_[i]))
80  {
81  ROS_ERROR_NAMED(LOGNAME, "Could not find tip name '%s' in joint group '%s'", tip_frames_[i].c_str(),
82  group_name.c_str());
83  return false;
84  }
85  ik_group_info_.link_names.push_back(tip_frames_[i]);
86  }
87 
88  // Setup the joint state groups that we need
89  robot_state_.reset(new robot_state::RobotState(robot_model_));
90  robot_state_->setToDefaultValues();
91 
92  // set geometric parameters for opw model
93  if (!setOPWParameters())
94  {
95  ROS_ERROR_STREAM_NAMED(LOGNAME, "Could not load OPW parameters. Please make "
96  "sure they are loaded on the parameter server and are of the correct type(s).");
97  return false;
98  }
99 
100  // check geometric parameters for opw model
101  if (!selfTest({ 0, 0, 0, 0, 0, 0 }))
102  {
103  ROS_ERROR_STREAM_NAMED(LOGNAME, "The OPW parameters loaded from the parameter "
104  "server appear to be incorrect (self-test failed for '0 0 0 0 0 0').");
105  return false;
106  }
107  const std::vector<double> joint_angles = { 0.1, -0.1, 0.2, -0.3, 0.5, -0.8 };
108  if (!selfTest(joint_angles))
109  {
110  ROS_ERROR_STREAM_NAMED(LOGNAME, "The OPW parameters loaded from the parameter "
111  "server appear to be incorrect (self-test failed for odd posture: '0.1, -0.1, 0.2, "
112  "-0.3, 0.5, -0.8').");
113  return false;
114  }
115 
116  active_ = true;
117  ROS_DEBUG_NAMED(LOGNAME, "OPW kinematics solver initialized");
118  return true;
119 }
120 
121 bool MoveItOPWKinematicsPlugin::setRedundantJoints(const std::vector<unsigned int>& redundant_joints)
122 {
124  {
125  ROS_ERROR_NAMED(LOGNAME, "This group cannot have redundant joints");
126  return false;
127  }
128  if (redundant_joints.size() > static_cast<std::size_t>(num_possible_redundant_joints_))
129  {
130  ROS_ERROR_NAMED(LOGNAME, "This group can only have %d redundant joints", num_possible_redundant_joints_);
131  return false;
132  }
133 
134  redundant_joint_indices_ = redundant_joints;
135 
136  return true;
137 }
138 
139 bool MoveItOPWKinematicsPlugin::isRedundantJoint(unsigned int index) const
140 {
141  for (std::size_t j = 0; j < redundant_joint_indices_.size(); ++j)
142  if (redundant_joint_indices_[j] == index)
143  return true;
144  return false;
145 }
146 
147 int MoveItOPWKinematicsPlugin::getJointIndex(const std::string& name) const
148 {
149  for (unsigned int i = 0; i < ik_group_info_.joint_names.size(); i++)
150  {
151  if (ik_group_info_.joint_names[i] == name)
152  return i;
153  }
154  return -1;
155 }
156 
157 bool MoveItOPWKinematicsPlugin::timedOut(const ros::WallTime& start_time, double duration) const
158 {
159  return ((ros::WallTime::now() - start_time).toSec() >= duration);
160 }
161 
162 bool MoveItOPWKinematicsPlugin::selfTest(const std::vector<double>& joint_angles)
163 {
164  auto fk_pose_opw = opw_kinematics::forward(opw_parameters_, &joint_angles[0]);
165  robot_state_->setJointGroupPositions(joint_model_group_, joint_angles);
166  auto fk_pose_moveit = robot_state_->getGlobalLinkTransform(tip_frames_[0]);
167  // group/robot might not be at origin, subtract base transform
168  auto base = robot_state_->getGlobalLinkTransform(base_frame_);
169  fk_pose_moveit = base.inverse() * fk_pose_moveit;
170 
171  if (!comparePoses(fk_pose_opw, fk_pose_moveit))
172  {
173  return false;
174  }
175 
176  // reset robot state
177  robot_state_->setToDefaultValues();
178  return true;
179 }
180 
181 bool MoveItOPWKinematicsPlugin::comparePoses(Eigen::Isometry3d& Ta, Eigen::Isometry3d& Tb)
182 {
183  const float TOLERANCE = 1e-6;
184 
185  auto Ra = Ta.rotation();
186  auto Rb = Tb.rotation();
187  bool valid = true;
188  for (int i = 0; i < Ra.rows(); ++i)
189  {
190  for (int j = 0; j < Ra.cols(); ++j)
191  {
192  if (std::abs(Ra(i, j) - Rb(i, j)) > TOLERANCE)
193  {
194  ROS_ERROR_NAMED(LOGNAME, "Pose orientation error on element (%d, %d).", i, j);
195  ROS_ERROR_NAMED(LOGNAME, "opw: %f, moveit: %f.", Ra(i, j), Rb(i, j));
196  valid = false;
197  }
198  }
199  }
200 
201  auto pa = Ta.translation();
202  auto pb = Tb.translation();
203  for (int i = 0; i < 3; ++i)
204  {
205  if (std::abs(pa(i) - pb(i)) > TOLERANCE)
206  {
207  ROS_ERROR_NAMED(LOGNAME, "Pose position error on element (%d).", i);
208  ROS_ERROR_NAMED(LOGNAME, "opw: %f, moveit: %f.", pa(i), pb(i));
209  valid = false;
210  }
211  }
212  return valid;
213 }
214 
215 bool MoveItOPWKinematicsPlugin::getPositionIK(const geometry_msgs::Pose& ik_pose,
216  const std::vector<double>& ik_seed_state, std::vector<double>& solution,
217  moveit_msgs::MoveItErrorCodes& error_code,
218  const kinematics::KinematicsQueryOptions& options) const
219 {
220  const IKCallbackFn solution_callback = 0;
221  std::vector<double> consistency_limits;
222 
223  return searchPositionIK(ik_pose, ik_seed_state, default_timeout_, solution, solution_callback, error_code,
224  consistency_limits, options);
225 }
226 
227 bool MoveItOPWKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose& ik_pose,
228  const std::vector<double>& ik_seed_state, double timeout,
229  std::vector<double>& solution,
230  moveit_msgs::MoveItErrorCodes& error_code,
231  const kinematics::KinematicsQueryOptions& options) const
232 {
233  const IKCallbackFn solution_callback = 0;
234  std::vector<double> consistency_limits;
235 
236  return searchPositionIK(ik_pose, ik_seed_state, timeout, solution, solution_callback, error_code, consistency_limits,
237  options);
238 }
239 
240 bool MoveItOPWKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose& ik_pose,
241  const std::vector<double>& ik_seed_state, double timeout,
242  const std::vector<double>& consistency_limits,
243  std::vector<double>& solution,
244  moveit_msgs::MoveItErrorCodes& error_code,
245  const kinematics::KinematicsQueryOptions& options) const
246 {
247  const IKCallbackFn solution_callback = 0;
248  return searchPositionIK(ik_pose, ik_seed_state, timeout, solution, solution_callback, error_code, consistency_limits,
249  options);
250 }
251 
252 bool MoveItOPWKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose& ik_pose,
253  const std::vector<double>& ik_seed_state, double timeout,
254  std::vector<double>& solution, const IKCallbackFn& solution_callback,
255  moveit_msgs::MoveItErrorCodes& error_code,
256  const kinematics::KinematicsQueryOptions& options) const
257 {
258  std::vector<double> consistency_limits;
259  return searchPositionIK(ik_pose, ik_seed_state, timeout, solution, solution_callback, error_code, consistency_limits,
260  options);
261 }
262 
263 bool MoveItOPWKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose& ik_pose,
264  const std::vector<double>& ik_seed_state, double timeout,
265  const std::vector<double>& consistency_limits,
266  std::vector<double>& solution, const IKCallbackFn& solution_callback,
267  moveit_msgs::MoveItErrorCodes& error_code,
268  const kinematics::KinematicsQueryOptions& options) const
269 {
270  return searchPositionIK(ik_pose, ik_seed_state, timeout, solution, solution_callback, error_code, consistency_limits,
271  options);
272 }
273 
274 bool MoveItOPWKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose& ik_pose,
275  const std::vector<double>& ik_seed_state, double timeout,
276  std::vector<double>& solution, const IKCallbackFn& solution_callback,
277  moveit_msgs::MoveItErrorCodes& error_code,
278  const std::vector<double>& consistency_limits,
279  const kinematics::KinematicsQueryOptions& options) const
280 {
281  // Convert single pose into a vector of one pose
282  std::vector<geometry_msgs::Pose> ik_poses;
283  ik_poses.push_back(ik_pose);
284 
285  return searchPositionIK(ik_poses, ik_seed_state, timeout, consistency_limits, solution, solution_callback, error_code,
286  options);
287 }
288 
289 void MoveItOPWKinematicsPlugin::expandIKSolutions(std::vector<std::vector<double>>& solutions) const
290 {
291  const std::vector<const robot_model::JointModel*>& ajms = joint_model_group_->getActiveJointModels();
292  for (size_t i = 0; i < ajms.size(); ++i)
293  {
294  const robot_model::JointModel* jm = ajms[i];
295  if (jm->getVariableBounds().size() > 0)
296  {
297  for (auto& bounds : jm->getVariableBounds())
298  {
299  // todo: what to do about continuous joints
300  if (!bounds.position_bounded_)
301  continue;
302 
303  std::vector<std::vector<double>> additional_solutions;
304  for (auto& sol : solutions)
305  {
306  std::vector<double> down_sol(sol);
307  while (down_sol[i] - 2.0 * M_PI > bounds.min_position_)
308  {
309  down_sol[i] -= 2.0 * M_PI;
310  additional_solutions.push_back(down_sol);
311  }
312  std::vector<double> up_sol(sol);
313  while (up_sol[i] + 2.0 * M_PI < bounds.max_position_)
314  {
315  up_sol[i] += 2.0 * M_PI;
316  additional_solutions.push_back(up_sol);
317  }
318  }
319  ROS_DEBUG_STREAM_NAMED(LOGNAME,
320  "Found " << additional_solutions.size() << " additional solutions for j=" << i + 1);
321  solutions.insert(solutions.end(), additional_solutions.begin(), additional_solutions.end());
322  }
323  }
324  }
325 }
326 
327 bool MoveItOPWKinematicsPlugin::searchPositionIK(const std::vector<geometry_msgs::Pose>& ik_poses,
328  const std::vector<double>& ik_seed_state, double /*timeout*/,
329  const std::vector<double>& /*consistency_limits*/,
330  std::vector<double>& solution, const IKCallbackFn& solution_callback,
331  moveit_msgs::MoveItErrorCodes& error_code,
332  const kinematics::KinematicsQueryOptions& /*options*/) const
333 {
334  // Check if active
335  if (!active_)
336  {
337  ROS_ERROR_NAMED(LOGNAME, "kinematics not active");
338  error_code.val = error_code.NO_IK_SOLUTION;
339  return false;
340  }
341 
342  // Check if seed state correct
343  if (ik_seed_state.size() != dimension_)
344  {
345  ROS_ERROR_STREAM_NAMED(LOGNAME,
346  "Seed state must have size " << dimension_ << " instead of size " << ik_seed_state.size());
347  error_code.val = error_code.NO_IK_SOLUTION;
348  return false;
349  }
350 
351  // Check that we have the same number of poses as tips
352  if (tip_frames_.size() != ik_poses.size())
353  {
354  ROS_ERROR_STREAM_NAMED(LOGNAME, "Mismatched number of pose requests (" << ik_poses.size() << ") to tip frames ("
355  << tip_frames_.size()
356  << ") in searchPositionIK");
357  error_code.val = error_code.NO_IK_SOLUTION;
358  return false;
359  }
360 
361  Eigen::Isometry3d pose;
362  tf::poseMsgToEigen(ik_poses[0], pose);
363  std::vector<std::vector<double>> solutions;
364  if (!getAllIK(pose, solutions))
365  {
366  ROS_DEBUG_STREAM_NAMED(LOGNAME, "Failed to find IK solution");
367  error_code.val = error_code.NO_IK_SOLUTION;
368  return false;
369  }
370 
371  // for all solutions, check if solution +-360° is still inside limits
372  // An opw solution might be outside the joint limits, while the extended one is inside (e.g. asymmetric limits)
373  // therefore first extend solution space, then apply joint limits later
374  expandIKSolutions(solutions);
375 
376  ROS_DEBUG_STREAM_NAMED(LOGNAME, "Now have " << solutions.size() << " potential solutions");
377 
378  std::vector<LimitObeyingSol> limit_obeying_solutions;
379 
380  for (auto& sol : solutions)
381  {
382  robot_state_->setJointGroupPositions(joint_model_group_, sol);
383  // robot_state_->update(); // not required for checking bounds
384  if (!robot_state_->satisfiesBounds(joint_model_group_))
385  {
386  ROS_DEBUG_STREAM_NAMED(LOGNAME, "Solution is outside bounds");
387  continue;
388  }
389  limit_obeying_solutions.push_back({ sol, distance(sol, ik_seed_state) });
390  }
391 
392  if (limit_obeying_solutions.empty())
393  {
394  ROS_DEBUG_NAMED(LOGNAME, "None of the solutions is within joint limits");
395  return false;
396  }
397 
398  ROS_DEBUG_STREAM_NAMED(LOGNAME, "Solutions within limits: " << limit_obeying_solutions.size());
399 
400  // sort solutions by distance to seed state
401  std::sort(limit_obeying_solutions.begin(), limit_obeying_solutions.end());
402 
403  if (!solution_callback)
404  {
405  solution = limit_obeying_solutions.front().value;
406  return true;
407  }
408 
409  for (auto& sol : limit_obeying_solutions)
410  {
411  solution_callback(ik_poses[0], sol.value, error_code);
412  if (error_code.val == moveit_msgs::MoveItErrorCodes::SUCCESS)
413  {
414  solution = sol.value;
415  ROS_DEBUG_STREAM_NAMED(LOGNAME, "Solution passes callback");
416  return true;
417  }
418  }
419 
420  ROS_DEBUG_STREAM_NAMED(LOGNAME, "No solution fullfilled requirements of solution callback");
421  return false;
422 }
423 
424 bool MoveItOPWKinematicsPlugin::getPositionIK(const std::vector<geometry_msgs::Pose>& ik_poses,
425  const std::vector<double>& /*ik_seed_state*/,
426  std::vector<std::vector<double>>& solutions, KinematicsResult& /*result*/,
427  const kinematics::KinematicsQueryOptions& /*options*/) const
428 {
429  if (ik_poses.size() > 1 || ik_poses.size() == 0)
430  {
431  ROS_ERROR_STREAM_NAMED(LOGNAME, "You can only get all solutions for a single pose.");
432  return false;
433  }
434  Eigen::Isometry3d pose;
435  tf::poseMsgToEigen(ik_poses[0], pose);
436  return getAllIK(pose, solutions);
437 }
438 
439 bool MoveItOPWKinematicsPlugin::getPositionFK(const std::vector<std::string>& link_names,
440  const std::vector<double>& joint_angles,
441  std::vector<geometry_msgs::Pose>& poses) const
442 {
443  if (!active_)
444  {
445  ROS_ERROR_NAMED(LOGNAME, "kinematics not active");
446  return false;
447  }
448  poses.resize(link_names.size());
449  if (joint_angles.size() != dimension_)
450  {
451  ROS_ERROR_NAMED(LOGNAME, "Joint angles vector must have size: %d", dimension_);
452  return false;
453  }
454 
455  // Check that we have the same number of poses as tips
456  if (tip_frames_.size() != poses.size())
457  {
458  ROS_ERROR_STREAM_NAMED(LOGNAME, "Mismatched number of pose requests (" << poses.size() << ") to tip frames ("
459  << tip_frames_.size()
460  << ") in searchPositionFK");
461  return false;
462  }
463 
464  // forward function expect pointer to first element of array of joint values
465  // that is why &joint_angles[0] is passed
466  tf::poseEigenToMsg(opw_kinematics::forward(opw_parameters_, &joint_angles[0]), poses[0]);
467 
468  return true;
469 }
470 
471 const std::vector<std::string>& MoveItOPWKinematicsPlugin::getJointNames() const
472 {
473  return ik_group_info_.joint_names;
474 }
475 
476 const std::vector<std::string>& MoveItOPWKinematicsPlugin::getLinkNames() const
477 {
478  return ik_group_info_.link_names;
479 }
480 
481 const std::vector<std::string>& MoveItOPWKinematicsPlugin::getVariableNames() const
482 {
483  return joint_model_group_->getVariableNames();
484 }
485 
487 {
488  ROS_INFO_STREAM("Getting kinematic parameters from parameter server.");
489 
490  ros::NodeHandle nh;
491 
492  std::map<std::string, double> geometric_parameters;
493  if (!lookupParam("opw_kinematics_geometric_parameters", geometric_parameters, {}))
494  {
495  ROS_ERROR_STREAM("Failed to load geometric parameters for ik solver.");
496  return false;
497  }
498 
499  std::vector<double> joint_offsets;
500  if (!lookupParam("opw_kinematics_joint_offsets", joint_offsets, {}))
501  {
502  ROS_ERROR_STREAM("Failed to load joint offsets for ik solver.");
503  return false;
504  }
505 
506  std::vector<int> joint_sign_corrections;
507  if (!lookupParam("opw_kinematics_joint_sign_corrections", joint_sign_corrections, {}))
508  {
509  ROS_ERROR_STREAM("Failed to load joint sign corrections for ik solver.");
510  return false;
511  }
512 
513  opw_parameters_.a1 = geometric_parameters["a1"];
514  opw_parameters_.a2 = geometric_parameters["a2"];
515  opw_parameters_.b = geometric_parameters["b"];
516  opw_parameters_.c1 = geometric_parameters["c1"];
517  opw_parameters_.c2 = geometric_parameters["c2"];
518  opw_parameters_.c3 = geometric_parameters["c3"];
519  opw_parameters_.c4 = geometric_parameters["c4"];
520 
521  if (joint_offsets.size() != 6)
522  {
523  ROS_ERROR_STREAM("Expected joint_offsets to contain 6 elements, but it has " << joint_offsets.size() << ".");
524  return false;
525  }
526 
527  if (joint_sign_corrections.size() != 6)
528  {
529  ROS_ERROR_STREAM("Expected joint_sign_corrections to contain 6 elements, but it has "
530  << joint_sign_corrections.size() << ".");
531  return false;
532  }
533 
534  for (std::size_t i = 0; i < joint_offsets.size(); ++i)
535  {
536  opw_parameters_.offsets[i] = joint_offsets[i];
537  opw_parameters_.sign_corrections[i] = static_cast<signed char>(joint_sign_corrections[i]);
538  }
539 
540  ROS_INFO_STREAM("Loaded parameters for ik solver:\n" << opw_parameters_);
541 
542  return true;
543 }
544 
545 double MoveItOPWKinematicsPlugin::distance(const std::vector<double>& a, const std::vector<double>& b)
546 {
547  double cost = 0.0;
548  for (size_t i = 0; i < a.size(); ++i)
549  cost += std::abs(b[i] - a[i]);
550  return cost;
551 }
552 
553 // Compute the index of the closest joint pose in 'candidates' from 'target'
554 std::size_t MoveItOPWKinematicsPlugin::closestJointPose(const std::vector<double>& target,
555  const std::vector<std::vector<double>>& candidates)
556 {
557  size_t closest = 0; // index into candidates
558  double lowest_cost = std::numeric_limits<double>::max();
559  for (size_t i = 0; i < candidates.size(); ++i)
560  {
561  assert(target.size() == candidates[i].size());
562  double c = distance(target, candidates[i]);
563  if (c < lowest_cost)
564  {
565  closest = i;
566  lowest_cost = c;
567  }
568  }
569  return closest;
570 }
571 
572 bool MoveItOPWKinematicsPlugin::getAllIK(const Eigen::Isometry3d& pose,
573  std::vector<std::vector<double>>& joint_poses) const
574 {
575  joint_poses.clear();
576 
577  // Transform input pose
578  // needed if we introduce a tip frame different from tool0
579  // or a different base frame
580  // Eigen::Isometry3d tool_pose = diff_base.inverse() * pose *
581  // tip_frame.inverse();
582 
583  std::array<double, 6 * 8> sols;
584  opw_kinematics::inverse(opw_parameters_, pose, sols.data());
585 
586  // Check the output
587  std::vector<double> tmp(6); // temporary storage for API reasons
588  for (int i = 0; i < 8; i++)
589  {
590  double* sol = sols.data() + 6 * i;
591  if (opw_kinematics::isValid(sol))
592  {
594 
595  // TODO: make this better...
596  std::copy(sol, sol + 6, tmp.data());
597  // if (isValid(tmp))
598  // {
599  joint_poses.push_back(tmp);
600  // }
601  }
602  }
603 
604  return joint_poses.size() > 0;
605 }
606 
607 bool MoveItOPWKinematicsPlugin::getIK(const Eigen::Isometry3d& pose, const std::vector<double>& seed_state,
608  std::vector<double>& joint_pose) const
609 {
610  // Descartes Robot Model interface calls for 'closest' point to seed position
611  std::vector<std::vector<double>> joint_poses;
612  if (!getAllIK(pose, joint_poses))
613  return false;
614  // Find closest joint pose; getAllIK() does isValid checks already
615  joint_pose = joint_poses[closestJointPose(seed_state, joint_poses)];
616  return true;
617 }
618 
619 } // namespace moveit_opw_kinematics_plugin
std::vector< unsigned int > redundant_joint_indices_
static std::size_t closestJointPose(const std::vector< double > &target, const std::vector< std::vector< double >> &candidates)
const std::vector< std::string > & getJointNames() const override
Return all the joint names in the order they are used internally.
const std::vector< std::string > & getVariableNames() const
Return all the variable names in the order they are represented internally.
#define ROS_DEBUG_STREAM_NAMED(name, args)
#define ROS_ERROR_STREAM_NAMED(name, args)
virtual bool getPositionFK(const std::vector< std::string > &link_names, const std::vector< double > &joint_angles, std::vector< geometry_msgs::Pose > &poses) const override
const std::vector< std::string > & getLinkNames() const override
Return all the link names in the order they are represented internally.
void poseEigenToMsg(const Eigen::Affine3d &e, geometry_msgs::Pose &m)
void poseMsgToEigen(const geometry_msgs::Pose &m, Eigen::Affine3d &e)
bool getIK(const Eigen::Isometry3d &pose, const std::vector< double > &seed_state, std::vector< double > &joint_pose) const
std::vector< std::string > tip_frames_
const double TOLERANCE
moveit::core::RobotModelConstPtr robot_model_
#define ROS_INFO_STREAM_NAMED(name, args)
#define M_PI
bool comparePoses(Eigen::Isometry3d &Ta, Eigen::Isometry3d &Tb)
check if two poses are the same within an absolute tolerance of 1e-6
virtual bool searchPositionIK(const geometry_msgs::Pose &ik_pose, const std::vector< double > &ik_seed_state, double timeout, std::vector< double > &solution, moveit_msgs::MoveItErrorCodes &error_code, const kinematics::KinematicsQueryOptions &options=kinematics::KinematicsQueryOptions()) const override
bool isValid(const T *qs)
Definition: opw_utilities.h:10
void harmonizeTowardZero(T *qs)
Definition: opw_utilities.h:17
virtual bool getPositionIK(const geometry_msgs::Pose &ik_pose, const std::vector< double > &ik_seed_state, std::vector< double > &solution, moveit_msgs::MoveItErrorCodes &error_code, const kinematics::KinematicsQueryOptions &options=kinematics::KinematicsQueryOptions()) const override
#define ROS_DEBUG_NAMED(name,...)
Specific implementation of kinematics using ROS service calls to communicate with external IK solvers...
void storeValues(const moveit::core::RobotModel &robot_model, const std::string &group_name, const std::string &base_frame, const std::vector< std::string > &tip_frames, double search_discretization)
bool lookupParam(const std::string &param, T &val, const T &default_val) const
signed char sign_corrections[6]
static double distance(const std::vector< double > &a, const std::vector< double > &b)
bool timedOut(const ros::WallTime &start_time, double duration) const
boost::function< void(const geometry_msgs::Pose &ik_pose, const std::vector< double > &ik_solution, moveit_msgs::MoveItErrorCodes &error_code)> IKCallbackFn
bool getAllIK(const Eigen::Isometry3d &pose, std::vector< std::vector< double >> &joint_poses) const
#define ROS_INFO_STREAM(args)
#define CLASS_LOADER_REGISTER_CLASS(Derived, Base)
static WallTime now()
bool selfTest(const std::vector< double > &joint_angles)
check forward and inverse kinematics consistency
void expandIKSolutions(std::vector< std::vector< double >> &solutions) const
append IK solutions by adding +-2pi
virtual bool setRedundantJoints(const std::vector< unsigned int > &redundant_joint_indices) override
#define ROS_ERROR_NAMED(name,...)
virtual bool initialize(const moveit::core::RobotModel &robot_model, const std::string &group_name, const std::string &base_frame, const std::vector< std::string > &tip_frames, double search_discretization) override
#define ROS_ERROR_STREAM(args)
void inverse(const Parameters< T > &params, const Transform< T > &pose, T *out) noexcept
Computes up to 8 kinematically unique joint solutions that put the tool flange of the robot described...
Transform< T > forward(const Parameters< T > &p, const T *qs) noexcept
Computes the tool pose of the robot described by when said robot has the joint positions given by qs...


moveit_opw_kinematics_plugin
Author(s): Jeroen De Maeyer, Simon Schmeisser (isys vision)
autogenerated on Mon Feb 28 2022 22:50:11