Main MRPT website > C++ reference for MRPT 1.9.9
PlannerRRT_SE2_TPS.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 
14 #include <mrpt/utils/CTicTac.h>
15 #include <mrpt/random.h>
16 #include <mrpt/system/filesystem.h>
17 
18 using namespace mrpt::nav;
19 using namespace mrpt::utils;
20 using namespace mrpt::math;
21 using namespace mrpt::poses;
22 using namespace std;
23 
24 MRPT_TODO("Optimize getNearestNode() with KD-tree!")
25 
26 PlannerRRT_SE2_TPS::PlannerRRT_SE2_TPS() : m_initialized(false) {}
27 /** Load all params from a config file source */
29  const mrpt::utils::CConfigFileBase& ini, const std::string& sSect)
30 {
32 }
33 
34 /** Must be called after setting all params (see `loadConfig()`) and before
35  * calling `solve()` */
37 {
39 
40  m_initialized = true;
41 }
42 
43 /** The main API entry point: tries to find a planned path from 'goal' to
44  * 'target' */
48 {
49  mrpt::utils::CTimeLoggerEntry tle(m_timelogger, "PT_RRT::solve");
50 
51  // Sanity checks:
52  ASSERTMSG_(m_initialized, "initialize() must be called before!");
53 
54  // Calc maximum vehicle shape radius:
55  double max_veh_radius = 0.;
56  for (const auto& ptg : m_PTGs)
57  mrpt::utils::keep_max(max_veh_radius, ptg->getMaxRobotRadius());
58 
59  // [Algo `tp_space_rrt`: Line 1]: Init tree adding the initial pose
60  if (result.move_tree.getAllNodes().empty())
61  {
62  result.move_tree.root = 0;
63  result.move_tree.insertNode(
64  result.move_tree.root, TNodeSE2_TP(pi.start_pose));
65  }
66 
67  mrpt::utils::CTicTac working_time;
68  working_time.Tic();
69  size_t rrt_iter_counter = 0;
70 
71  size_t SAVE_3D_TREE_LOG_DECIMATION_CNT = 0;
72  static size_t SAVE_LOG_SOLVE_COUNT = 0;
73  SAVE_LOG_SOLVE_COUNT++;
74 
75  // Keep track of the best solution so far:
76  // By reusing the contents of "result" we make the algorithm re-callable
77  // ("any-time" algorithm) to refine results
78 
79  // [Algo `tp_space_rrt`: Line 2]: Iterate
80  // ------------------------------------------
81  for (;;)
82  {
83  // Check end conditions:
84  const double elap_tim = working_time.Tac();
85  if ((end_criteria.maxComputationTime > 0 &&
86  elap_tim > end_criteria.maxComputationTime) // Max comp time
87  ||
88  (result.goal_distance < end_criteria.acceptedDistToTarget &&
89  elap_tim >=
90  end_criteria
91  .minComputationTime) // Reach closer than this to target
92  )
93  {
94  break;
95  }
96 
97  // [Algo `tp_space_rrt`: Line 3]: sample random state (with goal
98  // biasing)
99  // -----------------------------------------
100  node_pose_t x_rand;
101  // bool rand_is_target=false;
102  if (mrpt::random::getRandomGenerator().drawUniform(0.0, 1.0) <
103  params.goalBias)
104  {
105  x_rand = pi.goal_pose;
106  // rand_is_target=true;
107  }
108  else
109  {
110  // Sample uniform:
111  for (int i = 0; i < node_pose_t::static_size; i++)
113  pi.world_bbox_min[i], pi.world_bbox_max[i]);
114  }
115  const CPose2D x_rand_pose(x_rand);
116 
117  // [Algo `tp_space_rrt`: Line 4]: Init empty solution set
118  // -----------------------------------------
119  typedef std::map<double, TMoveEdgeSE2_TP> sorted_solution_list_t;
120  sorted_solution_list_t candidate_new_nodes; // Map: cost -> info. Pick
121  // begin() to select the
122  // lowest-cose one.
123 
125  distance_evaluator_se2; // Plain distances in SE(2), not along PTGs
126  bool is_new_best_solution = false; // Just for logging purposes
127 
128  //#define DO_LOG_TXTS
129  std::string sLogTxt;
130 
131  // [Algo `tp_space_rrt`: Line 5]: For each PTG
132  // -----------------------------------------
133  const size_t nPTGs = m_PTGs.size();
134  for (size_t idxPTG = 0; idxPTG < nPTGs; ++idxPTG)
135  {
136  rrt_iter_counter++;
137 
138  // [Algo `tp_space_rrt`: Line 5]: Search nearest neig. to x_rand
139  // -----------------------------------------------
140  const PoseDistanceMetric<TNodeSE2_TP> distance_evaluator(
141  *m_PTGs[idxPTG]);
142 
143  const TNodeSE2_TP query_node(x_rand);
144 
145  m_timelogger.enter("TMoveTree::getNearestNode");
146  mrpt::utils::TNodeID x_nearest_id =
147  result.move_tree.getNearestNode(query_node, distance_evaluator);
148  m_timelogger.leave("TMoveTree::getNearestNode");
149 
150  if (x_nearest_id == INVALID_NODEID)
151  {
152  // We can't find any close node, at least with this PTG's paths:
153  // skip
154 
155  // Before that, save log:
156  if (params.save_3d_log_freq > 0 &&
157  (++SAVE_3D_TREE_LOG_DECIMATION_CNT >=
158  params.save_3d_log_freq))
159  {
160  SAVE_3D_TREE_LOG_DECIMATION_CNT =
161  0; // Reset decimation counter
162  TRenderPlannedPathOptions render_options;
163  render_options.highlight_path_to_node_id =
164  result.best_goal_node_id;
165  render_options.highlight_last_added_edge = false;
166  render_options.x_rand_pose = &x_rand_pose;
167  render_options.log_msg = "SKIP: Can't find any close node";
168  render_options.log_msg_position = mrpt::math::TPoint3D(
169  pi.world_bbox_min.x, pi.world_bbox_min.y, 0);
170  render_options.ground_xy_grid_frequency = 1.0;
171 
173  renderMoveTree(scene, pi, result, render_options);
174  mrpt::system::createDirectory("./rrt_log_trees");
175  scene.saveToFile(
176  mrpt::format(
177  "./rrt_log_trees/rrt_log_%03u_%06u.3Dscene",
178  static_cast<unsigned int>(SAVE_LOG_SOLVE_COUNT),
179  static_cast<unsigned int>(rrt_iter_counter)));
180  }
181 
182  continue; // Skip
183  }
184 
185  const TNodeSE2_TP& x_nearest_node =
186  result.move_tree.getAllNodes().find(x_nearest_id)->second;
187 
188  // [Algo `tp_space_rrt`: Line 6]: Relative target
189  // -----------------------------------------------
190  const CPose2D x_nearest_pose(x_nearest_node.state);
191  const CPose2D x_rand_rel = x_rand_pose - x_nearest_pose;
192 
193  // [Algo `tp_space_rrt`: Line 7]: Relative target in TP-Space
194  // ------------------------------------------------------------
195  const double D_max =
196  std::min(params.maxLength, m_PTGs[idxPTG]->getRefDistance());
197 
198  double d_rand; // Coordinates in TP-space
199  int k_rand; // k_rand is the index of target_alpha in PTGs
200  // corresponding to a specific d_rand
201  // bool tp_point_is_exact =
202  m_PTGs[idxPTG]->inverseMap_WS2TP(
203  x_rand_rel.x(), x_rand_rel.y(), k_rand, d_rand);
204  d_rand *=
205  m_PTGs[idxPTG]
206  ->getRefDistance(); // distance to target, in "real meters"
207 
208  float d_free;
209  // bool local_obs_ok = false; // Just for 3D log files: indicates
210  // whether obstacle points have been recomputed
211 
212  // [Algo `tp_space_rrt`: Line 8]: TP-Obstacles
213  // ------------------------------------------------------------
214  // Transform obstacles as seen from x_nearest_node -> TP_obstacles
215  double TP_Obstacles_k_rand = .0; // vector<double> TP_Obstacles;
216  const double MAX_DIST_FOR_OBSTACLES =
217  1.5 * m_PTGs[idxPTG]->getRefDistance(); // Maximum Euclidean
218  // distance (radius)
219  // for considering
220  // obstacles around the
221  // current robot pose
222 
224  m_PTGs[idxPTG]->getRefDistance(),
225  1.1 * max_veh_radius); // Make sure the PTG covers at least a
226  // bit more than the vehicle shape!!
227  // (should be much, much higher)
228 
229  {
230  CTimeLoggerEntry tle(
231  m_timelogger, "PT_RRT::solve.changeCoordinatesReference");
232  transformPointcloudWithSquareClipping(
233  pi.obstacles_points, m_local_obs,
234  CPose2D(x_nearest_node.state), MAX_DIST_FOR_OBSTACLES);
235  // local_obs_ok=true;
236  }
237  {
238  CTimeLoggerEntry tle(
239  m_timelogger, "PT_RRT::solve.SpaceTransformer");
240  spaceTransformerOneDirectionOnly(
241  k_rand, m_local_obs, m_PTGs[idxPTG].get(),
242  MAX_DIST_FOR_OBSTACLES, TP_Obstacles_k_rand);
243  }
244 
245  // directions k_rand in TP_obstacles[k_rand] = d_free
246  // this is the collision free distance to the TP_target
247  d_free = TP_Obstacles_k_rand; // TP_Obstacles[k_rand];
248 
249  // [Algo `tp_space_rrt`: Line 10]: d_new
250  // ------------------------------------------------------------
251  double d_new = std::min(
252  D_max,
253  d_rand); // distance of the new candidate state in TP-space
254 
255 // mrpt::poses::CPose2D *log_new_state_ptr=NULL; // For graphical logs only
256 
257 #ifdef DO_LOG_TXTS
258  sLogTxt += mrpt::format(
259  "tp_idx=%u tp_exact=%c\n d_free: %f d_rand=%f d_new=%f\n",
260  static_cast<unsigned int>(idxPTG),
261  tp_point_is_exact ? 'Y' : 'N', d_free, d_rand, d_new);
262  sLogTxt += mrpt::format(
263  " nearest:%s\n", x_nearest_pose.asString().c_str());
264 #endif
265 
266  // [Algo `tp_space_rrt`: Line 13]: Do we have free space?
267  // ------------------------------------------------------------
268  if (d_free >= d_new)
269  {
270  // [Algo `tp_space_rrt`: Line 14]: PTG function
271  // ------------------------------------------------------------
272  // given d_rand and k_rand provides x,y,phi of the point in
273  // c-space
274  uint32_t nStep;
275  m_PTGs[idxPTG]->getPathStepForDist(k_rand, d_new, nStep);
276 
277  mrpt::math::TPose2D rel_pose;
278  m_PTGs[idxPTG]->getPathPose(k_rand, nStep, rel_pose);
279 
280  mrpt::math::wrapToPiInPlace(rel_pose.phi); // wrap to [-pi,pi]
281  // -->avoid out of
282  // bounds errors
283 
284  // [Algo `tp_space_rrt`: Line 15]: pose composition
285  // ------------------------------------------------------------
286  const mrpt::poses::CPose2D new_state_rel(rel_pose);
287  mrpt::poses::CPose2D new_state =
288  x_nearest_pose + new_state_rel; // compose the new_motion
289  // as the last nmotion and
290  // the new state
291  // log_new_state_ptr = &new_state;
292 
293  // Check whether there's already a too-close node around:
294  // --------------------------------------------------------
295  bool accept_this_node = true;
296 
297  // Is this a potential solution
298  const double goal_dist =
299  new_state.distance2DTo(pi.goal_pose.x, pi.goal_pose.y);
300  const double goal_ang = std::abs(
301  mrpt::math::angDistance(new_state.phi(), pi.goal_pose.phi));
302  const bool is_acceptable_goal =
303  (goal_dist < end_criteria.acceptedDistToTarget) &&
304  (goal_ang < end_criteria.acceptedAngToTarget);
305 
306  mrpt::utils::TNodeID new_nearest_id = INVALID_NODEID;
307  if (!is_acceptable_goal) // Only check for nearby nodes if this
308  // is not a solution!
309  {
310  double new_nearest_dist;
311  const TNodeSE2 new_state_node(new_state);
312 
313  m_timelogger.enter("TMoveTree::getNearestNode");
314  new_nearest_id = result.move_tree.getNearestNode(
315  new_state_node, distance_evaluator_se2,
316  &new_nearest_dist, &result.acceptable_goal_node_ids);
317  m_timelogger.leave("TMoveTree::getNearestNode");
318 
319  if (new_nearest_id != INVALID_NODEID)
320  {
321  // Also check angular distance:
322  const double new_nearest_ang = std::abs(
324  new_state.phi(), result.move_tree.getAllNodes()
325  .find(new_nearest_id)
326  ->second.state.phi));
327  accept_this_node =
328  (new_nearest_dist >=
329  params.minDistanceBetweenNewNodes ||
330  new_nearest_ang >= params.minAngBetweenNewNodes);
331  }
332  }
333 
334  if (!accept_this_node)
335  {
336 #ifdef DO_LOG_TXTS
337  if (new_nearest_id != INVALID_NODEID)
338  {
339  sLogTxt += mrpt::format(
340  " -> new node NOT accepted for closeness to: %s\n",
341  result.move_tree.getAllNodes()
342  .find(new_nearest_id)
343  ->second.state.asString()
344  .c_str());
345  }
346 #endif
347  continue; // Too close node, skip!
348  }
349 
350  // [Algo `tp_space_rrt`: Line 16]: Add to candidate solution set
351  // ------------------------------------------------------------
352  // Create "movement" (tree edge) object:
353  TMoveEdgeSE2_TP new_edge(
354  x_nearest_id, mrpt::math::TPose2D(new_state));
355 
356  new_edge.cost = d_new;
357  new_edge.ptg_index = idxPTG;
358  new_edge.ptg_K = k_rand;
359  new_edge.ptg_dist = d_new;
360 
361  candidate_new_nodes[new_edge.cost] = new_edge;
362 
363  } // end if the path is obstacle free
364  else
365  {
366 #ifdef DO_LOG_TXTS
367  sLogTxt += mrpt::format(" -> d_free NOT < d_rand\n");
368 #endif
369  }
370 
371  } // end for idxPTG
372 
373  // [Algo `tp_space_rrt`: Line 19]: Any solution found?
374  // ------------------------------------------------------------
375  if (!candidate_new_nodes.empty())
376  {
377  const TMoveEdgeSE2_TP& best_edge =
378  candidate_new_nodes.begin()->second;
379  const TNodeSE2_TP new_state_node(best_edge.end_state);
380 
381  // Insert into the tree:
382  const mrpt::utils::TNodeID new_child_id =
383  result.move_tree.getNextFreeNodeID();
385  best_edge.parent_id, new_child_id, new_state_node, best_edge);
386 
387  // Distance to goal:
388  const double goal_dist =
390  .distance2DTo(pi.goal_pose.x, pi.goal_pose.y);
391  const double goal_ang = std::abs(
393  best_edge.end_state.phi, pi.goal_pose.phi));
394 
395  const bool is_acceptable_goal =
396  (goal_dist < end_criteria.acceptedDistToTarget) &&
397  (goal_ang < end_criteria.acceptedAngToTarget);
398 
399  if (is_acceptable_goal)
400  result.acceptable_goal_node_ids.insert(new_child_id);
401 
402  // Total path length:
403  double this_path_cost = std::numeric_limits<double>::max();
404  if (is_acceptable_goal) // Don't waste time computing path length
405  // if it doesn't matter anyway
406  {
407  TMoveTreeSE2_TP::path_t candidate_solution_path;
408  result.move_tree.backtrackPath(
409  new_child_id, candidate_solution_path);
410  this_path_cost = 0;
412  candidate_solution_path.begin();
413  it != candidate_solution_path.end(); ++it)
414  if (it->edge_to_parent)
415  this_path_cost += it->edge_to_parent->cost;
416  }
417 
418  // Check if this should be the new optimal path:
419  if (is_acceptable_goal && this_path_cost < result.path_cost)
420  {
421  result.goal_distance = goal_dist;
422  result.path_cost = this_path_cost;
423 
424  result.best_goal_node_id = new_child_id;
425  is_new_best_solution = true;
426  }
427  } // end if any candidate found
428 
429  // Graphical logging, if enabled:
430  // ------------------------------------------------------
431  if (params.save_3d_log_freq > 0 &&
432  (++SAVE_3D_TREE_LOG_DECIMATION_CNT >= params.save_3d_log_freq ||
433  is_new_best_solution))
434  {
435  CTimeLoggerEntry tle(
436  m_timelogger, "PT_RRT::solve.generate_log_files");
437  SAVE_3D_TREE_LOG_DECIMATION_CNT = 0; // Reset decimation counter
438 
439  // Render & save to file:
440  TRenderPlannedPathOptions render_options;
441  render_options.highlight_path_to_node_id = result.best_goal_node_id;
442  render_options.x_rand_pose = &x_rand_pose;
443  // render_options.x_nearest_pose = &x_nearest_pose;
444  // if (local_obs_ok) render_options.local_obs_from_nearest_pose =
445  // &m_local_obs;
446  // render_options.new_state = log_new_state_ptr;
447  render_options.highlight_last_added_edge = true;
448  render_options.ground_xy_grid_frequency = 1.0;
449 
450  render_options.log_msg = sLogTxt;
451  render_options.log_msg_position = mrpt::math::TPoint3D(
452  pi.world_bbox_min.x, pi.world_bbox_min.y, 0);
453 
455  renderMoveTree(scene, pi, result, render_options);
456 
457  mrpt::system::createDirectory("./rrt_log_trees");
458  scene.saveToFile(
459  mrpt::format(
460  "./rrt_log_trees/rrt_log_%03u_%06u.3Dscene",
461  static_cast<unsigned int>(SAVE_LOG_SOLVE_COUNT),
462  static_cast<unsigned int>(rrt_iter_counter)));
463  }
464 
465  } // end loop until end conditions
466 
467  // [Algo `tp_space_rrt`: Line 17]: Tree back trace
468  // ------------------------------------------------------------
469  result.success = (result.goal_distance < end_criteria.acceptedDistToTarget);
470  result.computation_time = working_time.Tac();
471 
472 } // end solve()
double drawUniform(const double Min, const double Max)
Generate a uniformly distributed pseudo-random number using the MT19937 algorithm, scaled to the selected range.
mrpt::utils::TNodeID parent_id
The ID of the parent node in the tree.
Definition: TMoveTree.h:192
double x() const
Common members of all points & poses classes.
Definition: CPoseOrPoint.h:135
bool createDirectory(const std::string &dirName)
Creates a directory.
Definition: filesystem.cpp:158
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
#define min(a, b)
mrpt::math::TPose2D state
state in SE2 as 2D pose (x, y, phi)
Definition: TMoveTree.h:253
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
#define ASSERT_ABOVE_(__A, __B)
std::set< mrpt::utils::TNodeID > acceptable_goal_node_ids
The set of target nodes within an acceptable distance to target (including best_goal_node_id and othe...
void internal_loadConfig_PTG(const mrpt::utils::CConfigFileBase &cfgSource, const std::string &sSectionName=std::string("PTG_CONFIG"))
Load all PTG params from a config file source.
Pose metric for SE(2) limited to a given PTG manifold.
Definition: TMoveTree.h:261
T angDistance(T from, T to)
Computes the shortest angular increment (or distance) between two planar orientations, such that it is constrained to [-pi,pi] and is correct for any combination of angles (e.g.
Definition: wrap2pi.h:98
world_limits_t world_bbox_min
Bounding box of the world, used to draw uniform random pose samples.
#define INVALID_NODEID
std::list< node_t > path_t
A topological path up-tree.
Definition: TMoveTree.h:82
STL namespace.
const Scalar * const_iterator
Definition: eigen_plugins.h:27
const node_map_t & getAllNodes() const
Definition: TMoveTree.h:146
int ptg_index
indicate the type of trajectory used for this motion
Definition: TMoveTree.h:200
void Tic()
Starts the stopwatch.
Definition: CTicTac.cpp:82
mrpt::utils::TNodeID highlight_path_to_node_id
Highlight the path from root towards this node (usually, the target)
int ptg_K
identify the trajectory number K of the type ptg_index
Definition: TMoveTree.h:202
void initialize()
Must be called after setting all params (see loadConfig()) and before calling solve() ...
double cost
cost associated to each motion, this should be defined by the user according to a spefic cost functio...
Definition: TMoveTree.h:198
#define MRPT_TODO(x)
This class allows loading and storing values and vectors of different types from a configuration text...
void wrapToPiInPlace(T &a)
Modifies the given angle to translate it into the ]-pi,pi] range.
Definition: wrap2pi.h:64
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:19
uint64_t TNodeID
The type for node IDs in graphs of different types.
void loadConfig(const mrpt::utils::CConfigFileBase &cfgSource, const std::string &sSectionName=std::string("PTG_CONFIG"))
Load all params from a config file source.
bool success
Whether the target was reached or not.
This class implements a high-performance stopwatch.
Definition: CTicTac.h:23
void insertNode(const mrpt::utils::TNodeID node_id, const NODE_TYPE_DATA &node_data)
Insert a node without edges (should be used only for a tree root node)
Definition: TMoveTree.h:139
mrpt::utils::TNodeID getNearestNode(const NODE_TYPE_FOR_METRIC &query_pt, const PoseDistanceMetric< NODE_TYPE_FOR_METRIC > &distanceMetricEvaluator, double *out_distance=NULL, const std::set< mrpt::utils::TNodeID > *ignored_nodes=NULL) const
Finds the nearest node to a given pose, using the given metric.
Definition: TMoveTree.h:86
TNodeID root
The root of the tree.
Definition: CDirectedTree.h:84
double distance2DTo(double ax, double ay) const
Returns the 2D distance from this pose/point to a 2D point (ignores Z, if it exists).
Definition: CPoseOrPoint.h:233
GLsizei const GLchar ** string
Definition: glext.h:4101
mrpt::utils::TNodeID best_goal_node_id
The ID of the best target node in the tree.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Definition: CPoint.h:17
double ground_xy_grid_frequency
(Default=10 meters) Set to 0 to disable
bool saveToFile(const std::string &fil) const
Saves the scene to a 3Dscene file, loadable by the application SceneViewer3D.
double path_cost
Total cost of the best found path (cost ~~ Euclidean distance)
void insertNodeAndEdge(const mrpt::utils::TNodeID parent_id, const mrpt::utils::TNodeID new_child_id, const NODE_TYPE_DATA &new_child_node_data, const EDGE_TYPE &new_edge_data)
Definition: TMoveTree.h:118
void internal_initialize_PTG()
Must be called after setting all params (see internal_loadConfig_PTG()) and before calling solve() ...
void solve(const TPlannerInput &pi, TPlannerResult &result)
The main API entry point: tries to find a planned path from &#39;goal&#39; to &#39;target&#39;.
void backtrackPath(const mrpt::utils::TNodeID target_node, path_t &out_path) const
Builds the path (sequence of nodes, with info about next edge) up-tree from a target_node towards the...
Definition: TMoveTree.h:151
mrpt::maps::CSimplePointsMap obstacles_points
World obstacles, as a point cloud.
double goal_distance
Distance from best found path to goal.
double computation_time
Time spent (in secs)
A safe way to call enter() and leave() of a mrpt::utils::CTimeLogger upon construction and destructio...
Definition: CTimeLogger.h:152
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle...
Definition: CPose2D.h:40
const double & phi() const
Get the phi angle of the 2D pose (in radians)
Definition: CPose2D.h:91
Lightweight 2D pose.
mrpt::utils::TNodeID getNextFreeNodeID() const
Definition: TMoveTree.h:145
This class allows the user to create, load, save, and render 3D scenes using OpenGL primitives...
Definition: COpenGLScene.h:60
double Tac()
Stops the stopwatch.
Definition: CTicTac.cpp:97
double ptg_dist
identify the lenght of the trajectory for this motion
Definition: TMoveTree.h:204
An edge for the move tree used for planning in SE2 and TP-space.
Definition: TMoveTree.h:189
mrpt::math::TPose2D end_state
state in SE2 as 2D pose (x, y, phi) -
Definition: TMoveTree.h:195
Lightweight 3D point.
unsigned __int32 uint32_t
Definition: rptypes.h:47
CRandomGenerator & getRandomGenerator()
A static instance of a CRandomGenerator class, for use in single-thread applications.
#define ASSERTMSG_(f, __ERROR_MSG)
GLenum const GLfloat * params
Definition: glext.h:3534
TP Space-based RRT path planning for SE(2) (planar) robots.
double phi
Orientation (rads)
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...
tree_t move_tree
The generated motion tree that explores free space starting at "start".



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