constraint_app
|
00001 #include "MyTreeJntToJacSolver.hpp" 00002 #include <iostream> 00003 #include <kdl/kinfam_io.hpp> 00004 #include <kdl/treejnttojacsolver.hpp> 00005 00006 using namespace KDL; 00007 00008 MyTreeJntToJacSolver::MyTreeJntToJacSolver(const Tree& tree_in) : 00009 tree(tree_in) { 00010 } 00011 00012 MyTreeJntToJacSolver::~MyTreeJntToJacSolver() { 00013 } 00014 00015 int MyTreeJntToJacSolver::JntToJac(const JntArray& q_in, Jacobian& jac, const std::string& segmentname) { 00016 //First we check all the sizes: 00017 if (q_in.rows() != tree.getNrOfJoints() || jac.columns() != tree.getNrOfJoints()) 00018 return -1; 00019 00020 //Lets search the tree-element 00021 SegmentMap::const_iterator it = tree.getSegments().find(segmentname); 00022 00023 //If segmentname is not inside the tree, back out: 00024 if (it == tree.getSegments().end()) 00025 return -2; 00026 00027 //Let's make the jacobian zero: 00028 SetToZero(jac); 00029 00030 SegmentMap::const_iterator root = tree.getRootSegment(); 00031 00032 Frame T_total = Frame::Identity(); 00033 Frame T_local; 00034 //Lets recursively iterate until we are in the root segment 00035 while (it != root) { 00036 //get the corresponding q_nr for this TreeElement: 00037 unsigned int q_nr = it->second.q_nr; 00038 00039 //get the pose of the segment: 00040 std::string thisSegmentName(it->second.segment.getName()); 00041 if ( thisSegmentName == "segment_roll" ) { 00042 //compute the T_local all the way from segment_x 00043 SegmentMap::const_iterator it_temp = it; 00044 00045 while ( it_temp != root ) { 00046 unsigned int q_nr_temp = it_temp->second.q_nr; 00047 Frame T_local_temp = it_temp->second.segment.pose(q_in(q_nr_temp)); 00048 T_local = T_local_temp * T_local; 00049 if ( it_temp->second.segment.getName() == "segment_x" ) break; 00050 it_temp = it_temp->second.parent; 00051 } 00052 if ( it_temp == root ) return -3; 00053 T_total = T_local * T_total; 00054 00055 } else if ( thisSegmentName == "segment_pitch" || 00056 thisSegmentName == "segment_yaw" || 00057 thisSegmentName == "segment_z" || 00058 thisSegmentName == "segment_y" || 00059 thisSegmentName == "segment_x" ) { 00060 //do nothing because we've all these joints take place at the same point 00061 } else { 00062 // this is just a normal joint 00063 T_local = it->second.segment.pose(q_in(q_nr)); 00064 T_total = T_local * T_total; 00065 } 00066 //Frame T_local = it->second.segment.pose(q_in(q_nr)); 00067 //calculate new T_end: 00068 //T_total = T_local * T_total; 00069 00070 //get the twist of the segment: 00071 if (it->second.segment.getJoint().getType() != Joint::None) { 00072 Twist t_local = it->second.segment.twist(q_in(q_nr), 1.0); 00073 //transform the endpoint of the local twist to the global endpoint: 00074 t_local = t_local.RefPoint(T_total.p - T_local.p); 00075 //transform the base of the twist to the endpoint 00076 t_local = T_total.M.Inverse(t_local); 00077 //store the twist in the jacobian: 00078 jac.setColumn(q_nr,t_local); 00079 }//endif 00080 //goto the parent 00081 it = it->second.parent; 00082 }//endwhile 00083 //Change the base of the complete jacobian from the endpoint to the base 00084 changeBase(jac, T_total.M, jac); 00085 00086 return 0; 00087 00088 }//end JntToJac 00089 00090