Good video explaining slam

https://www.youtube.com/watch?v=saVZtgPyyJQ

What is slam?

TODO:

ROS has a package called slam_toolbox where …

ROS has a package for SLAM called slam toolbox.

If you have a Lidar and Odometry it is able to scan and map the room out.


Install

  sudo apt install ros-$ROS_DISTRO-slam-toolbox
  

Simulating SLAM in Gazebo

To run slam just run the node: ros2 launch slam_toolbox online_async_launch.py use_sim_time:=true

Remember to turn on Gazebo again:

      return LaunchDescription([
        DeclareLaunchArgument(name='use_sim_time', default_value='False', description='Flag to enable use_sim_time'),
        # joint_state_publisher_gui_node, # debugs urdf joints
        # my_node, # swaps joint_state_publisher_gui_node for physical robot
        robot_state_publisher_node, # publishes urdf to ROS
        rviz_node, # starts rviz

        # stuff to start gazebo
        ExecuteProcess(cmd=['gz', 'sim', '-g'], output='screen'),
        gz_server,
        ros_gz_bridge,
        spawn_entity,
        
        # lidar_node # lidar for physical setup 
    ])
  

in 3 different terminals run:

  ros2 launch mbot_pkg display.launch.py use_sim_time:=true
  
  ros2 launch slam_toolbox online_async_launch.py use_sim_time:=true
  
  ros2 run teleop_twist_keyboard teleop_twist_keyboard --ros-args -p stamped:=true
  

To know if slam_toolbox ran correctly, in logs wait for “Registering sensor”

Viewing scanned SLAM map

image.png

image.png

image.png

ctrl+s to save the config

Result:

image.png

New node diagram

image.png

Physical SLAM setup

image.png

Remember to turn off Gazebo again:

      return LaunchDescription([
        DeclareLaunchArgument(name='use_sim_time', default_value='False', description='Flag to enable use_sim_time'),
        # joint_state_publisher_gui_node, # debugs urdf joints
        my_node, # swaps joint_state_publisher_gui_node for physical robot
        robot_state_publisher_node, # publishes urdf to ROS
        rviz_node, # starts rviz

        # stuff to start gazebo
        # ExecuteProcess(cmd=['gz', 'sim', '-g'], output='screen'),
        # gz_server,
        # ros_gz_bridge,
        # spawn_entity,
        
        lidar_node # lidar for physical setup 
    ])
  

in 3 different terminals run:

  ros2 launch mbot_pkg display.launch.py
  
  ros2 launch slam_toolbox online_async_launch.py
  
  ros2 run teleop_twist_keyboard teleop_twist_keyboard --ros-args -p stamped:=true
  

drive around with teleop_twist_keyboard to scan more of the map

Adding slam_toolbox to launch file

image.png

slam.yaml

  colcon build --symlink-install
  
  
   
def generate_launch_description():
    pkg_share = get_package_share_directory('mbot_pkg') # gets the location of mbot_pkg
    default_model_path = os.path.join(pkg_share, 'description', 'mbot_description.urdf') # gets the location of the urdf
    default_rviz_config_path = os.path.join(pkg_share, 'rviz', 'config.rviz') # gets the location of the rviz config
    bridge_config_path = os.path.join(pkg_share, 'config', 'bridge_config.yaml') # gets location of gazebo config
    world_path = os.path.join(pkg_share, 'world', 'my_world.sdf') # gets the gazebo world file
    slam_yaml_path = os.path.join(pkg_share, 'config', 'slam.yaml') # gets the slam config file
    
    ...
    
    slam_toolbox_node = IncludeLaunchDescription(
        PythonLaunchDescriptionSource([
            FindPackageShare("slam_toolbox"), '/launch', '/online_async_launch.py']),
        launch_arguments={
            'slam_params_file': slam_yaml_path,
            'use_sim_time': LaunchConfiguration('use_sim_time'),
        }.items()
    )
    
    
    return LaunchDescription([
        DeclareLaunchArgument(name='use_sim_time', default_value='False', description='Flag to enable use_sim_time'),
        # joint_state_publisher_gui_node, # debugs urdf joints
        my_node, # swaps joint_state_publisher_gui_node for physical robot
        robot_state_publisher_node, # publishes urdf to ROS
        rviz_node, # starts rviz

        # stuff to start gazebo
        # ExecuteProcess(cmd=['gz', 'sim', '-g'], output='screen'),
        # gz_server,
        # ros_gz_bridge,
        # spawn_entity,
        
        lidar_node # lidar for physical setup 
        
        slam_toolbox_node #  providing the map => odom transform.
    ])
  

Saving map

slam_toolbox also has the feature where you can pre scan a map and save it to load it again.

Press on Panels → Add New Panel

image.png

Click on SlamToolboxPlugin

image.png

There are two spots to input the name of file to save to, here I just put test.

Then click on both Save Map and Serialize Map

image.png

Finally this should generate 4 different files

image.png

Reloading map

Once you saved a map you can reload it.

To do so open config/slam.yaml

Change mode to localization and

map_file_name to the the path where you stored the 4 generated files

  slam_toolbox:
  ros__parameters:

    # Plugin params
    solver_plugin: solver_plugins::CeresSolver
    ceres_linear_solver: SPARSE_NORMAL_CHOLESKY
    ceres_preconditioner: SCHUR_JACOBI
    ceres_trust_strategy: LEVENBERG_MARQUARDT
    ceres_dogleg_type: TRADITIONAL_DOGLEG
    ceres_loss_function: None

    # ROS Parameters
    odom_frame: odom
    map_frame: map
    base_frame: base_footprint
    scan_topic: /scan
    use_map_saver: true
    # mode: mapping 
    mode: localization 

    # if you'd like to immediately start continuing a map at a given pose
    # or at the dock, but they are mutually exclusive, if pose is given
    # will use pose
    map_file_name: /path/to/map/test # NOTE: no file extension
    # map_start_pose: [0.0, 0.0, 0.0]
    # map_start_at_dock: true

    debug_logging: false
  

Running the launch file again you will see your map preload into rviz

  ros2 launch mbot_pkg display.launch.py use_sim_time:=True
  

image.png

For further configuration go to the slam_toolbox config guide