SRBA: Sparser Relative Bundle Adjustment
|
00001 /* +---------------------------------------------------------------------------+ 00002 | Mobile Robot Programming Toolkit (MRPT) | 00003 | http://www.mrpt.org/ | 00004 | | 00005 | Copyright (c) 2005-2015, Individual contributors, see AUTHORS file | 00006 | See: http://www.mrpt.org/Authors - All rights reserved. | 00007 | Released under BSD License. See details in http://www.mrpt.org/License | 00008 +---------------------------------------------------------------------------+ */ 00009 00010 #pragma once 00011 00012 namespace srba { 00013 00014 00015 // Exports all the keyframes and landmarks as a directed graph in DOT (graphviz) format 00016 template <class KF2KF_POSE_TYPE,class LM_TYPE,class OBS_TYPE,class RBA_OPTIONS> 00017 bool RbaEngine<KF2KF_POSE_TYPE,LM_TYPE,OBS_TYPE,RBA_OPTIONS>::save_graph_as_dot( 00018 const std::string &targetFileName, 00019 const bool all_landmarks 00020 ) const 00021 { 00022 using namespace std; 00023 00024 std::ofstream f(targetFileName.c_str()); 00025 if (!f.is_open()) return false; 00026 00027 f << "digraph G {\n"; 00028 00029 if (!rba_state.keyframes.empty()) 00030 { 00031 // Keyframes: 00032 f << "/* KEYFRAMES */\n" 00033 "node [shape=box,style=filled];\n"; 00034 //for (typename rba_problem_state_t::keyframe_map_t::const_iterator it=rba_state.keyframes.begin();it!=rba_state.keyframes.end();++it) 00035 for (size_t id=0;id<rba_state.keyframes.size();++id) 00036 f << id << "; "; 00037 f << "\n"; 00038 00039 // k2k edges: 00040 f << "/* KEYFRAME->KEYFRAME edges */\n" 00041 "edge [style=bold];\n"; 00042 for (typename rba_problem_state_t::k2k_edges_deque_t::const_iterator itEdge = rba_state.k2k_edges.begin();itEdge!=rba_state.k2k_edges.end();++itEdge) 00043 { 00044 f << itEdge->from << "->" << itEdge->to << ";\n"; 00045 } 00046 00047 if (all_landmarks) 00048 { 00049 // Landmarks with fixed position: 00050 f << "/* LANDMARKS with known relative position, and its base keyframe */\n" 00051 "node [shape=triangle,style=filled,fillcolor=gray80];\n" 00052 "edge [style=bold,color=black];\n"; 00053 for (typename TRelativeLandmarkPosMap::const_iterator itLM = rba_state.known_lms.begin();itLM != rba_state.known_lms.end();++itLM) 00054 f << itLM->second.id_frame_base << " -> " << "L"<<itLM->first << "; "; 00055 f << "\n"; 00056 00057 // Landmarks with fixed position: 00058 f << "/* LANDMARKS with unknown relative position */\n" 00059 "node [shape=triangle,style=filled,fillcolor=white];\n" 00060 "edge [style=solid,color=gray20];\n"; 00061 for (typename TRelativeLandmarkPosMap::const_iterator itLM = rba_state.unknown_lms.begin();itLM != rba_state.unknown_lms.end();++itLM) 00062 f << itLM->second.id_frame_base << " -> " << "L"<<itLM->first << "; "; 00063 f << "\n"; 00064 00065 // Observations: 00066 f << "/* OBSERVATIONS */\n" 00067 "edge [style=dotted,color=black];\n"; 00068 00069 00070 for (typename rba_problem_state_t::all_observations_deque_t::const_iterator itO=rba_state.all_observations.begin();itO!=rba_state.all_observations.end();++itO) 00071 { 00072 f << itO->obs.kf_id << " -> L" << itO->obs.obs.feat_id << ";\n"; 00073 } 00074 f << "\n"; 00075 } 00076 00077 } // end if graph is not empty 00078 00079 f << "\n}\n"; 00080 00081 return true; 00082 } 00083 00084 // Exports the "high-level" structure of the map as a directed graph in DOT (graphviz) format: 00085 template <class KF2KF_POSE_TYPE,class LM_TYPE,class OBS_TYPE,class RBA_OPTIONS> 00086 bool RbaEngine<KF2KF_POSE_TYPE,LM_TYPE,OBS_TYPE,RBA_OPTIONS>::save_graph_top_structure_as_dot( 00087 const std::string &targetFileName, 00088 const bool set_node_coordinates 00089 ) const 00090 { 00091 using namespace std; 00092 00093 std::ofstream f(targetFileName.c_str()); 00094 if (!f.is_open()) return false; 00095 00096 f << "graph G {\n"; 00097 00098 const size_t nKFs = rba_state.keyframes.size(); 00099 if (nKFs) 00100 { 00101 // Count how many k2k edges does a kf have: 00102 f << "/* KEYFRAMES */\n" 00103 "node [shape=box,style=filled];\n"; 00104 for (size_t id=0;id<nKFs;id++) { 00105 if (rba_state.keyframes[id].adjacent_k2k_edges.size()>=2) { 00106 f << id << "; "; 00107 } 00108 } 00109 f << "\n"; 00110 00111 // k2k edges of selected KFs: 00112 f << "/* KEYFRAME->KEYFRAME edges */\n" 00113 "edge [style=bold];\n"; 00114 for (typename rba_problem_state_t::k2k_edges_deque_t::const_iterator itEdge = rba_state.k2k_edges.begin();itEdge!=rba_state.k2k_edges.end();++itEdge) 00115 { 00116 const TKeyFrameID id_from = itEdge->from, id_to = itEdge->to; 00117 if (rba_state.keyframes[id_from].adjacent_k2k_edges.size()>=2 && rba_state.keyframes[id_to].adjacent_k2k_edges.size()>=2) 00118 f << id_from << "--" << id_to << ";\n"; 00119 } 00120 } // end if graph is not empty 00121 00122 f << "\n}\n"; 00123 00124 return true; 00125 } 00126 00127 00128 00129 } // End of namespaces