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> 74 Eigen::MatrixXd cm(4, 3);
75 for (
unsigned int i = 0; i < 4; i++)
77 for (
unsigned int j = 0; j < 3; j++)
93 Eigen::MatrixXd cm(4, 3);
94 for (
unsigned int i = 0; i < 4; i++)
96 for (
unsigned int j = 0; j < 3; j++)
112 Eigen::MatrixXd cm(4, 3);
113 for (
unsigned int i = 0; i < 4; i++)
115 for (
unsigned int j = 0; j < 3; j++)
131 Eigen::MatrixXd cm(5, 4);
132 for (
unsigned int i = 0; i < 5; i++)
134 for (
unsigned int j = 0; j < 4; j++)
152 return Eigen::MatrixXd::Identity(5, 5);
178 moveit_msgs::KinematicSolverInfo
info;
193 bool getPositionIK(moveit_msgs::GetPositionIK::Request &request,
194 moveit_msgs::GetPositionIK::Response &response);
208 bool getPositionFK(moveit_msgs::GetPositionFK::Request &request,
209 moveit_msgs::GetPositionFK::Response &response);
220 std::string urdf_xml, full_urdf_xml;
221 nh.
param(
"urdf_xml", urdf_xml, std::string(
"robot_description"));
223 ROS_DEBUG(
"Reading xml file from parameter server");
227 ROS_FATAL(
"Could not load the xml from parameter server: %s", urdf_xml.c_str());
234 ROS_FATAL(
"GenericIK: No root name found on parameter server");
237 if (
root_name.find(
"palm") == string::npos)
239 ROS_FATAL(
"Current solver can only resolve to root frame = palm");
245 ROS_FATAL(
"GenericIK: No tip name found on parameter server");
249 if (
tip_name.find(
"tip") == string::npos)
251 ROS_FATAL(
"Current solver can only resolve to one of the tip frames");
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)
258 ROS_FATAL(
"Name of distal frame does not match any finger");
273 if (
tip_name.find(
"fftip") != string::npos)
278 if (
tip_name.find(
"mftip") != string::npos)
283 if (
tip_name.find(
"rftip") != string::npos)
288 if (
tip_name.find(
"lftip") != string::npos)
293 if (
tip_name.find(
"thtip") != string::npos)
299 Eigen::MatrixXd Mx(6, 6);
300 for (
unsigned int i = 0; i < 6; i++)
302 for (
unsigned int j = 0; j < 6; j++)
319 double epsilon, lambda;
323 maxIterations = 1000;
324 ROS_WARN(
"No maxIterations on param server, using %d as default", maxIterations);
330 ROS_WARN(
"No epsilon on param server, using %f as default", epsilon);
336 ROS_WARN(
"No lambda on param server, using %f as default", lambda);
339 ROS_DEBUG(
"IK Solver, maxIterations: %d, epsilon: %f, lambda: %f", maxIterations, epsilon, lambda);
347 maxIterations, epsilon);
363 ROS_FATAL(
"Could not initialize robot model");
368 ROS_ERROR(
"Could not initialize tree object");
373 ROS_ERROR(
"Could not initialize chain object");
378 ROS_FATAL(
"Could not read information about the joints");
392 urdf::Vector3 length;
396 joint = robot_model.getJoint(link->parent_joint->name);
399 ROS_ERROR(
"Could not find joint: %s", link->parent_joint->name.c_str());
402 if (joint->type != urdf::Joint::UNKNOWN && joint->type != urdf::Joint::FIXED)
404 ROS_DEBUG(
"adding joint: [%s]", joint->name.c_str());
407 link = robot_model.getLink(link->getParent()->name);
416 link = robot_model.getLink(
tip_name);
420 joint = robot_model.getJoint(link->parent_joint->name);
421 if (joint->type != urdf::Joint::UNKNOWN && joint->type != urdf::Joint::FIXED)
423 ROS_DEBUG(
"getting bounds for joint: [%s]", joint->name.c_str());
427 if (joint->type != urdf::Joint::CONTINUOUS)
429 lower = joint->limits->lower;
430 upper = joint->limits->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;
450 link = robot_model.getLink(link->getParent()->name);
458 for (
unsigned int i = 0; i <
info.joint_names.size(); i++)
460 if (
info.joint_names[i] == name)
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);
494 moveit_msgs::GetPositionIK::Response &response)
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))
502 ROS_ERROR(
"Only IK at fingertip frame can be computed\n");
506 geometry_msgs::PoseStamped pose_msg_in = request.ik_request.pose_stamped;
517 int tmp_index =
getJointIndex(request.ik_request.robot_state.joint_state.name[i]);
520 jnt_pos_in(tmp_index) = request.ik_request.robot_state.joint_state.position[i];
524 ROS_ERROR(
"i: %d, No joint index for %s", i, request.ik_request.robot_state.joint_state.name[i].c_str());
535 response.error_code.val = response.error_code.FRAME_TRANSFORM_FAILURE;
541 for (
int i = 0; i < 10 && ik_valid < 0; i++)
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),
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));
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)
555 jnt_pos_in(3) = jnt_pos_in(2);
557 else if (request.ik_request.ik_link_name.find(
"lftip") != std::string::npos)
559 jnt_pos_in(4) = jnt_pos_in(3);
562 ROS_DEBUG(
"IK Recalculation step: %d", i);
566 response.solution.joint_state.name =
info.joint_names;
567 response.solution.joint_state.position.resize(num_joints);
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));
573 response.error_code.val = response.error_code.SUCCESS;
578 ROS_DEBUG(
"An IK solution could not be found");
579 response.error_code.val = response.error_code.NO_IK_SOLUTION;
585 moveit_msgs::GetPositionFK::Response &response)
589 geometry_msgs::PoseStamped pose;
595 int tmp_index =
getJointIndex(request.robot_state.joint_state.name[i]);
598 jnt_pos_in(tmp_index) = request.robot_state.joint_state.position[i];
602 response.pose_stamped.
resize(request.fk_link_names.size());
603 response.fk_link_names.resize(request.fk_link_names.size());
606 for (
unsigned int i = 0; i < request.fk_link_names.size(); i++)
609 ROS_DEBUG(
"End effector index: %d", segmentIndex);
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;
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;
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;
644 int main(
int argc,
char **argv)
646 ros::init(argc, argv,
"hand_kinematics_coupling");
650 ROS_ERROR(
"Could not initialize kinematics node");
bool readJoints(urdf::Model &robot_model)
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)
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
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
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)
bool searchParam(const std::string &key, std::string &result) const
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
tf::TransformListener tf_listener
void setWeightTS(const Eigen::MatrixXd &Mx)
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)
bool getChain(const std::string &chain_root, const std::string &chain_tip, Chain &chain) 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)
KDL::Chain_coupling chain
void setLambda(const double &lambda)
Eigen::MatrixXd updateCouplingFF(const KDL::JntArray &q)