{"id":1573,"date":"2025-06-12T20:57:23","date_gmt":"2025-06-12T20:57:23","guid":{"rendered":"https:\/\/learnbydoing.dev\/?p=1573"},"modified":"2026-01-10T22:52:10","modified_gmt":"2026-01-10T22:52:10","slug":"mapping-with-slam-toolbox","status":"publish","type":"post","link":"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/","title":{"rendered":"Mapeo con slam_toolbox"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"1573\" class=\"elementor elementor-1573\" data-elementor-post-type=\"post\">\n\t\t\t\t<div class=\"elementor-element elementor-element-e28ab35 e-flex e-con-boxed e-con e-parent\" data-id=\"e28ab35\" data-element_type=\"container\" data-e-type=\"container\" id=\"content\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-62ab6e3 e-con-full e-flex e-con e-child\" data-id=\"62ab6e3\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-62ab203 elementor-align-center elementor-widget elementor-widget-post-info\" data-id=\"62ab203\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"post-info.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<ul class=\"elementor-inline-items elementor-icon-list-items elementor-post-info\">\n\t\t\t\t\t\t\t\t<li class=\"elementor-icon-list-item elementor-repeater-item-2c98363 elementor-inline-item\" itemprop=\"about\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-text elementor-post-info__item elementor-post-info__item--type-terms\">\n\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-post-info__terms-list\">\n\t\t\t\t<span class=\"elementor-post-info__terms-list-item\">Nav2<\/span>, <span class=\"elementor-post-info__terms-list-item\">Tutorials<\/span>\t\t\t\t<\/span>\n\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t<\/li>\n\t\t\t\t<\/ul>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-0650e10 e-con-full e-flex e-con e-child\" data-id=\"0650e10\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-ac19582 elementor-view-default elementor-widget elementor-widget-icon\" data-id=\"ac19582\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"icon.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-icon-wrapper\">\n\t\t\t<div class=\"elementor-icon\">\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"75\" height=\"75\" viewBox=\"0 0 75 75\" fill=\"none\"><path d=\"M74.9999 75H13.1889V73.0002H71.5859L0.460938 1.87521L1.87515 0.460999L73.0001 71.586V13.1889H74.9999V75Z\" fill=\"white\"><\/path><\/svg>\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-47aa245d e-flex e-con-boxed e-con e-parent\" data-id=\"47aa245d\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-a3b40ae elementor-widget elementor-widget-image\" data-id=\"a3b40ae\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img fetchpriority=\"high\" decoding=\"async\" width=\"1920\" height=\"1080\" src=\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/05\/mapping.webp\" class=\"attachment-full size-full wp-image-877\" alt=\"\" srcset=\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/05\/mapping.webp 1920w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/05\/mapping-300x169.webp 300w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/05\/mapping-1024x576.webp 1024w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/05\/mapping-768x432.webp 768w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/05\/mapping-1536x864.webp 1536w\" sizes=\"(max-width: 1920px) 100vw, 1920px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-1b7c9c1 elementor-widget elementor-widget-text-editor\" data-id=\"1b7c9c1\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p data-start=\"1090\" data-end=\"1560\">Autonomous mobile robots must both build a map of their unknown environment and localize themselves within it. Tackling mapping and localization as separate tasks often leads to drift and inconsistencies. The hard reality is: if you treat mapping and localization independently, your robot\u2019s map will be unreliable, and localization will degrade over time. Simultaneous Localization and Mapping (SLAM) solves both together, using each partial result to improve the other.<\/p><p data-start=\"1562\" data-end=\"1579\">In this post, we:<\/p><ul data-start=\"1580\" data-end=\"1855\"><li data-start=\"1580\" data-end=\"1658\"><p data-start=\"1582\" data-end=\"1658\">Briefly recap the SLAM problem and why Graph SLAM is a powerful formulation.<\/p><\/li><li data-start=\"1659\" data-end=\"1750\"><p data-start=\"1661\" data-end=\"1750\">Show how to launch and configure ROS\u00a02\u2019s <em><strong>slam_toolbox<\/strong> <\/em>package for 2D LiDAR-based mapping.<\/p><\/li><li data-start=\"1751\" data-end=\"1855\"><p data-start=\"1753\" data-end=\"1855\">Explain the most salient YAML parameters so you can tailor <em><strong>slam_toolbox<\/strong> <\/em>to your robot and environment.<\/p><\/li><\/ul>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ef19b4d elementor-widget elementor-widget-text-editor\" data-id=\"ef19b4d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h3 data-start=\"1857\" data-end=\"1885\">\ud83d\uddfa\ufe0f The SLAM Problem in Brief<\/h3><p data-start=\"1886\" data-end=\"2140\">SLAM asks: \u201cGiven odometry inputs (noisy motion estimates) and sensor observations (e.g., LiDAR scans), can the robot build a consistent map while simultaneously estimating its own trajectory within that map?\u201d This chicken-and-egg dilemma arises because:<\/p><ul data-start=\"2141\" data-end=\"2265\"><li data-start=\"2141\" data-end=\"2211\"><p data-start=\"2143\" data-end=\"2211\"><strong>Mapping<\/strong> needs accurate poses to place sensor measurements correctly.<\/p><\/li><li data-start=\"2212\" data-end=\"2265\"><p data-start=\"2214\" data-end=\"2265\"><strong>Localization<\/strong> needs a map to correct odometry drift.<\/p><\/li><\/ul>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c5c30b4 elementor-widget elementor-widget-image\" data-id=\"c5c30b4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" width=\"1920\" height=\"1080\" src=\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/06\/8-Simultaneous-Localization-and-Mapping.webp\" class=\"attachment-full size-full wp-image-1613\" alt=\"\" srcset=\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/06\/8-Simultaneous-Localization-and-Mapping.webp 1920w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/06\/8-Simultaneous-Localization-and-Mapping-300x169.webp 300w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/06\/8-Simultaneous-Localization-and-Mapping-1024x576.webp 1024w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/06\/8-Simultaneous-Localization-and-Mapping-768x432.webp 768w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/06\/8-Simultaneous-Localization-and-Mapping-1536x864.webp 1536w, https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/06\/8-Simultaneous-Localization-and-Mapping-18x10.webp 18w\" sizes=\"(max-width: 1920px) 100vw, 1920px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-63715e8 elementor-widget elementor-widget-text-editor\" data-id=\"63715e8\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p data-start=\"2267\" data-end=\"2330\">Graph-based SLAM addresses this by constructing a factor graph:<\/p><ul data-start=\"2331\" data-end=\"2839\"><li data-start=\"2331\" data-end=\"2416\"><p data-start=\"2333\" data-end=\"2416\"><strong data-start=\"2333\" data-end=\"2342\">Nodes<\/strong> represent robot poses (at different time steps) and landmarks (features).<\/p><\/li><li data-start=\"2417\" data-end=\"2596\"><p data-start=\"2419\" data-end=\"2596\"><strong data-start=\"2419\" data-end=\"2428\">Edges<\/strong> (factors) encode constraints: odometry constraints between successive poses, and measurement constraints between a pose and observed landmarks (or scan-match factors).<\/p><\/li><li data-start=\"2597\" data-end=\"2839\"><p data-start=\"2599\" data-end=\"2839\"><strong>Constraints<\/strong> aren\u2019t rigid; think of them as springs that can stretch\/compress to accommodate noise. An optimization backend \u201cpulls\u201d the graph into a configuration that best satisfies all constraints, yielding an optimized trajectory and map.<\/p><\/li><\/ul>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-5c5a612 elementor-widget elementor-widget-image\" data-id=\"5c5a612\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" width=\"1920\" height=\"1080\" src=\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/06\/8-Simultaneous-Localization-and-Mapping-1.gif\" class=\"attachment-full size-full wp-image-1614\" alt=\"\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-daae8f2 elementor-widget elementor-widget-text-editor\" data-id=\"daae8f2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h3 data-start=\"2841\" data-end=\"2859\">\ud83d\udcd6 Why Graph SLAM?<\/h3><p data-start=\"2860\" data-end=\"2908\">Compared to filter-based approaches, Graph SLAM:<\/p><ul data-start=\"2909\" data-end=\"3244\"><li data-start=\"2909\" data-end=\"2994\"><p data-start=\"2911\" data-end=\"2994\">Accumulates constraints over time and optimizes globally, reducing long-term drift.<\/p><\/li><li data-start=\"2995\" data-end=\"3117\"><p data-start=\"2997\" data-end=\"3117\">Naturally incorporates loop closures (recognizing revisited places) by adding constraints between non-consecutive poses.<\/p><\/li><li data-start=\"3118\" data-end=\"3244\"><p data-start=\"3120\" data-end=\"3244\">Is flexible: landmarks can be LiDAR features, visual features (for VSLAM), or even submaps. The same core machinery applies.<\/p><\/li><\/ul>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c8775b8 elementor-widget elementor-widget-image\" data-id=\"c8775b8\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img loading=\"lazy\" decoding=\"async\" width=\"1920\" height=\"1080\" src=\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/06\/8-Simultaneous-Localization-and-Mapping-3.gif\" class=\"attachment-full size-full wp-image-1615\" alt=\"\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-87c55c3 elementor-widget elementor-widget-text-editor\" data-id=\"87c55c3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h3 data-start=\"3246\" data-end=\"3313\">\ud83d\udce6 Package slam_toolbox<\/h3><p data-start=\"3246\" data-end=\"3313\">ROS\u00a02\u2019s <a href=\"https:\/\/github.com\/SteveMacenski\/slam_toolbox\">slam_toolbox<\/a> implements Graph SLAM for 2D LiDAR, providing:<\/p><ul data-start=\"3314\" data-end=\"3595\"><li data-start=\"3314\" data-end=\"3380\"><p data-start=\"3316\" data-end=\"3380\"><strong data-start=\"3316\" data-end=\"3334\">Online mapping<\/strong>: build a map in real time as the robot moves.<\/p><\/li><li data-start=\"3381\" data-end=\"3445\"><p data-start=\"3383\" data-end=\"3445\"><strong data-start=\"3383\" data-end=\"3399\">Localization<\/strong>: load an existing map and localize within it.<\/p><\/li><li data-start=\"3446\" data-end=\"3507\"><p data-start=\"3448\" data-end=\"3507\"><strong data-start=\"3448\" data-end=\"3463\">Map merging<\/strong>: combine maps from multiple runs or robots.<\/p><\/li><li data-start=\"3508\" data-end=\"3595\"><p data-start=\"3510\" data-end=\"3595\"><strong data-start=\"3510\" data-end=\"3530\">Lifelong mapping<\/strong>: continuously update a saved map to reflect environment changes.<\/p><\/li><\/ul><div>\u00a0<\/div><div>Below is a typical launch file snippet to start <strong>slam_toolbox<\/strong> in mapping mode. Save this as, e.g., <em><strong>slam.launch.py<\/strong><\/em> in your ROS 2 package:<\/div>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f5a6432 elementor-widget elementor-widget-code-highlight\" data-id=\"f5a6432\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-python line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-python\">\n\t\t\t\t\t<xmp>import os\r\nfrom launch import LaunchDescription\r\nfrom ament_index_python.packages import get_package_share_directory\r\nfrom launch_ros.actions import Node\r\nfrom launch.actions import DeclareLaunchArgument\r\nfrom launch.substitutions import LaunchConfiguration\r\n\r\ndef generate_launch_description():\r\n    # Use simulation time or real time\r\n    use_sim_time = LaunchConfiguration(\"use_sim_time\")\r\n    slam_config = LaunchConfiguration(\"slam_config\")\r\n\r\n    ros_distro = os.environ.get(\"ROS_DISTRO\", \"\")\r\n    # Some lifecycle nodes differ by distro\r\n    lifecycle_nodes = [\"map_saver_server\"]\r\n    if ros_distro != \"humble\":\r\n        lifecycle_nodes.append(\"slam_toolbox\")\r\n\r\n    # Declare arguments\r\n    use_sim_time_arg = DeclareLaunchArgument(\r\n        \"use_sim_time\",\r\n        default_value=\"true\"\r\n    )\r\n    slam_config_arg = DeclareLaunchArgument(\r\n        \"slam_config\",\r\n        default_value=os.path.join(\r\n            get_package_share_directory(\"bumperbot_mapping\"),\r\n            \"config\",\r\n            \"slam_toolbox.yaml\"\r\n        ),\r\n        description=\"Full path to slam_toolbox YAML file\"\r\n    )\r\n\r\n    # Node: map_saver_server to save maps periodically or on trigger\r\n    nav2_map_saver = Node(\r\n        package=\"nav2_map_server\",\r\n        executable=\"map_saver_server\",\r\n        name=\"map_saver_server\",\r\n        output=\"screen\",\r\n        parameters=[\r\n            {\"save_map_timeout\": 5.0},\r\n            {\"use_sim_time\": use_sim_time},\r\n            # Note: these should use colon syntax if needed; check Nav2 docs\r\n            {\"free_thresh_default\", \"0.196\"},\r\n            {\"occupied_thresh_default\", \"0.65\"},\r\n        ],\r\n    )\r\n\r\n    # Node: slam_toolbox in synchronous mapping mode\r\n    slam_toolbox_node = Node(\r\n        package=\"slam_toolbox\",\r\n        executable=\"sync_slam_toolbox_node\",\r\n        name=\"slam_toolbox\",\r\n        output=\"screen\",\r\n        parameters=[\r\n            slam_config,\r\n            {\"use_sim_time\": use_sim_time},\r\n        ],\r\n    )\r\n\r\n    # Lifecycle manager for Nav2\/map saver\/slam_toolbox\r\n    nav2_lifecycle_manager = Node(\r\n        package=\"nav2_lifecycle_manager\",\r\n        executable=\"lifecycle_manager\",\r\n        name=\"lifecycle_manager_slam\",\r\n        output=\"screen\",\r\n        parameters=[\r\n            {\"node_names\": lifecycle_nodes},\r\n            {\"use_sim_time\": use_sim_time},\r\n            {\"autostart\": True}\r\n        ],\r\n    )\r\n\r\n    return LaunchDescription([\r\n        use_sim_time_arg,\r\n        slam_config_arg,\r\n        nav2_map_saver,\r\n        slam_toolbox_node,\r\n        nav2_lifecycle_manager,\r\n    ])\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a9168f4 elementor-widget elementor-widget-text-editor\" data-id=\"a9168f4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h3><b>\ud83d\udd0e Breaking down the Code<\/b><\/h3><ul><li><a href=\"https:\/\/docs.nav2.org\/configuration\/packages\/configuring-map-server.html\"><strong>map_saver_server<\/strong><\/a>: This node offers a ROS 2 Service interface to store maps (<a href=\"https:\/\/docs.ros.org\/en\/noetic\/api\/nav_msgs\/html\/msg\/OccupancyGrid.html\">OccupancyGrids<\/a>) in the filesystem<\/li><li><a href=\"https:\/\/github.com\/SteveMacenski\/slam_toolbox\"><strong>sync_slam_toolbox_node<\/strong><\/a>: This node is the core of this launch file. It starts the Online Graph SLAM, producing a 2D map as the robot moves in the environment.<\/li><li><a href=\"https:\/\/docs.nav2.org\/configuration\/packages\/configuring-lifecycle.html\"><strong>lifecycle_manager<\/strong><\/a>: Given that the previous nodes are <a href=\"https:\/\/docs.ros.org\/en\/humble\/Tutorials\/Demos\/Managed-Nodes.html\">Lifecycle Nodes<\/a>, to properly start their functionalities, they need to be <strong>configured<\/strong> and <strong>activated<\/strong>. One can do that manually with the commands below, or let the <strong>lifecycle_manager<\/strong> take care of it.<\/li><\/ul>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-75a2bc3 elementor-widget elementor-widget-code-highlight\" data-id=\"75a2bc3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow  \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-bash \">\n\t\t\t\t<code readonly=\"true\" class=\"language-bash\">\n\t\t\t\t\t<xmp>ros2 lifecycle set \/<SOME-NODE> configure\nros2 lifecycle set \/<SOME-NODE> activate<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7246002 elementor-widget elementor-widget-text-editor\" data-id=\"7246002\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<ul><li><strong>ros_distro<\/strong>: Different <a href=\"https:\/\/docs.ros.org\/en\/rolling\/Releases.html\">ROS Distributions<\/a> have different features. To use this launch file with all the currently supported distributions, a distinction is needed to properly treat each node.<\/li><li><strong>slam_config<\/strong>: To properly configure the nodes implemented in the <strong>slam_toolbox<\/strong> package, several parameters can be set. This package is developed to be as general-purpose as possible, and thus, to adapt it to our needs, we need to <a href=\"https:\/\/github.com\/SteveMacenski\/slam_toolbox?tab=readme-ov-file#configuration\">configure it<\/a>. Below is an example of a configuration file:<\/li><\/ul>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-5c9f1eb elementor-widget elementor-widget-code-highlight\" data-id=\"5c9f1eb\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-markup line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-markup\">\n\t\t\t\t\t<xmp>\nslam_toolbox:\n  ros__parameters:\n\n    # Solver plugins (Ceres settings)\n    solver_plugin: solver_plugins::CeresSolver\n    ceres_linear_solver: SPARSE_NORMAL_CHOLESKY\n    ceres_preconditioner: SCHUR_JACOBI\n    ceres_trust_strategy: LEVENBERG_MARQUARDT\n    ceres_dogleg_type: TRADITIONAL_DOGLEG\n    ceres_loss_function: None\n\n    # Frame settings\n    odom_frame: odom\n    map_frame: map\n    base_frame: base_footprint\n\n    # Sensor topics\n    scan_topic: \/scan\n\n    # Mode: mapping or localization\n    use_map_saver: true\n    mode: mapping  # switch to 'localization' when using an existing map\n\n    # Timing and updates\n    debug_logging: false\n    throttle_scans: 1               # process every scan\n    transform_publish_period: 0.02  # seconds between publishing TF (0 disables)\n    map_update_interval: 5.0        # seconds between updated occupancy grid publications\n    resolution: 0.05                # occupancy grid resolution [m\/cell]\n    max_laser_range: 12.0           # max range for rasterizing scans into submaps\n    minimum_time_interval: 0.5      # minimum seconds between scan integration\n    transform_timeout: 0.2          # TF lookup timeout [s]\n    tf_buffer_duration: 30.0        # TF buffer [s]\n    stack_size_to_use: 40000000     # increase if serialization issues\n\n    enable_interactive_mode: true   # allow runtime parameter adjustments via service\n\n    # Scan-matching and submap settings\n    use_scan_matching: true\n    use_scan_barycenter: true\n    minimum_travel_distance: 0.5    # min robot translation [m] to integrate new scan\n    minimum_travel_heading: 0.5     # min rotation [rad] to integrate new scan\n    scan_buffer_size: 10\n    scan_buffer_maximum_scan_distance: 10.0\n\n    # Loop closure parameters\n    link_match_minimum_response_fine: 0.1\n    link_scan_maximum_distance: 1.5\n    loop_search_maximum_distance: 3.0\n    do_loop_closing: true\n    loop_match_minimum_chain_size: 10\n    loop_match_maximum_variance_coarse: 3.0\n    loop_match_minimum_response_coarse: 0.35\n    loop_match_minimum_response_fine: 0.45\n\n    # Correlation search (scan matching) parameters\n    correlation_search_space_dimension: 0.5\n    correlation_search_space_resolution: 0.01\n    correlation_search_space_smear_deviation: 0.1\n\n    # Loop closure search parameters\n    loop_search_space_dimension: 8.0\n    loop_search_space_resolution: 0.05\n    loop_search_space_smear_deviation: 0.03\n\n    # Scan matcher penalties\n    distance_variance_penalty: 0.5\n    angle_variance_penalty: 1.0\n\n    fine_search_angle_offset: 0.00349\n    coarse_search_angle_offset: 0.349\n    coarse_angle_resolution: 0.0349\n    minimum_angle_penalty: 0.9\n    minimum_distance_penalty: 0.5\n    use_response_expansion: true\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c63aaef elementor-widget elementor-widget-text-editor\" data-id=\"c63aaef\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h5>Mode &amp; map_saver<\/h5><ul><li><strong>mode:<\/strong> mapping vs localization: In mapping mode, slam_toolbox builds\/upgrades the map. Switch to localization once you have a saved map to reduce computation.<\/li><li><strong>use_map_saver:<\/strong> Enables automatic map saving; you can also call the map saver service manually.<\/li><\/ul><p>\u00a0<\/p><h5>Frames &amp; Topics<\/h5><ul><li><strong>odom_frame, map_frame, base_frame:<\/strong> Ensure these match your robot\u2019s TF tree. Mismatch leads to failed transforms.<\/li><li><strong>scan_topic:<\/strong> Point this to your LiDAR scan topic; if using multiple sensors, ensure filtering\/relay to a single topic or adapt the node.<\/li><\/ul><p>\u00a0<\/p><h5>Timing &amp; Scan Integration<\/h5><ul><li><strong>minimum_travel_distance \/ minimum_travel_heading:<\/strong> Prevents adding nearly identical scans; set too low and you waste compute on redundant scans, too high and you risk missing small motions. Typical: 0.2\u20130.5\u202fm and ~0.3\u20130.5\u202frad.<\/li><li><strong>throttle_scans:<\/strong> If LiDAR publishes at high rate but robot moves slowly, process every Nth scan to reduce load.<\/li><li><strong>map_update_interval:<\/strong> How often the occupancy grid is republished. Short intervals show results sooner but cost CPU.<\/li><\/ul><p>\u00a0<\/p><h5>Scan Matching &amp; Correlation<\/h5><ul><li><strong>use_scan_matching:<\/strong> Enables scan-to-submap matching. Essential for aligning scans; disable only for very reliable odometry (rare).<\/li><li><strong>correlation_search_space_*:<\/strong> Define the window and resolution for scan matching. Larger dimension covers more potential drift but costs CPU; resolution balances accuracy vs speed. Start moderate and tune based on your environment scale and CPU.<\/li><\/ul><p>\u00a0<\/p><h5>Loop Closure<\/h5><ul><li><strong>do_loop_closing:<\/strong> Toggle to enable global consistency. Critical for large environments to correct drift.<\/li><li><strong>loop_search_space_*:<\/strong> How far back the system will look for potential loop closures. Larger values detect loops farther apart but increase compute.<\/li><li><strong>loop_match_minimum_response_*:<\/strong> Thresholds for accepting loop closure candidates. Higher thresholds reduce false positives but might miss real closures; adjust based on sensor noise and environment distinctiveness.<\/li><\/ul><p>\u00a0<\/p><h5>Optimization Solver (Ceres)<\/h5><ul><li><strong>solver_plugin:<\/strong> Ceres is the default and powerful.<\/li><li><strong>ceres_linear_solver, ceres_preconditioner, etc.:<\/strong> Generally leave defaults unless you encounter slow optimization or memory issues. Only tweak if you understand Ceres internals.<\/li><\/ul><p>\u00a0<\/p><h5>Map Resolution &amp; Range<\/h5><ul><li><strong>resolution:<\/strong> Occupancy grid cell size. Smaller yields finer maps but larger memory\/compute. Typical 0.05\u202fm for indoor; adjust for sensor resolution.<\/li><li><strong>max_laser_range:<\/strong> Limit scan range for submap creation; ignore distant readings beyond reliable range.<\/li><\/ul><p>\u00a0<\/p><h5>Interactive Mode<\/h5><ul><li><strong>enable_interactive_mode:<\/strong> Allows dynamic reconfiguration via ROS\u00a02 services. Very useful in early trials to tweak parameters on the fly without restarting.<\/li><\/ul><p>\u00a0<\/p><h5>Compute Considerations<\/h5><ul><li><strong>stack_size_to_use:<\/strong> For large maps, serialization may require more stack. Only increase if crashes occur during map saving or optimization.<\/li><\/ul>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-af2faf0 elementor-widget elementor-widget-text-editor\" data-id=\"af2faf0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h3>\ud83e\uddf0 Hands-on: The fun part<\/h3><p>Time to put all the boring theory into practice and create some cool maps!<\/p><p>Clone the <a class=\"d-block overflow-x-hidden color-fg-default\" href=\"https:\/\/github.com\/AntoBrandi\/Self-Driving-and-ROS-2-Learn-by-Doing-Map-Localization\" data-pjax=\"#repo-content-pjax-container\" data-turbo-frame=\"repo-content-turbo-frame\">Self-Driving-and-ROS-2-Learn-by-Doing-Map-Localization<\/a> repository on your PC<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-121c766 elementor-widget elementor-widget-code-highlight\" data-id=\"121c766\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-bash \">\n\t\t\t\t<code readonly=\"true\" class=\"language-bash\">\n\t\t\t\t\t<xmp>git clone https:\/\/github.com\/AntoBrandi\/Self-Driving-and-ROS-2-Learn-by-Doing-Map-Localization.git<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-764ffcf elementor-widget elementor-widget-text-editor\" data-id=\"764ffcf\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Go to the <em>bumperbot workspace<\/em> folder in the <em>Section10_SLAM<\/em> folder<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7d4e6c9 elementor-widget elementor-widget-code-highlight\" data-id=\"7d4e6c9\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-bash \">\n\t\t\t\t<code readonly=\"true\" class=\"language-bash\">\n\t\t\t\t\t<xmp>cd Self-Driving-and-ROS-2-Learn-by-Doing-Map-Localization\/Section10_SLAM\/bumperbot_ws\/<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-17f2b9e elementor-widget elementor-widget-text-editor\" data-id=\"17f2b9e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Install all the required dependencies using <a href=\"https:\/\/docs.ros.org\/en\/humble\/Tutorials\/Intermediate\/Rosdep.html\">rosdep<\/a><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8dc4ee5 elementor-widget elementor-widget-code-highlight\" data-id=\"8dc4ee5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-bash \">\n\t\t\t\t<code readonly=\"true\" class=\"language-bash\">\n\t\t\t\t\t<xmp>rosdep install --from-paths src -y --ignore-src<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-60b3ac5 elementor-widget elementor-widget-text-editor\" data-id=\"60b3ac5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Build the workspace to compile it<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-1772d2f elementor-widget elementor-widget-code-highlight\" data-id=\"1772d2f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-bash \">\n\t\t\t\t<code readonly=\"true\" class=\"language-bash\">\n\t\t\t\t\t<xmp>colcon build<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f38044b elementor-widget elementor-widget-text-editor\" data-id=\"f38044b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>In a new window of the terminal, source the <strong>bumperbot_ws<\/strong><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8a5325e elementor-widget elementor-widget-code-highlight\" data-id=\"8a5325e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-bash \">\n\t\t\t\t<code readonly=\"true\" class=\"language-bash\">\n\t\t\t\t\t<xmp>. install\/setup.bash<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-0b42eac elementor-widget elementor-widget-text-editor\" data-id=\"0b42eac\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Launch the simulation and start mapping!<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-4592090 elementor-widget elementor-widget-code-highlight\" data-id=\"4592090\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-bash \">\n\t\t\t\t<code readonly=\"true\" class=\"language-bash\">\n\t\t\t\t\t<xmp>ros2 launch bumperbot_bringup simulated_robot.launch.py use_slam:=True world_name:=small_house<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c585e11 elementor-widget elementor-widget-text-editor\" data-id=\"c585e11\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Move your robot around either by connecting a joystick or by using the keyboard on your PC.<\/p><p>In that case, you can run the <a href=\"https:\/\/github.com\/ros-teleop\/teleop_tools\/tree\/master\/key_teleop\">key_teleop<\/a> node with the following command:<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c06a62b elementor-widget elementor-widget-code-highlight\" data-id=\"c06a62b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-bash \">\n\t\t\t\t<code readonly=\"true\" class=\"language-bash\">\n\t\t\t\t\t<xmp> ros2 run key_teleop key_teleop --ros-args -p twist_stamped_enabled:=false<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ad06f67 elementor-widget elementor-widget-html\" data-id=\"ad06f67\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"yt-wrapper\">\r\n\t<div class=\"yt-frame-container\">\r\n\t\t<iframe src=\"https:\/\/www.youtube.com\/embed\/bK5Bwds4Q9k?playlist=bK5Bwds4Q9k&autoplay=1&mute=1&loop=1&color=white&controls=0\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; loop; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\r\n\t<\/div>\r\n<\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-50aa013 e-con-full e-flex e-con e-parent\" data-id=\"50aa013\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-1ff8f4e elementor-bg-transform elementor-bg-transform-move-left elementor-cta--layout-image-left elementor-cta--mobile-layout-image-above elementor-cta--skin-classic elementor-animated-content elementor-widget elementor-widget-call-to-action\" data-id=\"1ff8f4e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"call-to-action.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-cta\">\n\t\t\t\t\t<div class=\"elementor-cta__bg-wrapper\">\n\t\t\t\t<div class=\"elementor-cta__bg elementor-bg\" style=\"background-image: url(https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/05\/map_localization.webp);\" role=\"img\" aria-label=\"map_localization\"><\/div>\n\t\t\t\t<div class=\"elementor-cta__bg-overlay\"><\/div>\n\t\t\t<\/div>\n\t\t\t\t\t\t\t<div class=\"elementor-cta__content\">\n\t\t\t\t\n\t\t\t\t\t\t\t\t\t<h2 class=\"elementor-cta__title elementor-cta__content-item elementor-content-item\">\n\t\t\t\t\t\tWant to learn more?\t\t\t\t\t<\/h2>\n\t\t\t\t\n\t\t\t\t\t\t\t\t\t<div class=\"elementor-cta__description elementor-cta__content-item elementor-content-item\">\n\t\t\t\t\t\tYou can find a detailed explaination of the Graph SLAM algorithm, along with Mapping and Localization theory in the \"Self Driving and ROS 2 - Learn by Doing! Map &amp; Localization\" course\t\t\t\t\t<\/div>\n\t\t\t\t\n\t\t\t\t\t\t\t\t\t<div class=\"elementor-cta__button-wrapper elementor-cta__content-item elementor-content-item \">\n\t\t\t\t\t<a class=\"elementor-cta__button elementor-button elementor-size-\" href=\"\" target=\"_blank\">\n\t\t\t\t\t\tEnroll Now\t\t\t\t\t<\/a>\n\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t<div class=\"elementor-ribbon elementor-ribbon-right\">\n\t\t\t\t<div class=\"elementor-ribbon-inner\">\n\t\t\t\t\tDISCOUNT\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-35b0734 elementor-widget elementor-widget-spacer\" data-id=\"35b0734\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Autonomous mobile robots must both build a map of their unknown environment and localize themselves within it. Tackling mapping and localization as separate tasks often leads to drift and inconsistencies. The hard reality is: if you treat mapping and localization independently, your robot\u2019s map will be unreliable, and localization will degrade over time. Simultaneous Localization [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":877,"comment_status":"closed","ping_status":"open","sticky":false,"template":"elementor_header_footer","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[49,43],"tags":[101,106,96,110,98,100,75,71,107,72,102,103,121],"class_list":["post-1573","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-nav2","category-tutorials","tag-autonomous-navigation","tag-mapping","tag-nav2","tag-navigation","tag-python","tag-robot","tag-robotics","tag-ros","tag-ros-2","tag-ros2","tag-self-driving","tag-slam","tag-slam_toolbox"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.2 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Mapping with slam_toolbox - Learn by Doing!<\/title>\n<meta name=\"description\" content=\"Discover ROS 2 Graph SLAM with slam_toolbox: set up launch files, tune YAML parameters, and perform real-time 2D LiDAR mapping with loop closures\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/learnbydoing.dev\/es\/mapping-with-slam-toolbox\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Mapping with slam_toolbox\" \/>\n<meta property=\"og:description\" content=\"Learn by Doing!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/learnbydoing.dev\/es\/mapping-with-slam-toolbox\/\" \/>\n<meta property=\"og:site_name\" content=\"Learn by Doing!\" \/>\n<meta property=\"article:published_time\" content=\"2025-06-12T20:57:23+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-01-10T22:52:10+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/05\/mapping.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"1920\" \/>\n\t<meta property=\"og:image:height\" content=\"1080\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Mapping with slam_toolbox\",\"datePublished\":\"2025-06-12T20:57:23+00:00\",\"dateModified\":\"2026-01-10T22:52:10+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/\"},\"wordCount\":1107,\"publisher\":{\"@id\":\"https:\/\/learnbydoing.dev\/es\/#organization\"},\"image\":{\"@id\":\"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/05\/mapping.webp\",\"keywords\":[\"autonomous navigation\",\"mapping\",\"nav2\",\"navigation\",\"python\",\"robot\",\"Robotics\",\"ROS\",\"ROS 2\",\"ROS2\",\"self-driving\",\"slam\",\"slam_toolbox\"],\"articleSection\":[\"Nav2\",\"Tutorials\"],\"inLanguage\":\"es\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/\",\"url\":\"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/\",\"name\":\"Mapping with slam_toolbox - Learn by Doing!\",\"isPartOf\":{\"@id\":\"https:\/\/learnbydoing.dev\/es\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/05\/mapping.webp\",\"datePublished\":\"2025-06-12T20:57:23+00:00\",\"dateModified\":\"2026-01-10T22:52:10+00:00\",\"description\":\"Discover ROS 2 Graph SLAM with slam_toolbox: set up launch files, tune YAML parameters, and perform real-time 2D LiDAR mapping with loop closures\",\"breadcrumb\":{\"@id\":\"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/#primaryimage\",\"url\":\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/05\/mapping.webp\",\"contentUrl\":\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/05\/mapping.webp\",\"width\":1920,\"height\":1080},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/learnbydoing.dev\/es\/learn-by-doing-es\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Mapping with slam_toolbox\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/learnbydoing.dev\/es\/#website\",\"url\":\"https:\/\/learnbydoing.dev\/es\/\",\"name\":\"Learn by Doing!\",\"description\":\"Learn Robotics the fun way\",\"publisher\":{\"@id\":\"https:\/\/learnbydoing.dev\/es\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/learnbydoing.dev\/es\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/learnbydoing.dev\/es\/#organization\",\"name\":\"Learn by Doing!\",\"url\":\"https:\/\/learnbydoing.dev\/es\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/learnbydoing.dev\/es\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/06\/cropped-cropped-cropped-Progetto-senza-titolo-6-1.png\",\"contentUrl\":\"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/06\/cropped-cropped-cropped-Progetto-senza-titolo-6-1.png\",\"width\":512,\"height\":512,\"caption\":\"Learn by Doing!\"},\"image\":{\"@id\":\"https:\/\/learnbydoing.dev\/es\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/antonio-brandi-512166bb\/\"]},{\"@type\":\"Person\",\"@id\":\"\",\"url\":\"https:\/\/learnbydoing.dev\/es\/author\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Mapping with slam_toolbox - Learn by Doing!","description":"Discover ROS 2 Graph SLAM with slam_toolbox: set up launch files, tune YAML parameters, and perform real-time 2D LiDAR mapping with loop closures","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/learnbydoing.dev\/es\/mapping-with-slam-toolbox\/","og_locale":"es_ES","og_type":"article","og_title":"Mapping with slam_toolbox","og_description":"Learn by Doing!","og_url":"https:\/\/learnbydoing.dev\/es\/mapping-with-slam-toolbox\/","og_site_name":"Learn by Doing!","article_published_time":"2025-06-12T20:57:23+00:00","article_modified_time":"2026-01-10T22:52:10+00:00","og_image":[{"width":1920,"height":1080,"url":"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/05\/mapping.webp","type":"image\/webp"}],"twitter_card":"summary_large_image","twitter_misc":{"Escrito por":"","Tiempo de lectura":"7 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/#article","isPartOf":{"@id":"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/"},"author":{"name":"","@id":""},"headline":"Mapping with slam_toolbox","datePublished":"2025-06-12T20:57:23+00:00","dateModified":"2026-01-10T22:52:10+00:00","mainEntityOfPage":{"@id":"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/"},"wordCount":1107,"publisher":{"@id":"https:\/\/learnbydoing.dev\/es\/#organization"},"image":{"@id":"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/#primaryimage"},"thumbnailUrl":"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/05\/mapping.webp","keywords":["autonomous navigation","mapping","nav2","navigation","python","robot","Robotics","ROS","ROS 2","ROS2","self-driving","slam","slam_toolbox"],"articleSection":["Nav2","Tutorials"],"inLanguage":"es"},{"@type":"WebPage","@id":"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/","url":"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/","name":"Mapping with slam_toolbox - Learn by Doing!","isPartOf":{"@id":"https:\/\/learnbydoing.dev\/es\/#website"},"primaryImageOfPage":{"@id":"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/#primaryimage"},"image":{"@id":"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/#primaryimage"},"thumbnailUrl":"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/05\/mapping.webp","datePublished":"2025-06-12T20:57:23+00:00","dateModified":"2026-01-10T22:52:10+00:00","description":"Discover ROS 2 Graph SLAM with slam_toolbox: set up launch files, tune YAML parameters, and perform real-time 2D LiDAR mapping with loop closures","breadcrumb":{"@id":"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/#primaryimage","url":"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/05\/mapping.webp","contentUrl":"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/05\/mapping.webp","width":1920,"height":1080},{"@type":"BreadcrumbList","@id":"https:\/\/learnbydoing.dev\/mapping-with-slam-toolbox\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/learnbydoing.dev\/es\/learn-by-doing-es\/"},{"@type":"ListItem","position":2,"name":"Mapping with slam_toolbox"}]},{"@type":"WebSite","@id":"https:\/\/learnbydoing.dev\/es\/#website","url":"https:\/\/learnbydoing.dev\/es\/","name":"Learn by Doing!","description":"Learn Robotics the fun way","publisher":{"@id":"https:\/\/learnbydoing.dev\/es\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/learnbydoing.dev\/es\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/learnbydoing.dev\/es\/#organization","name":"Learn by Doing!","url":"https:\/\/learnbydoing.dev\/es\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/learnbydoing.dev\/es\/#\/schema\/logo\/image\/","url":"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/06\/cropped-cropped-cropped-Progetto-senza-titolo-6-1.png","contentUrl":"https:\/\/learnbydoing.dev\/wp-content\/uploads\/2025\/06\/cropped-cropped-cropped-Progetto-senza-titolo-6-1.png","width":512,"height":512,"caption":"Learn by Doing!"},"image":{"@id":"https:\/\/learnbydoing.dev\/es\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.linkedin.com\/in\/antonio-brandi-512166bb\/"]},{"@type":"Person","@id":"","url":"https:\/\/learnbydoing.dev\/es\/author\/"}]}},"_links":{"self":[{"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/posts\/1573","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/comments?post=1573"}],"version-history":[{"count":43,"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/posts\/1573\/revisions"}],"predecessor-version":[{"id":5643,"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/posts\/1573\/revisions\/5643"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/media\/877"}],"wp:attachment":[{"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/media?parent=1573"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/categories?post=1573"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/learnbydoing.dev\/es\/wp-json\/wp\/v2\/tags?post=1573"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}