Go to the documentation of this file.00001 #include <tf_conversions/tf_kdl.h>
00002
00003 typedef double IKReal;
00004
00005 namespace arm_kinematics_constraint_aware {
00006 class ik_solver_base{
00007 public:
00008 virtual int solve(KDL::Frame &pose_frame, const std::vector<double> &ik_seed_state) = 0;
00009 virtual void getSolution(int i, std::vector<double> &solution) = 0;
00010 virtual void getClosestSolution(const std::vector<double> &ik_seed_state, std::vector<double> &solution) = 0;
00011 };
00012 template <class T> class ikfast_solver: public ik_solver_base{
00013 public:
00014 typedef bool (*ik_type)(const IKReal* eetrans, const IKReal* eerot, const IKReal* pfree, std::vector<T>& vsolutions);
00015 ikfast_solver(ik_type ik,int numJoints):ik(ik),numJoints(numJoints) {}
00016 virtual int solve(KDL::Frame &pose_frame, const std::vector<double> &vfree){
00017
00018 solutions.clear();
00019 KDL::Rotation rot = KDL::Rotation::RotY(M_PI/2);
00020 KDL::Rotation orig = pose_frame.M;
00021
00022 KDL::Rotation mult = orig;
00023
00024 double vals[9];
00025 vals[0] = mult(0,0);
00026 vals[1] = mult(0,1);
00027 vals[2] = mult(0,2);
00028 vals[3] = mult(1,0);
00029 vals[4] = mult(1,1);
00030 vals[5] = mult(1,2);
00031 vals[6] = mult(2,0);
00032 vals[7] = mult(2,1);
00033 vals[8] = mult(2,2);
00034
00035 double trans[3];
00036 trans[0] = pose_frame.p[0];
00037 trans[1] = pose_frame.p[1];
00038 trans[2] = pose_frame.p[2];
00039
00040 ik(trans, vals, vfree.size() > 0 ? &vfree[0] : NULL, solutions);
00041
00042 return solutions.size();
00043 }
00044 virtual void getSolution(int i, std::vector<double> &solution){
00045 solution.clear();
00046 std::vector<IKReal> vsolfree(solutions[i].GetFree().size());
00047 solution.clear();
00048 solution.resize(numJoints);
00049 solutions[i].GetSolution(&solution[0],vsolfree.size()>0?&vsolfree[0]:NULL);
00050
00051
00052
00053
00054
00055
00056 }
00057 double harmonize(const std::vector<double> &ik_seed_state, std::vector<double> &solution){
00058 double dist_sqr = 0;
00059 std::vector<double> ss = ik_seed_state;
00060 for(size_t i=0; i< ik_seed_state.size(); ++i){
00061 while(ss[i] > 2*M_PI) {
00062 ss[i] -= 2*M_PI;
00063 }
00064 while(ss[i] < 2*M_PI) {
00065 ss[i] += 2*M_PI;
00066 }
00067 while(solution[i] > 2*M_PI) {
00068 solution[i] -= 2*M_PI;
00069 }
00070 while(solution[i] < 2*M_PI) {
00071 solution[i] += 2*M_PI;
00072 }
00073 dist_sqr += fabs(ik_seed_state[i] - solution[i]);
00074 }
00075 return dist_sqr;
00076 }
00077
00078 double harmonize_old(const std::vector<double> &ik_seed_state, std::vector<double> &solution){
00079 double dist_sqr = 0;
00080 for(size_t i=0; i< ik_seed_state.size(); ++i){
00081 double diff = ik_seed_state[i] - solution[i];
00082 if( diff > M_PI ) solution[i]+=2*M_PI;
00083 else if (diff < -M_PI) solution[i]-=2*M_PI;
00084 diff = ik_seed_state[i] - solution[i];
00085 dist_sqr += fabs(diff);
00086 }
00087 return dist_sqr;
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 virtual void getClosestSolution(const std::vector<double> &ik_seed_state, std::vector<double> &solution){
00114 double mindist = DBL_MAX;
00115 int minindex = -1;
00116 std::vector<double> sol;
00117 for(size_t i=0;i<solutions.size();++i){
00118 getSolution(i,sol);
00119 double dist = harmonize(ik_seed_state, sol);
00120 ROS_INFO_STREAM("Dist " << i << " dist " << dist);
00121
00122 if(minindex == -1 || dist<mindist){
00123 minindex = i;
00124 mindist = dist;
00125 }
00126 }
00127 if(minindex >= 0){
00128 getSolution(minindex,solution);
00129 harmonize(ik_seed_state, solution);
00130 }
00131 }
00132
00133
00134
00135 private:
00136 ik_type ik;
00137 std::vector<T> solutions;
00138 int numJoints;
00139 };
00140 }