16 namespace mrpt {
namespace srba {
18 template <
class KF2KF_POSE_TYPE,
class LM_TYPE,
class OBS_TYPE,
class RBA_OPTIONS>
27 template <
class KF2KF_POSE_TYPE,
class LM_TYPE,
class OBS_TYPE,
class RBA_OPTIONS>
35 " From | Shortest path to:=>Next node to move to [Distance] \n"
36 "--------+-----------------------------------------------------------------\n";
39 s +=
format(
" %6u |",static_cast<unsigned int>(it1->first) );
42 s +=
format(
" %5u:=>%5u [%u] |",static_cast<unsigned int>(it2->first),
static_cast<unsigned int>(it2->second.next), static_cast<unsigned int>(it2->second.distance));
46 "--------+-----------------------------------------------------------------\n";
51 " From | To | Shortest path sequence \n"
52 "--------+--------+--------------------------------------------------------\n";
57 s +=
format(
" %6u | %6u |",static_cast<unsigned int>(it1->first),static_cast<unsigned int>(it2->first) );
61 s +=
format(
" [%4u => %4u] ",static_cast<unsigned int>((*it3)->from),
static_cast<unsigned int>((*it3)->to) );
65 "--------+--------+--------------------------------------------------------\n";
70 template <
class KF2KF_POSE_TYPE,
class LM_TYPE,
class OBS_TYPE,
class RBA_OPTIONS>
74 f.open(sFileName.c_str());
75 if (!f.is_open())
return false;
78 this->dump_as_text(s);
80 return !(f << s).fail();
85 template <
class KF2KF_POSE_TYPE,
class LM_TYPE,
class OBS_TYPE,
class RBA_OPTIONS>
87 std::set< std::pair<std::string,std::string> > & all_edges,
88 const std::string &prefix,
91 const std::map<TKeyFrameID,TSpanTreeEntry> &root_entries,
93 std::set<TKeyFrameID> &visited,
94 const std::map<TKeyFrameID,TSpanTreeEntry> &top_root_entries)
101 if (it->second.distance==1 && top_root_entries.find(it->first)!=top_root_entries.end())
105 const std::string s1 = prefix +
mrpt::format(
"%06u",static_cast<unsigned int>( std::max(root,child) ));
106 const std::string s2 = prefix +
mrpt::format(
"%06u",static_cast<unsigned int>( std::min(root,child) ));
107 all_edges.insert( make_pair(s1,s2) );
109 if (!visited.count(it->first))
121 template <
class KF2KF_POSE_TYPE,
class LM_TYPE,
class OBS_TYPE,
class RBA_OPTIONS>
128 f.open(sFileName.c_str());
129 if (!f.is_open())
return false;
131 vector<next_edge_maps_t::const_iterator> its_to_process;
133 if (kf_roots_to_save.empty())
136 its_to_process.reserve(sym.next_edge.size());
138 its_to_process.push_back(it1);
142 for (
size_t i=0;i<kf_roots_to_save.size();i++)
145 if (it!=sym.next_edge.end())
146 its_to_process.push_back(it);
154 map<size_t, set<string> > kfs_by_depth;
155 map<string, size_t> depth_kf;
158 for (
size_t k=0;k<its_to_process.size();k++)
163 const string sR =
format(
"%06u",static_cast<unsigned int>(root) );
165 const string sNodeDefR = sR +
mrpt::format(
"%06u [label=%u]",static_cast<unsigned int>(root),static_cast<unsigned int>(root));
166 kfs_by_depth[0].insert( sNodeDefR );
167 depth_kf[
mrpt::format(
"%06u%06u",static_cast<unsigned int>(root),static_cast<unsigned int>(root))] = 0;
172 const string sNodeDef = sR +
mrpt::format(
"%06u [label=%u]",static_cast<unsigned int>(it->first),static_cast<unsigned int>(it->first));
173 kfs_by_depth[it->second.distance].insert( sNodeDef );
174 depth_kf[
mrpt::format(
"%06u%06u",static_cast<unsigned int>(root),static_cast<unsigned int>(it->first))] = it->second.distance;
178 for (map<
size_t, set<string> >::
const_iterator it=kfs_by_depth.begin();it!=kfs_by_depth.end();++it)
181 const set<string> & sNodes = it->second;
192 set< pair<string,string> > all_edges;
194 for (
size_t k=0;k<its_to_process.size();k++)
211 ASSERT_(it_eds_id1 != sym.all_edges.end())
213 const std::map<TKeyFrameID, k2k_edge_vector_t> &eds_id1 = it_eds_id1->second;
219 for (
size_t i=0;i<eds.size();i++)
224 const string s1 =
mrpt::format(
"%06u%06u",static_cast<unsigned int>(root),static_cast<unsigned int>( std::max(to,from) ));
225 const string s2 =
mrpt::format(
"%06u%06u",static_cast<unsigned int>(root),static_cast<unsigned int>( std::min(to,from) ));
227 all_edges.insert( make_pair(s1,s2) );
234 for (set< pair<string,string> >::
const_iterator it=all_edges.begin();it!=all_edges.end();++it)
235 s << it->first <<
" -- " << it->second <<
";\n";
238 for (map<
size_t, set<string> >::
const_iterator it=kfs_by_depth.begin();it!=kfs_by_depth.end();++it)
240 const set<string> & sNodes = it->second;
241 if (sNodes.empty())
continue;
243 if (it!=kfs_by_depth.begin())
246 s << it->second.begin()->substr(0,12) <<
" ";
248 if (!kfs_by_depth.empty()) s <<
" [style=invis];\n";
252 return !(f << s.str()).fail();
257 template <
class KF2KF_POSE_TYPE,
class LM_TYPE,
class OBS_TYPE,
class RBA_OPTIONS>
259 size_t &num_nodes_min,
260 size_t &num_nodes_max,
261 double &num_nodes_mean,
262 double &num_nodes_std)
const
269 std::vector<size_t> num_nodes;
270 num_nodes.reserve(sym.next_edge.size());
273 num_nodes.push_back( it1->second.size() );
next_edge_maps_t next_edge
Given all interesting spanning tree roots (=SOURCE), this structure holds: map[SOURCE] |-> map[TARGET...
struct mrpt::srba::TRBA_Problem_state::TSpanningTree::TSpanningTreeSym sym
vec_t::const_iterator const_iterator
kf2kf_pose_traits< KF2KF_POSE_TYPE >::k2k_edge_vector_t k2k_edge_vector_t
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
iterator find(const size_t i)
Constant-time find, returning an iterator to the pair or to end() if not found (that is...
const Scalar * const_iterator
void clear()
Clear the contents of this container.
bool save_as_dot_file(const std::string &sFileName, const std::vector< TKeyFrameID > &kf_roots_to_save=std::vector< TKeyFrameID >()) const
Saves all (or a subset of all) the spanning trees If kf_roots_to_save is left empty, all STs are saved.
void recursive_print_st_dot(std::set< std::pair< std::string, std::string > > &all_edges, const std::string &prefix, const TKeyFrameID came_from, const TKeyFrameID root, const std::map< TKeyFrameID, TSpanTreeEntry > &root_entries, const typename TRBA_Problem_state< KF2KF_POSE_TYPE, LM_TYPE, OBS_TYPE, RBA_OPTIONS >::TSpanningTree::next_edge_maps_t &all, std::set< TKeyFrameID > &visited, const std::map< TKeyFrameID, TSpanTreeEntry > &top_root_entries)
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
void minimum_maximum(const std::vector< T > &V, T &curMin, T &curMax)
Return the maximum and minimum values of a std::vector.
all_edges_maps_t all_edges
From the previous data, we can build this alternative, more convenient representation: map[SOURCE] |-...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void get_stats(size_t &num_nodes_min, size_t &num_nodes_max, double &num_nodes_mean, double &num_nodes_std) const
Returns min/max and mean/std stats on the number of nodes found on all the spanning trees...
void meanAndStd(const VECTORLIKE &v, double &out_mean, double &out_std, bool unbiased=true)
Computes the standard deviation of a vector.
void clear()
Empty all sym & num data.
kf2kf_pose_traits< KF2KF_POSE_TYPE >::TRelativePosesForEachTarget num
"Numeric" spanning tree: the SE(3) pose of each node wrt to any other: num[SOURCE] |–> map[TARGET] =...
void dump_as_text(std::string &s) const
Useful for debugging.
bool dump_as_text_to_file(const std::string &sFileName) const
Useful for debugging.
uint64_t TKeyFrameID
Numeric IDs for key-frames (KFs)