hand_kinematics_coupling.cpp
Go to the documentation of this file.
1 /*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2008, 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 // majority of this code comes from package urdf_tool/arm_kinematics
35 // written by David Lu!!
36 // Copyright David Lu <David Lu>
37 //
38 // Modified by Juan A. Corrales, ISIR, UPMC
39 // -Added support for coupled joints of Shadow Hand. Now, the coupling is a fixed 1:1 value
40 // but the updateCoupling functions can be modified in order to implement dynamic coupling
41 // (which can be modified depending on the values of the joint values of the finger).
42 // -Use of WDLS velocity IK method in order to solve IK only for 3D position.
43 // -IK is solved at the fingertip frame, which should be defined in the URDF/Xacro file of the
44 // Shadow Hand.
45 
46 #include <cmath>
47 #include <ros/ros.h>
48 #include <tf/transform_listener.h>
49 #include <tf_conversions/tf_kdl.h>
50 #include <tf/transform_datatypes.h>
52 #include <kdl/jntarray.hpp>
54 #include <kdl/chainfksolverpos_recursive.hpp>
57 #include <moveit_msgs/GetPositionFK.h>
58 #include <moveit_msgs/GetPositionIK.h>
59 #include <moveit_msgs/KinematicSolverInfo.h>
60 #include <sr_utilities/sr_math_utils.hpp>
61 #include <urdf/model.h>
62 #include <string>
63 #include <vector>
64 
65 using std::string;
66 
67 static const std::string IK_SERVICE = "get_ik";
68 static const std::string FK_SERVICE = "get_fk";
69 
70 #define IK_EPS 1e-5
71 
72 Eigen::MatrixXd updateCouplingFF(const KDL::JntArray &q)
73 {
74  Eigen::MatrixXd cm(4, 3);
75  for (unsigned int i = 0; i < 4; i++)
76  {
77  for (unsigned int j = 0; j < 3; j++)
78  {
79  cm(i, j) = 0.0;
80  }
81  }
82 
83  cm(0, 0) = 1.0; // J4
84  cm(1, 1) = 1.0; // J3
85  cm(2, 2) = 1.0; // J2
86  cm(3, 2) = 1.0; // J1
87 
88  return cm;
89 }
90 
91 Eigen::MatrixXd updateCouplingMF(const KDL::JntArray &q)
92 {
93  Eigen::MatrixXd cm(4, 3);
94  for (unsigned int i = 0; i < 4; i++)
95  {
96  for (unsigned int j = 0; j < 3; j++)
97  {
98  cm(i, j) = 0.0;
99  }
100  }
101 
102  cm(0, 0) = 1.0; // J4
103  cm(1, 1) = 1.0; // J3
104  cm(2, 2) = 1.0; // J2
105  cm(3, 2) = 1.0; // J1
106 
107  return cm;
108 }
109 
110 Eigen::MatrixXd updateCouplingRF(const KDL::JntArray &q)
111 {
112  Eigen::MatrixXd cm(4, 3);
113  for (unsigned int i = 0; i < 4; i++)
114  {
115  for (unsigned int j = 0; j < 3; j++)
116  {
117  cm(i, j) = 0.0;
118  }
119  }
120 
121  cm(0, 0) = 1.0; // J4
122  cm(1, 1) = 1.0; // J3
123  cm(2, 2) = 1.0; // J2
124  cm(3, 2) = 1.0; // J1
125 
126  return cm;
127 }
128 
129 Eigen::MatrixXd updateCouplingLF(const KDL::JntArray &q)
130 {
131  Eigen::MatrixXd cm(5, 4);
132  for (unsigned int i = 0; i < 5; i++)
133  {
134  for (unsigned int j = 0; j < 4; j++)
135  {
136  cm(i, j) = 0.0;
137  }
138  }
139 
140  cm(0, 0) = 1.0; // J5
141  cm(1, 1) = 1.0; // J4
142  cm(2, 2) = 1.0; // J3
143  cm(3, 3) = 1.0; // J2
144  cm(4, 3) = 1.0; // J1
145 
146  return cm;
147 }
148 
149 Eigen::MatrixXd updateCouplingTH(const KDL::JntArray &q)
150 {
151  // There is no coupling in the thumb. So the coupling matrix is the identity matrix
152  return Eigen::MatrixXd::Identity(5, 5);
153 }
154 
156 {
157 public:
158  Kinematics();
159 
160  bool init();
161 
162 private:
167  unsigned int num_joints;
168 
172 
175 
177 
178  moveit_msgs::KinematicSolverInfo info;
179 
180  bool loadModel(const std::string xml);
181 
182  bool readJoints(urdf::Model &robot_model);
183 
184  int getJointIndex(const std::string &name);
185 
186  int getKDLSegmentIndex(const std::string &name);
187 
193  bool getPositionIK(moveit_msgs::GetPositionIK::Request &request,
194  moveit_msgs::GetPositionIK::Response &response);
195 
201  void generateRandomJntSeed(KDL::JntArray &jnt_pos_in);
202 
208  bool getPositionFK(moveit_msgs::GetPositionFK::Request &request,
209  moveit_msgs::GetPositionFK::Response &response);
210 };
211 
212 
214 {
215 }
216 
218 {
219  // Get URDF XML
220  std::string urdf_xml, full_urdf_xml;
221  nh.param("urdf_xml", urdf_xml, std::string("robot_description"));
222  nh.searchParam(urdf_xml, full_urdf_xml);
223  ROS_DEBUG("Reading xml file from parameter server");
224  std::string result;
225  if (!nh.getParam(full_urdf_xml, result))
226  {
227  ROS_FATAL("Could not load the xml from parameter server: %s", urdf_xml.c_str());
228  return false;
229  }
230 
231  // Get Root and Tip From Parameter Service
232  if (!nh_private.getParam("root_name", root_name))
233  {
234  ROS_FATAL("GenericIK: No root name found on parameter server");
235  return false;
236  }
237  if (root_name.find("palm") == string::npos)
238  {
239  ROS_FATAL("Current solver can only resolve to root frame = palm");
240  return false;
241  }
242 
243  if (!nh_private.getParam("tip_name", tip_name))
244  {
245  ROS_FATAL("GenericIK: No tip name found on parameter server");
246  return false;
247  }
248 
249  if (tip_name.find("tip") == string::npos)
250  {
251  ROS_FATAL("Current solver can only resolve to one of the tip frames");
252  return false;
253  }
254  if (tip_name.find("fftip") == string::npos && tip_name.find("mftip") == string::npos &&
255  tip_name.find("rftip") == string::npos && tip_name.find("lftip") == string::npos &&
256  tip_name.find("thtip") == string::npos)
257  {
258  ROS_FATAL("Name of distal frame does not match any finger");
259  return false;
260  }
261 
262  // Load and Read Models
263  if (!loadModel(result))
264  {
265  ROS_FATAL("Could not load models!");
266  return false;
267  }
268 
269  // Define coupling matrix for fingers ff, mf, rf: their first two joints (J1 and J2) are coupled while
270  // J3 and J4 are independent.
271  // The rows of coupling matrix correspond to all joints (unlocked ones) while the columns correspond to
272  // independent joints (not coupled).
273  if (tip_name.find("fftip") != string::npos)
274  {
275  // Assign update function for dynamic coupling
277  }
278  if (tip_name.find("mftip") != string::npos)
279  {
280  // Assign update function for dynamic coupling
282  }
283  if (tip_name.find("rftip") != string::npos)
284  {
285  // Assign update function for dynamic coupling
287  }
288  if (tip_name.find("lftip") != string::npos)
289  {
290  // Assign update function for dynamic coupling
292  }
293  if (tip_name.find("thtip") != string::npos)
294  {
295  // Assign update function for thumb: identity matrix is used since there is no coupling
297  }
298 
299  Eigen::MatrixXd Mx(6, 6); // Task space weighting matrix: We will only consider translation components.
300  for (unsigned int i = 0; i < 6; i++)
301  {
302  for (unsigned int j = 0; j < 6; j++)
303  {
304  Mx(i, j) = 0.0;
305  }
306  }
307  // Control only position of the fingertip. Discard error in orientation
308  Mx(0, 0) = 1.0; // coordinate X
309  Mx(1, 1) = 1.0; // coordinate Y
310  Mx(2, 2) = 1.0; // coordinate Z
311  Mx(3, 3) = 0.0; // rotation X
312  Mx(4, 4) = 0.0; // rotation Y
313  Mx(5, 5) = 0.0; // rotation Z
314 
315  ROS_DEBUG("CHAIN--> Joints:%d, Ind. Joints:%d, Segments:%d", chain.getNrOfJoints(), chain.getNrOfIndJoints(),
317  // Get Solver Parameters
318  int maxIterations;
319  double epsilon, lambda;
320 
321  if (!nh_private.getParam("maxIterations", maxIterations))
322  {
323  maxIterations = 1000;
324  ROS_WARN("No maxIterations on param server, using %d as default", maxIterations);
325  }
326 
327  if (!nh_private.getParam("epsilon", epsilon))
328  {
329  epsilon = 1e-2;
330  ROS_WARN("No epsilon on param server, using %f as default", epsilon);
331  }
332 
333  if (!nh_private.getParam("lambda", lambda))
334  {
335  lambda = 0.01;
336  ROS_WARN("No lambda on param server, using %f as default", lambda);
337  }
338 
339  ROS_DEBUG("IK Solver, maxIterations: %d, epsilon: %f, lambda: %f", maxIterations, epsilon, lambda);
340 
341  // Build Solvers
342  fk_solver = new KDL::ChainFkSolverPos_recursive(chain); // keep the standard arm_kinematics fk_solver
343  ik_solver_vel = new KDL::ChainIkSolverVel_wdls_coupling(chain, epsilon, maxIterations);
344  ik_solver_vel->setLambda(lambda);
347  maxIterations, epsilon);
348 
349  ROS_INFO("Advertising services");
352 
353  return true;
354 }
355 
356 bool Kinematics::loadModel(const std::string xml)
357 {
358  urdf::Model robot_model;
359  KDL::Tree tree;
360 
361  if (!robot_model.initString(xml))
362  {
363  ROS_FATAL("Could not initialize robot model");
364  return -1;
365  }
366  if (!kdl_parser::treeFromString(xml, tree))
367  {
368  ROS_ERROR("Could not initialize tree object");
369  return false;
370  }
371  if (!tree.getChain(root_name, tip_name, chain))
372  {
373  ROS_ERROR("Could not initialize chain object");
374  return false;
375  }
376  if (!readJoints(robot_model))
377  {
378  ROS_FATAL("Could not read information about the joints");
379  return false;
380  }
381 
382  return true;
383 }
384 
386 {
387  num_joints = 0;
388  // get joint maxs and mins
389  boost::shared_ptr<const urdf::Link> link = robot_model.getLink(tip_name);
391 
392  urdf::Vector3 length;
393 
394  while (link && link->name != root_name)
395  {
396  joint = robot_model.getJoint(link->parent_joint->name);
397  if (!joint)
398  {
399  ROS_ERROR("Could not find joint: %s", link->parent_joint->name.c_str());
400  return false;
401  }
402  if (joint->type != urdf::Joint::UNKNOWN && joint->type != urdf::Joint::FIXED)
403  {
404  ROS_DEBUG("adding joint: [%s]", joint->name.c_str());
405  num_joints++;
406  }
407  link = robot_model.getLink(link->getParent()->name);
408  }
409 
412  info.joint_names.resize(num_joints);
413  info.link_names.resize(num_joints);
414  info.limits.resize(num_joints);
415 
416  link = robot_model.getLink(tip_name);
417  unsigned int i = 0;
418  while (link && i < num_joints)
419  {
420  joint = robot_model.getJoint(link->parent_joint->name);
421  if (joint->type != urdf::Joint::UNKNOWN && joint->type != urdf::Joint::FIXED)
422  {
423  ROS_DEBUG("getting bounds for joint: [%s]", joint->name.c_str());
424 
425  float lower, upper;
426  int hasLimits;
427  if (joint->type != urdf::Joint::CONTINUOUS)
428  {
429  lower = joint->limits->lower;
430  upper = joint->limits->upper;
431  hasLimits = 1;
432  }
433  else
434  {
435  lower = -M_PI;
436  upper = M_PI;
437  hasLimits = 0;
438  }
439  int index = num_joints - i - 1;
440  joint_min.data[index] = lower;
441  joint_max.data[index] = upper;
442  info.joint_names[index] = joint->name;
443  info.link_names[index] = link->name;
444  info.limits[index].joint_name = joint->name;
445  info.limits[index].has_position_limits = hasLimits;
446  info.limits[index].min_position = lower;
447  info.limits[index].max_position = upper;
448  i++;
449  }
450  link = robot_model.getLink(link->getParent()->name);
451  }
452  return true;
453 }
454 
455 
456 int Kinematics::getJointIndex(const std::string &name)
457 {
458  for (unsigned int i = 0; i < info.joint_names.size(); i++)
459  {
460  if (info.joint_names[i] == name)
461  {
462  return i;
463  }
464  }
465  return -1;
466 }
467 
468 int Kinematics::getKDLSegmentIndex(const std::string &name)
469 {
470  int i = 0;
471  while (i < static_cast<int>(chain.getNrOfSegments()))
472  {
473  if (chain.getSegment(i).getName() == name)
474  {
475  return i + 1;
476  }
477  i++;
478  }
479  return -1;
480 }
481 
483 {
484  for (unsigned int i = 0; i < num_joints; i++)
485  {
486  double min = info.limits[i].min_position;
487  double max = info.limits[i].max_position;
488  double r = sr_math_utils::Random::instance().generate<double>(min, max);
489  jnt_pos_in(i) = r;
490  }
491 }
492 
493 bool Kinematics::getPositionIK(moveit_msgs::GetPositionIK::Request &request,
494  moveit_msgs::GetPositionIK::Response &response)
495 {
496  if ((request.ik_request.ik_link_name.find("fftip") == std::string::npos) &&
497  (request.ik_request.ik_link_name.find("mftip") == std::string::npos)
498  && (request.ik_request.ik_link_name.find("rftip") == std::string::npos) &&
499  (request.ik_request.ik_link_name.find("lftip") == std::string::npos) &&
500  (request.ik_request.ik_link_name.find("thtip") == std::string::npos))
501  {
502  ROS_ERROR("Only IK at fingertip frame can be computed\n");
503  return false;
504  }
505 
506  geometry_msgs::PoseStamped pose_msg_in = request.ik_request.pose_stamped;
507  tf::Stamped<tf::Pose> transform;
508  tf::Stamped<tf::Pose> transform_root;
509  tf::poseStampedMsgToTF(pose_msg_in, transform);
510 
511  // Do the IK
512  KDL::JntArray jnt_pos_in;
513  KDL::JntArray jnt_pos_out;
514  jnt_pos_in.resize(num_joints);
515  for (unsigned int i = 0; i < num_joints; i++)
516  {
517  int tmp_index = getJointIndex(request.ik_request.robot_state.joint_state.name[i]);
518  if (tmp_index >= 0)
519  {
520  jnt_pos_in(tmp_index) = request.ik_request.robot_state.joint_state.position[i];
521  }
522  else
523  {
524  ROS_ERROR("i: %d, No joint index for %s", i, request.ik_request.robot_state.joint_state.name[i].c_str());
525  }
526  }
527  // Convert F to our root_frame
528  try
529  {
530  tf_listener.transformPose(root_name, transform, transform_root);
531  }
532  catch (...)
533  {
534  ROS_ERROR("Could not transform IK pose to frame: %s", root_name.c_str());
535  response.error_code.val = response.error_code.FRAME_TRANSFORM_FAILURE;
536  return false;
537  }
538  KDL::Frame F_dest;
539  tf::transformTFToKDL(transform_root, F_dest);
540  int ik_valid = -1;
541  for (int i = 0; i < 10 && ik_valid < 0; i++)
542  {
543  if (request.ik_request.ik_link_name.find("thtip") != std::string::npos ||
544  request.ik_request.ik_link_name.find("lftip") != std::string::npos)
545  ROS_DEBUG("IK Seed: %f, %f, %f, %f, %f", jnt_pos_in(0), jnt_pos_in(1), jnt_pos_in(2), jnt_pos_in(3),
546  jnt_pos_in(4));
547  else
548  ROS_DEBUG("IK Seed: %f, %f, %f, %f", jnt_pos_in(0), jnt_pos_in(1), jnt_pos_in(2), jnt_pos_in(3));
549  ik_valid = ik_solver_pos->CartToJnt(jnt_pos_in, F_dest, jnt_pos_out);
550  generateRandomJntSeed(jnt_pos_in);
551  // maintain 1:1 coupling
552  if (request.ik_request.ik_link_name.find("thtip") == std::string::npos &&
553  request.ik_request.ik_link_name.find("lftip") == std::string::npos)
554  {
555  jnt_pos_in(3) = jnt_pos_in(2);
556  }
557  else if (request.ik_request.ik_link_name.find("lftip") != std::string::npos)
558  {
559  jnt_pos_in(4) = jnt_pos_in(3);
560  }
561  if (i > 0)
562  ROS_DEBUG("IK Recalculation step: %d", i);
563  }
564  if (ik_valid >= 0)
565  {
566  response.solution.joint_state.name = info.joint_names;
567  response.solution.joint_state.position.resize(num_joints);
568  for (unsigned int i = 0; i < num_joints; i++)
569  {
570  response.solution.joint_state.position[i] = jnt_pos_out(i);
571  ROS_DEBUG("IK Solution: %s %d: %f", response.solution.joint_state.name[i].c_str(), i, jnt_pos_out(i));
572  }
573  response.error_code.val = response.error_code.SUCCESS;
574  return true;
575  }
576  else
577  {
578  ROS_DEBUG("An IK solution could not be found");
579  response.error_code.val = response.error_code.NO_IK_SOLUTION;
580  return true;
581  }
582 }
583 
584 bool Kinematics::getPositionFK(moveit_msgs::GetPositionFK::Request &request,
585  moveit_msgs::GetPositionFK::Response &response)
586 {
587  KDL::Frame p_out;
588  KDL::JntArray jnt_pos_in;
589  geometry_msgs::PoseStamped pose;
590  tf::Stamped<tf::Pose> tf_pose;
591 
592  jnt_pos_in.resize(num_joints);
593  for (unsigned int i = 0; i < num_joints; i++)
594  {
595  int tmp_index = getJointIndex(request.robot_state.joint_state.name[i]);
596  if (tmp_index >= 0)
597  {
598  jnt_pos_in(tmp_index) = request.robot_state.joint_state.position[i];
599  }
600  }
601 
602  response.pose_stamped.resize(request.fk_link_names.size());
603  response.fk_link_names.resize(request.fk_link_names.size());
604 
605  bool valid = true;
606  for (unsigned int i = 0; i < request.fk_link_names.size(); i++)
607  {
608  int segmentIndex = Kinematics::getKDLSegmentIndex(request.fk_link_names[i]);
609  ROS_DEBUG("End effector index: %d", segmentIndex);
610  ROS_DEBUG("Chain indices: %d", chain.getNrOfSegments());
611 
612  int fk_valid = fk_solver->JntToCart(jnt_pos_in, p_out, segmentIndex);
613 
614  if (fk_valid >= 0)
615  {
616  tf_pose.frame_id_ = root_name;
617  tf_pose.stamp_ = ros::Time();
618  tf::poseKDLToTF(p_out, tf_pose);
619  try
620  {
621  tf_listener.transformPose(request.header.frame_id, tf_pose, tf_pose);
622  }
623  catch (...)
624  {
625  ROS_ERROR("Could not transform FK pose to frame: %s", request.header.frame_id.c_str());
626  response.error_code.val = response.error_code.FRAME_TRANSFORM_FAILURE;
627  return false;
628  }
629  tf::poseStampedTFToMsg(tf_pose, pose);
630  response.pose_stamped[i] = pose;
631  response.fk_link_names[i] = request.fk_link_names[i];
632  response.error_code.val = response.error_code.SUCCESS;
633  }
634  else
635  {
636  ROS_ERROR("Could not compute FK for %s", request.fk_link_names[i].c_str());
637  response.error_code.val = response.error_code.FAILURE;
638  valid = false;
639  }
640  }
641  return valid;
642 }
643 
644 int main(int argc, char **argv)
645 {
646  ros::init(argc, argv, "hand_kinematics_coupling");
647  Kinematics k;
648  if (k.init() < 0)
649  {
650  ROS_ERROR("Could not initialize kinematics node");
651  return -1;
652  }
653 
654  ros::spin();
655  return 0;
656 }
657 
658 
659 /* For the emacs weenies in the crowd.
660  Local Variables:
661  c-basic-offset: 2
662  End:
663 */
bool readJoints(urdf::Model &robot_model)
#define ROS_FATAL(...)
bool getPositionFK(moveit_msgs::GetPositionFK::Request &request, moveit_msgs::GetPositionFK::Response &response)
This is the basic forward kinematics service that will return information about the kinematics node...
bool getPositionIK(moveit_msgs::GetPositionIK::Request &request, moveit_msgs::GetPositionIK::Response &response)
This is the basic IK service method that will compute and return an IK solution.
KDL::ChainIkSolverVel_wdls_coupling * ik_solver_vel
const Segment & getSegment(unsigned int nr) const
virtual int JntToCart(const JntArray &q_in, Frame &p_out, int segmentNr=-1)
URDF_EXPORT bool initString(const std::string &xmlstring)
Eigen::MatrixXd updateCouplingLF(const KDL::JntArray &q)
KDL::ChainIkSolverPos_NR_JL_coupling * ik_solver_pos
static void poseStampedTFToMsg(const Stamped< Pose > &bt, geometry_msgs::PoseStamped &msg)
unsigned int getNrOfSegments() const
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
int main(int argc, char **argv)
#define M_PI
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
#define ROS_WARN(...)
bool setUpdateCouplingFunction(updateFuncPtr updateFunc)
ROSCPP_DECL void spin(Spinner &spinner)
Eigen::MatrixXd updateCouplingRF(const KDL::JntArray &q)
KDL::ChainFkSolverPos_recursive * fk_solver
const std::string & getName() const
unsigned int index
static const std::string IK_SERVICE
int getKDLSegmentIndex(const std::string &name)
unsigned int getNrOfIndJoints() const
void poseKDLToTF(const KDL::Frame &k, tf::Pose &t)
Eigen::MatrixXd updateCouplingMF(const KDL::JntArray &q)
void transformTFToKDL(const tf::Transform &t, KDL::Frame &k)
#define ROS_INFO(...)
bool searchParam(const std::string &key, std::string &result) const
bool param(const std::string &param_name, T &param_val, const T &default_val) const
tf::TransformListener tf_listener
void setWeightTS(const Eigen::MatrixXd &Mx)
Eigen::VectorXd data
ros::ServiceServer ik_service
ros::ServiceServer fk_service
unsigned int getNrOfJoints() const
KDL_PARSER_PUBLIC bool treeFromString(const std::string &xml, KDL::Tree &tree)
ros::NodeHandle nh_private
static const std::string FK_SERVICE
bool loadModel(const std::string xml)
Eigen::MatrixXd updateCouplingTH(const KDL::JntArray &q)
void resize(unsigned int newSize)
ros::Time stamp_
bool getChain(const std::string &chain_root, const std::string &chain_tip, Chain &chain) const
std::string frame_id_
void transformPose(const std::string &target_frame, const geometry_msgs::PoseStamped &stamped_in, geometry_msgs::PoseStamped &stamped_out) const
int getJointIndex(const std::string &name)
bool getParam(const std::string &key, std::string &s) const
moveit_msgs::KinematicSolverInfo info
static void poseStampedMsgToTF(const geometry_msgs::PoseStamped &msg, Stamped< Pose > &bt)
std::string finger_base_name
void generateRandomJntSeed(KDL::JntArray &jnt_pos_in)
This method generates a random joint array vector between the joint limits so that local minima in IK...
virtual int CartToJnt(const JntArray &q_init, const Frame &p_in, JntArray &q_out)
r
#define ROS_ERROR(...)
KDL::Chain_coupling chain
void setLambda(const double &lambda)
Eigen::MatrixXd updateCouplingFF(const KDL::JntArray &q)
#define ROS_DEBUG(...)


hand_kinematics
Author(s): Juan Antonio Corrales Ramon (UPMC),, Guillaume Walck (CITEC)
autogenerated on Wed Oct 14 2020 04:05:07