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_plugin.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 #include <pluginlib/class_list_macros.h>
00043
00044 using namespace KDL;
00045 using namespace tf;
00046 using namespace std;
00047 using namespace ros;
00048
00049
00050 PLUGINLIB_DECLARE_CLASS(pr2_arm_kinematics,PR2ArmKinematicsPlugin, pr2_arm_kinematics::PR2ArmKinematicsPlugin, kinematics::KinematicsBase)
00051
00052 namespace pr2_arm_kinematics {
00053
00054 PR2ArmKinematicsPlugin::PR2ArmKinematicsPlugin():active_(false){}
00055
00056 bool PR2ArmKinematicsPlugin::isActive()
00057 {
00058 if(active_)
00059 return true;
00060 return false;
00061 }
00062
00063 bool PR2ArmKinematicsPlugin::initialize(const std::string& group_name,
00064 const std::string& base_name,
00065 const std::string& tip_name,
00066 const double& search_discretization)
00067 {
00068 setValues(group_name, base_name, tip_name,search_discretization);
00069 urdf::Model robot_model;
00070 std::string xml_string;
00071 ros::NodeHandle private_handle("~/"+group_name);
00072 dimension_ = 7;
00073 while(!loadRobotModel(private_handle,robot_model,xml_string) && private_handle.ok())
00074 {
00075 ROS_ERROR("Could not load robot model. Are you sure the robot model is on the parameter server?");
00076 ros::Duration(0.5).sleep();
00077 }
00078
00079 ROS_DEBUG("Loading KDL Tree");
00080 if(!getKDLChain(xml_string,base_name_,tip_name_,kdl_chain_))
00081 {
00082 active_ = false;
00083 ROS_ERROR("Could not load kdl tree");
00084 }
00085 ROS_DEBUG("Advertising services");
00086 jnt_to_pose_solver_.reset(new KDL::ChainFkSolverPos_recursive(kdl_chain_));
00087 private_handle.param<int>("free_angle",free_angle_,2);
00088
00089 pr2_arm_ik_solver_.reset(new pr2_arm_kinematics::PR2ArmIKSolver(robot_model, base_name_,tip_name_, search_discretization_,free_angle_));
00090 if(!pr2_arm_ik_solver_->active_)
00091 {
00092 ROS_ERROR("Could not load ik");
00093 active_ = false;
00094 }
00095 else
00096 {
00097
00098 pr2_arm_ik_solver_->getSolverInfo(ik_solver_info_);
00099 pr2_arm_kinematics::getKDLChainInfo(kdl_chain_,fk_solver_info_);
00100 fk_solver_info_.joint_names = ik_solver_info_.joint_names;
00101
00102 for(unsigned int i=0; i < ik_solver_info_.joint_names.size(); i++)
00103 {
00104 ROS_DEBUG("PR2Kinematics:: joint name: %s",ik_solver_info_.joint_names[i].c_str());
00105 }
00106 for(unsigned int i=0; i < ik_solver_info_.link_names.size(); i++)
00107 {
00108 ROS_DEBUG("PR2Kinematics can solve IK for %s",ik_solver_info_.link_names[i].c_str());
00109 }
00110 for(unsigned int i=0; i < fk_solver_info_.link_names.size(); i++)
00111 {
00112 ROS_DEBUG("PR2Kinematics can solve FK for %s",fk_solver_info_.link_names[i].c_str());
00113 }
00114 ROS_DEBUG("PR2KinematicsPlugin::active for %s",group_name.c_str());
00115 active_ = true;
00116 }
00117 return active_;
00118 }
00119
00120 bool PR2ArmKinematicsPlugin::getPositionIK(const geometry_msgs::Pose &ik_pose,
00121 const std::vector<double> &ik_seed_state,
00122 std::vector<double> &solution,
00123 int &error_code)
00124 {
00125 if(!active_)
00126 {
00127 ROS_ERROR("kinematics not active");
00128 error_code = kinematics::NO_IK_SOLUTION;
00129 return false;
00130 }
00131
00132 KDL::Frame pose_desired;
00133 tf::poseMsgToKDL(ik_pose, pose_desired);
00134
00135
00136 KDL::JntArray jnt_pos_in;
00137 KDL::JntArray jnt_pos_out;
00138 jnt_pos_in.resize(dimension_);
00139 for(int i=0; i < dimension_; i++)
00140 {
00141 jnt_pos_in(i) = ik_seed_state[i];
00142 }
00143
00144 int ik_valid = pr2_arm_ik_solver_->CartToJnt(jnt_pos_in,
00145 pose_desired,
00146 jnt_pos_out);
00147 if(ik_valid == pr2_arm_kinematics::NO_IK_SOLUTION)
00148 {
00149 error_code = kinematics::NO_IK_SOLUTION;
00150 return false;
00151 }
00152
00153 if(ik_valid >= 0)
00154 {
00155 solution.resize(dimension_);
00156 for(int i=0; i < dimension_; i++)
00157 {
00158 solution[i] = jnt_pos_out(i);
00159 }
00160 error_code = kinematics::SUCCESS;
00161 return true;
00162 }
00163 else
00164 {
00165 ROS_DEBUG("An IK solution could not be found");
00166 error_code = kinematics::NO_IK_SOLUTION;
00167 return false;
00168 }
00169 }
00170
00171 bool PR2ArmKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
00172 const std::vector<double> &ik_seed_state,
00173 const double &timeout,
00174 std::vector<double> &solution,
00175 int &error_code)
00176 {
00177 if(!active_)
00178 {
00179 ROS_ERROR("kinematics not active");
00180 error_code = kinematics::INACTIVE;
00181 return false;
00182 }
00183 KDL::Frame pose_desired;
00184 tf::poseMsgToKDL(ik_pose, pose_desired);
00185
00186 KDL::JntArray jnt_pos_in;
00187 KDL::JntArray jnt_pos_out;
00188 jnt_pos_in.resize(dimension_);
00189 for(int i=0; i < dimension_; i++)
00190 {
00191 jnt_pos_in(i) = ik_seed_state[i];
00192 }
00193
00194 int ik_valid = pr2_arm_ik_solver_->CartToJntSearch(jnt_pos_in,
00195 pose_desired,
00196 jnt_pos_out,
00197 timeout);
00198 if(ik_valid == pr2_arm_kinematics::NO_IK_SOLUTION) {
00199 error_code = kinematics::NO_IK_SOLUTION;
00200 return false;
00201 }
00202
00203 if(ik_valid >= 0)
00204 {
00205 solution.resize(dimension_);
00206 for(int i=0; i < dimension_; i++)
00207 {
00208 solution[i] = jnt_pos_out(i);
00209 }
00210 error_code = kinematics::SUCCESS;
00211 return true;
00212 }
00213 else
00214 {
00215 ROS_DEBUG("An IK solution could not be found");
00216 error_code = kinematics::NO_IK_SOLUTION;
00217 return false;
00218 }
00219 }
00220
00221 bool PR2ArmKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
00222 const std::vector<double> &ik_seed_state,
00223 const double &timeout,
00224 const unsigned int& redundancy,
00225 const double &consistency_limit,
00226 std::vector<double> &solution,
00227 int &error_code)
00228 {
00229 if(!active_)
00230 {
00231 ROS_ERROR("kinematics not active");
00232 error_code = kinematics::INACTIVE;
00233 return false;
00234 }
00235 KDL::Frame pose_desired;
00236 tf::poseMsgToKDL(ik_pose, pose_desired);
00237
00238
00239 KDL::JntArray jnt_pos_in;
00240 KDL::JntArray jnt_pos_out;
00241 jnt_pos_in.resize(dimension_);
00242 for(int i=0; i < dimension_; i++)
00243 {
00244 jnt_pos_in(i) = ik_seed_state[i];
00245 }
00246
00247 unsigned int old_free_angle = pr2_arm_ik_solver_->getFreeAngle();
00248 pr2_arm_ik_solver_->setFreeAngle(redundancy);
00249 int ik_valid = pr2_arm_ik_solver_->CartToJntSearch(jnt_pos_in,
00250 pose_desired,
00251 consistency_limit,
00252 jnt_pos_out,
00253 timeout);
00254 pr2_arm_ik_solver_->setFreeAngle(old_free_angle);
00255
00256 if(ik_valid == pr2_arm_kinematics::NO_IK_SOLUTION)
00257 {
00258 error_code = kinematics::NO_IK_SOLUTION;
00259 return false;
00260 }
00261
00262 if(ik_valid >= 0)
00263 {
00264 solution.resize(dimension_);
00265 for(int i=0; i < dimension_; i++)
00266 {
00267 solution[i] = jnt_pos_out(i);
00268 }
00269 error_code = kinematics::SUCCESS;
00270 return true;
00271 }
00272 else
00273 {
00274 ROS_DEBUG("An IK solution could not be found");
00275 error_code = kinematics::NO_IK_SOLUTION;
00276 return false;
00277 }
00278 }
00279
00280
00281 void PR2ArmKinematicsPlugin::desiredPoseCallback(const KDL::JntArray& jnt_array,
00282 const KDL::Frame& ik_pose,
00283 arm_navigation_msgs::ArmNavigationErrorCodes& error_code)
00284 {
00285 std::vector<double> ik_seed_state;
00286 ik_seed_state.resize(dimension_);
00287 int int_error_code;
00288 for(int i=0; i < dimension_; i++)
00289 ik_seed_state[i] = jnt_array(i);
00290
00291 geometry_msgs::Pose ik_pose_msg;
00292 tf::poseKDLToMsg(ik_pose,ik_pose_msg);
00293
00294 desiredPoseCallback_(ik_pose_msg,ik_seed_state,int_error_code);
00295 if(int_error_code)
00296 error_code.val = arm_navigation_msgs::ArmNavigationErrorCodes::SUCCESS;
00297 else
00298 error_code.val = arm_navigation_msgs::ArmNavigationErrorCodes::NO_IK_SOLUTION;
00299 }
00300
00301
00302 void PR2ArmKinematicsPlugin::jointSolutionCallback(const KDL::JntArray& jnt_array,
00303 const KDL::Frame& ik_pose,
00304 arm_navigation_msgs::ArmNavigationErrorCodes& error_code)
00305 {
00306 std::vector<double> ik_seed_state;
00307 ik_seed_state.resize(dimension_);
00308 int int_error_code;
00309 for(int i=0; i < dimension_; i++)
00310 ik_seed_state[i] = jnt_array(i);
00311
00312 geometry_msgs::Pose ik_pose_msg;
00313 tf::poseKDLToMsg(ik_pose,ik_pose_msg);
00314
00315 solutionCallback_(ik_pose_msg,ik_seed_state,int_error_code);
00316 if(int_error_code > 0)
00317 error_code.val = arm_navigation_msgs::ArmNavigationErrorCodes::SUCCESS;
00318 else
00319 error_code.val = arm_navigation_msgs::ArmNavigationErrorCodes::NO_IK_SOLUTION;
00320 }
00321
00322 bool PR2ArmKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
00323 const std::vector<double> &ik_seed_state,
00324 const double &timeout,
00325 std::vector<double> &solution,
00326 const boost::function<void(const geometry_msgs::Pose &ik_pose,const std::vector<double> &ik_solution,int &error_code)> &desired_pose_callback,
00327 const boost::function<void(const geometry_msgs::Pose &ik_pose,const std::vector<double> &ik_solution,int &error_code)> &solution_callback,
00328 int &error_code_int)
00329 {
00330 if(!active_)
00331 {
00332 ROS_ERROR("kinematics not active");
00333 error_code_int = kinematics::INACTIVE;
00334 return false;
00335 }
00336 KDL::Frame pose_desired;
00337 tf::poseMsgToKDL(ik_pose, pose_desired);
00338
00339 desiredPoseCallback_ = desired_pose_callback;
00340 solutionCallback_ = solution_callback;
00341
00342
00343 KDL::JntArray jnt_pos_in;
00344 KDL::JntArray jnt_pos_out;
00345 jnt_pos_in.resize(dimension_);
00346 for(int i=0; i < dimension_; i++)
00347 {
00348 jnt_pos_in(i) = ik_seed_state[i];
00349 }
00350
00351 arm_navigation_msgs::ArmNavigationErrorCodes error_code;
00352 int ik_valid = pr2_arm_ik_solver_->CartToJntSearch(jnt_pos_in,
00353 pose_desired,
00354 jnt_pos_out,
00355 timeout,
00356 error_code,
00357 boost::bind(&PR2ArmKinematicsPlugin::desiredPoseCallback, this, _1, _2, _3),
00358 boost::bind(&PR2ArmKinematicsPlugin::jointSolutionCallback, this, _1, _2, _3));
00359 if(ik_valid == pr2_arm_kinematics::NO_IK_SOLUTION)
00360 return false;
00361
00362 if(ik_valid >= 0)
00363 {
00364 solution.resize(dimension_);
00365 for(int i=0; i < dimension_; i++)
00366 {
00367 solution[i] = jnt_pos_out(i);
00368 }
00369 error_code_int = kinematics::SUCCESS;
00370 return true;
00371 }
00372 else
00373 {
00374 ROS_DEBUG("An IK solution could not be found");
00375 error_code_int = error_code.val;
00376 return false;
00377 }
00378 }
00379
00380 bool PR2ArmKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
00381 const std::vector<double> &ik_seed_state,
00382 const double &timeout,
00383 const unsigned int& redundancy,
00384 const double &consistency_limit,
00385 std::vector<double> &solution,
00386 const boost::function<void(const geometry_msgs::Pose &ik_pose,const std::vector<double> &ik_solution,int &error_code)> &desired_pose_callback,
00387 const boost::function<void(const geometry_msgs::Pose &ik_pose,const std::vector<double> &ik_solution,int &error_code)> &solution_callback,
00388 int &error_code_int)
00389 {
00390 if(!active_)
00391 {
00392 ROS_ERROR("kinematics not active");
00393 error_code_int = kinematics::INACTIVE;
00394 return false;
00395 }
00396 KDL::Frame pose_desired;
00397 tf::poseMsgToKDL(ik_pose, pose_desired);
00398
00399 desiredPoseCallback_ = desired_pose_callback;
00400 solutionCallback_ = solution_callback;
00401
00402
00403 KDL::JntArray jnt_pos_in;
00404 KDL::JntArray jnt_pos_out;
00405 jnt_pos_in.resize(dimension_);
00406 for(int i=0; i < dimension_; i++)
00407 {
00408 jnt_pos_in(i) = ik_seed_state[i];
00409 }
00410
00411 arm_navigation_msgs::ArmNavigationErrorCodes error_code;
00412 unsigned int old_free_angle = pr2_arm_ik_solver_->getFreeAngle();
00413 pr2_arm_ik_solver_->setFreeAngle(redundancy);
00414 int ik_valid = pr2_arm_ik_solver_->CartToJntSearch(jnt_pos_in,
00415 pose_desired,
00416 jnt_pos_out,
00417 consistency_limit,
00418 timeout,
00419 error_code,
00420 boost::bind(&PR2ArmKinematicsPlugin::desiredPoseCallback, this, _1, _2, _3),
00421 boost::bind(&PR2ArmKinematicsPlugin::jointSolutionCallback, this, _1, _2, _3));
00422 pr2_arm_ik_solver_->setFreeAngle(old_free_angle);
00423 if(ik_valid == pr2_arm_kinematics::NO_IK_SOLUTION)
00424 return false;
00425
00426 if(ik_valid >= 0)
00427 {
00428 solution.resize(dimension_);
00429 for(int i=0; i < dimension_; i++)
00430 {
00431 solution[i] = jnt_pos_out(i);
00432 }
00433 error_code_int = kinematics::SUCCESS;
00434 return true;
00435 }
00436 else
00437 {
00438 ROS_DEBUG("An IK solution could not be found");
00439 error_code_int = error_code.val;
00440 return false;
00441 }
00442 }
00443
00444 bool PR2ArmKinematicsPlugin::getPositionFK(const std::vector<std::string> &link_names,
00445 const std::vector<double> &joint_angles,
00446 std::vector<geometry_msgs::Pose> &poses)
00447 {
00448 if(!active_)
00449 {
00450 ROS_ERROR("kinematics not active");
00451 return false;
00452 }
00453
00454 KDL::Frame p_out;
00455 KDL::JntArray jnt_pos_in;
00456 geometry_msgs::PoseStamped pose;
00457 tf::Stamped<tf::Pose> tf_pose;
00458
00459 jnt_pos_in.resize(dimension_);
00460 for(int i=0; i < dimension_; i++)
00461 {
00462 jnt_pos_in(i) = joint_angles[i];
00463 }
00464
00465 poses.resize(link_names.size());
00466
00467 bool valid = true;
00468 for(unsigned int i=0; i < poses.size(); i++)
00469 {
00470 ROS_DEBUG("End effector index: %d",pr2_arm_kinematics::getKDLSegmentIndex(kdl_chain_,link_names[i]));
00471 if(jnt_to_pose_solver_->JntToCart(jnt_pos_in,p_out,pr2_arm_kinematics::getKDLSegmentIndex(kdl_chain_,link_names[i])) >=0)
00472 {
00473 tf::poseKDLToMsg(p_out,poses[i]);
00474 }
00475 else
00476 {
00477 ROS_ERROR("Could not compute FK for %s",link_names[i].c_str());
00478 valid = false;
00479 }
00480 }
00481 return valid;
00482 }
00483
00484 const std::vector<std::string>& PR2ArmKinematicsPlugin::getJointNames() const
00485 {
00486 if(!active_)
00487 {
00488 ROS_ERROR("kinematics not active");
00489 }
00490 return ik_solver_info_.joint_names;
00491 }
00492
00493 const std::vector<std::string>& PR2ArmKinematicsPlugin::getLinkNames() const
00494 {
00495 if(!active_)
00496 {
00497 ROS_ERROR("kinematics not active");
00498 }
00499 return fk_solver_info_.link_names;
00500 }
00501
00502 }