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 #include <pr2_arm_kinematics/pr2_arm_kinematics.h>
00035 #include <geometry_msgs/PoseStamped.h>
00036 #include <kdl_parser/kdl_parser.hpp>
00037 #include <tf_conversions/tf_kdl.h>
00038 #include "ros/ros.h"
00039 #include <algorithm>
00040 #include <numeric>
00041
00042
00043 using namespace KDL;
00044 using namespace tf;
00045 using namespace std;
00046 using namespace ros;
00047
00048 namespace pr2_arm_kinematics {
00049
00050 static const std::string IK_SERVICE = "get_ik";
00051 static const std::string FK_SERVICE = "get_fk";
00052 static const std::string IK_INFO_SERVICE = "get_ik_solver_info";
00053 static const std::string FK_INFO_SERVICE = "get_fk_solver_info";
00054
00055 PR2ArmKinematics::PR2ArmKinematics(): node_handle_("~"),dimension_(7)
00056 {
00057 urdf::Model robot_model;
00058 std::string tip_name, xml_string;
00059
00060 while(!loadRobotModel(node_handle_,robot_model,root_name_,tip_name,xml_string) && node_handle_.ok())
00061 {
00062 ROS_ERROR("Could not load robot model. Are you sure the robot model is on the parameter server?");
00063 ros::Duration(0.5).sleep();
00064 }
00065
00066 ROS_INFO("Loading KDL Tree");
00067 if(!getKDLChain(xml_string,root_name_,tip_name,kdl_chain_))
00068 {
00069 active_ = false;
00070 ROS_ERROR("Could not load kdl tree");
00071 }
00072 ROS_INFO("Advertising services");
00073 jnt_to_pose_solver_.reset(new KDL::ChainFkSolverPos_recursive(kdl_chain_));
00074 node_handle_.param<int>("free_angle",free_angle_,2);
00075
00076 node_handle_.param<double>("search_discretization",search_discretization_,0.01);
00077 pr2_arm_ik_solver_.reset(new pr2_arm_kinematics::PR2ArmIKSolver(robot_model,root_name_,tip_name, search_discretization_,free_angle_));
00078 if(!pr2_arm_ik_solver_->active_)
00079 {
00080 ROS_ERROR("Could not load ik");
00081 active_ = false;
00082 }
00083 else
00084 {
00085
00086 pr2_arm_ik_solver_->getSolverInfo(ik_solver_info_);
00087 pr2_arm_kinematics::getKDLChainInfo(kdl_chain_,fk_solver_info_);
00088 fk_solver_info_.joint_names = ik_solver_info_.joint_names;
00089
00090 for(unsigned int i=0; i < ik_solver_info_.joint_names.size(); i++)
00091 {
00092 ROS_INFO("PR2Kinematics:: joint name: %s",ik_solver_info_.joint_names[i].c_str());
00093 }
00094 for(unsigned int i=0; i < ik_solver_info_.link_names.size(); i++)
00095 {
00096 ROS_INFO("PR2Kinematics can solve IK for %s",ik_solver_info_.link_names[i].c_str());
00097 }
00098 for(unsigned int i=0; i < fk_solver_info_.link_names.size(); i++)
00099 {
00100 ROS_INFO("PR2Kinematics can solve FK for %s",fk_solver_info_.link_names[i].c_str());
00101 }
00102 ROS_INFO("PR2Kinematics::active");
00103 active_ = true;
00104 fk_service_ = node_handle_.advertiseService(FK_SERVICE,&PR2ArmKinematics::getPositionFK,this);
00105 ik_service_ = node_handle_.advertiseService(IK_SERVICE,&PR2ArmKinematics::getPositionIK,this);
00106
00107 ik_solver_info_service_ = node_handle_.advertiseService(IK_INFO_SERVICE,&PR2ArmKinematics::getIKSolverInfo,this);
00108 fk_solver_info_service_ = node_handle_.advertiseService(FK_INFO_SERVICE,&PR2ArmKinematics::getFKSolverInfo,this);
00109
00110 }
00111 }
00112
00113 bool PR2ArmKinematics::isActive()
00114 {
00115 if(active_)
00116 return true;
00117 return false;
00118 }
00119
00120 bool PR2ArmKinematics::getPositionIK(kinematics_msgs::GetPositionIK::Request &request,
00121 kinematics_msgs::GetPositionIK::Response &response)
00122 {
00123 if(!active_)
00124 {
00125 ROS_ERROR("IK service not active");
00126 return true;
00127 }
00128
00129 if(!checkIKService(request,response,ik_solver_info_))
00130 return true;
00131
00132 geometry_msgs::PoseStamped pose_msg_in = request.ik_request.pose_stamped;
00133 KDL::Frame pose_desired;
00134 if(!convertPoseToRootFrame(pose_msg_in,pose_desired,root_name_,tf_))
00135 {
00136 response.error_code.val = response.error_code.FRAME_TRANSFORM_FAILURE;
00137 return true;
00138 }
00139
00140
00141 KDL::JntArray jnt_pos_in;
00142 KDL::JntArray jnt_pos_out;
00143 jnt_pos_in.resize(dimension_);
00144 for(int i=0; i < dimension_; i++)
00145 {
00146 int tmp_index = getJointIndex(request.ik_request.ik_seed_state.joint_state.name[i],ik_solver_info_);
00147 if(tmp_index >=0)
00148 {
00149 jnt_pos_in(tmp_index) = request.ik_request.ik_seed_state.joint_state.position[i];
00150 }
00151 else
00152 {
00153 ROS_ERROR("i: %d, No joint index for %s",i,request.ik_request.ik_seed_state.joint_state.name[i].c_str());
00154 }
00155 }
00156
00157 int ik_valid = pr2_arm_ik_solver_->CartToJntSearch(jnt_pos_in,
00158 pose_desired,
00159 jnt_pos_out,
00160 request.timeout.toSec());
00161 if(ik_valid == pr2_arm_kinematics::TIMED_OUT)
00162 response.error_code.val = response.error_code.TIMED_OUT;
00163 if(ik_valid == pr2_arm_kinematics::NO_IK_SOLUTION)
00164 response.error_code.val = response.error_code.NO_IK_SOLUTION;
00165
00166 if(ik_valid >= 0)
00167 {
00168 response.solution.joint_state.name = ik_solver_info_.joint_names;
00169 response.solution.joint_state.position.resize(dimension_);
00170 for(int i=0; i < dimension_; i++)
00171 {
00172 response.solution.joint_state.position[i] = jnt_pos_out(i);
00173 ROS_DEBUG("IK Solution: %s %d: %f",response.solution.joint_state.name[i].c_str(),i,jnt_pos_out(i));
00174 }
00175 response.error_code.val = response.error_code.SUCCESS;
00176 return true;
00177 }
00178 else
00179 {
00180 ROS_DEBUG("An IK solution could not be found");
00181 return true;
00182 }
00183 }
00184
00185 bool PR2ArmKinematics::getIKSolverInfo(kinematics_msgs::GetKinematicSolverInfo::Request &request,
00186 kinematics_msgs::GetKinematicSolverInfo::Response &response)
00187 {
00188 if(!active_)
00189 {
00190 ROS_ERROR("IK node not active");
00191 return true;
00192 }
00193 response.kinematic_solver_info = ik_solver_info_;
00194 return true;
00195 }
00196
00197 bool PR2ArmKinematics::getFKSolverInfo(kinematics_msgs::GetKinematicSolverInfo::Request &request,
00198 kinematics_msgs::GetKinematicSolverInfo::Response &response)
00199 {
00200 if(!active_)
00201 {
00202 ROS_ERROR("IK node not active");
00203 return true;
00204 }
00205 response.kinematic_solver_info = fk_solver_info_;
00206 return true;
00207 }
00208
00209 bool PR2ArmKinematics::getPositionFK(kinematics_msgs::GetPositionFK::Request &request,
00210 kinematics_msgs::GetPositionFK::Response &response)
00211 {
00212 if(!active_)
00213 {
00214 ROS_ERROR("FK service not active");
00215 return true;
00216 }
00217
00218 if(!checkFKService(request,response,fk_solver_info_))
00219 return true;
00220
00221 KDL::Frame p_out;
00222 KDL::JntArray jnt_pos_in;
00223 geometry_msgs::PoseStamped pose;
00224 tf::Stamped<tf::Pose> tf_pose;
00225
00226 jnt_pos_in.resize(dimension_);
00227 for(int i=0; i < (int) request.robot_state.joint_state.position.size(); i++)
00228 {
00229 int tmp_index = getJointIndex(request.robot_state.joint_state.name[i],fk_solver_info_);
00230 if(tmp_index >=0)
00231 jnt_pos_in(tmp_index) = request.robot_state.joint_state.position[i];
00232 }
00233
00234 response.pose_stamped.resize(request.fk_link_names.size());
00235 response.fk_link_names.resize(request.fk_link_names.size());
00236
00237 bool valid = true;
00238 for(unsigned int i=0; i < request.fk_link_names.size(); i++)
00239 {
00240 ROS_DEBUG("End effector index: %d",pr2_arm_kinematics::getKDLSegmentIndex(kdl_chain_,request.fk_link_names[i]));
00241 ROS_DEBUG("Chain indices: %d",kdl_chain_.getNrOfSegments());
00242 if(jnt_to_pose_solver_->JntToCart(jnt_pos_in,p_out,pr2_arm_kinematics::getKDLSegmentIndex(kdl_chain_,request.fk_link_names[i])) >=0)
00243 {
00244 tf_pose.frame_id_ = root_name_;
00245 tf_pose.stamp_ = ros::Time();
00246 tf::PoseKDLToTF(p_out,tf_pose);
00247 try{
00248 tf_.transformPose(request.header.frame_id,tf_pose,tf_pose);
00249 }
00250 catch(...)
00251 {
00252 ROS_ERROR("Could not transform FK pose to frame: %s",request.header.frame_id.c_str());
00253 response.error_code.val = response.error_code.FRAME_TRANSFORM_FAILURE;
00254 return false;
00255 }
00256 tf::poseStampedTFToMsg(tf_pose,pose);
00257 response.pose_stamped[i] = pose;
00258 response.fk_link_names[i] = request.fk_link_names[i];
00259 response.error_code.val = response.error_code.SUCCESS;
00260 }
00261 else
00262 {
00263 ROS_ERROR("Could not compute FK for %s",request.fk_link_names[i].c_str());
00264 response.error_code.val = response.error_code.NO_FK_SOLUTION;
00265 valid = false;
00266 }
00267 }
00268 return true;
00269 }
00270 }