00001 #include "ros/ros.h"
00002 #include "kinematics_msgs/GetPositionIK.h"
00003 #include "kinematics_msgs/GetPositionFK.h"
00004 #include "kinematics_msgs/GetConstraintAwarePositionIK.h"
00005 #include "kinematics_msgs/GetKinematicSolverInfo.h"
00006 #include <kdl_parser/kdl_parser.hpp>
00007 #include <geometry_msgs/Pose.h>
00008 #include <tf_conversions/tf_kdl.h>
00009
00010 #include <kdl/chainfksolver.hpp>
00011 #include <kdl/chainfksolverpos_recursive.hpp>
00012 #include <kdl/chainiksolvervel_pinv.hpp>
00013 #include <kdl/chainiksolverpos_nr.hpp>
00014 #include <kdl/chainiksolverpos_nr_jl.hpp>
00015 #include <kdl/frames_io.hpp>
00016 #include <kdl/jntarray.hpp>
00017
00018 using namespace std;
00019 using namespace KDL;
00020 KDL::Chain chain;
00021 KDL::Tree my_tree;
00022
00023 void getKDLChainInfo(kinematics_msgs::KinematicSolverInfo &chain_info)
00024 {
00025 unsigned int nj = chain.getNrOfJoints();
00026 unsigned int nl = chain.getNrOfSegments();
00027
00028 ROS_DEBUG("nj: %d", nj);
00029 ROS_DEBUG("nl: %d", nl);
00030
00031
00032
00033
00034 for(unsigned int i=0; i<nj; i++)
00035 {
00036 ROS_DEBUG("joint_name[%d]: %s", i, chain.getSegment(i).getJoint().getName().c_str());
00037 chain_info.joint_names.push_back(chain.getSegment(i).getJoint().getName());
00038 }
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 for(unsigned int i=0; i<nl; i++)
00054 {
00055 chain_info.link_names.push_back(chain.getSegment(i).getName());
00056 }
00057 }
00058
00059 int getJointIndex(const std::string &name,
00060 const kinematics_msgs::KinematicSolverInfo &chain_info)
00061 {
00062 for(unsigned int i=0; i < chain_info.joint_names.size(); i++)
00063 {
00064 if(chain_info.joint_names[i] == name)
00065 {
00066 return i;
00067 }
00068 }
00069 return -1;
00070 }
00071
00072
00073 bool ik_solve(kinematics_msgs::GetPositionIK::Request &req,
00074 kinematics_msgs::GetPositionIK::Response &res )
00075 {
00076 ROS_INFO("get_ik_service has been called!");
00077
00078 if(req.ik_request.ik_link_name.length() == 0)
00079 my_tree.getChain("base_link","arm_7_link", chain);
00080 else
00081 my_tree.getChain("base_link",req.ik_request.ik_link_name, chain);
00082
00083
00084
00085 unsigned int nj = chain.getNrOfJoints();
00086
00087 JntArray q_min(nj);
00088 JntArray q_max(nj);
00089
00090
00091 for(int i = 0; i < nj; i+=2)
00092 {
00093 q_min(i) =-2.9670;
00094 q_max(i) = 2.9670;
00095 }
00096 for(int i = 1; i < nj; i+=2)
00097 {
00098 q_min(i) =-2.0943951;
00099 q_max(i) = 2.0943951;
00100 }
00101
00102 ChainFkSolverPos_recursive fksolver1(chain);
00103 ChainIkSolverVel_pinv iksolver1v(chain);
00104 ChainIkSolverPos_NR_JL iksolverpos(chain, q_min, q_max, fksolver1,iksolver1v,1000,1e-6);
00105
00106 JntArray q(nj);
00107 JntArray q_init(nj);
00108 for(int i = 0; i < nj; i++)
00109 q_init(i) = req.ik_request.ik_seed_state.joint_state.position[i];
00110 Frame F_dest;
00111 Frame F_ist;
00112 fksolver1.JntToCart(q_init, F_ist);
00113 tf::PoseMsgToKDL(req.ik_request.pose_stamped.pose, F_dest);
00114 std::cout << "Getting Goal\n";
00115 std::cout << F_dest <<"\n";
00116 std::cout << "Calculated Position out of Seed-Configuration:\n";
00117 std::cout << F_ist <<"\n";
00118
00119
00120 int ret = iksolverpos.CartToJnt(q_init,F_dest,q);
00121
00122
00123 res.solution.joint_state.name.resize(nj);
00124 res.solution.joint_state.name[0]="arm_1_joint";
00125 res.solution.joint_state.name[1]="arm_2_joint";
00126 res.solution.joint_state.name[2]="arm_3_joint";
00127 res.solution.joint_state.name[3]="arm_4_joint";
00128 res.solution.joint_state.name[4]="arm_5_joint";
00129 res.solution.joint_state.name[5]="arm_6_joint";
00130 res.solution.joint_state.name[6]="arm_7_joint";
00131
00132 res.solution.joint_state.position.resize(nj);
00133 res.solution.joint_state.velocity.resize(nj);
00134 res.solution.joint_state.effort.resize(nj);
00135 if(ret < 0)
00136 {
00137
00138 res.error_code.val = res.error_code.NO_IK_SOLUTION;
00139 ROS_INFO("Inverse Kinematic found no solution");
00140 std::cout << "RET: " << ret << std::endl;
00141 for(int i = 0; i < nj; i++)
00142 {
00143 res.solution.joint_state.position[i] = q_init(i);
00144 res.solution.joint_state.velocity[i] = 0.0;
00145 res.solution.joint_state.effort[i] = 0.0;
00146 }
00147 }
00148 else
00149 {
00150 ROS_INFO("Inverse Kinematic found a solution");
00151
00152 res.error_code.val = res.error_code.SUCCESS;
00153 for(int i = 0; i < nj; i++)
00154 {
00155 res.solution.joint_state.position[i] = q(i);
00156 res.solution.joint_state.velocity[i] = 0.0;
00157 res.solution.joint_state.effort[i] = 0.0;
00158 }
00159 }
00160
00161 ROS_INFO("q_init: %f %f %f %f %f %f %f", q_init(0), q_init(1), q_init(2), q_init(3), q_init(4), q_init(5), q_init(6));
00162 ROS_INFO("q_out: %f %f %f %f %f %f %f", q(0), q(1), q(2), q(3), q(4), q(5), q(6));
00163
00164
00165
00166 return true;
00167 }
00168
00169
00170
00171 bool constraint_aware_ik_solve(kinematics_msgs::GetConstraintAwarePositionIK::Request &req,
00172 kinematics_msgs::GetConstraintAwarePositionIK::Response &res )
00173 {
00174 kinematics_msgs::GetPositionIK::Request request;
00175 kinematics_msgs::GetPositionIK::Response response;
00176
00177
00178
00179
00180
00181 request.ik_request=req.ik_request;
00182 request.timeout=req.timeout;
00183
00184
00185 bool success = ik_solve(request, response);
00186
00187 if(response.error_code.val == 1) res.error_code.val = res.error_code.SUCCESS;
00188 else res.error_code.val = res.error_code.NO_IK_SOLUTION;
00189
00190 res.solution=response.solution;
00191 res.solution.multi_dof_joint_state = motion_planning_msgs::MultiDOFJointState();
00192
00193 return true;
00194 }
00195
00196
00197 bool getIKSolverInfo(kinematics_msgs::GetKinematicSolverInfo::Request &req,
00198 kinematics_msgs::GetKinematicSolverInfo::Response &res )
00199 {
00200 ROS_INFO("[TESTING]: get_ik_solver_info_service has been called!");
00201
00203 getKDLChainInfo(res.kinematic_solver_info);
00204
00205 return true;
00206 }
00207
00208 bool fk_solve_TCP(kinematics_msgs::GetPositionFK::Request &req,
00209 kinematics_msgs::GetPositionFK::Response &res )
00210 {
00211 ROS_INFO("[TESTING]: get_fk_TCP_service has been called!");
00212
00213 unsigned int nj = chain.getNrOfJoints();
00214
00215 ChainFkSolverPos_recursive fksolver1(chain);
00216
00217 JntArray conf(nj);
00218 geometry_msgs::PoseStamped pose;
00219 tf::Stamped<tf::Pose> tf_pose;
00220
00221 for(int i = 0; i < nj; i++)
00222 conf(i) = req.robot_state.joint_state.position[i];
00223 Frame F_ist;
00224 res.pose_stamped.resize(1);
00225 res.fk_link_names.resize(1);
00226 if(fksolver1.JntToCart(conf, F_ist) >= 0)
00227 {
00228 std::cout << "Calculated Position out of Configuration:\n";
00229 std::cout << F_ist <<"\n";
00230
00231
00232
00233 tf_pose.frame_id_ = "base_link";
00234 tf_pose.stamp_ = ros::Time();
00235 tf::PoseKDLToTF(F_ist,tf_pose);
00236 try
00237 {
00238
00239 }
00240 catch(...)
00241 {
00242 ROS_ERROR("Could not transform FK pose to frame: %s",req.header.frame_id.c_str());
00243 res.error_code.val = res.error_code.FRAME_TRANSFORM_FAILURE;
00244 return false;
00245 }
00246 tf::poseStampedTFToMsg(tf_pose,pose);
00247 res.pose_stamped[0] = pose;
00248 res.fk_link_names[0] = "arm_7_link";
00249 res.error_code.val = res.error_code.SUCCESS;
00250 }
00251 else
00252 {
00253 ROS_ERROR("Could not compute FK for arm_7_link");
00254 res.error_code.val = res.error_code.NO_FK_SOLUTION;
00255 }
00256
00257 return true;
00258 }
00259
00260 bool fk_solve_all(kinematics_msgs::GetPositionFK::Request &req,
00261 kinematics_msgs::GetPositionFK::Response &res )
00262 {
00263 ROS_INFO("[TESTING]: get_fk_all_service has been called!");
00264
00265 unsigned int nj = chain.getNrOfJoints();
00266 unsigned int nl = chain.getNrOfSegments();
00267
00268 ChainFkSolverPos_recursive fksolver1(chain);
00269
00270 JntArray conf(nj);
00271 geometry_msgs::PoseStamped pose;
00272 tf::Stamped<tf::Pose> tf_pose;
00273
00274 for(int i = 0; i < nj; i++)
00275 conf(i) = req.robot_state.joint_state.position[i];
00276 Frame F_ist;
00277 res.pose_stamped.resize(nl);
00278 res.fk_link_names.resize(nl);
00279 for(int j = 0; j < nl; j++)
00280 {
00281 if(fksolver1.JntToCart(conf, F_ist, j+1) >= 0)
00282 {
00283 std::cout << "Calculated Position out of Configuration for segment " << j+1 << ":\n";
00284 std::cout << F_ist <<"\n";
00285
00286 std::cout << "Calculated Position out of Configuration:\n";
00287 std::cout << F_ist <<"\n";
00288
00289
00290
00291 tf_pose.frame_id_ = "base_link";
00292 tf_pose.stamp_ = ros::Time();
00293 tf::PoseKDLToTF(F_ist,tf_pose);
00294 try
00295 {
00296
00297 }
00298 catch(...)
00299 {
00300 ROS_ERROR("Could not transform FK pose to frame: %s",req.header.frame_id.c_str());
00301 res.error_code.val = res.error_code.FRAME_TRANSFORM_FAILURE;
00302 return false;
00303 }
00304 tf::poseStampedTFToMsg(tf_pose,pose);
00305 res.pose_stamped[j] = pose;
00306 res.fk_link_names[j] = chain.getSegment(j).getName();
00307 res.error_code.val = res.error_code.SUCCESS;
00308 }
00309 else
00310 {
00311 ROS_ERROR("Could not compute FK for segment %d", j);
00312 res.error_code.val = res.error_code.NO_FK_SOLUTION;
00313 }
00314
00315
00316
00317
00318 }
00319
00320 return true;
00321 }
00322
00323
00324 bool fk_solve(kinematics_msgs::GetPositionFK::Request &req,
00325 kinematics_msgs::GetPositionFK::Response &res )
00326 {
00327 ROS_INFO("[TESTING]: get_fk_service has been called!");
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 return true;
00388 }
00389
00390
00391 bool getFKSolverInfo(kinematics_msgs::GetKinematicSolverInfo::Request &req,
00392 kinematics_msgs::GetKinematicSolverInfo::Response &res)
00393 {
00394 ROS_INFO("[TESTING]: get_fk_solver_info_service has been called!");
00395
00396 getKDLChainInfo(res.kinematic_solver_info);
00397
00398 return true;
00399 }
00400
00401
00402
00403 int main(int argc, char **argv)
00404 {
00405 ros::init(argc, argv, "cob_ik_solver");
00406 ros::NodeHandle n;
00407 ros::NodeHandle node;
00408 std::string robot_desc_string;
00409 node.param("/robot_description", robot_desc_string, string());
00410 if (!kdl_parser::treeFromString(robot_desc_string, my_tree)){
00411 ROS_ERROR("Failed to construct kdl tree");
00412 return false;
00413 }
00414 my_tree.getChain("base_link","arm_7_link", chain);
00415
00416
00417 ros::ServiceServer get_ik_service = n.advertiseService("get_ik", ik_solve);
00418 ros::ServiceServer get_constraint_aware_ik_service = n.advertiseService("get_constraint_aware_ik", constraint_aware_ik_solve);
00419 ros::ServiceServer get_ik_solver_info_service = n.advertiseService("get_ik_solver_info", getIKSolverInfo);
00420 ros::ServiceServer get_fk_service = n.advertiseService("get_fk", fk_solve);
00421 ros::ServiceServer get_fk_tcp_service = n.advertiseService("get_fk_tcp", fk_solve_TCP);
00422 ros::ServiceServer get_fk_all_service = n.advertiseService("get_fk_all", fk_solve_all);
00423 ros::ServiceServer get_fk_solver_info_service = n.advertiseService("get_fk_solver_info", getFKSolverInfo);
00424
00425
00426 ROS_INFO("IK Server Running.");
00427 ros::spin();
00428
00429 return 0;
00430 }