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 #include <constrained_ik/constrained_ik_plugin.h>
00026 #include <constrained_ik/ik/basic_ik.h>
00027 #include <constrained_ik/ik/test_ik.h>
00028 #include <ros/ros.h>
00029
00030 #include <kdl_parser/kdl_parser.hpp>
00031 #include <tf_conversions/tf_kdl.h>
00032 #include <eigen_conversions/eigen_kdl.h>
00033
00034 #include <pluginlib/class_list_macros.h>
00035
00036 PLUGINLIB_EXPORT_CLASS(constrained_ik::ConstrainedIKPlugin, kinematics::KinematicsBase);
00037
00038 using namespace KDL;
00039 using namespace tf;
00040 using namespace std;
00041 using namespace ros;
00042
00043 namespace constrained_ik
00044 {
00045
00046
00047 typedef test_ik::Test_IK Solver;
00048
00049 ConstrainedIKPlugin::ConstrainedIKPlugin():active_(false), dimension_(0)
00050 {
00051 }
00052
00053 bool ConstrainedIKPlugin::isActive()
00054 {
00055 if(active_)
00056 return true;
00057 ROS_ERROR("kinematics not active");
00058 return false;
00059 }
00060
00061 bool ConstrainedIKPlugin::isActive() const
00062 {
00063 if(active_)
00064 return true;
00065 ROS_ERROR("kinematics not active");
00066 return false;
00067 }
00068
00069 bool ConstrainedIKPlugin::initialize(const std::string& robot_description,
00070 const std::string& group_name,
00071 const std::string& base_name,
00072 const std::string& tip_name,
00073 double search_discretization)
00074 {
00075 setValues(robot_description, group_name, base_name, tip_name, search_discretization);
00076
00077
00078 urdf::Model robot_model;
00079 if (!robot_model.initParam(robot_description))
00080 {
00081 ROS_ERROR_STREAM("Could not load URDF model from " << robot_description);
00082 active_ = false;
00083 return false;
00084 }
00085
00086
00087 if (!kin_.init(robot_model, base_frame_, tip_frame_))
00088 {
00089 ROS_ERROR("Could not load ik");
00090 active_ = false;
00091 }
00092 else
00093 {
00094 dimension_ = kin_.numJoints();
00095 kin_.getJointNames(joint_names_);
00096 kin_.getLinkNames(link_names_);
00097 active_ = true;
00098 }
00099 return active_;
00100 }
00101
00102 bool ConstrainedIKPlugin::getPositionIK(const geometry_msgs::Pose &ik_pose,
00103 const std::vector<double> &ik_seed_state,
00104 std::vector<double> &solution,
00105 moveit_msgs::MoveItErrorCodes &error_code,
00106 const kinematics::KinematicsQueryOptions &options) const
00107 {
00108
00109 if(!active_)
00110 {
00111 ROS_ERROR("kinematics not active");
00112 error_code.val = error_code.NO_IK_SOLUTION;
00113 return false;
00114 }
00115 if(ik_seed_state.size() != dimension_)
00116 {
00117 ROS_ERROR("ik_seed_state does not have same dimension as solver");
00118 error_code.val = error_code.NO_IK_SOLUTION;
00119 return false;
00120 }
00121
00122
00123 KDL::Frame pose_desired;
00124 tf::poseMsgToKDL(ik_pose, pose_desired);
00125 Eigen::Affine3d goal;
00126 tf::transformKDLToEigen(pose_desired, goal);
00127
00128 Eigen::VectorXd seed(dimension_), joint_angles(dimension_);
00129 for(size_t ii=0; ii < dimension_; ++ii)
00130 {
00131 seed(ii) = ik_seed_state[ii];
00132 }
00133
00134
00135 Solver solver;
00136 solver.init(kin_);
00137
00138
00139 try { solver.calcInvKin(goal, seed, joint_angles); }
00140 catch (exception &e)
00141 {
00142 ROS_ERROR_STREAM("Caught exception from IK: " << e.what());
00143 error_code.val = error_code.NO_IK_SOLUTION;
00144 return false;
00145 }
00146 solution.resize(dimension_);
00147 for(size_t ii=0; ii < dimension_; ++ii)
00148 {
00149 solution[ii] = joint_angles(ii);
00150 }
00151 error_code.val = error_code.SUCCESS;
00152 return true;
00153 }
00154
00155 bool ConstrainedIKPlugin::searchPositionIK( const geometry_msgs::Pose &ik_pose,
00156 const std::vector<double> &ik_seed_state,
00157 double timeout,
00158 std::vector<double> &solution,
00159 moveit_msgs::MoveItErrorCodes &error_code,
00160 const kinematics::KinematicsQueryOptions &options) const
00161 {
00162 static IKCallbackFn solution_callback = 0;
00163 static std::vector<double> consistency_limits;
00164 return searchPositionIK(ik_pose, ik_seed_state, timeout, consistency_limits, solution, solution_callback, error_code);
00165 }
00166
00167 bool ConstrainedIKPlugin::searchPositionIK( const geometry_msgs::Pose &ik_pose,
00168 const std::vector<double> &ik_seed_state,
00169 double timeout,
00170 const std::vector<double> &consistency_limits,
00171 std::vector<double> &solution,
00172 moveit_msgs::MoveItErrorCodes &error_code,
00173 const kinematics::KinematicsQueryOptions &options) const
00174 {
00175 static IKCallbackFn solution_callback = 0;
00176 return searchPositionIK(ik_pose, ik_seed_state, timeout, consistency_limits, solution, solution_callback, error_code);
00177 }
00178
00179 bool ConstrainedIKPlugin::searchPositionIK( const geometry_msgs::Pose &ik_pose,
00180 const std::vector<double> &ik_seed_state,
00181 double timeout,
00182 std::vector<double> &solution,
00183 const IKCallbackFn &solution_callback,
00184 moveit_msgs::MoveItErrorCodes &error_code,
00185 const kinematics::KinematicsQueryOptions &options) const
00186 {
00187 static std::vector<double> consistency_limits;
00188 return searchPositionIK(ik_pose, ik_seed_state, timeout, consistency_limits, solution, solution_callback, error_code);
00189 }
00190
00191 bool ConstrainedIKPlugin::searchPositionIK( const geometry_msgs::Pose &ik_pose,
00192 const std::vector<double> &ik_seed_state,
00193 double timeout,
00194 const std::vector<double> &consistency_limits,
00195 std::vector<double> &solution,
00196 const IKCallbackFn &solution_callback,
00197 moveit_msgs::MoveItErrorCodes &error_code,
00198 const kinematics::KinematicsQueryOptions &options) const
00199 {
00200
00201 if(!active_)
00202 {
00203 ROS_ERROR("kinematics not active");
00204 error_code.val = error_code.FAILURE;
00205 return false;
00206 }
00207
00208 KDL::Frame pose_desired;
00209 tf::poseMsgToKDL(ik_pose, pose_desired);
00210 Eigen::Affine3d goal;
00211 tf::transformKDLToEigen(pose_desired, goal);
00212
00213 Eigen::VectorXd seed(dimension_), joint_angles;
00214 for(size_t ii=0; ii < dimension_; ii++)
00215 {
00216 seed(ii) = ik_seed_state[ii];
00217 }
00218
00219 bool success(true);
00220
00221
00222 Solver solver;
00223 solver.init(kin_);
00224 try { solver.calcInvKin(goal, seed, joint_angles); }
00225 catch (exception &e)
00226 {
00227 ROS_ERROR_STREAM("Caught exception in plugin from IK: " << e.what());
00228 error_code.val = error_code.NO_IK_SOLUTION;
00229
00230 success &= false;
00231 }
00232 solution.resize(dimension_);
00233 for(size_t ii=0; ii < dimension_; ++ii)
00234 {
00235 solution[ii] = joint_angles(ii);
00236 }
00237
00238
00239 if (solution_callback)
00240 {
00241 solution_callback(ik_pose, solution, error_code);
00242 if(error_code.val != error_code.SUCCESS)
00243 success &= false;
00244 }
00245
00246
00247 if (success)
00248 error_code.val = error_code.SUCCESS;
00249
00250 return success;
00251
00252 }
00253
00254 bool ConstrainedIKPlugin::getPositionFK(const std::vector<std::string> &link_names,
00255 const std::vector<double> &joint_angles,
00256 std::vector<geometry_msgs::Pose> &poses) const
00257 {
00258 if(!active_)
00259 {
00260 ROS_ERROR("kinematics not active");
00261 return false;
00262 }
00263
00264 Eigen::VectorXd jnt_pos_in;
00265 geometry_msgs::PoseStamped pose;
00266 tf::Stamped<tf::Pose> tf_pose;
00267
00268 jnt_pos_in.resize(dimension_);
00269 for(int i=0; i < dimension_; i++)
00270 {
00271 jnt_pos_in(i) = joint_angles[i];
00272
00273 }
00274
00275 poses.resize(link_names.size());
00276
00277 std::vector<KDL::Frame> kdl_poses;
00278 bool valid = kin_.linkTransforms(jnt_pos_in, kdl_poses, link_names);
00279 for(size_t ii=0; ii < kdl_poses.size(); ++ii)
00280 {
00281 tf::poseKDLToMsg(kdl_poses[ii],poses[ii]);
00282 }
00283
00284 ROS_INFO_STREAM("poses: ");
00285 for (size_t ii=0; ii<poses.size(); ++ii)
00286 {
00287 ROS_INFO_STREAM(poses[ii]);
00288 }
00289 return valid;
00290 }
00291
00292 const std::vector<std::string>& ConstrainedIKPlugin::getJointNames() const
00293 {
00294 isActive();
00295 return joint_names_;
00296 }
00297
00298 const std::vector<std::string>& ConstrainedIKPlugin::getLinkNames() const
00299 {
00300 isActive();
00301 return link_names_;
00302 }
00303
00304
00305 }