kdl_kinematics_plugin.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2012, 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, David Lu!!, Ugo Cupcic */
36 
39 
40 #include <tf2_kdl/tf2_kdl.h>
42 
44 #include <kdl/chainfksolverpos_recursive.hpp>
45 #include <kdl/frames_io.hpp>
46 #include <kdl/kinfam_io.hpp>
47 
48 // register KDLKinematics as a KinematicsBase implementation
51 
52 namespace kdl_kinematics_plugin
53 {
54 KDLKinematicsPlugin::KDLKinematicsPlugin() : initialized_(false)
55 {
56 }
57 
58 void KDLKinematicsPlugin::getRandomConfiguration(Eigen::VectorXd& jnt_array) const
59 {
60  state_->setToRandomPositions(joint_model_group_);
61  state_->copyJointGroupPositions(joint_model_group_, &jnt_array[0]);
62 }
63 
64 void KDLKinematicsPlugin::getRandomConfiguration(const Eigen::VectorXd& seed_state,
65  const std::vector<double>& consistency_limits,
66  Eigen::VectorXd& jnt_array) const
67 {
68  joint_model_group_->getVariableRandomPositionsNearBy(state_->getRandomNumberGenerator(), &jnt_array[0],
69  &seed_state[0], consistency_limits);
70 }
71 
72 bool KDLKinematicsPlugin::checkConsistency(const Eigen::VectorXd& seed_state,
73  const std::vector<double>& consistency_limits,
74  const Eigen::VectorXd& solution) const
75 {
76  for (std::size_t i = 0; i < dimension_; ++i)
77  if (fabs(seed_state(i) - solution(i)) > consistency_limits[i])
78  return false;
79  return true;
80 }
81 
82 void KDLKinematicsPlugin::getJointWeights()
83 {
84  const std::vector<std::string>& active_names = joint_model_group_->getActiveJointModelNames();
85  std::vector<std::string> names;
86  std::vector<double> weights;
87  if (lookupParam("joint_weights/weights", weights, weights))
88  {
89  if (!lookupParam("joint_weights/names", names, names) || names.size() != weights.size())
90  {
91  ROS_ERROR_NAMED("kdl", "Expecting list parameter joint_weights/names of same size as list joint_weights/weights");
92  // fall back to default weights
93  weights.clear();
94  }
95  }
96  else if (lookupParam("joint_weights", weights, weights)) // try reading weight lists (for all active joints) directly
97  {
98  std::size_t num_active = active_names.size();
99  if (weights.size() == num_active)
100  {
101  joint_weights_ = weights;
102  return;
103  }
104  else if (!weights.empty())
105  {
106  ROS_ERROR_NAMED("kdl", "Expecting parameter joint_weights to list weights for all active joints (%zu) in order",
107  num_active);
108  // fall back to default weights
109  weights.clear();
110  }
111  }
112 
113  // by default assign weights of 1.0 to all joints
114  joint_weights_ = std::vector<double>(active_names.size(), 1.0);
115  if (weights.empty()) // indicates default case
116  return;
117 
118  // modify weights of listed joints
119  assert(names.size() == weights.size());
120  for (size_t i = 0; i != names.size(); ++i)
121  {
122  auto it = std::find(active_names.begin(), active_names.end(), names[i]);
123  if (it == active_names.cend())
124  ROS_WARN_NAMED("kdl", "Joint '%s' is not an active joint in group '%s'", names[i].c_str(),
125  joint_model_group_->getName().c_str());
126  else if (weights[i] < 0.0)
127  ROS_WARN_NAMED("kdl", "Negative weight %f for joint '%s' will be ignored", weights[i], names[i].c_str());
128  else
129  joint_weights_[it - active_names.begin()] = weights[i];
130  }
132  "kdl", "Joint weights for group '"
133  << getGroupName() << "': \n"
134  << Eigen::Map<const Eigen::VectorXd>(joint_weights_.data(), joint_weights_.size()).transpose());
135 }
136 
137 bool KDLKinematicsPlugin::initialize(const moveit::core::RobotModel& robot_model, const std::string& group_name,
138  const std::string& base_frame, const std::vector<std::string>& tip_frames,
139  double search_discretization)
140 {
141  storeValues(robot_model, group_name, base_frame, tip_frames, search_discretization);
142  joint_model_group_ = robot_model_->getJointModelGroup(group_name);
143  if (!joint_model_group_)
144  return false;
145 
146  if (!joint_model_group_->isChain())
147  {
148  ROS_ERROR_NAMED("kdl", "Group '%s' is not a chain", group_name.c_str());
149  return false;
150  }
151  if (!joint_model_group_->isSingleDOFJoints())
152  {
153  ROS_ERROR_NAMED("kdl", "Group '%s' includes joints that have more than 1 DOF", group_name.c_str());
154  return false;
155  }
156 
157  KDL::Tree kdl_tree;
158 
159  if (!kdl_parser::treeFromUrdfModel(*robot_model.getURDF(), kdl_tree))
160  {
161  ROS_ERROR_NAMED("kdl", "Could not initialize tree object");
162  return false;
163  }
164  if (!kdl_tree.getChain(base_frame_, getTipFrame(), kdl_chain_))
165  {
166  ROS_ERROR_NAMED("kdl", "Could not initialize chain object");
167  return false;
168  }
169 
170  dimension_ = joint_model_group_->getActiveJointModels().size() + joint_model_group_->getMimicJointModels().size();
171  for (std::size_t i = 0; i < joint_model_group_->getJointModels().size(); ++i)
172  {
173  if (joint_model_group_->getJointModels()[i]->getType() == moveit::core::JointModel::REVOLUTE ||
174  joint_model_group_->getJointModels()[i]->getType() == moveit::core::JointModel::PRISMATIC)
175  {
176  solver_info_.joint_names.push_back(joint_model_group_->getJointModelNames()[i]);
177  const std::vector<moveit_msgs::JointLimits>& jvec =
178  joint_model_group_->getJointModels()[i]->getVariableBoundsMsg();
179  solver_info_.limits.insert(solver_info_.limits.end(), jvec.begin(), jvec.end());
180  }
181  }
182 
183  if (!joint_model_group_->hasLinkModel(getTipFrame()))
184  {
185  ROS_ERROR_NAMED("kdl", "Could not find tip name in joint group '%s'", group_name.c_str());
186  return false;
187  }
188  solver_info_.link_names.push_back(getTipFrame());
189 
190  joint_min_.resize(solver_info_.limits.size());
191  joint_max_.resize(solver_info_.limits.size());
192 
193  for (unsigned int i = 0; i < solver_info_.limits.size(); i++)
194  {
195  joint_min_(i) = solver_info_.limits[i].min_position;
196  joint_max_(i) = solver_info_.limits[i].max_position;
197  }
198 
199  // Get Solver Parameters
200  lookupParam("max_solver_iterations", max_solver_iterations_, 500);
201  lookupParam("epsilon", epsilon_, 1e-5);
202  lookupParam("orientation_vs_position", orientation_vs_position_weight_, 1.0);
203 
204  bool position_ik;
205  lookupParam("position_only_ik", position_ik, false);
206  if (position_ik) // position_only_ik overrules orientation_vs_position
207  orientation_vs_position_weight_ = 0.0;
208  if (orientation_vs_position_weight_ == 0.0)
209  ROS_INFO_NAMED("kdl", "Using position only ik");
210 
211  getJointWeights();
212 
213  // Check for mimic joints
214  unsigned int joint_counter = 0;
215  for (std::size_t i = 0; i < kdl_chain_.getNrOfSegments(); ++i)
216  {
217  const moveit::core::JointModel* jm = robot_model_->getJointModel(kdl_chain_.segments[i].getJoint().getName());
218 
219  // first check whether it belongs to the set of active joints in the group
220  if (jm->getMimic() == nullptr && jm->getVariableCount() > 0)
221  {
222  JointMimic mimic_joint;
223  mimic_joint.reset(joint_counter);
224  mimic_joint.joint_name = kdl_chain_.segments[i].getJoint().getName();
225  mimic_joint.active = true;
226  mimic_joints_.push_back(mimic_joint);
227  ++joint_counter;
228  continue;
229  }
230  if (joint_model_group_->hasJointModel(jm->getName()))
231  {
232  if (jm->getMimic() && joint_model_group_->hasJointModel(jm->getMimic()->getName()))
233  {
234  JointMimic mimic_joint;
235  mimic_joint.joint_name = kdl_chain_.segments[i].getJoint().getName();
236  mimic_joint.offset = jm->getMimicOffset();
237  mimic_joint.multiplier = jm->getMimicFactor();
238  mimic_joints_.push_back(mimic_joint);
239  continue;
240  }
241  }
242  }
243  for (JointMimic& mimic_joint : mimic_joints_)
244  {
245  if (!mimic_joint.active)
246  {
247  const moveit::core::JointModel* joint_model =
248  joint_model_group_->getJointModel(mimic_joint.joint_name)->getMimic();
249  for (JointMimic& mimic_joint_recal : mimic_joints_)
250  {
251  if (mimic_joint_recal.joint_name == joint_model->getName())
252  {
253  mimic_joint.map_index = mimic_joint_recal.map_index;
254  }
255  }
256  }
257  }
258 
259  // Setup the joint state groups that we need
260  state_ = std::make_shared<moveit::core::RobotState>(robot_model_);
261 
262  fk_solver_ = std::make_unique<KDL::ChainFkSolverPos_recursive>(kdl_chain_);
263 
264  initialized_ = true;
265  ROS_DEBUG_NAMED("kdl", "KDL solver initialized");
266  return true;
267 }
268 
269 bool KDLKinematicsPlugin::timedOut(const ros::WallTime& start_time, double duration) const
270 {
271  return ((ros::WallTime::now() - start_time).toSec() >= duration);
272 }
273 
274 bool KDLKinematicsPlugin::getPositionIK(const geometry_msgs::Pose& ik_pose, const std::vector<double>& ik_seed_state,
275  std::vector<double>& solution, moveit_msgs::MoveItErrorCodes& error_code,
276  const kinematics::KinematicsQueryOptions& options) const
277 {
278  std::vector<double> consistency_limits;
279 
280  // limit search to a single attempt by setting a timeout of zero
281  return searchPositionIK(ik_pose, ik_seed_state, 0.0, consistency_limits, solution, IKCallbackFn(), error_code,
282  options);
283 }
284 
285 bool KDLKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose& ik_pose, const std::vector<double>& ik_seed_state,
286  double timeout, std::vector<double>& solution,
287  moveit_msgs::MoveItErrorCodes& error_code,
288  const kinematics::KinematicsQueryOptions& options) const
289 {
290  std::vector<double> consistency_limits;
291 
292  return searchPositionIK(ik_pose, ik_seed_state, timeout, consistency_limits, solution, IKCallbackFn(), error_code,
293  options);
294 }
295 
296 bool KDLKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose& ik_pose, const std::vector<double>& ik_seed_state,
297  double timeout, const std::vector<double>& consistency_limits,
298  std::vector<double>& solution, moveit_msgs::MoveItErrorCodes& error_code,
299  const kinematics::KinematicsQueryOptions& options) const
300 {
301  return searchPositionIK(ik_pose, ik_seed_state, timeout, consistency_limits, solution, IKCallbackFn(), error_code,
302  options);
303 }
304 
305 bool KDLKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose& ik_pose, const std::vector<double>& ik_seed_state,
306  double timeout, std::vector<double>& solution,
307  const IKCallbackFn& solution_callback,
308  moveit_msgs::MoveItErrorCodes& error_code,
309  const kinematics::KinematicsQueryOptions& options) const
310 {
311  std::vector<double> consistency_limits;
312  return searchPositionIK(ik_pose, ik_seed_state, timeout, consistency_limits, solution, solution_callback, error_code,
313  options);
314 }
315 
316 bool KDLKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose& ik_pose, const std::vector<double>& ik_seed_state,
317  double timeout, const std::vector<double>& consistency_limits,
318  std::vector<double>& solution, const IKCallbackFn& solution_callback,
319  moveit_msgs::MoveItErrorCodes& error_code,
320  const kinematics::KinematicsQueryOptions& options) const
321 {
322  ros::WallTime start_time = ros::WallTime::now();
323  if (!initialized_)
324  {
325  ROS_ERROR_NAMED("kdl", "kinematics solver not initialized");
326  error_code.val = error_code.NO_IK_SOLUTION;
327  return false;
328  }
329 
330  if (ik_seed_state.size() != dimension_)
331  {
333  "Seed state must have size " << dimension_ << " instead of size " << ik_seed_state.size());
334  error_code.val = error_code.NO_IK_SOLUTION;
335  return false;
336  }
337 
338  // Resize consistency limits to remove mimic joints
339  std::vector<double> consistency_limits_mimic;
340  if (!consistency_limits.empty())
341  {
342  if (consistency_limits.size() != dimension_)
343  {
344  ROS_ERROR_STREAM_NAMED("kdl", "Consistency limits must be empty or have size "
345  << dimension_ << " instead of size " << consistency_limits.size());
346  error_code.val = error_code.NO_IK_SOLUTION;
347  return false;
348  }
349 
350  for (std::size_t i = 0; i < dimension_; ++i)
351  {
352  if (mimic_joints_[i].active)
353  consistency_limits_mimic.push_back(consistency_limits[i]);
354  }
355  }
356  Eigen::Matrix<double, 6, 1> cartesian_weights;
357  cartesian_weights.topRows<3>().setConstant(1.0);
358  cartesian_weights.bottomRows<3>().setConstant(orientation_vs_position_weight_);
359 
360  KDL::JntArray jnt_seed_state(dimension_);
361  KDL::JntArray jnt_pos_in(dimension_);
362  KDL::JntArray jnt_pos_out(dimension_);
363  jnt_seed_state.data = Eigen::Map<const Eigen::VectorXd>(ik_seed_state.data(), ik_seed_state.size());
364  jnt_pos_in = jnt_seed_state;
365 
366  KDL::ChainIkSolverVelMimicSVD ik_solver_vel(kdl_chain_, mimic_joints_, orientation_vs_position_weight_ == 0.0);
367  solution.resize(dimension_);
368 
369  KDL::Frame pose_desired;
370  tf2::fromMsg(ik_pose, pose_desired);
371 
372  ROS_DEBUG_STREAM_NAMED("kdl", "searchPositionIK: Position request pose is "
373  << ik_pose.position.x << " " << ik_pose.position.y << " " << ik_pose.position.z
374  << " " << ik_pose.orientation.x << " " << ik_pose.orientation.y << " "
375  << ik_pose.orientation.z << " " << ik_pose.orientation.w);
376 
377  unsigned int attempt = 0;
378  do
379  {
380  ++attempt;
381  if (attempt > 1) // randomly re-seed after first attempt
382  {
383  if (!consistency_limits_mimic.empty())
384  getRandomConfiguration(jnt_seed_state.data, consistency_limits_mimic, jnt_pos_in.data);
385  else
386  getRandomConfiguration(jnt_pos_in.data);
387  ROS_DEBUG_STREAM_NAMED("kdl", "New random configuration (" << attempt << "): " << jnt_pos_in);
388  }
389 
390  int ik_valid =
391  CartToJnt(ik_solver_vel, jnt_pos_in, pose_desired, jnt_pos_out, max_solver_iterations_,
392  Eigen::Map<const Eigen::VectorXd>(joint_weights_.data(), joint_weights_.size()), cartesian_weights);
393  if (ik_valid == 0 || options.return_approximate_solution) // found acceptable solution
394  {
395  if (!consistency_limits_mimic.empty() &&
396  !checkConsistency(jnt_seed_state.data, consistency_limits_mimic, jnt_pos_out.data))
397  continue;
398 
399  Eigen::Map<Eigen::VectorXd>(solution.data(), solution.size()) = jnt_pos_out.data;
400  if (!solution_callback.empty())
401  {
402  solution_callback(ik_pose, solution, error_code);
403  if (error_code.val != error_code.SUCCESS)
404  continue;
405  }
406 
407  // solution passed consistency check and solution callback
408  error_code.val = error_code.SUCCESS;
409  ROS_DEBUG_STREAM_NAMED("kdl", "Solved after " << (ros::WallTime::now() - start_time).toSec() << " < " << timeout
410  << "s and " << attempt << " attempts");
411  return true;
412  }
413  } while (!timedOut(start_time, timeout));
414 
415  ROS_DEBUG_STREAM_NAMED("kdl", "IK timed out after " << (ros::WallTime::now() - start_time).toSec() << " > " << timeout
416  << "s and " << attempt << " attempts");
417  error_code.val = error_code.TIMED_OUT;
418  return false;
419 }
420 
421 // NOLINTNEXTLINE(readability-identifier-naming)
422 int KDLKinematicsPlugin::CartToJnt(KDL::ChainIkSolverVelMimicSVD& ik_solver, const KDL::JntArray& q_init,
423  const KDL::Frame& p_in, KDL::JntArray& q_out, const unsigned int max_iter,
424  const Eigen::VectorXd& joint_weights, const Twist& cartesian_weights) const
425 {
426  double last_delta_twist_norm = DBL_MAX;
427  double step_size = 1.0;
428  KDL::Frame f;
429  KDL::Twist delta_twist;
430  KDL::JntArray delta_q(q_out.rows()), q_backup(q_out.rows());
431  Eigen::ArrayXd extra_joint_weights(joint_weights.rows());
432  extra_joint_weights.setOnes();
433 
434  q_out = q_init;
435  ROS_DEBUG_STREAM_NAMED("kdl", "Input: " << q_init);
436 
437  unsigned int i;
438  bool success = false;
439  for (i = 0; i < max_iter; ++i)
440  {
441  fk_solver_->JntToCart(q_out, f);
442  delta_twist = diff(f, p_in);
443  ROS_DEBUG_STREAM_NAMED("kdl", "[" << std::setw(3) << i << "] delta_twist: " << delta_twist);
444 
445  // check norms of position and orientation errors
446  const double position_error = delta_twist.vel.Norm();
447  const double orientation_error = ik_solver.isPositionOnly() ? 0 : delta_twist.rot.Norm();
448  const double delta_twist_norm = std::max(position_error, orientation_error);
449  if (delta_twist_norm <= epsilon_)
450  {
451  success = true;
452  break;
453  }
454 
455  if (delta_twist_norm >= last_delta_twist_norm)
456  {
457  // if the error increased, we are close to a singularity -> reduce step size
458  double old_step_size = step_size;
459  step_size *= std::min(0.2, last_delta_twist_norm / delta_twist_norm); // reduce scale;
460  KDL::Multiply(delta_q, step_size / old_step_size, delta_q);
461  ROS_DEBUG_NAMED("kdl", " error increased: %f -> %f, scale: %f", last_delta_twist_norm, delta_twist_norm,
462  step_size);
463  q_out = q_backup; // restore previous unclipped joint values
464  }
465  else
466  {
467  q_backup = q_out; // remember joint values of last successful step
468  step_size = 1.0; // reset step size
469  last_delta_twist_norm = delta_twist_norm;
470 
471  ik_solver.CartToJnt(q_out, delta_twist, delta_q, extra_joint_weights * joint_weights.array(), cartesian_weights);
472  }
473 
474  clipToJointLimits(q_out, delta_q, extra_joint_weights);
475 
476  const double delta_q_norm = delta_q.data.lpNorm<1>();
477  ROS_DEBUG_NAMED("kdl", "[%3d] pos err: %f rot err: %f delta_q: %f", i, position_error, orientation_error,
478  delta_q_norm);
479  if (delta_q_norm < epsilon_) // stuck in singularity
480  {
481  if (step_size < epsilon_) // cannot reach target
482  break;
483  // wiggle joints
484  last_delta_twist_norm = DBL_MAX;
485  delta_q.data.setRandom();
486  delta_q.data *= std::min(0.1, delta_twist_norm);
487  clipToJointLimits(q_out, delta_q, extra_joint_weights);
488  extra_joint_weights.setOnes();
489  }
490 
491  KDL::Add(q_out, delta_q, q_out);
492 
493  ROS_DEBUG_STREAM_NAMED("kdl", " delta_q: " << delta_q);
494  ROS_DEBUG_STREAM_NAMED("kdl", " q: " << q_out);
495  }
496 
497  int result = (i == max_iter) ? -3 : (success ? 0 : -2);
498  ROS_DEBUG_STREAM_NAMED("kdl", "Result " << result << " after " << i << " iterations: " << q_out);
499 
500  return result;
501 }
502 
503 void KDLKinematicsPlugin::clipToJointLimits(const KDL::JntArray& q, KDL::JntArray& q_delta,
504  Eigen::ArrayXd& weighting) const
505 {
506  weighting.setOnes();
507  for (std::size_t i = 0; i < q.rows(); ++i)
508  {
509  const double delta_max = joint_max_(i) - q(i);
510  const double delta_min = joint_min_(i) - q(i);
511  if (q_delta(i) > delta_max)
512  q_delta(i) = delta_max;
513  else if (q_delta(i) < delta_min)
514  q_delta(i) = delta_min;
515  else
516  continue;
517 
518  weighting[mimic_joints_[i].map_index] = 0.01;
519  }
520 }
521 
522 bool KDLKinematicsPlugin::getPositionFK(const std::vector<std::string>& link_names,
523  const std::vector<double>& joint_angles,
524  std::vector<geometry_msgs::Pose>& poses) const
525 {
526  if (!initialized_)
527  {
528  ROS_ERROR_NAMED("kdl", "kinematics solver not initialized");
529  return false;
530  }
531  poses.resize(link_names.size());
532  if (joint_angles.size() != dimension_)
533  {
534  ROS_ERROR_NAMED("kdl", "Joint angles vector must have size: %d", dimension_);
535  return false;
536  }
537 
538  KDL::Frame p_out;
539  KDL::JntArray jnt_pos_in(dimension_);
540  jnt_pos_in.data = Eigen::Map<const Eigen::VectorXd>(joint_angles.data(), joint_angles.size());
541 
542  bool valid = true;
543  for (unsigned int i = 0; i < poses.size(); i++)
544  {
545  if (fk_solver_->JntToCart(jnt_pos_in, p_out) >= 0)
546  {
547  poses[i] = tf2::toMsg(p_out);
548  }
549  else
550  {
551  ROS_ERROR_NAMED("kdl", "Could not compute FK for %s", link_names[i].c_str());
552  valid = false;
553  }
554  }
555  return valid;
556 }
557 
558 const std::vector<std::string>& KDLKinematicsPlugin::getJointNames() const
559 {
560  return solver_info_.joint_names;
561 }
562 
563 const std::vector<std::string>& KDLKinematicsPlugin::getLinkNames() const
564 {
565  return solver_info_.link_names;
566 }
567 
568 } // namespace kdl_kinematics_plugin
CLASS_LOADER_REGISTER_CLASS
#define CLASS_LOADER_REGISTER_CLASS(Derived, Base)
kinematics::KinematicsQueryOptions::return_approximate_solution
bool return_approximate_solution
moveit::core::JointModel::getVariableCount
std::size_t getVariableCount() const
moveit::core::JointModel::getMimicOffset
double getMimicOffset() const
duration
std::chrono::system_clock::duration duration
moveit::core::RobotModel::getURDF
const urdf::ModelInterfaceSharedPtr & getURDF() const
tf2::fromMsg
void fromMsg(const A &, B &b)
ROS_DEBUG_STREAM_NAMED
#define ROS_DEBUG_STREAM_NAMED(name, args)
kdl_kinematics_plugin.h
moveit::core::RobotModel
moveit::core::JointModel::getName
const std::string & getName() const
moveit::core::JointModel::getMimicFactor
double getMimicFactor() const
KDL::ChainIkSolverVelMimicSVD::isPositionOnly
bool isPositionOnly() const
Return true iff we ignore orientation but only consider position for inverse kinematics.
Definition: chainiksolver_vel_mimic_svd.hpp:97
ROS_ERROR_NAMED
#define ROS_ERROR_NAMED(name,...)
kdl_kinematics_plugin
Definition: joint_mimic.hpp:39
moveit::core::JointModel::PRISMATIC
PRISMATIC
kinematics::KinematicsBase::IKCallbackFn
boost::function< void(const geometry_msgs::Pose &, const std::vector< double > &, moveit_msgs::MoveItErrorCodes &)> IKCallbackFn
kdl_parser::treeFromUrdfModel
KDL_PARSER_PUBLIC bool treeFromUrdfModel(const urdf::ModelInterface &robot_model, KDL::Tree &tree)
chainiksolver_vel_mimic_svd.hpp
kdl_kinematics_plugin::KDLKinematicsPlugin::KDLKinematicsPlugin
KDLKinematicsPlugin()
Default constructor.
Definition: kdl_kinematics_plugin.cpp:86
moveit::core::JointModel::REVOLUTE
REVOLUTE
ROS_INFO_NAMED
#define ROS_INFO_NAMED(name,...)
kinematics::KinematicsBase
ROS_DEBUG_NAMED
#define ROS_DEBUG_NAMED(name,...)
ros::WallTime::now
static WallTime now()
ROS_ERROR_STREAM_NAMED
#define ROS_ERROR_STREAM_NAMED(name, args)
tf2_kdl.h
class_loader.hpp
ros::WallTime
KDL::ChainIkSolverVelMimicSVD
Definition: chainiksolver_vel_mimic_svd.hpp:46
kdl_kinematics_plugin::KDLKinematicsPlugin
Specific implementation of kinematics using KDL. This version supports any kinematic chain,...
Definition: kdl_kinematics_plugin.h:72
kdl_parser.hpp
round_collada_numbers.f
f
Definition: round_collada_numbers.py:114
transform_datatypes.h
KDL::ChainIkSolverVelMimicSVD::CartToJnt
int CartToJnt(const JntArray &q_in, const Twist &v_in, JntArray &qdot_out) override
Definition: chainiksolver_vel_mimic_svd.hpp:76
moveit::core::JointModel::getMimic
const JointModel * getMimic() const
kinematics::KinematicsQueryOptions
ROS_WARN_NAMED
#define ROS_WARN_NAMED(name,...)
ROS_INFO_STREAM_NAMED
#define ROS_INFO_STREAM_NAMED(name, args)
tf2::toMsg
B toMsg(const A &a)
moveit::core::JointModel


moveit_kinematics
Author(s): Dave Coleman , Ioan Sucan , Sachin Chitta
autogenerated on Sat Apr 27 2024 02:26:15