MRPT  1.9.9
graph_slam_levmarq_test_common.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include <mrpt/graphslam/types.h>
11 #include <mrpt/graphslam/levmarq.h>
12 #include <mrpt/graphs.h>
13 #include <mrpt/random.h>
14 #include <mrpt/io/CMemoryStream.h>
15 
16 using namespace mrpt;
17 using namespace mrpt::random;
18 using namespace mrpt::poses;
19 using namespace mrpt::graphs;
20 using namespace mrpt::math;
21 using namespace std;
22 
23 template <class my_graph_t>
25 {
26  public:
27  // adds a new edge to the graph. The edge is annotated with the relative
28  // position of the two nodes
29  static void addEdge(
30  TNodeID from, TNodeID to,
31  const typename my_graph_t::global_poses_t& real_poses,
32  my_graph_t& graph)
33  {
34  auto RelativePose =
35  real_poses.find(to)->second - real_poses.find(from)->second;
36 
37  // Add information matrix if present:
38  if constexpr (my_graph_t::edge_t::is_PDF())
39  {
40  const auto N = my_graph_t::edge_t::state_length;
42  auto mat = getRandomGenerator()
43  .drawDefinitePositiveMatrix<InfMat, Eigen::VectorXd>(
44  N, 2.0 /*std*/, 1.0 /*diagonal offset*/);
45  graph.insertEdge(
46  from, to, typename my_graph_t::edge_t(RelativePose, mat));
47  }
48  else
49  {
50  graph.insertEdge(from, to, RelativePose);
51  }
52  }
53 
54  // The graph: nodes + edges:
55  static void create_ring_path(
56  my_graph_t& graph, size_t N_VERTEX = 50, double DIST_THRES = 7,
57  double NODES_XY_MAX = 20)
58  {
59  // The global poses of each node (without covariance):
60  typename my_graph_t::global_poses_t real_node_poses;
61 
62  // ----------------------------
63  // Create a random graph:
64  // ----------------------------
65  // Level of noise in nodes initial positions:
66  const double STD_NOISE_NODE_XYZ = 0.5;
67  const double STD_NOISE_NODE_ANG = DEG2RAD(5);
68 
69  // Level of noise in edges:
70  const double STD_NOISE_EDGE_XYZ = 0; // 0.01;
71  const double STD_NOISE_EDGE_ANG = 0; // DEG2RAD(0.1);
72 
73  for (TNodeID j = 0; j < N_VERTEX; j++)
74  {
75  static double ang = 2 * M_PI / N_VERTEX;
76  const double R = NODES_XY_MAX + 2 * (j % 2 ? 1 : -1);
77  CPose2D p(R * cos(ang * j), R * sin(ang * j), ang);
78 
79  // Save real pose:
80  real_node_poses[j] = p;
81 
82  // Copy the nodes to the graph, and add some noise:
83  graph.nodes[j] = p;
84  }
85 
86  // Add some edges
87  for (TNodeID i = 0; i < N_VERTEX; i++)
88  {
89  for (TNodeID j = i + 1; j < N_VERTEX; j++)
90  {
91  if (real_node_poses[i].distanceTo(real_node_poses[j]) <
92  DIST_THRES)
93  addEdge(i, j, real_node_poses, graph);
94  }
95  }
96 
97  // Cross-links:
98  addEdge(0, N_VERTEX / 2, real_node_poses, graph);
99 
100  // The root node (the origin of coordinates):
101  graph.root = TNodeID(0);
102 
103  // This is the ground truth graph (make a copy for later use):
104  const my_graph_t graph_GT = graph;
105 
106  // Add noise to edges & nodes:
107  for (auto& edge : graph.edges)
108  {
109  // edge_t::type_value: for edge_t a plain pose, type_value is the
110  // edge_t itself. For poses+uncertainty, it is the underlying pose
111  // type.
112  if constexpr (my_graph_t::edge_t::type_value::size() == 6)
113  {
114  const auto noise = CPose3D(
115  getRandomGenerator().drawGaussian1D(0, STD_NOISE_EDGE_XYZ),
116  getRandomGenerator().drawGaussian1D(0, STD_NOISE_EDGE_XYZ),
117  getRandomGenerator().drawGaussian1D(0, STD_NOISE_EDGE_XYZ),
118  getRandomGenerator().drawGaussian1D(0, STD_NOISE_EDGE_ANG),
119  getRandomGenerator().drawGaussian1D(0, STD_NOISE_EDGE_ANG),
120  getRandomGenerator().drawGaussian1D(0, STD_NOISE_EDGE_ANG));
121 
122  if constexpr (my_graph_t::edge_t::is_PDF())
123  {
124  const auto N = my_graph_t::edge_t::state_length;
125  using InfMat =
127  InfMat mat;
128  mat.setIdentity();
129  edge.second += typename my_graph_t::edge_t(noise, mat);
130  }
131  else
132  {
133  edge.second += typename my_graph_t::edge_t(noise);
134  }
135  }
136  else
137  {
138  const auto noise = CPose2D(
139  getRandomGenerator().drawGaussian1D(0, STD_NOISE_EDGE_XYZ),
140  getRandomGenerator().drawGaussian1D(0, STD_NOISE_EDGE_XYZ),
141  getRandomGenerator().drawGaussian1D(0, STD_NOISE_EDGE_ANG));
142  if constexpr (my_graph_t::edge_t::is_PDF())
143  {
144  const auto N = my_graph_t::edge_t::state_length;
145  using InfMat =
147  InfMat mat;
148  mat.setIdentity();
149  edge.second += typename my_graph_t::edge_t(noise, mat);
150  }
151  else
152  {
153  edge.second += typename my_graph_t::edge_t(noise);
154  }
155  }
156  }
157 
158  for (typename my_graph_t::global_poses_t::iterator itNode =
159  graph.nodes.begin();
160  itNode != graph.nodes.end(); ++itNode)
161  if (itNode->first != graph.root)
162  itNode
163  ->second += typename my_graph_t::edge_t::type_value(CPose3D(
164  getRandomGenerator().drawGaussian1D(0, STD_NOISE_NODE_XYZ),
165  getRandomGenerator().drawGaussian1D(0, STD_NOISE_NODE_XYZ),
166  getRandomGenerator().drawGaussian1D(0, STD_NOISE_NODE_XYZ),
167  getRandomGenerator().drawGaussian1D(0, STD_NOISE_NODE_ANG),
168  getRandomGenerator().drawGaussian1D(0, STD_NOISE_NODE_ANG),
169  getRandomGenerator().drawGaussian1D(
170  0, STD_NOISE_NODE_ANG)));
171  }
172 };
A namespace of pseudo-random numbers generators of diferent distributions.
Scalar * iterator
Definition: eigen_plugins.h:26
MATRIX drawDefinitePositiveMatrix(const size_t dim, const double std_scale=1.0, const double diagonal_epsilon=1e-8)
Generates a random definite-positive matrix of the given size, using the formula C = v*v^t + epsilon*...
void addEdge(TNodeID from, TNodeID to, const mrpt::aligned_std_map< TNodeID, CPose2D > &real_poses, CNetworkOfPoses2D &graph_links)
double DEG2RAD(const double x)
Degrees to radians.
Abstract graph and tree data structures, plus generic graph algorithms.
STL namespace.
A numeric matrix of compile-time fixed size.
const double STD_NOISE_NODE_XYZ
This base provides a set of functions for maths stuff.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
static void addEdge(TNodeID from, TNodeID to, const typename my_graph_t::global_poses_t &real_poses, my_graph_t &graph)
const double STD_NOISE_EDGE_ANG
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle...
Definition: CPose2D.h:38
const float R
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:86
uint64_t TNodeID
A generic numeric type for unique IDs of nodes or entities.
Definition: TNodeID.h:16
static void create_ring_path(my_graph_t &graph, size_t N_VERTEX=50, double DIST_THRES=7, double NODES_XY_MAX=20)
const double STD_NOISE_NODE_ANG
GLsizeiptr size
Definition: glext.h:3923
CRandomGenerator & getRandomGenerator()
A static instance of a CRandomGenerator class, for use in single-thread applications.
GLfloat GLfloat p
Definition: glext.h:6305
const double STD_NOISE_EDGE_XYZ



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020