Main MRPT website > C++ reference for MRPT 1.9.9
CICP_unittest.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, 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/slam/CICP.h>
13 #include <mrpt/poses/CPosePDF.h>
14 #include <mrpt/poses/CPose3DPDF.h>
15 
19 #include <mrpt/opengl/CSphere.h>
20 #include <mrpt/opengl/CDisk.h>
22 #include <gtest/gtest.h>
23 
24 using namespace mrpt;
25 using namespace mrpt::slam;
26 using namespace mrpt::maps;
27 using namespace mrpt::opengl;
28 using namespace mrpt::utils;
29 using namespace mrpt::poses;
30 using namespace mrpt::math;
31 using namespace mrpt::obs;
32 using namespace std;
33 
34 class ICPTests : public ::testing::Test
35 {
36  protected:
37  virtual void SetUp() {}
38  virtual void TearDown() {}
39  void align2scans(const TICPAlgorithm icp_method)
40  {
41  float SCAN_RANGES_1[] = {
42  0.910f, 0.900f, 0.910f, 0.900f, 0.900f, 0.890f, 0.890f,
43  0.880f, 0.890f, 0.880f, 0.880f, 0.880f, 0.880f, 0.880f,
44  0.880f, 0.870f, 0.880f, 0.870f, 0.870f, 0.870f, 0.880f,
45  0.880f, 0.880f, 0.880f, 0.880f, 0.880f, 0.880f, 0.880f,
46  0.880f, 0.880f, 0.880f, 0.880f, 0.880f, 0.880f, 0.880f,
47  0.880f, 0.890f, 0.880f, 0.880f, 0.880f, 0.890f, 0.880f,
48  0.890f, 0.890f, 0.880f, 0.890f, 0.890f, 0.880f, 0.890f,
49  0.890f, 0.890f, 0.890f, 0.890f, 0.890f, 0.900f, 0.900f,
50  0.900f, 0.900f, 0.900f, 0.910f, 0.910f, 0.910f, 0.910f,
51  0.920f, 0.920f, 0.920f, 0.920f, 0.920f, 0.930f, 0.930f,
52  0.930f, 0.930f, 0.940f, 0.940f, 0.950f, 0.950f, 0.950f,
53  0.950f, 0.960f, 0.960f, 0.970f, 0.970f, 0.970f, 0.980f,
54  0.980f, 0.990f, 1.000f, 1.000f, 1.000f, 1.010f, 1.010f,
55  1.020f, 1.030f, 1.030f, 1.030f, 1.040f, 1.050f, 1.060f,
56  1.050f, 1.060f, 1.070f, 1.070f, 1.080f, 1.080f, 1.090f,
57  1.100f, 1.110f, 1.120f, 1.120f, 1.130f, 1.140f, 1.140f,
58  1.160f, 1.170f, 1.180f, 1.180f, 1.190f, 1.200f, 1.220f,
59  1.220f, 1.230f, 1.230f, 1.240f, 1.250f, 1.270f, 1.280f,
60  1.290f, 1.300f, 1.320f, 1.320f, 1.350f, 1.360f, 1.370f,
61  1.390f, 1.410f, 1.410f, 1.420f, 1.430f, 1.450f, 1.470f,
62  1.490f, 1.500f, 1.520f, 1.530f, 1.560f, 1.580f, 1.600f,
63  1.620f, 1.650f, 1.670f, 1.700f, 1.730f, 1.750f, 1.780f,
64  1.800f, 1.830f, 1.850f, 1.880f, 1.910f, 1.940f, 1.980f,
65  2.010f, 2.060f, 2.090f, 2.130f, 2.180f, 2.220f, 2.250f,
66  2.300f, 2.350f, 2.410f, 2.460f, 2.520f, 2.570f, 2.640f,
67  2.700f, 2.780f, 2.850f, 2.930f, 3.010f, 3.100f, 3.200f,
68  3.300f, 3.390f, 3.500f, 3.620f, 3.770f, 3.920f, 4.070f,
69  4.230f, 4.430f, 4.610f, 4.820f, 5.040f, 5.290f, 5.520f,
70  8.970f, 8.960f, 8.950f, 8.930f, 8.940f, 8.930f, 9.050f,
71  9.970f, 9.960f, 10.110f, 13.960f, 18.870f, 19.290f, 81.910f,
72  20.890f, 48.750f, 48.840f, 48.840f, 19.970f, 19.980f, 19.990f,
73  15.410f, 20.010f, 19.740f, 17.650f, 17.400f, 14.360f, 12.860f,
74  11.260f, 11.230f, 8.550f, 8.630f, 9.120f, 9.120f, 8.670f,
75  8.570f, 7.230f, 7.080f, 7.040f, 6.980f, 6.970f, 5.260f,
76  5.030f, 4.830f, 4.620f, 4.440f, 4.390f, 4.410f, 4.410f,
77  4.410f, 4.430f, 4.440f, 4.460f, 4.460f, 4.490f, 4.510f,
78  4.540f, 3.970f, 3.820f, 3.730f, 3.640f, 3.550f, 3.460f,
79  3.400f, 3.320f, 3.300f, 3.320f, 3.320f, 3.340f, 2.790f,
80  2.640f, 2.600f, 2.570f, 2.540f, 2.530f, 2.510f, 2.490f,
81  2.490f, 2.480f, 2.470f, 2.460f, 2.460f, 2.460f, 2.450f,
82  2.450f, 2.450f, 2.460f, 2.460f, 2.470f, 2.480f, 2.490f,
83  2.490f, 2.520f, 2.510f, 2.550f, 2.570f, 2.610f, 2.640f,
84  2.980f, 3.040f, 3.010f, 2.980f, 2.940f, 2.920f, 2.890f,
85  2.870f, 2.830f, 2.810f, 2.780f, 2.760f, 2.740f, 2.720f,
86  2.690f, 2.670f, 2.650f, 2.630f, 2.620f, 2.610f, 2.590f,
87  2.560f, 2.550f, 2.530f, 2.510f, 2.500f, 2.480f, 2.460f,
88  2.450f, 2.430f, 2.420f, 2.400f, 2.390f, 2.380f, 2.360f,
89  2.350f, 2.340f, 2.330f, 2.310f, 2.300f, 2.290f, 2.280f,
90  2.270f, 2.260f, 2.250f, 2.240f, 2.230f, 2.230f, 2.220f,
91  2.210f, 2.200f, 2.190f, 2.180f, 2.170f, 1.320f, 1.140f,
92  1.130f, 1.130f, 1.120f, 1.120f, 1.110f, 1.110f, 1.110f,
93  1.110f, 1.100f, 1.110f, 1.100f};
94  char SCAN_VALID_1[] = {
95  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
96  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
97  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
98  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
99  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
100  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
101  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
102  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
103  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
104  1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
105  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
106  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
107  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
108  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
109  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
110  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
111 
112  float SCAN_RANGES_2[] = {
113  0.720f, 0.720f, 0.720f, 0.720f, 0.720f, 0.720f, 0.710f,
114  0.720f, 0.710f, 0.710f, 0.710f, 0.710f, 0.710f, 0.710f,
115  0.710f, 0.710f, 0.710f, 0.710f, 0.710f, 0.710f, 0.720f,
116  0.720f, 0.720f, 0.720f, 0.730f, 0.730f, 0.730f, 0.730f,
117  0.730f, 0.730f, 0.730f, 0.740f, 0.740f, 0.740f, 0.740f,
118  0.740f, 0.740f, 0.750f, 0.750f, 0.750f, 0.750f, 0.750f,
119  0.750f, 0.750f, 0.750f, 0.760f, 0.760f, 0.760f, 0.760f,
120  0.760f, 0.760f, 0.760f, 0.760f, 0.770f, 0.770f, 0.770f,
121  0.770f, 0.780f, 0.780f, 0.780f, 0.790f, 0.790f, 0.800f,
122  0.800f, 0.800f, 0.800f, 0.800f, 0.800f, 0.810f, 0.810f,
123  0.820f, 0.820f, 0.830f, 0.830f, 0.840f, 0.840f, 0.850f,
124  0.850f, 0.860f, 0.860f, 0.860f, 0.870f, 0.870f, 0.880f,
125  0.890f, 0.890f, 0.900f, 0.900f, 0.910f, 0.920f, 0.930f,
126  0.930f, 0.940f, 0.940f, 0.940f, 0.950f, 0.960f, 0.960f,
127  0.970f, 0.980f, 0.990f, 1.000f, 1.010f, 1.020f, 1.030f,
128  1.040f, 1.050f, 1.060f, 1.070f, 1.080f, 1.080f, 1.100f,
129  1.100f, 1.120f, 1.120f, 1.140f, 1.140f, 1.170f, 1.160f,
130  1.180f, 1.190f, 1.210f, 1.220f, 1.240f, 1.250f, 1.280f,
131  1.290f, 1.300f, 1.320f, 1.340f, 1.350f, 1.380f, 1.390f,
132  1.420f, 1.440f, 1.460f, 1.470f, 1.500f, 1.520f, 1.550f,
133  1.570f, 1.600f, 1.630f, 1.670f, 1.690f, 1.730f, 1.760f,
134  1.790f, 1.820f, 1.870f, 1.900f, 1.940f, 1.970f, 2.030f,
135  2.080f, 2.130f, 2.170f, 2.230f, 2.280f, 2.340f, 2.400f,
136  2.490f, 2.550f, 2.630f, 2.700f, 2.810f, 2.880f, 3.010f,
137  3.090f, 3.240f, 3.340f, 3.500f, 3.620f, 3.810f, 3.950f,
138  4.180f, 4.340f, 4.620f, 8.170f, 8.140f, 8.150f, 8.120f,
139  8.110f, 8.100f, 8.100f, 8.300f, 9.040f, 9.130f, 9.130f,
140  13.030f, 18.050f, 19.150f, 81.910f, 20.070f, 47.980f, 48.040f,
141  48.030f, 19.140f, 19.180f, 19.180f, 19.190f, 14.550f, 19.210f,
142  16.850f, 16.840f, 7.800f, 7.770f, 7.770f, 7.750f, 7.770f,
143  7.760f, 7.780f, 7.760f, 8.320f, 8.350f, 8.350f, 8.090f,
144  7.720f, 7.730f, 6.430f, 6.360f, 6.290f, 6.260f, 6.230f,
145  6.220f, 6.160f, 5.800f, 4.510f, 4.410f, 4.240f, 4.140f,
146  4.000f, 3.910f, 3.790f, 3.680f, 3.660f, 3.680f, 3.680f,
147  3.700f, 3.710f, 3.730f, 3.730f, 3.760f, 3.770f, 3.790f,
148  3.820f, 3.850f, 3.900f, 3.940f, 3.980f, 3.250f, 3.180f,
149  3.140f, 3.070f, 3.030f, 2.970f, 2.930f, 2.880f, 2.850f,
150  2.790f, 2.760f, 2.710f, 2.680f, 2.660f, 2.670f, 2.690f,
151  2.710f, 2.720f, 2.740f, 2.760f, 2.770f, 2.780f, 2.800f,
152  2.170f, 2.120f, 2.090f, 2.060f, 2.020f, 2.010f, 1.990f,
153  1.980f, 1.970f, 1.960f, 1.950f, 1.950f, 1.940f, 1.940f,
154  1.950f, 1.940f, 1.940f, 1.950f, 1.930f, 1.940f, 1.940f,
155  1.940f, 1.940f, 1.940f, 1.950f, 1.960f, 1.960f, 1.980f,
156  1.980f, 2.000f, 2.010f, 2.030f, 2.060f, 2.090f, 2.120f,
157  2.190f, 2.560f, 2.540f, 2.530f, 2.520f, 2.500f, 2.490f,
158  2.470f, 2.460f, 2.450f, 2.440f, 2.420f, 2.410f, 2.400f,
159  2.390f, 2.380f, 2.370f, 2.360f, 2.350f, 2.340f, 2.340f,
160  2.330f, 2.320f, 2.310f, 2.300f, 2.290f, 2.290f, 2.290f,
161  2.280f, 2.270f, 2.260f, 2.260f, 2.250f, 2.240f, 2.240f,
162  2.230f, 2.230f, 2.220f, 2.220f, 2.210f, 2.210f, 2.200f,
163  2.200f, 2.190f, 2.190f, 2.190f, 2.180f, 2.180f, 2.170f,
164  2.170f, 2.170f, 2.160f, 2.160f};
165  char SCAN_VALID_2[] = {
166  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
167  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
168  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
169  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
170  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
171  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
172  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
173  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
174  1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
175  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
176  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
177  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
178  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
179  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
180  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
181  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
182 
183 #define SCANS_SIZE (sizeof(SCAN_RANGES_1) / sizeof(SCAN_RANGES_1[0]))
184 
185  CSimplePointsMap m1, m2;
186  float runningTime;
187  CICP::TReturnInfo info;
188  CICP ICP;
189 
190  // Load scans:
192  scan1.aperture = M_PIf;
193  scan1.rightToLeft = true;
194 
195  ASSERT_(sizeof(SCAN_RANGES_1) == sizeof(float) * SCANS_SIZE);
196  scan1.loadFromVectors(SCANS_SIZE, SCAN_RANGES_1, SCAN_VALID_1);
197 
198  CObservation2DRangeScan scan2 = scan1;
199  scan2.loadFromVectors(SCANS_SIZE, SCAN_RANGES_2, SCAN_VALID_2);
200 
201  // Build the points maps from the scans:
202  m1.insertObservation(&scan1);
203  m2.insertObservation(&scan2);
204 
205  // -----------------------------------------------------
206  ICP.options.ICP_algorithm = icp_method;
207 
208  ICP.options.maxIterations = 100;
209  ICP.options.thresholdAng = DEG2RAD(10.0f);
210  ICP.options.thresholdDist = 0.75f;
211  ICP.options.ALFA = 0.5f;
212  ICP.options.smallestThresholdDist = 0.05f;
213  ICP.options.doRANSAC = false;
214  // ICP.options.dumpToConsole();
215  // -----------------------------------------------------
216  CPose2D initialPose(0.8f, 0.0f, (float)DEG2RAD(0.0f));
217 
218  CPosePDF::Ptr pdf =
219  ICP.Align(&m1, &m2, initialPose, &runningTime, (void*)&info);
220 
221  /*printf("ICP run in %.02fms, %d iterations (%.02fms/iter), %.01f%%
222  goodness\n -> ",
223  runningTime*1000,
224  info.nIterations,
225  runningTime*1000.0f/info.nIterations,
226  info.goodness*100 );*/
227 
228  // cout << "Mean of estimation: " << pdf->getEstimatedPose() << endl<<
229  // endl;
230  // Should be around: Mean of estimation: (0.820,0.084,8.73deg)
231 
232  const CPose2D good_pose(0.820, 0.084, DEG2RAD(8.73));
233 
234  EXPECT_NEAR(good_pose.distanceTo(pdf->getMeanVal()), 0, 0.02);
235  }
236 
238  {
239  CSphere::Ptr sph = mrpt::make_aligned_shared<CSphere>(0.5);
240  sph->setLocation(0, 0, 0);
241  sph->setColor(1, 0, 0);
242  world->insert(sph);
243 
244  CDisk::Ptr pln = mrpt::make_aligned_shared<opengl::CDisk>();
245  pln->setDiskRadius(2);
246  pln->setPose(CPose3D(0, 0, 0, 0, DEG2RAD(5), DEG2RAD(5)));
247  pln->setColor(0.8, 0, 0);
248  world->insert(pln);
249 
250  {
251  CDisk::Ptr pln = mrpt::make_aligned_shared<opengl::CDisk>();
252  pln->setDiskRadius(2);
253  pln->setPose(
254  CPose3D(0, 0, 0, DEG2RAD(30), DEG2RAD(-20), DEG2RAD(-2)));
255  pln->setColor(0.9, 0, 0);
256  world->insert(pln);
257  }
258  }
259 };
260 
261 TEST_F(ICPTests, AlignScans_icpClassic) { align2scans(icpClassic); }
262 TEST_F(ICPTests, AlignScans_icpLevenbergMarquardt)
263 
264 {
265  align2scans(icpLevenbergMarquardt);
266 }
267 
268 TEST_F(ICPTests, RayTracingICP3D)
269 {
270  // Increase this values to get more precision. It will also increase run
271  // time.
272  const size_t HOW_MANY_YAWS = 150;
273  const size_t HOW_MANY_PITCHS = 150;
274 
275  // The scans of the 3D object, taken from 2 different places:
276  vector<CObservation2DRangeScan> sequence_scans1, sequence_scans2;
277 
278  // The two origins for the 3D scans
279  CPose3D viewpoint1(-0.3, 0.7, 3, DEG2RAD(5), DEG2RAD(80), DEG2RAD(3));
280  CPose3D viewpoint2(0.5, -0.2, 2.6, DEG2RAD(-5), DEG2RAD(100), DEG2RAD(-7));
281 
282  CPose3D SCAN2_POSE_ERROR(0.15, -0.07, 0.10, -0.03, 0.1, 0.1);
283 
284  // Create the reference objects:
285  COpenGLScene::Ptr scene1 = mrpt::make_aligned_shared<COpenGLScene>();
286  COpenGLScene::Ptr scene2 = mrpt::make_aligned_shared<COpenGLScene>();
287  COpenGLScene::Ptr scene3 = mrpt::make_aligned_shared<COpenGLScene>();
288 
290  mrpt::make_aligned_shared<CGridPlaneXY>(-20, 20, -20, 20, 0, 1);
291  plane1->setColor(0.3, 0.3, 0.3);
292  scene1->insert(plane1);
293  scene2->insert(plane1);
294  scene3->insert(plane1);
295 
296  CSetOfObjects::Ptr world = mrpt::make_aligned_shared<CSetOfObjects>();
297  generateObjects(world);
298  scene1->insert(world);
299 
300  // Perform the 3D scans:
302  mrpt::make_aligned_shared<CAngularObservationMesh>();
304  mrpt::make_aligned_shared<CAngularObservationMesh>();
305 
306  CAngularObservationMesh::trace2DSetOfRays(
307  scene1, viewpoint1, aom1,
308  CAngularObservationMesh::TDoubleRange::CreateFromAperture(
309  M_PI, HOW_MANY_PITCHS),
310  CAngularObservationMesh::TDoubleRange::CreateFromAperture(
311  M_PI, HOW_MANY_YAWS));
312  CAngularObservationMesh::trace2DSetOfRays(
313  scene1, viewpoint2, aom2,
314  CAngularObservationMesh::TDoubleRange::CreateFromAperture(
315  M_PI, HOW_MANY_PITCHS),
316  CAngularObservationMesh::TDoubleRange::CreateFromAperture(
317  M_PI, HOW_MANY_YAWS));
318 
319  // Put the viewpoints origins:
320  {
322  origin1->setPose(viewpoint1);
323  origin1->setScale(0.6f);
324  scene1->insert(origin1);
325  scene2->insert(origin1);
326  }
327  {
329  origin2->setPose(viewpoint2);
330  origin2->setScale(0.6f);
331  scene1->insert(origin2);
332  scene2->insert(origin2);
333  }
334 
335  // Show the scanned points:
336  CSimplePointsMap M1, M2;
337 
338  aom1->generatePointCloud(&M1);
339  aom2->generatePointCloud(&M2);
340 
341  // Create the wrongly-localized M2:
342  CSimplePointsMap M2_noisy;
343  M2_noisy = M2;
344  M2_noisy.changeCoordinatesReference(SCAN2_POSE_ERROR);
345 
346  CSetOfObjects::Ptr PTNS1 = mrpt::make_aligned_shared<CSetOfObjects>();
347  CSetOfObjects::Ptr PTNS2 = mrpt::make_aligned_shared<CSetOfObjects>();
348 
349  CPointsMap::COLOR_3DSCENE(mrpt::utils::TColorf(1, 0, 0));
350  M1.getAs3DObject(PTNS1);
351 
352  CPointsMap::COLOR_3DSCENE(mrpt::utils::TColorf(0, 0, 1));
353  M2_noisy.getAs3DObject(PTNS2);
354 
355  scene2->insert(PTNS1);
356  scene2->insert(PTNS2);
357 
358  // --------------------------------------
359  // Do the ICP-3D
360  // --------------------------------------
361  float run_time;
362  CICP icp;
363  CICP::TReturnInfo icp_info;
364 
365  icp.options.thresholdDist = 0.40f;
366  icp.options.thresholdAng = 0;
367 
368  CPose3DPDF::Ptr pdf = icp.Align3D(
369  &M2_noisy, // Map to align
370  &M1, // Reference map
371  CPose3D(), // Initial gross estimate
372  &run_time, &icp_info);
373 
374  CPose3D mean = pdf->getMeanVal();
375 
376  // Checks:
377  EXPECT_NEAR(
378  0, (mean.getAsVectorVal() - SCAN2_POSE_ERROR.getAsVectorVal())
379  .array()
380  .abs()
381  .mean(),
382  0.02)
383  << "ICP output: mean= " << mean << endl
384  << "Real displacement: " << SCAN2_POSE_ERROR << endl;
385 }
virtual void SetUp()
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
void changeCoordinatesReference(const mrpt::poses::CPose2D &b)
Replace each point by (pose compounding operator).
Definition: CPointsMap.cpp:613
double distanceTo(const CPoseOrPoint< OTHERCLASS > &b) const
Returns the Euclidean distance to another pose/point:
Definition: CPoseOrPoint.h:206
mrpt::math::CVectorDouble getAsVectorVal() const
Return the pose or point as a 1xN vector with all the components (see derived classes for each implem...
Definition: CPoseOrPoint.h:265
float thresholdDist
Initial threshold distance for two points to become a correspondence.
Definition: CICP.h:122
TICPAlgorithm ICP_algorithm
The algorithm to use (default: icpClassic).
Definition: CICP.h:89
mrpt::poses::CPosePDF::Ptr Align(const mrpt::maps::CMetricMap *m1, const mrpt::maps::CMetricMap *m2, const mrpt::poses::CPose2D &grossEst, float *runningTime=nullptr, void *info=nullptr)
The method for aligning a pair of metric maps, aligning only 2D + orientation.
mrpt::poses::CPose3DPDF::Ptr Align3D(const mrpt::maps::CMetricMap *m1, const mrpt::maps::CMetricMap *m2, const mrpt::poses::CPose3D &grossEst, float *runningTime=nullptr, void *info=nullptr)
The method for aligning a pair of metric maps, aligning the full 6D pose.
Several implementations of ICP (Iterative closest point) algorithms for aligning two point maps or a ...
Definition: CICP.h:67
virtual void getAs3DObject(mrpt::opengl::CSetOfObjects::Ptr &outObj) const override
Returns a 3D object representing the map.
Definition: CPointsMap.cpp:801
A cloud of points in 2D or 3D, which can be built from a sequence of laser scans. ...
STL namespace.
#define M_PI
Definition: bits.h:92
TEST_F(ICPTests, AlignScans_icpClassic)
void align2scans(const TICPAlgorithm icp_method)
float ALFA
The scale factor for threshold everytime convergence is achieved.
Definition: CICP.h:124
TConfigParams options
The options employed by the ICP align.
Definition: CICP.h:185
#define SCANS_SIZE
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:19
std::shared_ptr< CPosePDF > Ptr
Definition: CPosePDF.h:44
#define M_PIf
unsigned int maxIterations
Maximum number of iterations to run.
Definition: CICP.h:109
std::shared_ptr< CPose3DPDF > Ptr
Definition: CPose3DPDF.h:45
std::shared_ptr< CSetOfObjects > Ptr
Definition: CSetOfObjects.h:32
This namespace contains representation of robot actions and observations.
bool doRANSAC
Perform a RANSAC step, mrpt::tfest::se2_l2_robust(), after the ICP convergence, to obtain a better es...
Definition: CICP.h:140
#define DEG2RAD
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Definition: CPoint.h:17
TICPAlgorithm
The ICP algorithm selection, used in mrpt::slam::CICP::options mrpt_slam_grp.
Definition: CICP.h:22
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
A "CObservation"-derived class that represents a 2D range scan measurement (typically from a laser sc...
static void generateObjects(CSetOfObjects::Ptr &world)
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle...
Definition: CPose2D.h:40
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:88
std::shared_ptr< CAngularObservationMesh > Ptr
float smallestThresholdDist
The size for threshold such that iterations will stop, since it is considered precise enough...
Definition: CICP.h:127
CSetOfObjects::Ptr CornerXYZ(float scale=1.0)
Returns three arrows representing a X,Y,Z 3D corner.
std::shared_ptr< COpenGLScene > Ptr
Definition: COpenGLScene.h:62
The ICP algorithm return information.
Definition: CICP.h:195
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:15
float aperture
The "aperture" or field-of-view of the range finder, in radians (typically M_PI = 180 degrees)...
#define ASSERT_(f)
A RGB color - floats in the range [0,1].
Definition: TColor.h:78
void loadFromVectors(size_t nRays, const float *scanRanges, const char *scanValidity)
std::shared_ptr< CDisk > Ptr
Definition: CDisk.h:35
virtual void TearDown()
std::shared_ptr< CSphere > Ptr
Definition: CSphere.h:33
bool insertObservation(const mrpt::obs::CObservation *obs, const mrpt::poses::CPose3D *robotPose=NULL)
Insert the observation information into this map.
Definition: CMetricMap.cpp:95
EIGEN_STRONG_INLINE double mean() const
Computes the mean of the entire matrix.
std::shared_ptr< CGridPlaneXY > Ptr
Definition: CGridPlaneXY.h:34
bool rightToLeft
The scanning direction: true=counterclockwise; false=clockwise.



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019