48 template <
class GRAPH,
bool EDGES_ARE_PDF = GRAPH::edge_t::is_PDF_val>
55 template <
class GRAPH>
63 const typename GRAPH::global_poses_t& real_poses, GRAPH& graph,
73 typename GRAPH::edge_t RelativePose(
74 real_poses.find(to)->second - real_poses.find(from)->second);
75 graph.insertEdge(from, to, RelativePose);
79 template <
class GRAPH>
87 const typename GRAPH::global_poses_t& real_poses, GRAPH& graph,
90 typename GRAPH::edge_t RelativePose(
91 real_poses.find(to)->second - real_poses.find(from)->second,
93 graph.insertEdge(from, to, RelativePose);
102 template <
class my_graph_t>
105 template <
class GRAPH_T>
106 static void my_levmarq_feedback(
107 const GRAPH_T& graph,
const size_t iter,
const size_t max_iter,
108 const double cur_sq_error)
111 if ((iter % 100) == 0)
112 cout <<
"Progress: " << iter <<
" / " << max_iter
113 <<
", total sq err = " << cur_sq_error << endl;
119 void run(
bool add_extra_tightening_edge)
125 typename my_graph_t::global_poses_t real_node_poses;
136 const size_t N_VERTEX = 50;
137 const double DIST_THRES = 7;
138 const double NODES_XY_MAX = 20;
144 for (
TNodeID j = 0; j < N_VERTEX; j++)
147 static double ang = 2 *
M_PI / N_VERTEX;
148 const double R = NODES_XY_MAX + 2 * (j % 2 ? 1 : -1);
149 CPose2D p(
R * cos(ang * j),
R * sin(ang * j), ang);
152 real_node_poses[j] =
p;
167 typename edge_adder_t::cov_t inf_matrix;
169 edge_adder_t::cov_t::RowsAtCompileTime,
175 for (
TNodeID i = 0; i < N_VERTEX; i++)
177 for (
TNodeID j = i + 1; j < N_VERTEX; j++)
179 if (real_node_poses[i].distanceTo(real_node_poses[j]) <
182 i, j, real_node_poses, graph, inf_matrix);
187 if (add_extra_tightening_edge)
191 0, N_VERTEX / 2, real_node_poses, graph, inf_matrix);
195 typename my_graph_t::edge_t& ed =
206 const my_graph_t graph_GT = graph;
208 cout <<
"graph nodes: " << graph_GT.nodeCount() << endl;
209 cout <<
"graph edges: " << graph_GT.edgeCount() << endl;
214 itEdge != graph.edges.end(); ++itEdge)
216 const typename my_graph_t::edge_t::type_value delta_noise(
225 itEdge->second.getPoseMean() +=
226 typename my_graph_t::edge_t::type_value(delta_noise);
231 itNode != graph.nodes.end(); ++itNode)
232 if (itNode->first != graph.root)
233 itNode->second.getPoseMean() +=
234 typename my_graph_t::edge_t::type_value(
250 const my_graph_t graph_initial = graph;
260 params[
"max_iterations"] = 500;
261 params[
"scale_hessian"] = 0.1;
274 cout <<
"Global graph RMS error / edge = "
275 << std::sqrt(graph.getGlobalSquareError(
false) / graph.edgeCount())
277 cout <<
"Global graph RMS error / edge = "
278 << std::sqrt(graph.getGlobalSquareError(
true) / graph.edgeCount())
279 <<
" (ignoring information matrices)." << endl;
286 params, &my_levmarq_feedback<my_graph_t>);
288 cout <<
"Global graph RMS error / edge = "
289 << std::sqrt(graph.getGlobalSquareError(
false) / graph.edgeCount())
291 cout <<
"Global graph RMS error / edge = "
292 << std::sqrt(graph.getGlobalSquareError(
true) / graph.edgeCount())
293 <<
" (ignoring information matrices)." << endl;
303 graph_render_params1[
"show_edges"] = 1;
304 graph_render_params1[
"edge_width"] = 1;
305 graph_render_params1[
"nodes_corner_scale"] = 1;
308 graph, graph_render_params1);
312 graph_render_params2[
"show_ground_grid"] = 0;
313 graph_render_params2[
"show_edges"] = 0;
314 graph_render_params2[
"show_node_corners"] = 0;
315 graph_render_params2[
"nodes_point_size"] = 7;
319 graph_initial, graph_render_params2);
321 graph_render_params2[
"nodes_point_size"] = 5;
324 graph, graph_render_params2);
328 graph_render_params3[
"show_ground_grid"] = 0;
329 graph_render_params3[
"show_ID_labels"] = 1;
330 graph_render_params3[
"show_edges"] = 1;
331 graph_render_params3[
"edge_width"] = 3;
332 graph_render_params3[
"nodes_corner_scale"] = 2;
335 graph_GT, graph_render_params3);
338 graph_initial, graph_render_params3);
341 5, 5,
"Ground truth: Big corners & thick edges",
TColorf(0, 0, 0),
345 5, 5 + 15,
"Initial graph: Gray thick points.",
TColorf(0, 0, 0),
349 5, 5 + 30,
"Final graph: Small corners & thin edges",
354 5, 5,
"Ground truth: Big corners & thick edges",
TColorf(0, 0, 0),
358 5, 5 + 15,
"Initial graph: Small corners & thin edges",
364 scene->insert(gl_graph1);
365 scene->insert(gl_graph3);
366 scene->insert(gl_graph2);
367 scene->insert(gl_graph5);
368 win.unlockAccess3DScene();
374 scene->insert(gl_graph3);
375 scene->insert(gl_graph4);
376 win2.unlockAccess3DScene();
386 cout <<
"Close any window to end...\n";
387 while (
win.isOpen() && win2.isOpen() && win_err.isOpen() &&
390 std::this_thread::sleep_for(10ms);
401 cout <<
"Select the type of graph to optimize:\n"
402 "1. CNetworkOfPoses2D \n"
403 "2. CNetworkOfPoses2DInf \n"
404 "3. CNetworkOfPoses3D \n"
405 "4. CNetworkOfPoses3DInf \n";
412 std::getline(cin, l);
417 bool add_extra_tightening_edge;
418 cout <<
"Add an extra, incompatible tightening edge? [y/N] ";
421 std::getline(cin, l);
423 add_extra_tightening_edge = l[0] ==
'Y' || l[0] ==
'y';
431 demo.
run(add_extra_tightening_edge);
437 demo.
run(add_extra_tightening_edge);
443 demo.
run(add_extra_tightening_edge);
449 demo.
run(add_extra_tightening_edge);
454 std::this_thread::sleep_for(20ms);
459 cout <<
"MRPT exception caught: " << e.what() << endl;
464 printf(
"Another exception!!");