bool KDLRobotModel::computeFastIK(const std::vector<double> &pose, const std::vector<double> &start, std::vector<double> &solution)
{
  //pose: {x,y,z,r,p,y} or {x,y,z,qx,qy,qz,qw}

  KDL::Frame frame_des;
  frame_des.p.x(pose[0]);
  frame_des.p.y(pose[1]);
  frame_des.p.z(pose[2]);

  // RPY
  if(pose.size() == 6)
    frame_des.M = KDL::Rotation::RPY(pose[3],pose[4],pose[5]);
  // quaternion
  else
    frame_des.M = KDL::Rotation::Quaternion(pose[3],pose[4],pose[5],pose[6]);

  // transform into kinematics frame
  frame_des = T_planning_to_kinematics_ * frame_des;

  // seed configuration
  for(size_t i = 0; i < start.size(); i++)
    jnt_pos_in_(i) = angles::normalize_angle(start[i]); // must be normalized for CartToJntSearch

  if(ik_solver_->CartToJnt(jnt_pos_in_, frame_des, jnt_pos_out_) < 0)
    return false;

  solution.resize(start.size());
  for(size_t i = 0; i < solution.size(); ++i)
    solution[i] = angles::normalize_angle(jnt_pos_out_(i));

  return true;
}
bool KDLRobotModel::computeIKSearch(const std::vector<double> &pose, const std::vector<double> &start, std::vector<double> &solution, double timeout)
{
  //pose: {x,y,z,r,p,y} or {x,y,z,qx,qy,qz,qw}
  KDL::Frame frame_des;
  frame_des.p.x(pose[0]);
  frame_des.p.y(pose[1]);
  frame_des.p.z(pose[2]);

  // RPY
  if(pose.size() == 6)
    frame_des.M = KDL::Rotation::RPY(pose[3],pose[4],pose[5]);
  // quaternion
  else
    frame_des.M = KDL::Rotation::Quaternion(pose[3],pose[4],pose[5],pose[6]);

  // transform into kinematics frame
  frame_des = T_planning_to_kinematics_ * frame_des;

  // seed configuration
  for(size_t i = 0; i < start.size(); i++)
    jnt_pos_in_(i) = angles::normalize_angle(start[i]); // must be normalized for CartToJntSearch

  double initial_guess = jnt_pos_in_(free_angle_);
  double search_discretization_angle = 0.02;

  ros::Time start_time = ros::Time::now();
  double loop_time = 0;
  int count = 0;

  int num_positive_increments = (int)((min_limits_[free_angle_]-initial_guess)/search_discretization_angle);
  int num_negative_increments = (int)((initial_guess-min_limits_[free_angle_])/search_discretization_angle);
  while(loop_time < timeout)
  {
    if(ik_solver_->CartToJnt(jnt_pos_in_, frame_des, jnt_pos_out_) >= 0)
    {
      solution.resize(start.size());
      for(size_t i = 0; i < solution.size(); ++i)
        solution[i] = angles::normalize_angle(jnt_pos_out_(i));
      return true;
    }
    if(!getCount(count,num_positive_increments,-num_negative_increments))
      return false;
    jnt_pos_in_(free_angle_) = initial_guess + search_discretization_angle * count;
    ROS_DEBUG("%d, %f",count,jnt_pos_in_(free_angle_));
    loop_time = (ros::Time::now()-start_time).toSec();
  }
  if(loop_time >= timeout)
  {
    ROS_DEBUG("IK Timed out in %f seconds",timeout);
    return false;
  }
  else
  {
    ROS_DEBUG("No IK solution was found");
    return false;
  }
  return false;
}
bool KDLKinematicsPlugin::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
{
  ros::WallTime n1 = ros::WallTime::now();
  if(!active_)
  {
    ROS_ERROR("kinematics not active");
    error_code.val = error_code.NO_IK_SOLUTION;
    return false;
  }

  if(ik_seed_state.size() != dimension_)
  {
    ROS_ERROR_STREAM("Seed state must have size " << dimension_ << " instead of size " << ik_seed_state.size());
    error_code.val = error_code.NO_IK_SOLUTION;
    return false;    
  }

  if(!consistency_limits.empty() && consistency_limits.size() != dimension_)
  {
    ROS_ERROR_STREAM("Consistency limits be empty or must have size " << dimension_ << " instead of size " << consistency_limits.size());
    error_code.val = error_code.NO_IK_SOLUTION;
    return false;        
  }  

  solution.resize(dimension_);
  
  KDL::Frame pose_desired;
  tf::poseMsgToKDL(ik_pose, pose_desired);
  
  ROS_DEBUG_STREAM("searchPositionIK2: Position request pose is " <<
                   ik_pose.position.x << " " <<
                   ik_pose.position.y << " " <<
                   ik_pose.position.z << " " <<
                   ik_pose.orientation.x << " " << 
                   ik_pose.orientation.y << " " << 
                   ik_pose.orientation.z << " " << 
                   ik_pose.orientation.w);
  //Do the IK
  for(unsigned int i=0; i < dimension_; i++)
    jnt_seed_state_(i) = ik_seed_state[i]; 
  jnt_pos_in_ = jnt_seed_state_;

  unsigned int counter(0);  
  while(1)  
  {
    //    ROS_DEBUG("Iteration: %d, time: %f, Timeout: %f",counter,(ros::WallTime::now()-n1).toSec(),timeout);    
    counter++;    
    if(timedOut(n1,timeout))
    {
      ROS_DEBUG("IK timed out");
      error_code.val = error_code.TIMED_OUT;
      return false;      
    }    
    int ik_valid = ik_solver_pos_->CartToJnt(jnt_pos_in_,pose_desired,jnt_pos_out_);                     
    if(!consistency_limits.empty()) 
    {
      getRandomConfiguration(jnt_seed_state_, consistency_limits, jnt_pos_in_);
      if(ik_valid < 0 || !checkConsistency(jnt_seed_state_, consistency_limits, jnt_pos_out_))
      {
        ROS_DEBUG("Could not find IK solution");        
        continue;
      } 
    }
    else
    {
      getRandomConfiguration(jnt_pos_in_);
      if(ik_valid < 0)
      {
        ROS_DEBUG("Could not find IK solution");        
        continue;
      }      
    }
    ROS_DEBUG("Found IK solution");    
    for(unsigned int j=0; j < dimension_; j++)
      solution[j] = jnt_pos_out_(j);
    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)
    {
      ROS_DEBUG_STREAM("Solved after " << counter << " iterations");
      return true;
    }
  }
  ROS_DEBUG("An IK that satisifes the constraints and is collision free could not be found");   
  error_code.val = error_code.NO_IK_SOLUTION;
  return false;
}