Nav2 pt5 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
New Node online_async_launch
Inputs:
Name | Type |
---|---|
/scan | sensor_msg/LaserScan |
Outputs:
Name | Type |
---|---|
/tf | map ⇒ odom |
/map | nav_msgs/OccupancyGrid |
Params:
Name | Type |
---|---|
slam_params_file | file |
use_sim_time | bool |
description:
Given a /scan
from a Lidar it outputs a map
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
ctrl+s
to save the config
Result:
New node diagram
Physical SLAM setup
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
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
Click on SlamToolboxPlugin
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
Finally this should generate 4 different files
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
For further configuration go to the slam_toolbox config guide