constraint_app
|
00001 #ifndef FASTFKSOLVER_H 00002 #define FASTFKSOLVER_H 00003 00004 #include <iostream> 00005 #include <kdl/frames_io.hpp> 00006 #include <boost/graph/adjacency_list.hpp> 00007 #include <boost/tuple/tuple.hpp> 00008 #include <boost/utility.hpp> 00009 #include <boost/property_map/property_map.hpp> 00010 00011 class FastFKSolver { 00012 public: 00013 class Data { 00014 public: 00015 Data(const KDL::TreeElement& _element) : name(_element.segment.getName()), 00016 element(_element), frameValid(false) {} 00017 00018 std::string name; 00019 KDL::TreeElement element; 00020 00021 KDL::Frame frame; 00022 bool frameValid; 00023 }; 00024 00025 typedef boost::adjacency_list<boost::listS, boost::listS, boost::bidirectionalS, Data> SegmentGraph; 00026 typedef boost::graph_traits<SegmentGraph>::vertex_descriptor SegmentGraphVertex; 00027 typedef boost::graph_traits<SegmentGraph>::out_edge_iterator SegmentGraphOutEdges; 00028 typedef std::map<std::string, SegmentGraphVertex> VertexMap; 00029 00030 FastFKSolver(const KDL::Tree& tree) : m_tree(tree), 00031 m_log("/tmp/cam2.log", std::ios::trunc|std::ios::binary) { 00032 00033 m_graph.clear(); 00034 m_rootVertex = buildGraph(m_tree.getRootSegment()); 00035 00036 printGraph(); 00037 } 00038 00039 SegmentGraphVertex buildGraph(const KDL::SegmentMap::const_iterator thisSegment) { 00040 m_log << "buildGraph: adding node " << thisSegment->first 00041 << ", with " << thisSegment->second.children.size() << " children" << std::endl; 00042 m_log.flush(); 00043 00044 Data d(thisSegment->second); 00045 SegmentGraphVertex thisVertex = add_vertex(d, m_graph); 00046 00047 m_map.insert(std::pair<std::string, SegmentGraphVertex>(d.name, thisVertex)); 00048 00049 for ( std::vector<KDL::SegmentMap::const_iterator>::const_iterator child = 00050 thisSegment->second.children.begin(); 00051 child != thisSegment->second.children.end(); 00052 ++child ) { 00053 SegmentGraphVertex childVertex = buildGraph(*child); 00054 add_edge(thisVertex, childVertex, m_graph); 00055 } 00056 00057 return thisVertex; 00058 } 00059 00060 void printGraph() { 00061 00062 //loop through the verticies 00063 SegmentGraph::vertex_iterator iter, end; 00064 for ( boost::tie(iter, end) = vertices(m_graph); iter != end; ++iter ) { 00065 SegmentGraphVertex thisVertex = *iter; 00066 m_log << m_graph[thisVertex].name << std::endl; 00067 00068 //loop through all outgoing edges 00069 SegmentGraph::out_edge_iterator out_begin, out_end; 00070 for (boost::tie(out_begin, out_end) = out_edges(thisVertex, m_graph); 00071 out_begin != out_end; ++out_begin) { 00072 SegmentGraphVertex t = target(*out_begin, m_graph); 00073 m_log << " out:" << m_graph[t].name << std::endl; 00074 } 00075 00076 //loop through all incoming edges 00077 SegmentGraph::in_edge_iterator in_begin, in_end; 00078 for (boost::tie(in_begin, in_end) = in_edges(thisVertex, m_graph); 00079 in_begin != in_end; ++in_begin) { 00080 SegmentGraphVertex s = source(*in_begin, m_graph); 00081 m_log << " in:" << m_graph[s].name << std::endl; 00082 } 00083 m_log << std::endl; 00084 } 00085 } 00086 00087 bool getFrame(const std::string& segmentName, 00088 KDL::Frame& frame) { 00089 VertexMap::const_iterator iter = m_map.find(segmentName); 00090 if ( iter == m_map.end() ) return false; 00091 00092 //m_log << "getFrame for " << segmentName << std::endl; 00093 00094 typedef std::list<SegmentGraphVertex> VertexList; 00095 VertexList pendingVertices; 00096 00097 SegmentGraphVertex currentVertex = iter->second; 00098 00099 while ( !m_graph[currentVertex].frameValid ) { 00100 pendingVertices.push_back(currentVertex); 00101 00102 SegmentGraph::in_edge_iterator in_begin, in_end; 00103 boost::tie(in_begin, in_end) = in_edges(currentVertex, m_graph); 00104 00105 if ( in_begin == in_end ) { 00106 m_log << "ERROR: we reached the root vertex without it being known" << std::endl 00107 << m_graph[currentVertex].name << " has no parents, but frameValid=false" << std::endl; 00108 return false; 00109 } 00110 00111 currentVertex = source(*in_begin, m_graph); 00112 } 00113 00114 //at this point, we know that m_graph[currentVertex].frame is correctly calculated 00115 // and we can follow the kinematic chain starting at the back of pendingVertices 00116 frame = m_graph[currentVertex].frame; 00117 for ( VertexList::const_reverse_iterator iter = pendingVertices.rbegin(); 00118 iter != pendingVertices.rend(); ++iter ) { 00119 KDL::TreeElement& currentElement(m_graph[*iter].element); 00120 KDL::Frame currentFrame = currentElement.segment.pose(m_currentJoints(currentElement.q_nr)); 00121 frame = frame * currentFrame; 00122 00123 //m_log << " calculating frame " << m_graph[*iter].name << std::endl; 00124 00125 m_graph[*iter].frameValid = true; 00126 m_graph[*iter].frame = frame; 00127 } 00128 00129 return true; 00130 00131 /* 00132 SegmentGraphVertex currentVertex = iter->second; 00133 KDL::TreeElement currentElement = m_graph[currentVertex].element; 00134 KDL::Frame currentFrame = currentElement.segment.pose(m_currentJoints(currentElement.q_nr)); 00135 00136 //m_log << "starting with frame: " << m_graph[currentVertex].name << std::endl; 00137 frame = currentFrame; 00138 00139 SegmentGraph::in_edge_iterator in_begin, in_end; 00140 boost::tie(in_begin, in_end) = in_edges(currentVertex, m_graph); 00141 00142 // follow the tree back up the incoming edges 00143 while ( in_begin != in_end ) { 00144 currentVertex = source(*in_begin, m_graph); 00145 currentElement = m_graph[currentVertex].element; 00146 currentFrame = currentElement.segment.pose(m_currentJoints(currentElement.q_nr)); 00147 00148 frame = currentFrame * frame; 00149 //m_log << " linked from: " << m_graph[currentVertex].name << std::endl; 00150 00151 boost::tie(in_begin, in_end) = in_edges(currentVertex, m_graph); 00152 } 00153 00154 return true; 00155 */ 00156 } 00157 00158 void setJointPositions(const KDL::JntArray& q_in) { 00159 m_currentJoints = q_in; 00160 00161 //loop through the verticies and clear all the frames 00162 SegmentGraph::vertex_iterator iter, end; 00163 for ( boost::tie(iter, end) = vertices(m_graph); iter != end; ++iter ) { 00164 SegmentGraphVertex thisVertex = *iter; 00165 m_graph[thisVertex].frameValid = false; 00166 } 00167 00168 // by construction, every frame links to the rootVertex 00169 m_graph[m_rootVertex].frameValid = true; 00170 m_graph[m_rootVertex].frame = KDL::Frame::Identity(); 00171 } 00172 00173 KDL::JntArray m_currentJoints; 00174 KDL::Tree m_tree; 00175 SegmentGraph m_graph; 00176 VertexMap m_map; 00177 SegmentGraphVertex m_rootVertex; 00178 std::ofstream m_log; 00179 }; 00180 00181 00182 #endif