Main MRPT website > C++ reference for MRPT 1.9.9
CPTG_DiffDrive_CollisionGridBased.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 "nav-precomp.h" // Precomp header
11 
13 
16 #include <mrpt/utils/CTicTac.h>
17 #include <mrpt/math/geometry.h>
20 
21 using namespace mrpt::nav;
22 
23 /** Constructor: possible values in "params":
24  * - ref_distance: The maximum distance in PTGs
25  * - resolution: The cell size
26  * - v_max, w_max: Maximum robot speeds.
27  */
29  : V_MAX(.0),
30  W_MAX(.0),
31  turningRadiusReference(.10),
32  m_resolution(0.05),
33  m_stepTimeDuration(0.01),
34  m_collisionGrid(-1, 1, -1, 1, 0.5, this)
35 {
36 }
37 
39 {
42 
43  m_resolution = 0.10;
44  V_MAX = 1.0;
46 }
47 
49  const mrpt::utils::CConfigFileBase& cfg, const std::string& sSection)
50 {
53 
55  resolution, double, m_resolution, cfg, sSection);
57  v_max_mps, double, V_MAX, cfg, sSection);
59  w_max_dps, double, W_MAX, cfg, sSection);
60  MRPT_LOAD_CONFIG_VAR(turningRadiusReference, double, cfg, sSection);
61 }
63  mrpt::utils::CConfigFileBase& cfg, const std::string& sSection) const
64 {
66  const int WN = 25, WV = 30;
67 
69 
70  cfg.write(
71  sSection, "resolution", m_resolution, WN, WV,
72  "Resolution of the collision-check look-up-table [m].");
73  cfg.write(
74  sSection, "v_max_mps", V_MAX, WN, WV,
75  "Maximum linear velocity for trajectories [m/s].");
76  cfg.write(
77  sSection, "w_max_dps", mrpt::utils::RAD2DEG(W_MAX), WN, WV,
78  "Maximum angular velocity for trajectories [deg/s].");
79  cfg.write(
80  sSection, "turningRadiusReference", turningRadiusReference, WN, WV,
81  "An approximate dimension of the robot (not a critical parameter) "
82  "[m].");
83 
85 
86  MRPT_END
87 }
88 
91 {
92  o << p.x << p.y << p.phi << p.t << p.dist << p.v << p.w;
93  return o;
94 }
97 {
98  i >> p.x >> p.y >> p.phi >> p.t >> p.dist >> p.v >> p.w;
99  return i;
100 }
101 
102 /*---------------------------------------------------------------
103  simulateTrajectories
104  Solve trajectories and fill cells.
105  ---------------------------------------------------------------*/
107  float max_time, float max_dist, unsigned int max_n, float diferencial_t,
108  float min_dist, float* out_max_acc_v, float* out_max_acc_w)
109 {
110  using mrpt::math::square;
111 
112  internal_deinitialize(); // Free previous paths
113 
114  m_stepTimeDuration = diferencial_t;
115 
116  // Reserve the size in the buffers:
118 
119  const float radio_max_robot = 1.0f; // Arbitrary "robot radius", only to
120  // determine the spacing of points
121  // under pure rotation
122 
123  // Aux buffer:
125 
126  float ult_dist, ult_dist1, ult_dist2;
127 
128  // For the grid:
129  float x_min = 1e3f, x_max = -1e3;
130  float y_min = 1e3f, y_max = -1e3;
131 
132  // Para averiguar las maximas ACELERACIONES lineales y angulares:
133  float max_acc_lin, max_acc_ang;
134 
135  max_acc_lin = max_acc_ang = 0;
136 
137  try
138  {
139  for (unsigned int k = 0; k < m_alphaValuesCount; k++)
140  {
141  // Simulate / evaluate the trajectory selected by this "alpha":
142  // ------------------------------------------------------------
143  const float alpha = index2alpha(k);
144 
145  points.clear();
146  float t = .0f, dist = .0f, girado = .0f;
147  float x = .0f, y = .0f, phi = .0f, v = .0f, w = .0f, _x = .0f,
148  _y = .0f, _phi = .0f;
149 
150  // Sliding window with latest movement commands (for the optional
151  // low-pass filtering):
152  float last_vs[2] = {.0f, .0f}, last_ws[2] = {.0f, .0f};
153 
154  // Add the first, initial point:
155  points.push_back(TCPoint(x, y, phi, t, dist, v, w));
156 
157  // Simulate until...
158  while (t < max_time && dist < max_dist && points.size() < max_n &&
159  fabs(girado) < 1.95 * M_PI)
160  {
161  // Max. aceleraciones:
162  if (t > 1)
163  {
164  float acc_lin =
165  fabs((last_vs[0] - last_vs[1]) / diferencial_t);
166  float acc_ang =
167  fabs((last_ws[0] - last_ws[1]) / diferencial_t);
168  mrpt::utils::keep_max(max_acc_lin, acc_lin);
169  mrpt::utils::keep_max(max_acc_ang, acc_ang);
170  }
171 
172  // Compute new movement command (v,w):
174 
175  // History of v/w ----------------------------------
176  last_vs[1] = last_vs[0];
177  last_ws[1] = last_ws[0];
178  last_vs[0] = v;
179  last_ws[0] = w;
180  // -------------------------------------------
181 
182  // Finite difference equation:
183  x += cos(phi) * v * diferencial_t;
184  y += sin(phi) * v * diferencial_t;
185  phi += w * diferencial_t;
186 
187  // Counters:
188  girado += w * diferencial_t;
189 
190  float v_inTPSpace =
191  sqrt(square(v) + square(w * turningRadiusReference));
192 
193  dist += v_inTPSpace * diferencial_t;
194 
195  t += diferencial_t;
196 
197  // Save sample if we moved far enough:
198  ult_dist1 = sqrt(square(_x - x) + square(_y - y));
199  ult_dist2 = fabs(radio_max_robot * (_phi - phi));
200  ult_dist = std::max(ult_dist1, ult_dist2);
201 
202  if (ult_dist > min_dist)
203  {
204  // Set the (v,w) to the last record:
205  points.back().v = v;
206  points.back().w = w;
207 
208  // And add the new record:
209  points.push_back(TCPoint(x, y, phi, t, dist, v, w));
210 
211  // For the next iter:
212  _x = x;
213  _y = y;
214  _phi = phi;
215  }
216 
217  // for the grid:
218  x_min = std::min(x_min, x);
219  x_max = std::max(x_max, x);
220  y_min = std::min(y_min, y);
221  y_max = std::max(y_max, y);
222  }
223 
224  // Add the final point:
225  points.back().v = v;
226  points.back().w = w;
227  points.push_back(TCPoint(x, y, phi, t, dist, v, w));
228 
229  // Save data to C-Space path structure:
230  m_trajectory[k] = points;
231 
232  } // end for "k"
233 
234  // Save accelerations
235  if (out_max_acc_v) *out_max_acc_v = max_acc_lin;
236  if (out_max_acc_w) *out_max_acc_w = max_acc_ang;
237 
238  // --------------------------------------------------------
239  // Build the speeding-up grid for lambda function:
240  // --------------------------------------------------------
241  const TCellForLambdaFunction defaultCell;
243  x_min - 0.5f, x_max + 0.5f, y_min - 0.5f, y_max + 0.5f, 0.25f,
244  &defaultCell);
245 
246  for (uint16_t k = 0; k < m_alphaValuesCount; k++)
247  {
248  const uint32_t M = static_cast<uint32_t>(m_trajectory[k].size());
249  for (uint32_t n = 0; n < M; n++)
250  {
251  TCellForLambdaFunction* cell =
252  m_lambdaFunctionOptimizer.cellByPos(
253  m_trajectory[k][n].x, m_trajectory[k][n].y);
254  ASSERT_(cell)
255  // Keep limits:
256  mrpt::utils::keep_min(cell->k_min, k);
257  mrpt::utils::keep_max(cell->k_max, k);
258  mrpt::utils::keep_min(cell->n_min, n);
259  mrpt::utils::keep_max(cell->n_max, n);
260  }
261  }
262  }
263  catch (...)
264  {
265  std::cout << format(
266  "[CPTG_DiffDrive_CollisionGridBased::simulateTrajectories] "
267  "Simulation aborted: unexpected exception!\n");
268  }
269 }
270 
271 /** In this class, `out_action_cmd` contains: [0]: linear velocity (m/s), [1]:
272  * angular velocity (rad/s) */
275  uint16_t k) const
276 {
277  float v, w;
278  ptgDiffDriveSteeringFunction(index2alpha(k), 0, 0, 0, 0, v, w);
279 
282  cmd->lin_vel = v;
283  cmd->ang_vel = w;
285 }
286 
287 /*---------------------------------------------------------------
288  getTPObstacle
289  ---------------------------------------------------------------*/
292  const float obsX, const float obsY) const
293 {
294  static const TCollisionCell emptyCell;
295  const TCollisionCell* cell = cellByPos(obsX, obsY);
296  return cell != nullptr ? *cell : emptyCell;
297 }
298 
299 /*---------------------------------------------------------------
300  Updates the info into a cell: It updates the cell only
301  if the distance d for the path k is lower than the previous value:
302  ---------------------------------------------------------------*/
304  const unsigned int icx, const unsigned int icy, const uint16_t k,
305  const float dist)
306 {
307  TCollisionCell* cell = cellByIndex(icx, icy);
308  if (!cell) return;
309 
310  // For such a small number of elements, brute-force search is not such a bad
311  // idea:
312  TCollisionCell::iterator itK = cell->end();
313  for (TCollisionCell::iterator it = cell->begin(); it != cell->end(); ++it)
314  if (it->first == k)
315  {
316  itK = it;
317  break;
318  }
319 
320  if (itK == cell->end())
321  { // New entry:
322  cell->push_back(std::make_pair(k, dist));
323  }
324  else
325  { // Only update that "k" if the distance is shorter now:
326  if (dist < itK->second) itK->second = dist;
327  }
328 }
329 
330 /*---------------------------------------------------------------
331  Save to file
332  ---------------------------------------------------------------*/
334  const std::string& filename,
335  const mrpt::math::CPolygon& computed_robotShape) const
336 {
337  try
338  {
340  if (!fo.fileOpenCorrectly()) return false;
341 
342  const uint32_t n = 1; // for backwards compatibility...
343  fo << n;
344  return m_collisionGrid.saveToFile(&fo, computed_robotShape);
345  }
346  catch (...)
347  {
348  return false;
349  }
350 }
351 
352 /*---------------------------------------------------------------
353  Load from file
354  ---------------------------------------------------------------*/
356  const std::string& filename, const mrpt::math::CPolygon& current_robotShape)
357 {
358  try
359  {
360  mrpt::utils::CFileGZInputStream fi(filename);
361  if (!fi.fileOpenCorrectly()) return false;
362 
363  uint32_t n;
364  fi >> n;
365  if (n != 1)
366  return false; // Incompatible (old) format, just discard and
367  // recompute.
368 
369  return m_collisionGrid.loadFromFile(&fi, current_robotShape);
370  }
371  catch (...)
372  {
373  return false;
374  }
375 }
376 
377 const uint32_t COLGRID_FILE_MAGIC = 0xC0C0C0C3;
378 
379 /*---------------------------------------------------------------
380  Save to file
381  ---------------------------------------------------------------*/
384  const mrpt::math::CPolygon& computed_robotShape) const
385 {
386  try
387  {
388  if (!f) return false;
389 
390  const uint8_t serialize_version =
391  2; // v1: As of jun 2012, v2: As of dec-2013
392 
393  // Save magic signature && serialization version:
394  *f << COLGRID_FILE_MAGIC << serialize_version;
395 
396  // Robot shape:
397  *f << computed_robotShape;
398 
399  // and standard PTG data:
400  *f << m_parent->getDescription() << m_parent->getAlphaValuesCount()
401  << static_cast<float>(m_parent->getMax_V())
402  << static_cast<float>(m_parent->getMax_W());
403 
404  *f << m_x_min << m_x_max << m_y_min << m_y_max;
405  *f << m_resolution;
406 
407  // v1 was: *f << m_map;
408  uint32_t N = m_map.size();
409  *f << N;
410  for (uint32_t i = 0; i < N; i++)
411  {
412  uint32_t M = m_map[i].size();
413  *f << M;
414  for (uint32_t k = 0; k < M; k++)
415  *f << m_map[i][k].first << m_map[i][k].second;
416  }
417 
418  return true;
419  }
420  catch (...)
421  {
422  return false;
423  }
424 }
425 
426 /*---------------------------------------------------------------
427  loadFromFile
428  ---------------------------------------------------------------*/
430  mrpt::utils::CStream* f, const mrpt::math::CPolygon& current_robotShape)
431 {
432  try
433  {
434  if (!f) return false;
435 
436  // Return false if the file contents doesn't match what we expected:
437  uint32_t file_magic;
438  *f >> file_magic;
439 
440  // It doesn't seem to be a valid file or was in an old format, just
441  // recompute the grid:
442  if (COLGRID_FILE_MAGIC != file_magic) return false;
443 
444  uint8_t serialized_version;
445  *f >> serialized_version;
446 
447  switch (serialized_version)
448  {
449  case 2:
450  {
451  mrpt::math::CPolygon stored_shape;
452  *f >> stored_shape;
453 
454  const bool shapes_match =
455  (stored_shape.size() == current_robotShape.size() &&
456  std::equal(
457  stored_shape.begin(), stored_shape.end(),
458  current_robotShape.begin()));
459 
460  if (!shapes_match)
461  return false; // Must recompute if the robot shape changed.
462  }
463  break;
464 
465  case 1:
466  default:
467  // Unknown version: Maybe we are loading a file from a more
468  // recent version of MRPT? Whatever, we can't read it: It's
469  // safer just to re-generate the PTG data
470  return false;
471  };
472 
473  // Standard PTG data:
474  const std::string expected_desc = m_parent->getDescription();
475  std::string desc;
476  *f >> desc;
477  if (desc != expected_desc) return false;
478 
479 // and standard PTG data:
480 #define READ_UINT16_CHECK_IT_MATCHES_STORED(_VAR) \
481  { \
482  uint16_t ff; \
483  *f >> ff; \
484  if (ff != _VAR) return false; \
485  }
486 #define READ_FLOAT_CHECK_IT_MATCHES_STORED(_VAR) \
487  { \
488  float ff; \
489  *f >> ff; \
490  if (std::abs(ff - _VAR) > 1e-4f) return false; \
491  }
492 #define READ_DOUBLE_CHECK_IT_MATCHES_STORED(_VAR) \
493  { \
494  double ff; \
495  *f >> ff; \
496  if (std::abs(ff - _VAR) > 1e-6) return false; \
497  }
498 
499  READ_UINT16_CHECK_IT_MATCHES_STORED(m_parent->getAlphaValuesCount())
500  READ_FLOAT_CHECK_IT_MATCHES_STORED(m_parent->getMax_V())
501  READ_FLOAT_CHECK_IT_MATCHES_STORED(m_parent->getMax_W())
502 
503  // Cell dimensions:
509 
510  // OK, all parameters seem to be exactly the same than when we
511  // precomputed the table: load it.
512  // v1 was: *f >> m_map;
513  uint32_t N;
514  *f >> N;
515  m_map.resize(N);
516  for (uint32_t i = 0; i < N; i++)
517  {
518  uint32_t M;
519  *f >> M;
520  m_map[i].resize(M);
521  for (uint32_t k = 0; k < M; k++)
522  *f >> m_map[i][k].first >> m_map[i][k].second;
523  }
524 
525  return true;
526  }
527  catch (std::exception& e)
528  {
529  std::cerr << "[CCollisionGrid::loadFromFile] " << e.what();
530  return false;
531  }
532  catch (...)
533  {
534  return false;
535  }
536 }
537 
539  double x, double y, int& out_k, double& out_d, double tolerance_dist) const
540 {
541  using mrpt::math::square;
542 
543  ASSERTMSG_(
544  m_alphaValuesCount > 0, "Have you called simulateTrajectories() first?")
545 
546  // -------------------------------------------------------------------
547  // Optimization: (24-JAN-2007 @ Jose Luis Blanco):
548  // Use a "grid" to determine the range of [k,d] values to check!!
549  // If the point (x,y) is not found in the grid, then directly skip
550  // to the next step.
551  // -------------------------------------------------------------------
552  uint16_t k_min = 0, k_max = m_alphaValuesCount - 1;
553  uint32_t n_min = 0, n_max = 0;
554  bool at_least_one = false;
555 
556  // Cell indexes:
557  int cx0 = m_lambdaFunctionOptimizer.x2idx(x);
558  int cy0 = m_lambdaFunctionOptimizer.y2idx(y);
559 
560  // (cx,cy)
561  for (int cx = cx0 - 1; cx <= cx0 + 1; cx++)
562  {
563  for (int cy = cy0 - 1; cy <= cy0 + 1; cy++)
564  {
565  const TCellForLambdaFunction* cell =
566  m_lambdaFunctionOptimizer.cellByIndex(cx, cy);
567  if (cell && !cell->isEmpty())
568  {
569  if (!at_least_one)
570  {
571  k_min = cell->k_min;
572  k_max = cell->k_max;
573  n_min = cell->n_min;
574  n_max = cell->n_max;
575  at_least_one = true;
576  }
577  else
578  {
579  mrpt::utils::keep_min(k_min, cell->k_min);
580  mrpt::utils::keep_max(k_max, cell->k_max);
581 
582  mrpt::utils::keep_min(n_min, cell->n_min);
583  mrpt::utils::keep_max(n_max, cell->n_max);
584  }
585  }
586  }
587  }
588 
589  // Try to find a closest point to the paths:
590  // ----------------------------------------------
591  int selected_k = -1;
592  float selected_d = 0;
593  float selected_dist = std::numeric_limits<float>::max();
594 
595  if (at_least_one) // Otherwise, don't even lose time checking...
596  {
597  ASSERT_BELOW_(k_max, m_trajectory.size())
598  for (int k = k_min; k <= k_max; k++)
599  {
600  const size_t n_real = m_trajectory[k].size();
601  const uint32_t n_max_this =
602  std::min(static_cast<uint32_t>(n_real ? n_real - 1 : 0), n_max);
603 
604  for (uint32_t n = n_min; n <= n_max_this; n++)
605  {
606  const float dist_a_punto = square(m_trajectory[k][n].x - x) +
607  square(m_trajectory[k][n].y - y);
608  if (dist_a_punto < selected_dist)
609  {
610  selected_dist = dist_a_punto;
611  selected_k = k;
612  selected_d = m_trajectory[k][n].dist;
613  }
614  }
615  }
616  }
617 
618  if (selected_k != -1)
619  {
620  out_k = selected_k;
621  out_d = selected_d / refDistance;
622  return (selected_dist <= square(tolerance_dist));
623  }
624 
625  // If not found, compute an extrapolation:
626 
627  // ------------------------------------------------------------------------------------
628  // Given a point (x,y), compute the "k_closest" whose extrapolation
629  // is closest to the point, and the associated "d_closest" distance,
630  // which can be normalized by "1/refDistance" to get TP-Space distances.
631  // ------------------------------------------------------------------------------------
632  selected_dist = std::numeric_limits<float>::max();
633  for (uint16_t k = 0; k < m_alphaValuesCount; k++)
634  {
635  const int n = int(m_trajectory[k].size()) - 1;
636  const float dist_a_punto = square(m_trajectory[k][n].dist) +
637  square(m_trajectory[k][n].x - x) +
638  square(m_trajectory[k][n].y - y);
639 
640  if (dist_a_punto < selected_dist)
641  {
642  selected_dist = dist_a_punto;
643  selected_k = k;
644  selected_d = dist_a_punto;
645  }
646  }
647 
648  selected_d = std::sqrt(selected_d);
649 
650  out_k = selected_k;
651  out_d = selected_d / refDistance;
652 
653  // If the target dist. > refDistance, then it's normal that we had to
654  // extrapolate.
655  // Otherwise, it may actually mean that the target is not reachable by this
656  // set of paths:
657  const float target_dist = std::sqrt(x * x + y * y);
658  return (target_dist > target_dist);
659 }
660 
662 {
663  ASSERTMSG_(
664  m_trajectory.empty(),
665  "Changing reference distance not allowed in this class after "
666  "initialization!");
667  this->refDistance = refDist;
668 }
669 
671 {
672  ASSERTMSG_(
673  m_trajectory.empty(),
674  "Changing robot shape not allowed in this class after initialization!");
675 }
676 
678 {
679  m_trajectory.clear(); // Free trajectories
680 }
681 
683  const std::string& cacheFilename, const bool verbose)
684 {
685  using namespace std;
686 
687  MRPT_START
688 
689  if (verbose)
690  cout << endl
691  << "[CPTG_DiffDrive_CollisionGridBased::initialize] Starting... "
692  "*** THIS MAY TAKE A WHILE, BUT MUST BE COMPUTED ONLY ONCE!! **"
693  << endl;
694 
695  // Sanity checks:
696  ASSERTMSG_(!m_robotShape.empty(), "Robot shape was not defined");
697  ASSERTMSG_(
698  m_robotShape.size() >= 3, "Robot shape must have 3 or more vertices");
699  ASSERT_(refDistance > 0);
700  ASSERT_(V_MAX > 0);
701  ASSERT_(W_MAX > 0);
702  ASSERT_(m_resolution > 0);
703 
704  mrpt::utils::CTicTac tictac;
705  tictac.Tic();
706 
707  if (verbose) cout << "Initializing PTG '" << cacheFilename << "'...";
708 
709  // Simulate paths:
710  const float min_dist = 0.015f;
712  100, // max.tim,
713  refDistance, // max.dist,
714  10 * refDistance / min_dist, // max.n,
715  0.0005f, // diferencial_t
716  min_dist // min_dist
717  );
718 
719  // Just for debugging, etc.
720  // debugDumpInFiles(n);
721 
722  // Check for collisions between the robot shape and the grid cells:
723  // ----------------------------------------------------------------------------
726 
727  const size_t Ki = getAlphaValuesCount();
728  ASSERTMSG_(Ki > 0, "The PTG seems to be not initialized!");
729 
730  // Load the cached version, if possible
731  if (loadColGridsFromFile(cacheFilename, m_robotShape))
732  {
733  if (verbose) cout << "loaded from file OK" << endl;
734  }
735  else
736  {
737  // BUGFIX: In case we start reading the file and in the end detected an
738  // error,
739  // we must make sure that there's space enough for the grid:
743 
744  const int grid_cx_max = m_collisionGrid.getSizeX() - 1;
745  const int grid_cy_max = m_collisionGrid.getSizeY() - 1;
746  const double half_cell = m_collisionGrid.getResolution() * 0.5;
747 
748  const size_t nVerts = m_robotShape.verticesCount();
749  std::vector<mrpt::math::TPoint2D> transf_shape(
750  nVerts); // The robot shape at each location
751 
752  // RECOMPUTE THE COLLISION GRIDS:
753  // ---------------------------------------
754  for (size_t k = 0; k < Ki; k++)
755  {
756  const size_t nPoints = getPathStepCount(k);
757  ASSERT_(nPoints > 1)
758 
759  for (size_t n = 0; n < (nPoints - 1); n++)
760  {
761  // Translate and rotate the robot shape at this C-Space pose:
763  getPathPose(k, n, p);
764 
765  mrpt::math::TPoint2D bb_min(
766  std::numeric_limits<double>::max(),
767  std::numeric_limits<double>::max());
768  mrpt::math::TPoint2D bb_max(
769  -std::numeric_limits<double>::max(),
770  -std::numeric_limits<double>::max());
771 
772  for (size_t m = 0; m < nVerts; m++)
773  {
774  transf_shape[m].x =
775  p.x + cos(p.phi) * m_robotShape.GetVertex_x(m) -
776  sin(p.phi) * m_robotShape.GetVertex_y(m);
777  transf_shape[m].y =
778  p.y + sin(p.phi) * m_robotShape.GetVertex_x(m) +
779  cos(p.phi) * m_robotShape.GetVertex_y(m);
780  mrpt::utils::keep_max(bb_max.x, transf_shape[m].x);
781  mrpt::utils::keep_max(bb_max.y, transf_shape[m].y);
782  mrpt::utils::keep_min(bb_min.x, transf_shape[m].x);
783  mrpt::utils::keep_min(bb_min.y, transf_shape[m].y);
784  }
785 
786  // Robot shape polygon:
787  const mrpt::math::TPolygon2D poly(transf_shape);
788 
789  // Get the range of cells that may collide with this shape:
790  const int ix_min =
791  std::max(0, m_collisionGrid.x2idx(bb_min.x) - 1);
792  const int iy_min =
793  std::max(0, m_collisionGrid.y2idx(bb_min.y) - 1);
794  const int ix_max =
795  std::min(m_collisionGrid.x2idx(bb_max.x) + 1, grid_cx_max);
796  const int iy_max =
797  std::min(m_collisionGrid.y2idx(bb_max.y) + 1, grid_cy_max);
798 
799  for (int ix = ix_min; ix < ix_max; ix++)
800  {
801  const double cx = m_collisionGrid.idx2x(ix) - half_cell;
802 
803  for (int iy = iy_min; iy < iy_max; iy++)
804  {
805  const double cy = m_collisionGrid.idx2y(iy) - half_cell;
806 
807  if (poly.contains(mrpt::math::TPoint2D(cx, cy)))
808  {
809  // Collision!! Update cell info:
810  const float d = this->getPathDist(k, n);
811  m_collisionGrid.updateCellInfo(ix, iy, k, d);
812  m_collisionGrid.updateCellInfo(ix - 1, iy, k, d);
813  m_collisionGrid.updateCellInfo(ix, iy - 1, k, d);
815  ix - 1, iy - 1, k, d);
816  }
817  } // for iy
818  } // for ix
819 
820  } // n
821 
822  if (verbose) cout << k << "/" << Ki << ",";
823  } // k
824 
825  if (verbose) cout << format("Done! [%.03f sec]\n", tictac.Tac());
826 
827  // save it to the cache file for the next run:
828  saveColGridsToFile(cacheFilename, m_robotShape);
829 
830  } // "else" recompute all PTG
831 
832  MRPT_END
833 }
834 
836 {
837  ASSERT_(k < m_trajectory.size());
838 
839  return m_trajectory[k].size();
840 }
841 
843  uint16_t k, uint32_t step, mrpt::math::TPose2D& p) const
844 {
845  ASSERT_(k < m_trajectory.size());
846  ASSERT_(step < m_trajectory[k].size());
847 
848  p.x = m_trajectory[k][step].x;
849  p.y = m_trajectory[k][step].y;
850  p.phi = m_trajectory[k][step].phi;
851 }
852 
854  uint16_t k, uint32_t step) const
855 {
856  ASSERT_(k < m_trajectory.size());
857  ASSERT_(step < m_trajectory[k].size());
858 
859  return m_trajectory[k][step].dist;
860 }
861 
863  uint16_t k, double dist, uint32_t& out_step) const
864 {
865  ASSERT_(k < m_trajectory.size());
866  const size_t numPoints = m_trajectory[k].size();
867 
868  ASSERT_(numPoints > 0);
869 
870  for (size_t n = 0; n < numPoints - 1; n++)
871  {
872  if (m_trajectory[k][n + 1].dist >= dist)
873  {
874  out_step = n;
875  return true;
876  }
877  }
878 
879  out_step = numPoints - 1;
880  return false;
881 }
882 
884  double ox, double oy, std::vector<double>& tp_obstacles) const
885 {
886  ASSERTMSG_(!m_trajectory.empty(), "PTG has not been initialized!");
887  const TCollisionCell& cell = m_collisionGrid.getTPObstacle(ox, oy);
888  // Keep the minimum distance:
889  for (TCollisionCell::const_iterator i = cell.begin(); i != cell.end(); ++i)
890  {
891  const double dist = i->second;
892  internal_TPObsDistancePostprocess(ox, oy, dist, tp_obstacles[i->first]);
893  }
894 }
895 
897  double ox, double oy, uint16_t k, double& tp_obstacle_k) const
898 {
899  ASSERTMSG_(!m_trajectory.empty(), "PTG has not been initialized!");
900  const TCollisionCell& cell = m_collisionGrid.getTPObstacle(ox, oy);
901  // Keep the minimum distance:
902  for (TCollisionCell::const_iterator i = cell.begin(); i != cell.end(); ++i)
903  if (i->first == k)
904  {
905  const double dist = i->second;
906  internal_TPObsDistancePostprocess(ox, oy, dist, tp_obstacle_k);
907  }
908 }
909 
912 {
915 
916  uint8_t version;
917  in >> version;
918  switch (version)
919  {
920  case 0:
924  break;
925  default:
927  };
928 }
929 
931  mrpt::utils::CStream& out) const
932 {
935 
936  const uint8_t version = 0;
937  out << version;
938 
941 }
942 
945  const
946 {
949 }
950 
952 {
953  return m_stepTimeDuration;
954 }
double index2alpha(uint16_t k) const
Alpha value for the discrete corresponding value.
void internal_shape_saveToStream(mrpt::utils::CStream &out) const
double GetVertex_x(size_t i) const
Methods for accessing the vertices.
Definition: CPolygon.h:37
virtual void saveToConfigFile(mrpt::utils::CConfigFileBase &cfg, const std::string &sSection) const override
This method saves the options to a ".ini"-like file or memory-stored string list. ...
GLclampf GLclampf GLclampf alpha
Definition: glext.h:3525
virtual void setRefDistance(const double refDist) override
Launches an exception in this class: it is not allowed in numerical integration-based PTGs to change ...
#define READ_DOUBLE_CHECK_IT_MATCHES_STORED(_VAR)
GLdouble GLdouble t
Definition: glext.h:3689
#define min(a, b)
unsigned __int16 uint16_t
Definition: rptypes.h:44
bool saveColGridsToFile(const std::string &filename, const mrpt::math::CPolygon &computed_robotShape) const
size_t verticesCount() const
Returns the vertices count in the polygon:
Definition: CPolygon.h:49
bool getPathStepForDist(uint16_t k, double dist, uint32_t &out_step) const override
Access path k ([0,N-1]=>[-pi,pi] in alpha): largest step count for which the traversed distance is < ...
double x
X,Y coordinates.
void internal_initialize(const std::string &cacheFilename=std::string(), const bool verbose=true) override
Must be called after setting all PTG parameters and before requesting converting obstacles to TP-Spac...
Specifies the min/max values for "k" and "n", respectively.
double DEG2RAD(const double x)
Degrees to radians.
void saveToConfigFile(mrpt::utils::CConfigFileBase &cfg, const std::string &sSection) const override
This method saves the options to a ".ini"-like file or memory-stored string list. ...
virtual void saveToConfigFile(mrpt::utils::CConfigFileBase &cfg, const std::string &sSection) const override
This method saves the options to a ".ini"-like file or memory-stored string list. ...
const TCollisionCell & getTPObstacle(const float obsX, const float obsY) const
For an obstacle (x,y), returns a vector with all the pairs (a,d) such as the robot collides...
#define MRPT_LOAD_HERE_CONFIG_VAR_DEGREES_NO_DEFAULT( variableName, variableType, targetVariable, configFileObject, sectionNameStr)
GLint * first
Definition: glext.h:3827
Trajectory points in C-Space for non-holonomic robots.
mrpt::utils::CDynamicGrid< TCellForLambdaFunction > m_lambdaFunctionOptimizer
This grid will contain indexes data for speeding-up the default, brute-force lambda function...
int x2idx(double x) const
Transform a coordinate values into cell indexes.
Definition: CDynamicGrid.h:268
#define ASSERT_BELOW_(__A, __B)
GLenum GLsizei n
Definition: glext.h:5074
Scalar * iterator
Definition: eigen_plugins.h:26
void internal_readFromStream(mrpt::utils::CStream &in) override
void internal_deinitialize() override
This must be called to de-initialize the PTG if some parameter is to be changed.
void loadDefaultParams() override
Loads a set of default parameters; provided exclusively for the PTG-configurator tool.
mrpt::utils::CStream & operator>>(mrpt::utils::CStream &i, mrpt::nav::TCPoint &p)
A wrapper of a TPolygon2D class, implementing CSerializable.
Definition: CPolygon.h:22
size_t getSizeY() const
Returns the vertical size of grid map in cells count.
Definition: CDynamicGrid.h:256
STL namespace.
std::vector< TCPoint > TCPointVector
#define M_PI
Definition: bits.h:92
const Scalar * const_iterator
Definition: eigen_plugins.h:27
void Tic()
Starts the stopwatch.
Definition: CTicTac.cpp:82
void loadShapeFromConfigFile(const mrpt::utils::CConfigFileBase &source, const std::string &section)
void keep_min(T &var, const K test_val)
If the second argument is below the first one, set the first argument to this lower value...
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:4178
const uint32_t COLGRID_FILE_MAGIC
void updateTPObstacleSingle(double ox, double oy, uint16_t k, double &tp_obstacle_k) const override
Like updateTPObstacle() but for one direction only (k) in TP-Space.
#define READ_FLOAT_CHECK_IT_MATCHES_STORED(_VAR)
virtual void internal_writeToStream(mrpt::utils::CStream &out) const
This class allows loading and storing values and vectors of different types from a configuration text...
T square(const T x)
Inline function for the square of a number.
Definition: bits.h:55
int y2idx(double y) const
Definition: CDynamicGrid.h:272
void internal_TPObsDistancePostprocess(const double ox, const double oy, const double new_tp_obs_dist, double &inout_tp_obs) const
To be called by implementors of updateTPObstacle() and updateTPObstacleSingle() to honor the user set...
GLsizei const GLfloat * points
Definition: glext.h:5339
virtual mrpt::kinematics::CVehicleVelCmd::Ptr directionToMotionCommand(uint16_t k) const override
In this class, out_action_cmd contains: [0]: linear velocity (m/s), [1]: angular velocity (rad/s)...
unsigned char uint8_t
Definition: rptypes.h:41
virtual void loadFromConfigFile(const mrpt::utils::CConfigFileBase &cfg, const std::string &sSection) override
Parameters accepted by this base class:
TCollisionCell * cellByPos(double x, double y)
Returns a pointer to the contents of a cell given by its coordinates, or nullptr if it is out of the ...
Definition: CDynamicGrid.h:213
double idx2y(int cy) const
Definition: CDynamicGrid.h:295
virtual void loadDefaultParams()
Loads a set of default parameters into the PTG.
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:41
virtual void loadFromConfigFile(const mrpt::utils::CConfigFileBase &cfg, const std::string &sSection) override
Possible values in "params" (those in CParameterizedTrajectoryGenerator, which is called internally...
virtual bool inverseMap_WS2TP(double x, double y, int &out_k, double &out_d, double tolerance_dist=0.10) const override
The default implementation in this class relies on a look-up-table.
double RAD2DEG(const double x)
Radians to degrees.
virtual void internal_readFromStream(mrpt::utils::CStream &in)
#define MRPT_END
double getPathDist(uint16_t k, uint32_t step) const override
Access path k ([0,N-1]=>[-pi,pi] in alpha): traversed distance at discrete step step.
void internal_shape_loadFromStream(mrpt::utils::CStream &in)
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
Transparently opens a compressed "gz" file and reads uncompressed data from it.
This class implements a high-performance stopwatch.
Definition: CTicTac.h:23
size_t getSizeX() const
Returns the horizontal size of grid map in cells count.
Definition: CDynamicGrid.h:254
CPTG_DiffDrive_CollisionGridBased()
Constructor: possible values in "params":
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:19
bool loadColGridsFromFile(const std::string &filename, const mrpt::math::CPolygon &current_robotShape)
std::vector< std::pair< uint16_t, float > > TCollisionCell
A list of all the pairs (alpha,distance) such as the robot collides at that cell. ...
GLsizei const GLchar ** string
Definition: glext.h:4101
double idx2x(int cx) const
Transform a cell index into a coordinate value of the cell central point.
Definition: CDynamicGrid.h:291
void updateCellInfo(const unsigned int icx, const unsigned int icy, const uint16_t k, const float dist)
Updates the info into a cell: It updates the cell only if the distance d for the path k is lower than...
uint16_t getAlphaValuesCount() const
Get the number of different, discrete paths in this family.
size_t getPathStepCount(uint16_t k) const override
Access path k ([0,N-1]=>[-pi,pi] in alpha): number of discrete "steps" along the trajectory.
bool contains(const TPoint2D &point) const
Check whether a point is inside (or within geometryEpsilon of a polygon edge).
#define MRPT_START
const GLdouble * v
Definition: glext.h:3678
#define MRPT_LOAD_HERE_CONFIG_VAR_NO_DEFAULT( variableName, variableType, targetVariable, configFileObject, sectionNameStr)
void internal_processNewRobotShape() override
Will be called whenever the robot shape is set / updated.
void write(const std::string &section, const std::string &name, enum_t value, const int name_padding_width=-1, const int value_padding_width=-1, const std::string &comment=std::string())
#define CFileGZOutputStream
Saves data to a file and transparently compress the data using the given compression level...
double getResolution() const
Returns the resolution of the grid map.
Definition: CDynamicGrid.h:266
bool loadFromFile(mrpt::utils::CStream *fil, const mrpt::math::CPolygon &current_robotShape)
Load from file, true = OK.
bool saveToFile(mrpt::utils::CStream *fil, const mrpt::math::CPolygon &computed_robotShape) const
Save to file, true = OK.
bool fileOpenCorrectly()
Returns true if the file was open without errors.
T square(const T x)
Inline function for the square of a number.
void setSize(const double x_min, const double x_max, const double y_min, const double y_max, const double resolution, const T *fill_value=nullptr)
Changes the size of the grid, ERASING all previous contents.
Definition: CDynamicGrid.h:84
GLuint in
Definition: glext.h:7274
Lightweight 2D pose.
double Tac()
Stops the stopwatch.
Definition: CTicTac.cpp:97
void internal_writeToStream(mrpt::utils::CStream &out) const override
#define ASSERT_(f)
GLenum GLint GLint y
Definition: glext.h:3538
#define READ_UINT16_CHECK_IT_MATCHES_STORED(_VAR)
void getPathPose(uint16_t k, uint32_t step, mrpt::math::TPose2D &p) const override
Access path k ([0,N-1]=>[-pi,pi] in alpha): pose of the vehicle at discrete step step.
void updateTPObstacle(double ox, double oy, std::vector< double > &tp_obstacles) const override
Updates the radial map of closest TP-Obstacles given a single obstacle point at (ox,oy)
virtual void ptgDiffDriveSteeringFunction(float alpha, float t, float x, float y, float phi, float &v, float &w) const =0
The main method to be implemented in derived classes: it defines the differential-driven differential...
GLsizeiptr size
Definition: glext.h:3923
mrpt::utils::CStream & operator<<(mrpt::utils::CStream &o, const mrpt::nav::TCPoint &p)
#define MRPT_LOAD_CONFIG_VAR( variableName, variableType, configFileObject, sectionNameStr)
An useful macro for loading variables stored in a INI-like file under a key with the same name that t...
double GetVertex_y(size_t i) const
Definition: CPolygon.h:42
virtual void loadDefaultParams() override
Loads a set of default parameters; provided exclusively for the PTG-configurator tool.
GLenum GLint x
Definition: glext.h:3538
std::shared_ptr< CVehicleVelCmd > Ptr
unsigned __int32 uint32_t
Definition: rptypes.h:47
Lightweight 2D point.
#define ASSERTMSG_(f, __ERROR_MSG)
GLfloat GLfloat p
Definition: glext.h:6305
virtual mrpt::kinematics::CVehicleVelCmd::Ptr getSupportedKinematicVelocityCommand() const override
Returns an empty kinematic velocity command object of the type supported by this PTG.
void keep_max(T &var, const K test_val)
If the second argument is above the first one, set the first argument to this higher value...
Kinematic model for Ackermann-like or differential-driven vehicles.
2D polygon, inheriting from std::vector<TPoint2D>.
uint16_t m_alphaValuesCount
The number of discrete values for "alpha" between -PI and +PI.
void simulateTrajectories(float max_time, float max_dist, unsigned int max_n, float diferencial_t, float min_dist, float *out_max_acc_v=nullptr, float *out_max_acc_w=nullptr)
Numerically solve the diferential equations to generate a family of trajectories. ...
double getPathStepDuration() const override
Returns the duration (in seconds) of each "step".



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