35 #define LOAD_MAP_FROM_FILE 0 // 1: load from "sMAP_FILE", 0: random map. 36 #define SHOW_POINT_LABELS 0 42 #if !LOAD_MAP_FROM_FILE 73 "MRPT example: ransac-data-association", 800, 600);
84 #if LOAD_MAP_FROM_FILE 87 M.loadFromTextFile(sMAP_FILE);
88 ASSERT_(M.cols() == 3 && M.rows() > 2)
90 const size_t nPts = M.rows();
92 for (
size_t i = 0; i < nPts; i++) the_map.
setPoint(i, M(i, 1), M(i, 2));
105 const size_t nMapPts = the_map.
size();
106 cout <<
"Loaded/generated map with " << nMapPts <<
" landmarks.\n";
111 mrpt::make_aligned_shared<mrpt::opengl::CPointCloud>();
113 mrpt::make_aligned_shared<mrpt::opengl::CPointCloud>();
115 mrpt::make_aligned_shared<mrpt::opengl::CSetOfObjects>();
117 mrpt::make_aligned_shared<mrpt::opengl::CSetOfObjects>();
119 mrpt::make_aligned_shared<mrpt::opengl::CSetOfLines>();
123 scene->getViewport(
"main")->setCustomBackgroundColor(
133 mrpt::make_aligned_shared<mrpt::opengl::CPointCloud>();
134 gl_map->loadFromPointsMap(&the_map);
135 gl_map->setColor(0, 0, 1);
136 gl_map->setPointSize(3);
138 scene->insert(gl_map);
140 #if SHOW_POINT_LABELS 141 for (
size_t i = 0; i < the_map.
size(); i++)
144 mrpt::make_aligned_shared<mrpt::opengl::CText>(
148 gl_txt->setLocation(
x + 0.05,
y + 0.05, 0.01);
150 scene->insert(gl_txt);
155 scene->insert(gl_lines);
158 gl_obs_map->setColor(1, 0, 0);
159 gl_obs_map->setPointSize(5);
161 gl_result->setColor(0, 1, 0);
162 gl_result->setPointSize(4);
166 gl_obs->insert(gl_obs_map);
167 gl_obs->insert(gl_obs_txts);
168 scene->insert(gl_obs);
169 scene->insert(gl_result);
171 win.unlockAccess3DScene();
179 vector<TObs> observations;
180 observations.resize(nObs);
191 std::vector<std::pair<size_t, float>> idxs;
195 for (
size_t i = 0; i < nObs; i++)
203 observations[i].ID = idxs[i].first;
219 all_correspondences.reserve(nMapPts * nObs);
222 for (
size_t j = 0; j < nObs; j++)
227 match.
other_x = observations[j].x;
228 match.
other_y = observations[j].y;
230 for (
size_t i = 0; i < nMapPts; i++)
235 all_correspondences.push_back(match);
238 cout <<
"Generated " << all_correspondences.size()
239 <<
" potential pairings.\n";
244 timelog.
enter(
"robustRigidTransformation");
250 params.ransac_minSetSize =
253 params.ransac_maxSetSize =
256 params.ransac_mahalanobisDistanceThreshold =
258 params.ransac_nSimulations = 0;
259 params.ransac_fuseByCorrsMatch =
true;
260 params.ransac_fuseMaxDiffXY = 0.01f;
262 params.ransac_algorithmForLandmarks =
true;
263 params.probability_find_good_model = 0.999999;
264 params.ransac_min_nSimulations =
273 timelog.
leave(
"robustRigidTransformation");
278 const double tim = timer.
Tac();
282 cout <<
"# of SOG modes: " << best_poses.
size() << endl;
283 cout <<
"Best match has " << out_best_pairings.size() <<
" features:\n";
284 for (
size_t i = 0; i < out_best_pairings.size(); i++)
285 cout << out_best_pairings[i].this_idx <<
" <-> " 286 << out_best_pairings[i].other_idx << endl;
290 vector<int> obs2map_pairings(nObs, -1);
291 for (
size_t i = 0; i < out_best_pairings.size(); i++)
292 obs2map_pairings[out_best_pairings[i].other_idx] =
293 out_best_pairings[i].this_idx == ((
unsigned int)-1)
295 : out_best_pairings[i].this_idx;
298 for (
size_t i = 0; i < nObs; i++) cout << obs2map_pairings[i] <<
" ";
310 cout <<
"Solution pose: " << solution_pose.
mean << endl;
311 cout <<
"Ground truth pose: " << GT_pose << endl;
315 win.get3DSceneAndLock();
319 "Blue: map landmarks | Red: Observations | White lines: Found " 325 for (
size_t k = 0; k < nObs; k++)
326 gl_obs_map->insertPoint(
327 observations[k].x, observations[k].y, 0.0);
329 gl_obs->setPose(solution_pose.
mean);
331 #if SHOW_POINT_LABELS 332 gl_obs_txts->clear();
333 for (
size_t i = 0; i < nObs; i++)
336 mrpt::make_aligned_shared<mrpt::opengl::CText>(
338 const double x = observations[i].x;
339 const double y = observations[i].y;
340 gl_txt->setLocation(
x + 0.05,
y + 0.05, 0.01);
341 gl_obs_txts->insert(gl_txt);
349 for (
size_t k = 0; k < nObs; k++)
351 int map_idx = obs2map_pairings[k];
352 if (map_idx < 0)
continue;
356 the_map.
getPoint(map_idx, map_x, map_y);
360 observations[k].
x, observations[k].
y, obs_x, obs_y);
364 gl_lines->appendLine(map_x, map_y, 0, obs_x, obs_y,
z);
366 sqerr += mrpt::math::distanceSqrBetweenPoints<double>(
367 map_x, map_y, obs_x, obs_y);
371 5, 20,
"Ground truth pose : " + GT_pose.asString(),
375 "RANSAC estimated pose: " + solution_pose.
mean.
asString() +
376 mrpt::format(
" | RMSE=%f", (nPairs ? sqerr / nPairs : 0.0)),
379 win.unlockAccess3DScene();
382 cout <<
"nPairings: " << nPairs
383 <<
" RMSE = " << (nPairs ? sqerr / nPairs : 0.0) << endl;
401 catch (std::exception& e)
403 std::cout <<
"MRPT exception caught: " << e.what() << std::endl;
408 printf(
"Untyped exception!!");
A namespace of pseudo-random numbers generators of diferent distributions.
double Tac() noexcept
Stops the stopwatch.
CPose2D mean
The mean value.
const float normalizationStd
void asString(std::string &s) const
Returns a human-readable textual representation of the object (eg: "[x y yaw]", yaw in degrees) ...
Declares a class that represents a Probability Density function (PDF) of a 2D pose ...
bool se2_l2(const mrpt::tfest::TMatchingPairList &in_correspondences, mrpt::math::TPose2D &out_transformation, mrpt::math::CMatrixDouble33 *out_estimateCovariance=nullptr)
Least-squares (L2 norm) solution to finding the optimal SE(2) (x,y,yaw) between two reference frames...
Parameters for se2_l2_robust().
double DEG2RAD(const double x)
Degrees to radians.
void randomize(const uint32_t seed)
Initialize the PRNG from the given random seed.
const size_t MINIMUM_RANSAC_ITERS
A high-performance stopwatch, with typical resolution of nanoseconds.
const float ransac_mahalanobisDistanceThreshold
A cloud of points in 2D or 3D, which can be built from a sequence of laser scans. ...
std::string formatTimeInterval(const double timeSeconds)
Returns a formated string with the given time difference (passed as the number of seconds)...
void composePoint(double lx, double ly, double &gx, double &gy) const
An alternative, slightly more efficient way of doing with G and L being 2D points and P this 2D pose...
mrpt::math::CMatrixDouble33 cov
The 3x3 covariance matrix.
double drawGaussian1D(const double mean, const double std)
Generate a normally distributed pseudo-random number.
T square(const T x)
Inline function for the square of a number.
#define ASSERT_(f)
Defines an assertion mechanism.
This base provides a set of functions for maths stuff.
size_t kdTreeRadiusSearch2D(const num_t x0, const num_t y0, const num_t maxRadiusSqr, std::vector< std::pair< size_t, num_t >> &out_indices_dist) const
KD Tree-based search for all the points within a given radius of some 2D point.
bool se2_l2_robust(const mrpt::tfest::TMatchingPairList &in_correspondences, const double in_normalizationStd, const TSE2RobustParams &in_ransac_params, TSE2RobustResult &out_results)
Robust least-squares (L2 norm) solution to finding the optimal SE(2) (x,y,yaw) between two reference ...
map< string, CVectorDouble > results
Declares a class that represents a Probability Density function (PDF) of a 2D pose ...
double leave(const char *func_name)
End of a named section.
mrpt::gui::CDisplayWindow3D::Ptr win
GLsizei const GLchar ** string
A structure for holding correspondences between two sets of points or points-like entities in 2D or 3...
const size_t NUM_OBSERVATIONS_TO_SIMUL
unsigned long getPoint(size_t index, float &x, float &y, float &z) const
Access to a given point from map, as a 2D point.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void setPoint(size_t index, float x, float y, float z)
Changes a given point from map, with Z defaulting to 0 if not provided.
A versatile "profiler" that logs the time spent within each pair of calls to enter(X)-leave(X), among other stats.
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle...
CSetOfObjects::Ptr CornerXYZ(float scale=1.0)
Returns three arrows representing a X,Y,Z 3D corner.
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
A RGB color - floats in the range [0,1].
renders glyphs filled with antialiased outlines
size_t size() const
Return the number of Gaussian modes.
void Tic() noexcept
Starts the stopwatch.
CRandomGenerator & getRandomGenerator()
A static instance of a CRandomGenerator class, for use in single-thread applications.
size_t size() const
Returns the number of stored points in the map.
virtual void resize(size_t newLength) override
Resizes all point buffers so they can hold the given number of points: newly created points are set t...
Functions for estimating the optimal transformation between two frames of references given measuremen...
GLenum const GLfloat * params
Output placeholder for se2_l2_robust()
const size_t NUM_MAP_FEATS
void enter(const char *func_name)
Start of a named section.
A graphical user interface (GUI) for efficiently rendering 3D scenes in real-time.
const size_t RANSAC_MINIMUM_INLIERS