00001 #include <class_loader/class_loader.h>
00002
00003
00004 #include <tf_conversions/tf_kdl.h>
00005 #include <kdl_parser/kdl_parser.hpp>
00006
00007
00008 #include <urdf_model/model.h>
00009 #include <srdfdom/model.h>
00010
00011 #include <moveit/rdf_loader/rdf_loader.h>
00012
00013
00014 #include <aubo_kinematics/aubo_moveit_plugin.h>
00015 #include <aubo_kinematics/aubo_kin.h>
00016
00017
00018 CLASS_LOADER_REGISTER_CLASS(aubo_kinematics::AuboKinematicsPlugin, kinematics::KinematicsBase)
00019
00020 namespace aubo_kinematics
00021 {
00022
00023 AuboKinematicsPlugin::AuboKinematicsPlugin():active_(false) {}
00024
00025 void AuboKinematicsPlugin::getRandomConfiguration(KDL::JntArray &jnt_array, bool lock_redundancy) const
00026 {
00027 std::vector<double> jnt_array_vector(dimension_, 0.0);
00028 state_->setToRandomPositions(joint_model_group_);
00029 state_->copyJointGroupPositions(joint_model_group_, &jnt_array_vector[0]);
00030 for (std::size_t i = 0; i < dimension_; ++i)
00031 {
00032 if (lock_redundancy)
00033 if (isRedundantJoint(i))
00034 continue;
00035 jnt_array(i) = jnt_array_vector[i];
00036 }
00037 }
00038
00039 bool AuboKinematicsPlugin::isRedundantJoint(unsigned int index) const
00040 {
00041 for (std::size_t j=0; j < redundant_joint_indices_.size(); ++j)
00042 if (redundant_joint_indices_[j] == index)
00043 return true;
00044 return false;
00045 }
00046
00047 void AuboKinematicsPlugin::getRandomConfiguration(const KDL::JntArray &seed_state,
00048 const std::vector<double> &consistency_limits,
00049 KDL::JntArray &jnt_array,
00050 bool lock_redundancy) const
00051 {
00052 std::vector<double> values(dimension_, 0.0);
00053 std::vector<double> near(dimension_, 0.0);
00054 for (std::size_t i = 0 ; i < dimension_; ++i)
00055 near[i] = seed_state(i);
00056
00057
00058 std::vector<double> consistency_limits_mimic;
00059 for(std::size_t i = 0; i < dimension_; ++i)
00060 {
00061 if(!mimic_joints_[i].active)
00062 continue;
00063 consistency_limits_mimic.push_back(consistency_limits[i]);
00064 }
00065
00066 joint_model_group_->getVariableRandomPositionsNearBy(state_->getRandomNumberGenerator(), values, near, consistency_limits_mimic);
00067
00068 for (std::size_t i = 0; i < dimension_; ++i)
00069 {
00070 bool skip = false;
00071 if (lock_redundancy)
00072 for (std::size_t j = 0; j < redundant_joint_indices_.size(); ++j)
00073 if (redundant_joint_indices_[j] == i)
00074 {
00075 skip = true;
00076 break;
00077 }
00078 if (skip)
00079 continue;
00080 jnt_array(i) = values[i];
00081 }
00082 }
00083
00084 bool AuboKinematicsPlugin::checkConsistency(const KDL::JntArray& seed_state,
00085 const std::vector<double> &consistency_limits,
00086 const KDL::JntArray& solution) const
00087 {
00088 for (std::size_t i = 0; i < dimension_; ++i)
00089 if (fabs(seed_state(i) - solution(i)) > consistency_limits[i])
00090 return false;
00091 return true;
00092 }
00093
00094 bool AuboKinematicsPlugin::initialize(const std::string &robot_description,
00095 const std::string& group_name,
00096 const std::string& base_frame,
00097 const std::string& tip_frame,
00098 double search_discretization)
00099 {
00100 setValues(robot_description, group_name, base_frame, tip_frame, search_discretization);
00101
00102 ros::NodeHandle private_handle("~");
00103 rdf_loader::RDFLoader rdf_loader(robot_description_);
00104 const boost::shared_ptr<srdf::Model> &srdf = rdf_loader.getSRDF();
00105 const boost::shared_ptr<urdf::ModelInterface>& urdf_model = rdf_loader.getURDF();
00106
00107 if (!urdf_model || !srdf)
00108 {
00109 ROS_ERROR_NAMED("kdl","URDF and SRDF must be loaded for KDL kinematics solver to work.");
00110 return false;
00111 }
00112
00113 robot_model_.reset(new robot_model::RobotModel(urdf_model, srdf));
00114
00115 robot_model::JointModelGroup* joint_model_group = robot_model_->getJointModelGroup(group_name);
00116 if (!joint_model_group)
00117 return false;
00118
00119 if(!joint_model_group->isChain())
00120 {
00121 ROS_ERROR_NAMED("kdl","Group '%s' is not a chain", group_name.c_str());
00122 return false;
00123 }
00124 if(!joint_model_group->isSingleDOFJoints())
00125 {
00126 ROS_ERROR_NAMED("kdl","Group '%s' includes joints that have more than 1 DOF", group_name.c_str());
00127 return false;
00128 }
00129
00130 KDL::Tree kdl_tree;
00131
00132 if (!kdl_parser::treeFromUrdfModel(*urdf_model, kdl_tree))
00133 {
00134 ROS_ERROR_NAMED("kdl","Could not initialize tree object");
00135 return false;
00136 }
00137 if (!kdl_tree.getChain(base_frame_, getTipFrame(), kdl_chain_))
00138 {
00139 ROS_ERROR_NAMED("kdl","Could not initialize chain object");
00140 return false;
00141 }
00142
00143 dimension_ = joint_model_group->getActiveJointModels().size() + joint_model_group->getMimicJointModels().size();
00144 for (std::size_t i=0; i < joint_model_group->getJointModels().size(); ++i)
00145 {
00146 if(joint_model_group->getJointModels()[i]->getType() == moveit::core::JointModel::REVOLUTE || joint_model_group->getJointModels()[i]->getType() == moveit::core::JointModel::PRISMATIC)
00147 {
00148 ik_chain_info_.joint_names.push_back(joint_model_group->getJointModelNames()[i]);
00149 const std::vector<moveit_msgs::JointLimits> &jvec = joint_model_group->getJointModels()[i]->getVariableBoundsMsg();
00150 ik_chain_info_.limits.insert(ik_chain_info_.limits.end(), jvec.begin(), jvec.end());
00151 }
00152 }
00153
00154 fk_chain_info_.joint_names = ik_chain_info_.joint_names;
00155 fk_chain_info_.limits = ik_chain_info_.limits;
00156
00157 if(!joint_model_group->hasLinkModel(getTipFrame()))
00158 {
00159 ROS_ERROR_NAMED("kdl","Could not find tip name in joint group '%s'", group_name.c_str());
00160 return false;
00161 }
00162 ik_chain_info_.link_names.push_back(getTipFrame());
00163 fk_chain_info_.link_names = joint_model_group->getLinkModelNames();
00164
00165 joint_min_.resize(ik_chain_info_.limits.size());
00166 joint_max_.resize(ik_chain_info_.limits.size());
00167
00168 for(unsigned int i=0; i < ik_chain_info_.limits.size(); i++)
00169 {
00170 joint_min_(i) = ik_chain_info_.limits[i].min_position;
00171 joint_max_(i) = ik_chain_info_.limits[i].max_position;
00172 }
00173
00174
00175 int max_solver_iterations;
00176 double epsilon;
00177 bool position_ik;
00178
00179 private_handle.param("max_solver_iterations", max_solver_iterations, 500);
00180 private_handle.param("epsilon", epsilon, 1e-5);
00181 private_handle.param(group_name+"/position_only_ik", position_ik, false);
00182 ROS_DEBUG_NAMED("kdl","Looking in private handle: %s for param name: %s",
00183 private_handle.getNamespace().c_str(),
00184 (group_name+"/position_only_ik").c_str());
00185
00186 if(position_ik)
00187 ROS_ERROR_NAMED("kdl","Using position only ik");
00188
00189 num_possible_redundant_joints_ = kdl_chain_.getNrOfJoints() - joint_model_group->getMimicJointModels().size() - (position_ik? 3:6);
00190
00191
00192 bool has_mimic_joints = joint_model_group->getMimicJointModels().size() > 0;
00193 std::vector<unsigned int> redundant_joints_map_index;
00194
00195 std::vector<kdl_kinematics_plugin::JointMimic> mimic_joints;
00196 unsigned int joint_counter = 0;
00197 for (std::size_t i = 0; i < kdl_chain_.getNrOfSegments(); ++i)
00198 {
00199 const robot_model::JointModel *jm = robot_model_->getJointModel(kdl_chain_.segments[i].getJoint().getName());
00200
00201
00202 if (jm->getMimic() == NULL && jm->getVariableCount() > 0)
00203 {
00204 kdl_kinematics_plugin::JointMimic mimic_joint;
00205 mimic_joint.reset(joint_counter);
00206 mimic_joint.joint_name = kdl_chain_.segments[i].getJoint().getName();
00207 mimic_joint.active = true;
00208 mimic_joints.push_back(mimic_joint);
00209 ++joint_counter;
00210 continue;
00211 }
00212 if (joint_model_group->hasJointModel(jm->getName()))
00213 {
00214 if (jm->getMimic() && joint_model_group->hasJointModel(jm->getMimic()->getName()))
00215 {
00216 kdl_kinematics_plugin::JointMimic mimic_joint;
00217 mimic_joint.reset(joint_counter);
00218 mimic_joint.joint_name = kdl_chain_.segments[i].getJoint().getName();
00219 mimic_joint.offset = jm->getMimicOffset();
00220 mimic_joint.multiplier = jm->getMimicFactor();
00221 mimic_joints.push_back(mimic_joint);
00222 continue;
00223 }
00224 }
00225 }
00226 for (std::size_t i = 0; i < mimic_joints.size(); ++i)
00227 {
00228 if(!mimic_joints[i].active)
00229 {
00230 const robot_model::JointModel* joint_model = joint_model_group->getJointModel(mimic_joints[i].joint_name)->getMimic();
00231 for(std::size_t j=0; j < mimic_joints.size(); ++j)
00232 {
00233 if(mimic_joints[j].joint_name == joint_model->getName())
00234 {
00235 mimic_joints[i].map_index = mimic_joints[j].map_index;
00236 }
00237 }
00238 }
00239 }
00240 mimic_joints_ = mimic_joints;
00241
00242
00243 state_.reset(new robot_state::RobotState(robot_model_));
00244 state_2_.reset(new robot_state::RobotState(robot_model_));
00245
00246
00247 position_ik_ = position_ik;
00248 joint_model_group_ = joint_model_group;
00249 max_solver_iterations_ = max_solver_iterations;
00250 epsilon_ = epsilon;
00251
00252 private_handle.param<std::string>("arm_prefix", arm_prefix_, "");
00253
00254 aubo_joint_names_.push_back(arm_prefix_ + "shoulder_joint");
00255 aubo_joint_names_.push_back(arm_prefix_ + "upperArm_joint");
00256 aubo_joint_names_.push_back(arm_prefix_ + "foreArm_joint");
00257 aubo_joint_names_.push_back(arm_prefix_ + "wrist1_joint");
00258 aubo_joint_names_.push_back(arm_prefix_ + "wrist2_joint");
00259 aubo_joint_names_.push_back(arm_prefix_ + "wrist3_joint");
00260
00261 aubo_link_names_.push_back(arm_prefix_ + "base_Link");
00262 aubo_link_names_.push_back(arm_prefix_ + "shoulder_Link");
00263 aubo_link_names_.push_back(arm_prefix_ + "upperArm_Link");
00264 aubo_link_names_.push_back(arm_prefix_ + "foreArm_Link");
00265 aubo_link_names_.push_back(arm_prefix_ + "wrist1_Link");
00266 aubo_link_names_.push_back(arm_prefix_ + "wrist2_Link");
00267 aubo_link_names_.push_back(arm_prefix_ + "wrist3_Link");
00268 aubo_link_names_.push_back(arm_prefix_ + "ee_Link");
00269
00270 aubo_joint_inds_start_ = getJointIndex(aubo_joint_names_[0]);
00271
00272
00273 int cur_aubo_joint_ind, last_aubo_joint_ind = aubo_joint_inds_start_;
00274 for(int i=1; i<6; i++) {
00275 cur_aubo_joint_ind = getJointIndex(aubo_joint_names_[i]);
00276 if(cur_aubo_joint_ind < 0) {
00277 ROS_ERROR_NAMED("kdl",
00278 "Kin chain provided in model doesn't contain standard Aubo joint '%s'.",
00279 aubo_joint_names_[i].c_str());
00280 return false;
00281 }
00282 if(cur_aubo_joint_ind != last_aubo_joint_ind + 1) {
00283 ROS_ERROR_NAMED("kdl",
00284 "Kin chain provided in model doesn't have proper serial joint order: '%s'.",
00285 aubo_joint_names_[i].c_str());
00286 return false;
00287 }
00288 last_aubo_joint_ind = cur_aubo_joint_ind;
00289 }
00290
00291
00292 kdl_tree.getChain(getBaseFrame(), aubo_link_names_.front(), kdl_base_chain_);
00293 kdl_tree.getChain(aubo_link_names_.back(), getTipFrame(), kdl_tip_chain_);
00294
00295
00296 ik_weights_.resize(6);
00297 if(private_handle.hasParam("ik_weights")) {
00298 private_handle.getParam("ik_weights", ik_weights_);
00299 } else {
00300 ik_weights_[0] = 1.0;
00301 ik_weights_[1] = 1.0;
00302 ik_weights_[2] = 0.1;
00303 ik_weights_[3] = 0.1;
00304 ik_weights_[4] = 0.3;
00305 ik_weights_[5] = 0.3;
00306 }
00307
00308 active_ = true;
00309 ROS_DEBUG_NAMED("kdl","KDL solver initialized");
00310 return true;
00311 }
00312
00313 bool AuboKinematicsPlugin::setRedundantJoints(const std::vector<unsigned int> &redundant_joints)
00314 {
00315 if(num_possible_redundant_joints_ < 0)
00316 {
00317 ROS_ERROR_NAMED("kdl","This group cannot have redundant joints");
00318 return false;
00319 }
00320 if(redundant_joints.size() > num_possible_redundant_joints_)
00321 {
00322 ROS_ERROR_NAMED("kdl","This group can only have %d redundant joints", num_possible_redundant_joints_);
00323 return false;
00324 }
00325 std::vector<unsigned int> redundant_joints_map_index;
00326 unsigned int counter = 0;
00327 for(std::size_t i=0; i < dimension_; ++i)
00328 {
00329 bool is_redundant_joint = false;
00330 for(std::size_t j=0; j < redundant_joints.size(); ++j)
00331 {
00332 if(i == redundant_joints[j])
00333 {
00334 is_redundant_joint = true;
00335 counter++;
00336 break;
00337 }
00338 }
00339 if(!is_redundant_joint)
00340 {
00341
00342 if(mimic_joints_[i].active)
00343 {
00344 redundant_joints_map_index.push_back(counter);
00345 counter++;
00346 }
00347 }
00348 }
00349 for(std::size_t i=0; i < redundant_joints_map_index.size(); ++i)
00350 ROS_DEBUG_NAMED("kdl","Redundant joint map index: %d %d", (int) i, (int) redundant_joints_map_index[i]);
00351
00352 redundant_joints_map_index_ = redundant_joints_map_index;
00353 redundant_joint_indices_ = redundant_joints;
00354 return true;
00355 }
00356
00357 int AuboKinematicsPlugin::getJointIndex(const std::string &name) const
00358 {
00359 for (unsigned int i=0; i < ik_chain_info_.joint_names.size(); i++) {
00360 if (ik_chain_info_.joint_names[i] == name)
00361 return i;
00362 }
00363 return -1;
00364 }
00365
00366 int AuboKinematicsPlugin::getKDLSegmentIndex(const std::string &name) const
00367 {
00368 int i=0;
00369 while (i < (int)kdl_chain_.getNrOfSegments()) {
00370 if (kdl_chain_.getSegment(i).getName() == name) {
00371 return i+1;
00372 }
00373 i++;
00374 }
00375 return -1;
00376 }
00377
00378 bool AuboKinematicsPlugin::timedOut(const ros::WallTime &start_time, double duration) const
00379 {
00380 return ((ros::WallTime::now()-start_time).toSec() >= duration);
00381 }
00382
00383 bool AuboKinematicsPlugin::getPositionIK(const geometry_msgs::Pose &ik_pose,
00384 const std::vector<double> &ik_seed_state,
00385 std::vector<double> &solution,
00386 moveit_msgs::MoveItErrorCodes &error_code,
00387 const kinematics::KinematicsQueryOptions &options) const
00388 {
00389 const IKCallbackFn solution_callback = 0;
00390 std::vector<double> consistency_limits;
00391
00392 return searchPositionIK(ik_pose,
00393 ik_seed_state,
00394 default_timeout_,
00395 solution,
00396 solution_callback,
00397 error_code,
00398 consistency_limits,
00399 options);
00400 }
00401
00402 bool AuboKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
00403 const std::vector<double> &ik_seed_state,
00404 double timeout,
00405 std::vector<double> &solution,
00406 moveit_msgs::MoveItErrorCodes &error_code,
00407 const kinematics::KinematicsQueryOptions &options) const
00408 {
00409 const IKCallbackFn solution_callback = 0;
00410 std::vector<double> consistency_limits;
00411
00412 return searchPositionIK(ik_pose,
00413 ik_seed_state,
00414 timeout,
00415 solution,
00416 solution_callback,
00417 error_code,
00418 consistency_limits,
00419 options);
00420 }
00421
00422 bool AuboKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
00423 const std::vector<double> &ik_seed_state,
00424 double timeout,
00425 const std::vector<double> &consistency_limits,
00426 std::vector<double> &solution,
00427 moveit_msgs::MoveItErrorCodes &error_code,
00428 const kinematics::KinematicsQueryOptions &options) const
00429 {
00430 const IKCallbackFn solution_callback = 0;
00431 return searchPositionIK(ik_pose,
00432 ik_seed_state,
00433 timeout,
00434 solution,
00435 solution_callback,
00436 error_code,
00437 consistency_limits,
00438 options);
00439 }
00440
00441 bool AuboKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
00442 const std::vector<double> &ik_seed_state,
00443 double timeout,
00444 std::vector<double> &solution,
00445 const IKCallbackFn &solution_callback,
00446 moveit_msgs::MoveItErrorCodes &error_code,
00447 const kinematics::KinematicsQueryOptions &options) const
00448 {
00449 std::vector<double> consistency_limits;
00450 return searchPositionIK(ik_pose,
00451 ik_seed_state,
00452 timeout,
00453 solution,
00454 solution_callback,
00455 error_code,
00456 consistency_limits,
00457 options);
00458 }
00459
00460 bool AuboKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
00461 const std::vector<double> &ik_seed_state,
00462 double timeout,
00463 const std::vector<double> &consistency_limits,
00464 std::vector<double> &solution,
00465 const IKCallbackFn &solution_callback,
00466 moveit_msgs::MoveItErrorCodes &error_code,
00467 const kinematics::KinematicsQueryOptions &options) const
00468 {
00469 return searchPositionIK(ik_pose,
00470 ik_seed_state,
00471 timeout,
00472 solution,
00473 solution_callback,
00474 error_code,
00475 consistency_limits,
00476 options);
00477 }
00478
00479 typedef std::pair<int, double> idx_double;
00480 bool comparator(const idx_double& l, const idx_double& r)
00481 { return l.second < r.second; }
00482
00483 bool AuboKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
00484 const std::vector<double> &ik_seed_state,
00485 double timeout,
00486 std::vector<double> &solution,
00487 const IKCallbackFn &solution_callback,
00488 moveit_msgs::MoveItErrorCodes &error_code,
00489 const std::vector<double> &consistency_limits,
00490 const kinematics::KinematicsQueryOptions &options) const
00491 {
00492 ros::WallTime n1 = ros::WallTime::now();
00493 if(!active_) {
00494 ROS_ERROR_NAMED("kdl","kinematics not active");
00495 error_code.val = error_code.NO_IK_SOLUTION;
00496 return false;
00497 }
00498
00499 if(ik_seed_state.size() != dimension_) {
00500 ROS_ERROR_STREAM_NAMED("kdl","Seed state must have size " << dimension_ << " instead of size " << ik_seed_state.size());
00501 error_code.val = error_code.NO_IK_SOLUTION;
00502 return false;
00503 }
00504
00505 if(!consistency_limits.empty() && consistency_limits.size() != dimension_) {
00506 ROS_ERROR_STREAM_NAMED("kdl","Consistency limits be empty or must have size " << dimension_ << " instead of size " << consistency_limits.size());
00507 error_code.val = error_code.NO_IK_SOLUTION;
00508 return false;
00509 }
00510
00511 KDL::JntArray jnt_seed_state(dimension_);
00512 for(int i=0; i<dimension_; i++)
00513 jnt_seed_state(i) = ik_seed_state[i];
00514
00515 solution.resize(dimension_);
00516
00517 KDL::ChainFkSolverPos_recursive fk_solver_base(kdl_base_chain_);
00518 KDL::ChainFkSolverPos_recursive fk_solver_tip(kdl_tip_chain_);
00519
00520 KDL::JntArray jnt_pos_test(jnt_seed_state);
00521 KDL::JntArray jnt_pos_base(aubo_joint_inds_start_);
00522 KDL::JntArray jnt_pos_tip(dimension_ - 6 - aubo_joint_inds_start_);
00523 KDL::Frame pose_base, pose_tip;
00524
00525 KDL::Frame kdl_ik_pose;
00526 KDL::Frame kdl_ik_pose_aubo_chain;
00527 double homo_ik_pose[4][4];
00528 double q_ik_sols[8][6];
00529 uint16_t num_sols;
00530
00531 while(1) {
00532 if(timedOut(n1, timeout)) {
00533 ROS_DEBUG_NAMED("kdl","IK timed out");
00534 error_code.val = error_code.TIMED_OUT;
00535 return false;
00536 }
00537
00539
00540 for(uint32_t i=0; i<jnt_pos_base.rows(); i++)
00541 jnt_pos_base(i) = jnt_pos_test(i);
00542 for(uint32_t i=0; i<jnt_pos_tip.rows(); i++)
00543 jnt_pos_tip(i) = jnt_pos_test(i + aubo_joint_inds_start_ + 6);
00544 for(uint32_t i=0; i<jnt_seed_state.rows(); i++)
00545 solution[i] = jnt_pos_test(i);
00546
00547 if(fk_solver_base.JntToCart(jnt_pos_base, pose_base) < 0) {
00548 ROS_ERROR_NAMED("kdl", "Could not compute FK for base chain");
00549 return false;
00550 }
00551
00552 if(fk_solver_tip.JntToCart(jnt_pos_tip, pose_tip) < 0) {
00553 ROS_ERROR_NAMED("kdl", "Could not compute FK for tip chain");
00554 return false;
00555 }
00557
00559
00560 tf::poseMsgToKDL(ik_pose, kdl_ik_pose);
00561 kdl_ik_pose_aubo_chain = pose_base.Inverse() * kdl_ik_pose * pose_tip.Inverse();
00562
00563 kdl_ik_pose_aubo_chain.Make4x4((double*) homo_ik_pose);
00564 #if KDL_OLD_BUG_FIX
00565
00566 for(int i=0; i<3; i++) homo_ik_pose[i][3] *= 1000;
00567 #endif
00568
00569
00570
00571
00572
00573 num_sols = inverse((double*) homo_ik_pose, (double*) q_ik_sols);
00574
00575
00576
00577
00578
00579
00580
00581 uint16_t num_valid_sols;
00582 std::vector< std::vector<double> > q_ik_valid_sols;
00583 for(uint16_t i=0; i<num_sols; i++)
00584 {
00585 bool valid = true;
00586 std::vector< double > valid_solution;
00587 valid_solution.assign(6,0.0);
00588
00589 for(uint16_t j=0; j<6; j++)
00590 {
00591 if((q_ik_sols[i][j] <= ik_chain_info_.limits[j].max_position) && (q_ik_sols[i][j] >= ik_chain_info_.limits[j].min_position))
00592 {
00593 valid_solution[j] = q_ik_sols[i][j];
00594 valid = true;
00595 continue;
00596 }
00597 else if ((q_ik_sols[i][j] > ik_chain_info_.limits[j].max_position) && (q_ik_sols[i][j]-2*M_PI > ik_chain_info_.limits[j].min_position))
00598 {
00599 valid_solution[j] = q_ik_sols[i][j]-2*M_PI;
00600 valid = true;
00601 continue;
00602 }
00603 else if ((q_ik_sols[i][j] < ik_chain_info_.limits[j].min_position) && (q_ik_sols[i][j]+2*M_PI < ik_chain_info_.limits[j].max_position))
00604 {
00605 valid_solution[j] = q_ik_sols[i][j]+2*M_PI;
00606 valid = true;
00607 continue;
00608 }
00609 else
00610 {
00611 valid = false;
00612 break;
00613 }
00614 }
00615
00616 if(valid)
00617 {
00618 q_ik_valid_sols.push_back(valid_solution);
00619 }
00620 }
00621
00622
00623
00624 std::vector<idx_double> weighted_diffs;
00625 for(uint16_t i=0; i<q_ik_valid_sols.size(); i++) {
00626 double cur_weighted_diff = 0;
00627 for(uint16_t j=0; j<6; j++) {
00628
00629 double abs_diff = std::fabs(ik_seed_state[aubo_joint_inds_start_+j] - q_ik_valid_sols[i][j]);
00630 if(!consistency_limits.empty() && abs_diff > consistency_limits[aubo_joint_inds_start_+j]) {
00631 cur_weighted_diff = std::numeric_limits<double>::infinity();
00632 break;
00633 }
00634 cur_weighted_diff += ik_weights_[j] * abs_diff;
00635 }
00636 weighted_diffs.push_back(idx_double(i, cur_weighted_diff));
00637 }
00638
00639 std::sort(weighted_diffs.begin(), weighted_diffs.end(), comparator);
00640
00641 #if 0
00642 printf("start\n");
00643 printf(" q %1.2f, %1.2f, %1.2f, %1.2f, %1.2f, %1.2f\n", ik_seed_state[1], ik_seed_state[2], ik_seed_state[3], ik_seed_state[4], ik_seed_state[5], ik_seed_state[6]);
00644 for(uint16_t i=0; i<weighted_diffs.size(); i++) {
00645 int cur_idx = weighted_diffs[i].first;
00646 printf("diff %f, i %d, q %1.2f, %1.2f, %1.2f, %1.2f, %1.2f, %1.2f\n", weighted_diffs[i].second, cur_idx, q_ik_valid_sols[cur_idx][0], q_ik_valid_sols[cur_idx][1], q_ik_valid_sols[cur_idx][2], q_ik_valid_sols[cur_idx][3], q_ik_valid_sols[cur_idx][4], q_ik_valid_sols[cur_idx][5]);
00647 }
00648 printf("end\n");
00649 #endif
00650
00651 for(uint16_t i=0; i<weighted_diffs.size(); i++) {
00652 if(weighted_diffs[i].second == std::numeric_limits<double>::infinity()) {
00653
00654 break;
00655 }
00656
00657
00658 int cur_idx = weighted_diffs[i].first;
00659 solution = q_ik_valid_sols[cur_idx];
00660
00661
00662 if(!solution_callback.empty())
00663 solution_callback(ik_pose, solution, error_code);
00664 else
00665 error_code.val = error_code.SUCCESS;
00666
00667 if(error_code.val == error_code.SUCCESS) {
00668 #if 0
00669 std::vector<std::string> fk_link_names;
00670 fk_link_names.push_back(aubo_link_names_.back());
00671 std::vector<geometry_msgs::Pose> fk_poses;
00672 getPositionFK(fk_link_names, solution, fk_poses);
00673 KDL::Frame kdl_fk_pose;
00674 tf::poseMsgToKDL(fk_poses[0], kdl_fk_pose);
00675 printf("FK(solution) - pose \n");
00676 for(int i=0; i<4; i++) {
00677 for(int j=0; j<4; j++)
00678 printf("%1.6f ", kdl_fk_pose(i, j)-kdl_ik_pose(i, j));
00679 printf("\n");
00680 }
00681 #endif
00682 return true;
00683 }
00684 }
00685
00686
00687 if(options.lock_redundant_joints) {
00688 ROS_DEBUG_NAMED("kdl","Will not pertubate redundant joints to find solution");
00689 break;
00690 }
00691
00692 if(dimension_ == 6) {
00693 ROS_DEBUG_NAMED("kdl","No other joints to pertubate, cannot find solution");
00694 break;
00695 }
00696
00697
00698 if(!consistency_limits.empty()) {
00699 getRandomConfiguration(jnt_seed_state, consistency_limits, jnt_pos_test, false);
00700 } else {
00701 getRandomConfiguration(jnt_pos_test, false);
00702 }
00703 }
00704
00705 ROS_DEBUG_NAMED("kdl","An IK that satisifes the constraints and is collision free could not be found");
00706 error_code.val = error_code.NO_IK_SOLUTION;
00707 return false;
00708 }
00709
00710 bool AuboKinematicsPlugin::getPositionFK(const std::vector<std::string> &link_names,
00711 const std::vector<double> &joint_angles,
00712 std::vector<geometry_msgs::Pose> &poses) const
00713 {
00714 ros::WallTime n1 = ros::WallTime::now();
00715 if(!active_)
00716 {
00717 ROS_ERROR_NAMED("kdl","kinematics not active");
00718 return false;
00719 }
00720 poses.resize(link_names.size());
00721 if(joint_angles.size() != dimension_)
00722 {
00723 ROS_ERROR_NAMED("kdl","Joint angles vector must have size: %d",dimension_);
00724 return false;
00725 }
00726
00727 KDL::Frame p_out;
00728 geometry_msgs::PoseStamped pose;
00729 tf::Stamped<tf::Pose> tf_pose;
00730
00731 KDL::JntArray jnt_pos_in(dimension_);
00732 for(unsigned int i=0; i < dimension_; i++)
00733 {
00734 jnt_pos_in(i) = joint_angles[i];
00735 }
00736
00737 KDL::ChainFkSolverPos_recursive fk_solver(kdl_chain_);
00738
00739 bool valid = true;
00740 for(unsigned int i=0; i < poses.size(); i++)
00741 {
00742 ROS_DEBUG_NAMED("kdl","End effector index: %d",getKDLSegmentIndex(link_names[i]));
00743 if(fk_solver.JntToCart(jnt_pos_in,p_out,getKDLSegmentIndex(link_names[i])) >=0)
00744 {
00745 tf::poseKDLToMsg(p_out,poses[i]);
00746 }
00747 else
00748 {
00749 ROS_ERROR_NAMED("kdl","Could not compute FK for %s",link_names[i].c_str());
00750 valid = false;
00751 }
00752 }
00753 return valid;
00754 }
00755
00756 const std::vector<std::string>& AuboKinematicsPlugin::getJointNames() const
00757 {
00758 return ik_chain_info_.joint_names;
00759 }
00760
00761 const std::vector<std::string>& AuboKinematicsPlugin::getLinkNames() const
00762 {
00763 return ik_chain_info_.link_names;
00764 }
00765
00766 }