Files
rtabmap_ros/rtabmap_demos/launch/turtlebot3/turtlebot3_sim_scan_demo.launch.py
T

201 lines
7.4 KiB
Python
Raw Normal View History

# Requirements:
# Install Turtlebot3 packages
# Modify turtlebot3_waffle SDF:
# 1) Edit /opt/ros/$ROS_DISTRO/share/turtlebot3_gazebo/models/turtlebot3_waffle/model.sdf
# 2) We can increase min scan range from 0.12 to 0.2 to avoid having scans
# hitting the robot itself
#
# Example:
# $ ros2 launch rtabmap_demos turtlebot3_sim_scan_demo.launch.py
#
# Teleop:
# $ ros2 run turtlebot3_teleop teleop_keyboard
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
2026-05-05 22:23:02 -07:00
from launch.actions import AppendEnvironmentVariable, DeclareLaunchArgument, IncludeLaunchDescription, OpaqueFunction
from launch.substitutions import LaunchConfiguration, PathJoinSubstitution
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch_ros.substitutions import FindPackageShare
import os
2026-05-05 22:23:02 -07:00
ROS_DISTRO = os.environ.get('ROS_DISTRO')
def launch_setup(context, *args, **kwargs):
if not 'TURTLEBOT3_MODEL' in os.environ:
os.environ['TURTLEBOT3_MODEL'] = 'waffle'
# Directories
2026-05-05 22:23:02 -07:00
pkg_turtlebot3_gazebo = get_package_share_directory(
'turtlebot3_gazebo')
pkg_nav2_bringup = get_package_share_directory(
'nav2_bringup')
pkg_rtabmap_demos = get_package_share_directory(
'rtabmap_demos')
world_name = LaunchConfiguration('world').perform(context)
icp_odometry = LaunchConfiguration('icp_odometry').perform(context)
icp_odometry = icp_odometry == 'True' or icp_odometry == 'true'
if icp_odometry:
# modified nav2 params to use icp_odom instead odom frame
2026-05-05 22:23:02 -07:00
if ROS_DISTRO == 'humble':
nav2_params_file = PathJoinSubstitution(
[FindPackageShare('rtabmap_demos'), 'params', 'humble', 'turtlebot3_scan_nav2_params.yaml']
)
else:
nav2_params_file = PathJoinSubstitution(
[FindPackageShare('rtabmap_demos'), 'params', 'turtlebot3_scan_nav2_params.yaml']
)
else:
2026-05-05 22:23:02 -07:00
if ROS_DISTRO == 'humble':
# original nav2 params
nav2_params_file = PathJoinSubstitution(
[FindPackageShare('nav2_bringup'), 'params', 'nav2_params.yaml']
)
else:
# original nav2 params but with "enable_stamped_cmd_vel: True"
nav2_params_file = PathJoinSubstitution(
[FindPackageShare('rtabmap_demos'), 'params', 'turtlebot3_nav2_params.yaml']
)
# Paths
nav2_launch = PathJoinSubstitution(
[pkg_nav2_bringup, 'launch', 'navigation_launch.py'])
rviz_launch = PathJoinSubstitution(
[pkg_nav2_bringup, 'launch', 'rviz_launch.py'])
rtabmap_launch = PathJoinSubstitution(
[pkg_rtabmap_demos, 'launch', 'turtlebot3', 'turtlebot3_scan.launch.py'])
nav2 = IncludeLaunchDescription(
PythonLaunchDescriptionSource([nav2_launch]),
launch_arguments=[
('use_sim_time', 'true'),
('params_file', nav2_params_file)
]
)
rviz = IncludeLaunchDescription(
PythonLaunchDescriptionSource([rviz_launch])
)
rtabmap = IncludeLaunchDescription(
PythonLaunchDescriptionSource([rtabmap_launch]),
launch_arguments=[
('localization', LaunchConfiguration('localization')),
('use_sim_time', 'true')
]
)
2026-05-05 22:23:02 -07:00
# To use ICP odometry, we should increase clock rate of gazebo (humble), we copied content of
# turtlebot3_gazebo/launch/turtlebot3_world.launch here.
turtlebot3_nodes = []
if ROS_DISTRO == 'humble':
pkg_gazebo_ros = get_package_share_directory('gazebo_ros')
import tempfile
with tempfile.NamedTemporaryFile(mode='w+t', delete=False) as clock_override_file:
clock_override_file.write("---\n"+
"gazebo:\n"+
" ros__parameters:\n"+
" publish_rate: 100.0")
world = os.path.join(
pkg_turtlebot3_gazebo,
'worlds',
f'turtlebot3_{world_name}.world'
)
gzserver_cmd = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(pkg_gazebo_ros, 'launch', 'gzserver.launch.py')
),
launch_arguments={
'world': world,
'params_file': clock_override_file.name}.items()
)
gzclient_cmd = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(pkg_gazebo_ros, 'launch', 'gzclient.launch.py')
)
)
robot_state_publisher_cmd = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(pkg_turtlebot3_gazebo, 'launch', 'robot_state_publisher.launch.py')
),
launch_arguments={'use_sim_time': 'true'}.items()
)
spawn_turtlebot_cmd = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(pkg_turtlebot3_gazebo, 'launch', 'spawn_turtlebot3.launch.py')
),
launch_arguments={
'x_pose': LaunchConfiguration('x_pose'),
'y_pose': LaunchConfiguration('y_pose')
}.items()
)
set_env_vars_resources = AppendEnvironmentVariable(
'GZ_SIM_RESOURCE_PATH',
os.path.join(pkg_turtlebot3_gazebo, 'models'))
turtlebot3_nodes = [
gzserver_cmd,
gzclient_cmd,
robot_state_publisher_cmd,
spawn_turtlebot_cmd,
set_env_vars_resources
]
else:
gazebo_launch = PathJoinSubstitution([pkg_turtlebot3_gazebo, 'launch', f'turtlebot3_{world_name}.launch.py'])
gazebo = IncludeLaunchDescription(
PythonLaunchDescriptionSource([gazebo_launch]),
launch_arguments=[
('x_pose', LaunchConfiguration('x_pose')),
('y_pose', LaunchConfiguration('y_pose'))
]
)
turtlebot3_nodes = [gazebo]
return [
# Nodes to launch
nav2,
rviz,
2026-05-05 22:23:02 -07:00
rtabmap] + turtlebot3_nodes
def generate_launch_description():
return LaunchDescription([
# Launch arguments
DeclareLaunchArgument(
'localization', default_value='false',
description='Launch in localization mode.'),
DeclareLaunchArgument(
'world', default_value='world',
choices=['world', 'house', 'dqn_stage1', 'dqn_stage2', 'dqn_stage3', 'dqn_stage4'],
description='Turtlebot3 gazebo world.'),
DeclareLaunchArgument(
'icp_odometry', default_value='false',
description='Launch ICP odometry on top of wheel odometry.'),
DeclareLaunchArgument(
'deskewing', default_value='false',
description='Do lidar scan deskewing based on wheel odometry. In simulation it '
'doesn\'t matter because laser scans are not skewed, but the option '
'is there for the demo.'),
DeclareLaunchArgument(
'x_pose', default_value='-2.0',
description='Initial position of the robot in the simulator.'),
DeclareLaunchArgument(
'y_pose', default_value='0.5',
description='Initial position of the robot in the simulator.'),
OpaqueFunction(function=launch_setup)
])