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
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
00065
00066
00067
00068
00069
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
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 }