24 MRPT_TODO(
"Optimize getNearestNode() with KD-tree!")
53 ASSERTMSG_(m_initialized,
"initialize() must be called before!");
56 double max_veh_radius=0.;
57 for (
const auto & ptg : m_PTGs)
69 size_t rrt_iter_counter=0;
71 size_t SAVE_3D_TREE_LOG_DECIMATION_CNT=0;
72 static size_t SAVE_LOG_SOLVE_COUNT=0;
73 SAVE_LOG_SOLVE_COUNT++;
83 const double elap_tim = working_time.
Tac();
85 (end_criteria.maxComputationTime>0 && elap_tim>end_criteria.maxComputationTime)
86 || (result.
goal_distance<end_criteria.acceptedDistToTarget && elap_tim>=end_criteria.minComputationTime)
105 const CPose2D x_rand_pose(x_rand);
109 typedef std::map<double,TMoveEdgeSE2_TP> sorted_solution_list_t;
110 sorted_solution_list_t candidate_new_nodes;
113 bool is_new_best_solution =
false;
120 const size_t nPTGs = m_PTGs.size();
121 for (
size_t idxPTG=0;idxPTG<nPTGs;++idxPTG)
131 m_timelogger.enter(
"TMoveTree::getNearestNode");
133 m_timelogger.leave(
"TMoveTree::getNearestNode");
140 if (
params.save_3d_log_freq>0 && (++SAVE_3D_TREE_LOG_DECIMATION_CNT >=
params.save_3d_log_freq))
142 SAVE_3D_TREE_LOG_DECIMATION_CNT=0;
147 render_options.
log_msg =
"SKIP: Can't find any close node";
152 renderMoveTree(scene, pi,result,render_options);
154 scene.
saveToFile(
mrpt::format(
"./rrt_log_trees/rrt_log_%03u_%06u.3Dscene",
static_cast<unsigned int>(SAVE_LOG_SOLVE_COUNT),
static_cast<unsigned int>(rrt_iter_counter) ) );
165 const CPose2D x_rand_rel = x_rand_pose - x_nearest_pose;
169 const double D_max =
std::min(
params.maxLength, m_PTGs[idxPTG]->getRefDistance() );
174 m_PTGs[idxPTG]->inverseMap_WS2TP(
175 x_rand_rel.
x(), x_rand_rel.
y(),
177 d_rand *= m_PTGs[idxPTG]->getRefDistance();
185 double TP_Obstacles_k_rand = .0;
186 const double MAX_DIST_FOR_OBSTACLES = 1.5*m_PTGs[idxPTG]->getRefDistance();
188 ASSERT_ABOVE_(m_PTGs[idxPTG]->getRefDistance(),1.1*max_veh_radius);
191 CTimeLoggerEntry tle(m_timelogger,
"PT_RRT::solve.changeCoordinatesReference");
197 spaceTransformerOneDirectionOnly(k_rand, m_local_obs, m_PTGs[idxPTG].
pointer(), MAX_DIST_FOR_OBSTACLES, TP_Obstacles_k_rand);
202 d_free = TP_Obstacles_k_rand;
206 double d_new =
std::min(D_max, d_rand);
211 sLogTxt +=
mrpt::format(
"tp_idx=%u tp_exact=%c\n d_free: %f d_rand=%f d_new=%f\n",
static_cast<unsigned int>(idxPTG), tp_point_is_exact ?
'Y':
'N',d_free,d_rand,d_new);
223 m_PTGs[idxPTG]->getPathStepForDist(k_rand, d_new, nStep);
226 m_PTGs[idxPTG]->getPathPose(k_rand, nStep, rel_pose);
238 bool accept_this_node =
true;
244 const bool is_acceptable_goal =
245 (goal_dist<end_criteria.acceptedDistToTarget) &&
246 (goal_ang <end_criteria.acceptedAngToTarget);
249 if (!is_acceptable_goal)
251 double new_nearest_dist;
252 const TNodeSE2 new_state_node(new_state);
254 m_timelogger.enter(
"TMoveTree::getNearestNode");
256 m_timelogger.leave(
"TMoveTree::getNearestNode");
262 accept_this_node = (new_nearest_dist>=
params.minDistanceBetweenNewNodes || new_nearest_ang >=
params.minAngBetweenNewNodes);
266 if (!accept_this_node)
270 sLogTxt +=
mrpt::format(
" -> new node NOT accepted for closeness to: %s\n",result.
move_tree.
getAllNodes().find(new_nearest_id)->second.state.asString().c_str());
281 new_edge.
cost = d_new;
283 new_edge.
ptg_K = k_rand;
286 candidate_new_nodes[new_edge.
cost] = new_edge;
301 if (!candidate_new_nodes.empty())
303 const TMoveEdgeSE2_TP & best_edge = candidate_new_nodes.begin()->second;
314 const bool is_acceptable_goal =
315 (goal_dist<end_criteria.acceptedDistToTarget) &&
316 (goal_ang <end_criteria.acceptedAngToTarget);
318 if (is_acceptable_goal)
322 double this_path_cost = std::numeric_limits<double>::max();
323 if (is_acceptable_goal)
329 if (it->edge_to_parent)
330 this_path_cost+=it->edge_to_parent->cost;
334 if (is_acceptable_goal && this_path_cost<result.
path_cost)
340 is_new_best_solution=
true;
346 if (
params.save_3d_log_freq>0 && (++SAVE_3D_TREE_LOG_DECIMATION_CNT >=
params.save_3d_log_freq || is_new_best_solution))
349 SAVE_3D_TREE_LOG_DECIMATION_CNT=0;
361 render_options.
log_msg = sLogTxt;
365 renderMoveTree(scene, pi,result,render_options);
368 scene.
saveToFile(
mrpt::format(
"./rrt_log_trees/rrt_log_%03u_%06u.3Dscene",
static_cast<unsigned int>(SAVE_LOG_SOLVE_COUNT),
static_cast<unsigned int>(rrt_iter_counter) ) );
TNodeID root
The root of the tree.
TP Space-based RRT path planning for SE(2) (planar) robots.
void loadConfig(const mrpt::utils::CConfigFileBase &cfgSource, const std::string &sSectionName=std::string("PTG_CONFIG"))
Load all params from a config file source.
void initialize()
Must be called after setting all params (see loadConfig()) and before calling solve()
void solve(const TPlannerInput &pi, TPlannerResult &result)
The main API entry point: tries to find a planned path from 'goal' to 'target'.
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.
void internal_initialize_PTG()
Must be called after setting all params (see internal_loadConfig_PTG()) and before calling solve()
mrpt::utils::TNodeID getNextFreeNodeID() const
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.
const node_map_t & getAllNodes() const
std::list< node_t > path_t
A topological path up-tree.
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)
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...
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)
This class allows the user to create, load, save, and render 3D scenes using OpenGL primitives.
bool saveToFile(const std::string &fil) const
Saves the scene to a 3Dscene file, loadable by the application SceneViewer3D.
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle.
void asString(std::string &s) const
Returns a human-readable textual representation of the object (eg: "[x y yaw]", yaw in degrees)
const double & phi() const
Get the phi angle of the 2D pose (in radians)
double x() const
Common members of all points & poses classes.
double distance2DTo(double ax, double ay) const
Returns the 2D distance from this pose/point to a 2D point (ignores Z, if it exists).
This class allows loading and storing values and vectors of different types from a configuration text...
This class implements a high-performance stopwatch.
double Tac()
Stops the stopwatch.
void Tic()
Starts the stopwatch.
const Scalar * const_iterator
GLsizei const GLvoid * pointer
GLenum const GLfloat * params
GLsizei const GLchar ** string
T angDistance(T from, T to)
Computes the shortest angular increment (or distance) between two planar orientations,...
void wrapToPiInPlace(T &a)
Modifies the given angle to translate it into the ]-pi,pi] range.
bool BASE_IMPEXP createDirectory(const std::string &dirName)
Creates a directory.
uint64_t TNodeID
The type for node IDs in graphs of different types.
#define ASSERT_ABOVE_(__A, __B)
#define ASSERTMSG_(f, __ERROR_MSG)
This base provides a set of functions for maths stuff.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
BASE_IMPEXP CRandomGenerator randomGenerator
A static instance of a CRandomGenerator class, for use in single-thread applications.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values,...
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::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
unsigned __int32 uint32_t
double phi
Orientation (rads)
Options for renderMoveTree()
mrpt::utils::TNodeID highlight_path_to_node_id
Highlight the path from root towards this node (usually, the target)
double ground_xy_grid_frequency
(Default=10 meters) Set to 0 to disable
const mrpt::poses::CPose2D * x_rand_pose
mrpt::math::TPoint3D log_msg_position
bool highlight_last_added_edge
(Default=false)
Pose metric for SE(2) limited to a given PTG manifold.
An edge for the move tree used for planning in SE2 and TP-space.
mrpt::math::TPose2D end_state
state in SE2 as 2D pose (x, y, phi) -
double cost
cost associated to each motion, this should be defined by the user according to a spefic cost functio...
int ptg_index
indicate the type of trajectory used for this motion
mrpt::utils::TNodeID parent_id
The ID of the parent node in the tree.
double ptg_dist
identify the lenght of the trajectory for this motion
int ptg_K
identify the trajectory number K of the type ptg_index
mrpt::math::TPose2D state
state in SE2 as 2D pose (x, y, phi)
mrpt::utils::TNodeID best_goal_node_id
The ID of the best target node in the tree.
bool success
Whether the target was reached or not.
tree_t move_tree
The generated motion tree that explores free space starting at "start".
double path_cost
Total cost of the best found path (cost ~~ Euclidean distance)
double goal_distance
Distance from best found path to goal.
double computation_time
Time spent (in secs)
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...
A safe way to call enter() and leave() of a mrpt::utils::CTimeLogger upon construction and destructio...