Skip to content
Snippets Groups Projects
ur_moveit_plugin.cpp 4.1 KiB
Newer Older
hyatt's avatar
hyatt committed

Kelsey's avatar
Kelsey committed
#include <ur_kinematics/ur_moveit_plugin.h>
#include <geometry_msgs/PoseStamped.h>
#include <ros/ros.h>
#include <pluginlib/class_list_macros.h>
#include <ur_kinematics/ur_kin.h>
hyatt's avatar
hyatt committed
#include <tf_conversions/tf_kdl.h>
hyatt's avatar
hyatt committed

Kelsey's avatar
Kelsey committed
//register URKinematicsPlugin as a KinematicsBase implementation
PLUGINLIB_EXPORT_CLASS(ur_kinematics::URKinematicsPlugin,kinematics::KinematicsBase);
hyatt's avatar
hyatt committed

Kelsey's avatar
Kelsey committed
namespace ur_kinematics
hyatt's avatar
hyatt committed
{
URKinematicsPlugin::URKinematicsPlugin() 
  : kdl_kinematics_plugin::KDLKinematicsPlugin(), ik_weights_(6) {}
hyatt's avatar
hyatt committed

Kelsey's avatar
Kelsey committed
bool URKinematicsPlugin::searchPositionIK(const geometry_msgs::Pose &ik_pose,
                                          const std::vector<double> &ik_seed_state,
                                          double timeout,
                                          std::vector<double> &solution,
                                          const IKCallbackFn &solution_callback,
                                          moveit_msgs::MoveItErrorCodes &error_code,
                                          const std::vector<double> &consistency_limits,
                                          const kinematics::KinematicsQueryOptions &options) const
hyatt's avatar
hyatt committed
{
Kelsey's avatar
Kelsey committed
  KDL::Frame kdl_ik_pose;
  tf::poseMsgToKDL(ik_pose, kdl_ik_pose);
  double homo_ik_pose[4][4];
  kdl_ik_pose.Make4x4((double*) homo_ik_pose);
  for(int i=0; i<3; i++) homo_ik_pose[i][3] *= 1000;
  double q_ik_sols[8][6]; // maximum of 8 IK solutions
Kelsey's avatar
Kelsey committed
  uint16_t num_sols = inverse((double*) homo_ik_pose, (double*) q_ik_sols, ik_seed_state[5]);
  if(num_sols <= 0) {
    // NO SOLUTION
hyatt's avatar
hyatt committed
    error_code.val = error_code.NO_IK_SOLUTION;
    return false;
  }

  std::vector<int> tried_solutions;
  while(true) {
    // use weighted absolute deviations to determine the solution closest the seed state
    double min_weighted_diff = std::numeric_limits<double>::infinity();
    int min_diff_index = -1;
    for(uint16_t i=0; i<num_sols; i++) {
      if(std::find(tried_solutions.begin(), tried_solutions.end(), i) != tried_solutions.end())
        continue;

      double cur_weighted_diff = 0;
      for(uint16_t j=0; j<6; j++) {
        // solution violates the consistency_limits, throw it out
        if(std::fabs(ik_seed_state[j] - q_ik_sols[i][j]) > consistency_limits[j]) {
          cur_weighted_diff = std::numeric_limits<double>::infinity();
          break;
        }

        cur_weighted_diff += ik_weights_[j] * std::fabs(q_ik_sols[i][j] - ik_seed_state[j]);
      }
      if(cur_weighted_diff != std::numeric_limits<double>::infinity() &&
         cur_weighted_diff < min_weighted_diff) {
        min_weighted_diff = cur_weighted_diff;
        min_diff_index = i;
      }
hyatt's avatar
hyatt committed
    }

    if(min_diff_index < 0) {
      // NO SOLUTION, failed consistency_limits/solution_callback
      error_code.val = error_code.NO_IK_SOLUTION;
      return false;
    // copy the best solution to the output
    solution.resize(6);
    std::copy(q_ik_sols[min_diff_index], q_ik_sols[min_diff_index+1], solution.begin());

    if(!solution_callback.empty())
      solution_callback(ik_pose, solution, error_code);
    else
      error_code.val = error_code.SUCCESS;

    if(error_code.val == error_code.SUCCESS) 
      return true;

    tried_solutions.push_back(min_diff_index);
  }
hyatt's avatar
hyatt committed
}
Kelsey's avatar
Kelsey committed
  /**
* @brief Initialization function for the kinematics
* @return True if initialization was successful, false otherwise
*/
bool URKinematicsPlugin::initialize(const std::string& robot_description,
                                    const std::string& group_name,
                                    const std::string& base_frame,
                                    const std::string& tip_frame,
                                    double search_discretization)
{ 
  ros::NodeHandle private_handle("~");
  if(private_handle.hasParam("ik_weights")) {
    private_handle.getParam("ik_weights", ik_weights_);
  } else {
    ik_weights_[0] = 1.0;
    ik_weights_[1] = 1.0;
    ik_weights_[2] = 0.1;
    ik_weights_[3] = 0.1;
    ik_weights_[4] = 0.3;
    ik_weights_[5] = 0.3;
  }

  return kdl_kinematics_plugin::KDLKinematicsPlugin::initialize(
           robot_description, group_name, base_frame, tip_frame, search_discretization);
}
hyatt's avatar
hyatt committed
}