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 }
const float R
#define M_PI
Definition: bits.h:92
This is the base class for any user-defined PTG.
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)...
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< CGridPlaneXY > Ptr
Definition: CGridPlaneXY.h:34
This class allows the user to create, load, save, and render 3D scenes using OpenGL primitives.
Definition: COpenGLScene.h:61
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).
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:36
std::shared_ptr< CSetOfLines > Ptr
Definition: CSetOfLines.h:37
std::shared_ptr< CSetOfObjects > Ptr
Definition: CSetOfObjects.h:32
std::shared_ptr< CText3D > Ptr
Definition: CText3D.h:47
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle.
Definition: CPose2D.h:41
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:89
const Scalar * const_iterator
Definition: eigen_plugins.h:27
GLsizei GLsizei GLuint * obj
Definition: glext.h:4070
GLenum const GLfloat * params
Definition: glext.h:3534
GLsizei const GLchar ** string
Definition: glext.h:4101
#define INVALID_NODEID
Definition: types_simple.h:52
#define ASSERT_ABOVE_(__A, __B)
Definition: mrpt_macros.h:327
#define ASSERT_(f)
Definition: mrpt_macros.h:309
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...
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.
Definition: bits.h:227
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Lightweight 2D pose.
Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).
mrpt::utils::TColor color_local_obstacles
local obstacles color
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)
double ground_xy_grid_frequency
(Default=10 meters) Set to 0 to disable
double vehicle_shape_z
(Default=0.01) Height (Z coordinate) for the vehicle shapes.
double vehicle_line_width
Robot line width for visualization - default 2.0.
mrpt::utils::TColor color_start
START indication color
size_t draw_shape_decimation
(Default=1) Draw one out of N vehicle shapes along the highlighted path
mrpt::maps::CSimplePointsMap obstacles_points
World obstacles, as a point cloud.
world_limits_t world_bbox_min
Bounding box of the world, used to draw uniform random pose samples.
tree_t move_tree
The generated motion tree that explores free space starting at "start".



Page generated by Doxygen 1.9.1 for MRPT 1.9.9 Git: 63ea9d1f1 Thu Nov 23 00:06:53 2017 +0100 at mar 26 may 2026 12:19:29 CEST