00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <pr2_arm_kinematics/pr2_arm_kinematics.h>
00038 #include <geometry_msgs/PoseStamped.h>
00039 #include <kdl_parser/kdl_parser.hpp>
00040 #include <tf_conversions/tf_kdl.h>
00041 #include "ros/ros.h"
00042 #include <algorithm>
00043 #include <numeric>
00044
00045
00046 using namespace KDL;
00047 using namespace tf;
00048 using namespace std;
00049 using namespace ros;
00050
00051 namespace pr2_arm_kinematics {
00052
00053 static const std::string IK_SERVICE = "get_ik";
00054 static const std::string FK_SERVICE = "get_fk";
00055 static const std::string IK_INFO_SERVICE = "get_ik_solver_info";
00056 static const std::string FK_INFO_SERVICE = "get_fk_solver_info";
00057
00058 PR2ArmKinematics::PR2ArmKinematics(bool create_tf_listener): node_handle_("~"),dimension_(7)
00059 {
00060 urdf::Model robot_model;
00061 std::string tip_name, xml_string;
00062
00063 while(!loadRobotModel(node_handle_,robot_model, xml_string) && node_handle_.ok())
00064 {
00065 ROS_ERROR("Could not load robot model. Are you sure the robot model is on the parameter server?");
00066 ros::Duration(0.5).sleep();
00067 }
00068
00069 if (!node_handle_.getParam("root_name", root_name_)){
00070 ROS_FATAL("PR2IK: No root name found on parameter server");
00071 exit(-1);
00072 }
00073 if (!node_handle_.getParam("tip_name", tip_name)){
00074 ROS_FATAL("PR2IK: No tip name found on parameter server");
00075 exit(-1);
00076 }
00077
00078 ROS_DEBUG("Loading KDL Tree");
00079 if(!getKDLChain(xml_string,root_name_,tip_name,kdl_chain_))
00080 {
00081 active_ = false;
00082 ROS_ERROR("Could not load kdl tree");
00083 }
00084 if(create_tf_listener) {
00085 tf_ = new TransformListener();
00086 } else {
00087 tf_ = NULL;
00088 }
00089
00090 ROS_DEBUG("Advertising services");
00091 jnt_to_pose_solver_.reset(new KDL::ChainFkSolverPos_recursive(kdl_chain_));
00092 node_handle_.param<int>("free_angle",free_angle_,2);
00093
00094 node_handle_.param<double>("search_discretization",search_discretization_,0.01);
00095 pr2_arm_ik_solver_.reset(new pr2_arm_kinematics::PR2ArmIKSolver(robot_model,root_name_,tip_name, search_discretization_,free_angle_));
00096 if(!pr2_arm_ik_solver_->active_)
00097 {
00098 ROS_ERROR("Could not load ik");
00099 active_ = false;
00100 }
00101 else
00102 {
00103
00104 pr2_arm_ik_solver_->getSolverInfo(ik_solver_info_);
00105 pr2_arm_kinematics::getKDLChainInfo(kdl_chain_,fk_solver_info_);
00106 fk_solver_info_.joint_names = ik_solver_info_.joint_names;
00107
00108 for(unsigned int i=0; i < ik_solver_info_.joint_names.size(); i++)
00109 {
00110 ROS_DEBUG("PR2Kinematics:: joint name: %s",ik_solver_info_.joint_names[i].c_str());
00111 }
00112 for(unsigned int i=0; i < ik_solver_info_.link_names.size(); i++)
00113 {
00114 ROS_DEBUG("PR2Kinematics can solve IK for %s",ik_solver_info_.link_names[i].c_str());
00115 }
00116 for(unsigned int i=0; i < fk_solver_info_.link_names.size(); i++)
00117 {
00118 ROS_DEBUG("PR2Kinematics can solve FK for %s",fk_solver_info_.link_names[i].c_str());
00119 }
00120 ROS_DEBUG("PR2Kinematics::active");
00121 active_ = true;
00122 fk_service_ = node_handle_.advertiseService(FK_SERVICE,&PR2ArmKinematics::getPositionFK,this);
00123 ik_service_ = node_handle_.advertiseService(IK_SERVICE,&PR2ArmKinematics::getPositionIK,this);
00124
00125 ik_solver_info_service_ = node_handle_.advertiseService(IK_INFO_SERVICE,&PR2ArmKinematics::getIKSolverInfo,this);
00126 fk_solver_info_service_ = node_handle_.advertiseService(FK_INFO_SERVICE,&PR2ArmKinematics::getFKSolverInfo,this);
00127
00128 }
00129 }
00130
00131 PR2ArmKinematics::~PR2ArmKinematics()
00132 {
00133 if(tf_ != NULL) {
00134 delete tf_;
00135 }
00136 }
00137
00138 bool PR2ArmKinematics::isActive()
00139 {
00140 if(active_)
00141 return true;
00142 return false;
00143 }
00144
00145 bool PR2ArmKinematics::getPositionIK(kinematics_msgs::GetPositionIK::Request &request,
00146 kinematics_msgs::GetPositionIK::Response &response)
00147 {
00148 if(!active_)
00149 {
00150 ROS_ERROR("IK service not active");
00151 return false;
00152 }
00153
00154 if(!checkIKService(request,response,ik_solver_info_))
00155 return false;
00156
00157 geometry_msgs::PoseStamped pose_msg_in = request.ik_request.pose_stamped;
00158 geometry_msgs::PoseStamped pose_msg_out;
00159
00160 if(tf_ != NULL) {
00161 if(!convertPoseToRootFrame(pose_msg_in,pose_msg_out,root_name_, *tf_))
00162 {
00163 response.error_code.val = response.error_code.FRAME_TRANSFORM_FAILURE;
00164 return true;
00165 }
00166 } else {
00167 ROS_WARN_STREAM("No tf listener. Can't transform anything");
00168 response.error_code.val = response.error_code.FRAME_TRANSFORM_FAILURE;
00169 return false;
00170 }
00171 request.ik_request.pose_stamped = pose_msg_out;
00172 return getPositionIKHelper(request, response);
00173 }
00174
00175
00176 bool PR2ArmKinematics::getPositionIKHelper(kinematics_msgs::GetPositionIK::Request &request,
00177 kinematics_msgs::GetPositionIK::Response &response)
00178 {
00179 KDL::Frame pose_desired;
00180 tf::PoseMsgToKDL(request.ik_request.pose_stamped.pose, pose_desired);
00181
00182
00183 KDL::JntArray jnt_pos_in;
00184 KDL::JntArray jnt_pos_out;
00185 jnt_pos_in.resize(dimension_);
00186 for(int i=0; i < dimension_; i++)
00187 {
00188 int tmp_index = getJointIndex(request.ik_request.ik_seed_state.joint_state.name[i],ik_solver_info_);
00189 if(tmp_index >=0)
00190 {
00191 jnt_pos_in(tmp_index) = request.ik_request.ik_seed_state.joint_state.position[i];
00192 }
00193 else
00194 {
00195 ROS_ERROR("i: %d, No joint index for %s",i,request.ik_request.ik_seed_state.joint_state.name[i].c_str());
00196 }
00197 }
00198
00199 int ik_valid = pr2_arm_ik_solver_->CartToJntSearch(jnt_pos_in,
00200 pose_desired,
00201 jnt_pos_out,
00202 request.timeout.toSec());
00203 if(ik_valid == pr2_arm_kinematics::TIMED_OUT)
00204 response.error_code.val = response.error_code.TIMED_OUT;
00205 if(ik_valid == pr2_arm_kinematics::NO_IK_SOLUTION)
00206 response.error_code.val = response.error_code.NO_IK_SOLUTION;
00207
00208 response.solution.joint_state.header = request.ik_request.pose_stamped.header;
00209
00210 if(ik_valid >= 0)
00211 {
00212 response.solution.joint_state.name = ik_solver_info_.joint_names;
00213 response.solution.joint_state.position.resize(dimension_);
00214 for(int i=0; i < dimension_; i++)
00215 {
00216 response.solution.joint_state.position[i] = jnt_pos_out(i);
00217 ROS_DEBUG("IK Solution: %s %d: %f",response.solution.joint_state.name[i].c_str(),i,jnt_pos_out(i));
00218 }
00219 response.error_code.val = response.error_code.SUCCESS;
00220 return true;
00221 }
00222 else
00223 {
00224 ROS_DEBUG("An IK solution could not be found");
00225 return false;
00226 }
00227 }
00228
00229 bool PR2ArmKinematics::getIKSolverInfo(kinematics_msgs::GetKinematicSolverInfo::Request &request,
00230 kinematics_msgs::GetKinematicSolverInfo::Response &response)
00231 {
00232 if (active_)
00233 {
00234 response.kinematic_solver_info = ik_solver_info_;
00235 return true;
00236 }
00237 ROS_ERROR("IK node not active");
00238 return false;
00239 }
00240
00241 bool PR2ArmKinematics::getFKSolverInfo(kinematics_msgs::GetKinematicSolverInfo::Request &request,
00242 kinematics_msgs::GetKinematicSolverInfo::Response &response)
00243 {
00244 if(active_)
00245 {
00246 response.kinematic_solver_info = fk_solver_info_;
00247 return true;
00248 }
00249 ROS_ERROR("IK node not active");
00250 return false;
00251 }
00252
00253 bool PR2ArmKinematics::getPositionFK(kinematics_msgs::GetPositionFK::Request &request,
00254 kinematics_msgs::GetPositionFK::Response &response)
00255 {
00256 if(!active_)
00257 {
00258 ROS_ERROR("FK service not active");
00259 return false;
00260 }
00261
00262 if(!checkFKService(request,response,fk_solver_info_))
00263 return false;
00264
00265 KDL::Frame p_out;
00266 KDL::JntArray jnt_pos_in;
00267 geometry_msgs::PoseStamped pose;
00268 tf::Stamped<tf::Pose> tf_pose;
00269
00270 jnt_pos_in.resize(dimension_);
00271 for(int i=0; i < (int) request.robot_state.joint_state.position.size(); i++)
00272 {
00273 int tmp_index = getJointIndex(request.robot_state.joint_state.name[i],fk_solver_info_);
00274 if(tmp_index >=0)
00275 jnt_pos_in(tmp_index) = request.robot_state.joint_state.position[i];
00276 }
00277
00278 response.pose_stamped.resize(request.fk_link_names.size());
00279 response.fk_link_names.resize(request.fk_link_names.size());
00280
00281 for(unsigned int i=0; i < request.fk_link_names.size(); i++)
00282 {
00283 ROS_DEBUG("End effector index: %d",pr2_arm_kinematics::getKDLSegmentIndex(kdl_chain_,request.fk_link_names[i]));
00284 ROS_DEBUG("Chain indices: %d",kdl_chain_.getNrOfSegments());
00285 if(jnt_to_pose_solver_->JntToCart(jnt_pos_in,p_out,pr2_arm_kinematics::getKDLSegmentIndex(kdl_chain_,request.fk_link_names[i])) >=0)
00286 {
00287 tf_pose.frame_id_ = root_name_;
00288 tf_pose.stamp_ = ros::Time();
00289 tf::PoseKDLToTF(p_out,tf_pose);
00290 tf::poseStampedTFToMsg(tf_pose,pose);
00291 if(!transformPose(request.header.frame_id, pose, response.pose_stamped[i])) {
00292 response.error_code.val = response.error_code.FRAME_TRANSFORM_FAILURE;
00293 return false;
00294 }
00295 response.fk_link_names[i] = request.fk_link_names[i];
00296 response.error_code.val = response.error_code.SUCCESS;
00297 }
00298 else
00299 {
00300 ROS_ERROR("Could not compute FK for %s",request.fk_link_names[i].c_str());
00301 response.error_code.val = response.error_code.NO_FK_SOLUTION;
00302 return false;
00303 }
00304 }
00305 return true;
00306 }
00307 bool PR2ArmKinematics::transformPose(const std::string& des_frame,
00308 const geometry_msgs::PoseStamped& pose_in,
00309 geometry_msgs::PoseStamped& pose_out)
00310 {
00311 if(tf_ != NULL) {
00312 try {
00313 tf_->transformPose(des_frame,pose_in,pose_out);
00314 }
00315 catch(...) {
00316 ROS_ERROR("Could not transform FK pose to frame: %s",des_frame.c_str());
00317 return false;
00318 }
00319 } else if(des_frame != root_name_){
00320 ROS_WARN_STREAM("No tf listener, can't transform to frame " << des_frame);
00321 return false;
00322 }
00323 return true;
00324 }
00325 }