ik_fast_solver.h
Go to the documentation of this file.
00001 #include <Eigen/Geometry>
00002 #include <float.h>
00003 #include <algorithm>
00004 #include <vector>
00005 
00006 typedef double IKReal;
00007 
00008 inline bool distance_op(std::pair<unsigned int, double> i,
00009                         std::pair<unsigned int, double> j) {
00010   return i.second < j.second;
00011 }
00012 
00013 namespace moveit_setup_assistant
00014 {
00015 class ik_solver_base {
00016 public:
00017   virtual int solve(Eigen::Affine3d &pose, const std::vector<double> &ik_seed_state) = 0;
00018   virtual void getSolution(int i, std::vector<double> &solution) = 0;
00019   virtual void getClosestSolution(const std::vector<double> &ik_seed_state, std::vector<double> &solution) = 0;
00020   virtual void getOrderedSolutions(const std::vector<double> &ik_seed_state,
00021                                    int num_solutions,
00022                                    std::vector<std::vector<double> >& solutions) = 0;
00023 
00024 };
00025 template <class  T> class ikfast_solver: public ik_solver_base{
00026 public:
00027   typedef bool (*ik_type)(const IKReal* eetrans, const IKReal* eerot, const IKReal* pfree, std::vector<T>& vsolutions);
00028   ikfast_solver(ik_type ik,int numJoints):ik(ik),numJoints(numJoints) {}
00029 
00030   virtual int solve(Eigen::Affine3d &pose, const std::vector<double> &vfree){
00031 
00032     solutions.clear();
00033 
00034     //Eigen::Affine3d rot(Eigen::AngleAxisd(M_PI/2, Eigen::Vector3d::UnitY()));
00035 
00036     Eigen::Matrix3d rot = pose.rotation();
00037 
00038     double vals[9];
00039     vals[0] = rot(0,0);
00040     vals[1] = rot(0,1);
00041     vals[2] = rot(0,2);
00042     vals[3] = rot(1,0);
00043     vals[4] = rot(1,1);
00044     vals[5] = rot(1,2);
00045     vals[6] = rot(2,0);
00046     vals[7] = rot(2,1);
00047     vals[8] = rot(2,2);
00048 
00049     double trans[3];
00050     trans[0] = pose.translation().x();
00051     trans[1] = pose.translation().y();
00052     trans[2] = pose.translation().z();
00053 
00054     ik(trans, vals, vfree.size() > 0 ? &vfree[0] : NULL, solutions);
00055 
00056     return solutions.size();
00057   }
00058   virtual void getSolution(int i, std::vector<double> &solution){
00059     solution.clear();
00060     std::vector<IKReal> vsolfree(solutions[i].GetFree().size());
00061     solution.clear();
00062     solution.resize(numJoints);
00063     solutions[i].GetSolution(&solution[0],vsolfree.size()>0?&vsolfree[0]:NULL);
00064     // std::cout << "solution " << i << ":" ;
00065     // for(int j=0;j<numJoints; ++j)
00066     //   std::cout << " " << solution[j];
00067     // std::cout << std::endl;
00068 
00069     //ROS_ERROR("%f %d",solution[2],vsolfree.size());
00070   }
00071   double harmonize(const std::vector<double> &ik_seed_state, std::vector<double> &solution){
00072     if(ik_seed_state.size() != solution.size()) {
00073       ROS_WARN_STREAM("Different number of values in seed and solution!");
00074     }
00075     for(unsigned int i = 0; i < ik_seed_state.size(); i++) {
00076       ROS_DEBUG_STREAM(i << " " << ik_seed_state[i] << " " << solution[i]);
00077     }
00078     double dist = 0;
00079     std::vector<double> ss = ik_seed_state;
00080     for(size_t i=0; i< ik_seed_state.size(); ++i){
00081       while(ss[i] > 2*M_PI) {
00082         ss[i] -= 2*M_PI;
00083       }
00084       while(ss[i] < -2*M_PI) {
00085         ss[i] += 2*M_PI;
00086       }
00087       while(solution[i] > 2*M_PI) {
00088         solution[i] -= 2*M_PI;
00089       }
00090       while(solution[i] < -2*M_PI) {
00091         solution[i] += 2*M_PI;
00092       }
00093       dist += fabs(ik_seed_state[i] - solution[i]);
00094     }
00095     ROS_DEBUG_STREAM("Dist " << dist);
00096     return dist;
00097   }
00098 
00099   double harmonize_old(const std::vector<double> &ik_seed_state, std::vector<double> &solution){
00100     double dist_sqr = 0;
00101     for(size_t i=0; i< ik_seed_state.size(); ++i){
00102       double diff = ik_seed_state[i] - solution[i];
00103       if( diff > M_PI ) solution[i]+=2*M_PI;
00104       else if (diff < -M_PI) solution[i]-=2*M_PI;
00105       diff = ik_seed_state[i] - solution[i];
00106       dist_sqr += fabs(diff);
00107     }
00108     return dist_sqr;
00109   }
00110 
00111   virtual void getOrderedSolutions(const std::vector<double> &ik_seed_state,
00112                                    int num_solutions,
00113                                    std::vector<std::vector<double> >& solutions){
00114     solutions.resize(num_solutions);
00115     std::vector<std::pair<unsigned int, double> > distances;
00116     std::vector<double> sol;
00117     for(unsigned int i = 0; i < (unsigned int)num_solutions; i++){
00118       getSolution(i,sol);
00119       double dist = harmonize(ik_seed_state, sol);
00120       solutions[i] = sol;
00121       distances.push_back(std::pair<unsigned int, double>(i, dist));
00122     };
00123     std::sort(distances.begin(), distances.end(), distance_op);
00124     std::vector<std::vector<double> > solutions_ret(solutions.size());
00125     for(unsigned int i = 0; i < distances.size(); i++) {
00126       solutions_ret[i] = solutions[distances[i].first];
00127     }
00128     solutions = solutions_ret;
00129   }
00130 
00131   virtual void getClosestSolution(const std::vector<double> &ik_seed_state, std::vector<double> &solution){
00132     double mindist = DBL_MAX;
00133     int minindex = -1;
00134     std::vector<double> sol;
00135     for(size_t i=0;i<solutions.size();++i){
00136       getSolution(i,sol);
00137       double dist = harmonize(ik_seed_state, sol);
00138       ROS_INFO_STREAM("Dist " << i << " dist " << dist);
00139       //std::cout << "dist[" << i << "]= " << dist << std::endl;
00140       if(minindex == -1 || dist<mindist){
00141         minindex = i;
00142         mindist = dist;
00143       }
00144     }
00145     if(minindex >= 0){
00146       getSolution(minindex,solution);
00147       harmonize(ik_seed_state, solution);
00148     }
00149   }
00150 
00151 
00152 
00153 private:
00154   ik_type ik;
00155   std::vector<T> solutions;
00156   int numJoints;
00157 };
00158 }


moveit_setup_assistant
Author(s): Dave Coleman
autogenerated on Mon Oct 6 2014 02:32:27