Main MRPT website > C++ reference for MRPT 1.9.9
impl_renderMoveTree.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-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 #pragma once
11 
12 // For 3D log files
18 #include <mrpt/opengl/CText3D.h>
19 
20 namespace mrpt
21 {
22 namespace nav
23 {
24 template <typename node_pose_t, typename world_limits_t, typename tree_t>
28  const TPlannerResultTempl<tree_t>& result,
29  const TRenderPlannedPathOptions& options)
30 {
31  using std::string;
32 
33  // Build a model of the vehicle shape:
34  mrpt::opengl::CSetOfLines::Ptr gl_veh_shape =
35  mrpt::make_aligned_shared<mrpt::opengl::CSetOfLines>();
36  double
37  xyzcorners_scale; // Size of XYZ corners (scaled to vehicle dimensions)
38  {
39  gl_veh_shape->setLineWidth(options.vehicle_line_width);
40  gl_veh_shape->setColor_u8(options.color_vehicle);
41 
42  double max_veh_radius = 0.;
43  if (!params.robot_shape.empty())
44  {
45  gl_veh_shape->appendLine(
46  params.robot_shape[0].x, params.robot_shape[0].y, 0,
47  params.robot_shape[1].x, params.robot_shape[1].y, 0);
48  for (size_t i = 2; i <= params.robot_shape.size(); i++)
49  {
50  const size_t idx = i % params.robot_shape.size();
52  max_veh_radius, params.robot_shape[idx].norm());
53  gl_veh_shape->appendLineStrip(
54  params.robot_shape[idx].x, params.robot_shape[idx].y, 0);
55  }
56  }
57  else if (params.robot_shape_circular_radius > 0)
58  {
59  const int NUM_VERTICES = 10;
60  const double R = params.robot_shape_circular_radius;
61  for (int i = 0; i <= NUM_VERTICES; i++)
62  {
63  const size_t idx = i % NUM_VERTICES;
64  const size_t idxn = (i + 1) % NUM_VERTICES;
65  const double ang = idx * 2 * M_PI / (NUM_VERTICES - 1);
66  const double angn = idxn * 2 * M_PI / (NUM_VERTICES - 1);
67  gl_veh_shape->appendLine(
68  R * cos(ang), R * sin(ang), 0, R * cos(angn), R * sin(angn),
69  0);
70  }
71  mrpt::utils::keep_max(max_veh_radius, R);
72  }
73 
74  xyzcorners_scale = max_veh_radius * 0.5;
75  }
76  // Override with user scale?
77  if (options.xyzcorners_scale != 0)
78  xyzcorners_scale = options.xyzcorners_scale;
79 
80  // "ground"
81  if (options.ground_xy_grid_frequency > 0)
82  {
84  mrpt::make_aligned_shared<mrpt::opengl::CGridPlaneXY>(
86  pi.world_bbox_max.y, 0, options.ground_xy_grid_frequency);
87  obj->setColor_u8(options.color_ground_xy_grid);
88  scene.insert(obj);
89  }
90 
91  // Original randomly-pick pose:
92  if (options.x_rand_pose)
93  {
95  mrpt::opengl::stock_objects::CornerXYZ(xyzcorners_scale * 1.0);
96  string m_name = "X_rand";
97  obj->setName(m_name);
98  obj->enableShowName();
99  obj->setPose(mrpt::poses::CPose3D(*options.x_rand_pose));
100  scene.insert(obj);
101  }
102 
103  // Nearest state pose:
104  if (options.x_nearest_pose)
105  {
107  mrpt::opengl::stock_objects::CornerXYZ(xyzcorners_scale * 1.0);
108  string m_name = "X_near";
109  obj->setName(m_name);
110  obj->enableShowName();
111  obj->setPose(mrpt::poses::CPose3D(*options.x_nearest_pose));
112  scene.insert(obj);
113  }
114 
115  // Determine the up-to-now best solution, so we can highlight the best path
116  // so far:
117  typename tree_t::path_t best_path;
119  result.move_tree.backtrackPath(
120  options.highlight_path_to_node_id, best_path);
121 
122  // make list of nodes in the way of the best path:
123  std::set<const typename tree_t::edge_t *> edges_best_path,
124  edges_best_path_decim;
125  if (!best_path.empty())
126  {
127  typename tree_t::path_t::const_iterator it_end = best_path.end();
128  typename tree_t::path_t::const_iterator it_end_1 = best_path.end();
129  std::advance(it_end_1, -1);
130 
131  for (typename tree_t::path_t::const_iterator it = best_path.begin();
132  it != it_end; ++it)
133  if (it->edge_to_parent) edges_best_path.insert(it->edge_to_parent);
134 
135  // Decimate the path (always keeping the first and last entry):
137  for (typename tree_t::path_t::const_iterator it = best_path.begin();
138  it != it_end;)
139  {
140  if (it->edge_to_parent)
141  edges_best_path_decim.insert(it->edge_to_parent);
142  if (it == it_end_1) break;
143  for (size_t k = 0; k < options.draw_shape_decimation; k++)
144  {
145  if (it == it_end || it == it_end_1) break;
146  ++it;
147  }
148  }
149  }
150 
151  // The starting pose vehicle shape must be inserted independently, because
152  // the rest are edges and we draw the END pose of each edge:
153  {
155  new mrpt::opengl::CSetOfLines(*gl_veh_shape));
157  shapePose.z_incr(options.vehicle_shape_z);
158  vehShape->setPose(shapePose);
159  scene.insert(vehShape);
160  }
161 
162  // Existing nodes & edges between them:
163  {
164  const typename tree_t::node_map_t& lstNodes =
165  result.move_tree.getAllNodes();
166 
167  for (typename tree_t::node_map_t::const_iterator itNode =
168  lstNodes.begin();
169  itNode != lstNodes.end(); ++itNode)
170  {
171  const typename tree_t::node_t& node = itNode->second;
172 
173  mrpt::math::TPose2D parent_state;
174  if (node.parent_id != INVALID_NODEID)
175  {
176  parent_state = lstNodes.find(node.parent_id)->second.state;
177  }
178  const mrpt::math::TPose2D& trg_state = node.state;
179 
180  const bool is_new_one = (itNode == (lstNodes.end() - 1));
181  const bool is_best_path =
182  edges_best_path.count(node.edge_to_parent) != 0;
183  const bool is_best_path_and_draw_shape =
184  edges_best_path_decim.count(node.edge_to_parent) != 0;
185 
186  // Draw children nodes:
187  {
188  const float corner_scale =
189  xyzcorners_scale * (is_new_one ? 1.5f : 1.0f);
190 
193  obj->setPose(mrpt::poses::CPose3D(trg_state));
194  scene.insert(obj);
195 
196  // Insert vehicle shapes along optimal path:
197  if (is_best_path_and_draw_shape)
198  {
200  new mrpt::opengl::CSetOfLines(*gl_veh_shape));
201  mrpt::poses::CPose3D shapePose =
202  mrpt::poses::CPose3D(trg_state);
203  shapePose.z_incr(options.vehicle_shape_z);
204  vehShape->setPose(shapePose);
205  scene.insert(vehShape);
206  }
207  }
208 
209  // Draw line parent -> children nodes.
210  if (node.parent_id != INVALID_NODEID)
211  {
212  // Draw actual PT path between parent and children nodes:
213  ASSERT_(node.edge_to_parent)
215  m_PTGs[node.edge_to_parent->ptg_index].get();
216 
217  // Create the path shape, in relative coords to the parent node:
219  mrpt::make_aligned_shared<mrpt::opengl::CSetOfLines>();
220  obj->setPose(
221  mrpt::poses::CPose3D(parent_state)); // Points are relative
222  // to this pose: let
223  // OpenGL to deal with
224  // the coords.
225  // composition
226 
228  node.edge_to_parent->ptg_K, *obj, 0.25f /*decimation*/,
229  node.edge_to_parent->ptg_dist /*max path length*/);
230 
231  if (is_new_one && options.highlight_last_added_edge)
232  {
233  // Last edge format:
234  obj->setColor_u8(options.color_last_edge);
235  obj->setLineWidth(options.width_last_edge);
236  }
237  else
238  {
239  // Normal format:
240  obj->setColor_u8(options.color_normal_edge);
241  obj->setLineWidth(options.width_normal_edge);
242  }
243  if (is_best_path)
244  {
245  obj->setColor_u8(options.color_optimal_edge);
246  obj->setLineWidth(options.width_optimal_edge);
247  }
248 
249  scene.insert(obj);
250  }
251  }
252  }
253 
254  // The new node:
255  if (options.new_state)
256  {
258  mrpt::opengl::stock_objects::CornerXYZ(xyzcorners_scale * 1.2);
259  string m_name = "X_new";
260  obj->setName(m_name);
261  obj->enableShowName();
262  obj->setPose(mrpt::poses::CPose3D(*options.new_state));
263  scene.insert(obj);
264  }
265 
266  // Obstacles:
267  if (options.draw_obstacles)
268  {
270  mrpt::make_aligned_shared<mrpt::opengl::CPointCloud>();
271 
272  obj->loadFromPointsMap(&pi.obstacles_points);
273  obj->setPose(
276  0.0, 0.0, 0.0))); // Points are relative to the origin
277 
278  obj->setPointSize(options.point_size_obstacles);
279  obj->setColor_u8(options.color_obstacles);
280  scene.insert(obj);
281  }
282 
283  // The current set of local obstacles:
284  // Draw this AFTER the global map so it's visible:
285  if (options.draw_obstacles && options.local_obs_from_nearest_pose &&
286  options.x_nearest_pose)
287  {
289  mrpt::make_aligned_shared<mrpt::opengl::CPointCloud>();
290 
291  obj->loadFromPointsMap(options.local_obs_from_nearest_pose);
292  obj->setPose(*options.x_nearest_pose); // Points are relative to this
293  // pose: let OpenGL to deal with
294  // the coords. composition
295  obj->setPointSize(options.point_size_local_obstacles);
296  obj->setColor_u8(options.color_local_obstacles);
297  scene.insert(obj);
298  }
299 
300  // Start:
301  {
303  mrpt::opengl::stock_objects::CornerXYZ(xyzcorners_scale * 1.5);
304  obj->setName("START");
305  obj->enableShowName();
306  obj->setColor_u8(options.color_start);
307  obj->setPose(pi.start_pose);
308  scene.insert(obj);
309  }
310 
311  // Target:
312  {
314  mrpt::opengl::stock_objects::CornerXYZ(xyzcorners_scale * 1.5);
315  string m_name = "GOAL";
316  obj->setName(m_name);
317  obj->enableShowName();
318  obj->setColor_u8(options.color_goal);
319  obj->setPose(pi.goal_pose);
320  scene.insert(obj);
321  }
322 
323  // Log msg:
324  if (!options.log_msg.empty())
325  {
327  mrpt::make_aligned_shared<mrpt::opengl::CText3D>(
328  options.log_msg, "sans", options.log_msg_scale);
329  gl_txt->setLocation(options.log_msg_position);
330  scene.insert(gl_txt);
331  }
332 
333 } // end renderMoveTree()
334 }
335 }
mrpt::utils::TColor color_goal
END indication color.
double vehicle_shape_z
(Default=0.01) Height (Z coordinate) for the vehicle shapes.
#define ASSERT_ABOVE_(__A, __B)
virtual void renderPathAsSimpleLine(const uint16_t k, mrpt::opengl::CSetOfLines &gl_obj, const double decimate_distance=0.1, const double max_path_distance=-1.0) const
Returns the representation of one trajectory of this PTG as a 3D OpenGL object (a simple curved line)...
world_limits_t world_bbox_min
Bounding box of the world, used to draw uniform random pose samples.
#define INVALID_NODEID
#define M_PI
Definition: bits.h:92
const Scalar * const_iterator
Definition: eigen_plugins.h:27
GLsizei GLsizei GLuint * obj
Definition: glext.h:4070
mrpt::utils::TNodeID highlight_path_to_node_id
Highlight the path from root towards this node (usually, the target)
double xyzcorners_scale
A scale factor to all XYZ corners (default=0, means auto determien from vehicle shape) ...
std::shared_ptr< CText3D > Ptr
Definition: CText3D.h:47
This is the base class for any user-defined PTG.
std::shared_ptr< CSetOfObjects > Ptr
Definition: CSetOfObjects.h:32
double vehicle_line_width
Robot line width for visualization - default 2.0.
GLsizei const GLchar ** string
Definition: glext.h:4101
double ground_xy_grid_frequency
(Default=10 meters) Set to 0 to disable
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
mrpt::maps::CSimplePointsMap obstacles_points
World obstacles, as a point cloud.
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle...
Definition: CPose2D.h:40
const float R
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:88
CSetOfObjects::Ptr CornerXYZ(float scale=1.0)
Returns three arrows representing a X,Y,Z 3D corner.
CSetOfObjects::Ptr CornerXYZSimple(float scale=1.0, float lineWidth=1.0)
Returns three arrows representing a X,Y,Z 3D corner (just thick lines instead of complex arrows for f...
Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).
Lightweight 2D pose.
This class allows the user to create, load, save, and render 3D scenes using OpenGL primitives...
Definition: COpenGLScene.h:60
#define ASSERT_(f)
std::shared_ptr< CSetOfLines > Ptr
Definition: CSetOfLines.h:37
size_t draw_shape_decimation
(Default=1) Draw one out of N vehicle shapes along the highlighted path
mrpt::utils::TColor color_start
START indication color.
void renderMoveTree(mrpt::opengl::COpenGLScene &scene, const TPlannerInputTempl< node_pose_t, world_limits_t > &pi, const TPlannerResultTempl< tree_t > &result, const TRenderPlannedPathOptions &options)
std::shared_ptr< CPointCloud > Ptr
Definition: CPointCloud.h:52
A set of independent lines (or segments), one line with its own start and end positions (X...
Definition: CSetOfLines.h:35
void insert(const CRenderizable::Ptr &newObject, const std::string &viewportName=std::string("main"))
Insert a new object into the scene, in the given viewport (by default, into the "main" viewport)...
GLenum const GLfloat * params
Definition: glext.h:3534
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...
std::shared_ptr< CGridPlaneXY > Ptr
Definition: CGridPlaneXY.h:34
mrpt::utils::TColor color_local_obstacles
local obstacles color
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