Example: nav_rrt_planning_example
Path planning with the RRT planner in mrpt::nav::PlannerRRT_SE2_TPS, for a robot with arbitrary shape and kinematic constraints, in an obstacle map.
Modules: mrpt_config, mrpt_gui, mrpt_io, mrpt_maps, mrpt_serialization, mrpt_system | Requires: gui
C++ example source code:
/* _ | | Mobile Robot Programming Toolkit (MRPT) _ __ ___ _ __ _ __ | |_ | '_ ` _ \| '__| '_ \| __| https://www.mrpt.org/ | | | | | | | | |_) | |_ |_| |_| |_|_| | .__/ \__| https://github.com/MRPT/mrpt/ | | |_| Copyright (c) 2005-2026, Individual contributors, see AUTHORS file See: https://www.mrpt.org/Authors - All rights reserved. SPDX-License-Identifier: BSD-3-Clause */ #include <mrpt/config/CConfigFile.h> #include <mrpt/gui/CDisplayWindow3D.h> #include <mrpt/io/CCompressedInputStream.h> #include <mrpt/maps/CSimpleMap.h> #include <mrpt/nav.h> #include <mrpt/random.h> #include <mrpt/serialization/CArchive.h> #include <mrpt/system/filesystem.h> // directoryExists(), ... #include <iostream> using namespace mrpt; using namespace mrpt::nav; using namespace mrpt::maps; using namespace std; // Load example grid map // MRPT_EXAMPLES_BASE_DIRECTORY provided via compile definition string mySimpleMap(MRPT_DATA_DIR + string("/datasets/malaga-cs-fac-building.simplemap.gz")); string myCfgFileName( MRPT_DATA_DIR + string("/config_files/navigation-ptgs/ptrrt_config_example1.ini")); // ------------------------------------------------------ // TestRRT1 // ------------------------------------------------------ void TestRRT1() { mrpt::random::Randomize(); // Load the gridmap: CSimpleMap simplemap; ASSERT_FILE_EXISTS_(mySimpleMap); std::cout << "Loading map..."; { mrpt::io::CCompressedInputStream f(mySimpleMap); auto arch = mrpt::serialization::archiveFrom(f); arch >> simplemap; } std::cout << "Done! Number of sensory frames: " << simplemap.size() << "\n"; // Set planner params: // ------------------------------ mrpt::nav::PlannerRRT_SE2_TPS planner; // Parameters: planner.loadConfig(mrpt::config::CConfigFile(myCfgFileName)); planner.params.maxLength = 2.0; planner.params.minDistanceBetweenNewNodes = 0.10; planner.params.minAngBetweenNewNodes = mrpt::DEG2RAD(20); planner.params.goalBias = 0.05; // Logging: planner.params.save_3d_log_freq = 0; // 500; // save some iterations for debugging // End criteria: planner.end_criteria.acceptedDistToTarget = 0.25; planner.end_criteria.acceptedAngToTarget = 180.0_deg; // 180d=Any orientation is ok planner.end_criteria.maxComputationTime = 15.0; planner.end_criteria.minComputationTime = 1.0; // 0=accept first found acceptable solution // Init planner: // ------------------------------ planner.initialize(); // Set up planning problem: // ------------------------------ PlannerRRT_SE2_TPS::TPlannerResult planner_result; PlannerRRT_SE2_TPS::TPlannerInput planner_input; // Start & goal: planner_input.start_pose = mrpt::math::TPose2D(0, 0, 0); planner_input.goal_pose = mrpt::math::TPose2D(-20, -30, 0); // Obstacles: planner_input.obstacles_points.loadFromSimpleMap(simplemap); const auto bbox = planner_input.obstacles_points.boundingBox(); // Convert gridmap -> obstacle points: // gridmap.getAsPointCloud( planner_input.obstacles_points ); // Workspace bounding box: planner_input.world_bbox_min = {bbox.min.x, bbox.min.y, -M_PI}; planner_input.world_bbox_max = {bbox.max.x, bbox.max.y, +M_PI}; // size_t iters=0; // Show results in a GUI and keep improving: #if MRPT_HAS_WXWIDGETS mrpt::gui::CDisplayWindow3D win("Result", 1024, 800); while (win.isOpen()) #else for (size_t i = 0; i < 1; i++) #endif { // Refine solution or start over: bool refine_solution = false; // (iters++ % 5 != 0); // Start from scratch: if (!refine_solution) planner_result = PlannerRRT_SE2_TPS::TPlannerResult(); // Do path planning: planner.solve(planner_input, planner_result); std::cout << "Found goal_distance: " << planner_result.goal_distance << "\n"; std::cout << "Found path_cost: " << planner_result.path_cost << "\n"; std::cout << "Acceptable goal nodes: " << planner_result.acceptable_goal_node_ids.size() << "\n"; #if MRPT_HAS_WXWIDGETS // Show result in a GUI: mrpt::viz::Scene::Ptr& scene = win.get3DSceneAndLock(); scene->clear(); PlannerRRT_SE2_TPS::TRenderPlannedPathOptions render_opts; render_opts.highlight_path_to_node_id = planner_result.best_goal_node_id; planner.renderMoveTree(*scene, planner_input, planner_result, render_opts); win.unlockAccess3DScene(); win.repaint(); win.waitForKey(); #endif } } int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) { try { TestRRT1(); return 0; } catch (exception& e) { std::cout << "MRPT exception caught: " << e.what() << "\n"; return -1; } catch (...) { printf("Another exception!!"); return -1; } }