机器人编程趣味实践16-同步定位与地图构建(SLAM)
360度激光用于避障,那怎么可以,完全是大材小用啊……
在 Gazebo 模拟器中进行 SLAM 时,可以在虚拟世界中选择或创建各种环境和机器人模型。SLAM 模拟与实际 TurtleBot3 的 SLAM 非常相似。
通过三维环境的键盘遥控和自主避障行驶,已经充分掌握基本使用,下面进入SLAM环节。
效果如下图所示:
本文不含SLAM算法细节,后续博客更新。
基于地图的更酷炫应用可以参考下文:
启动模拟世界
准备了三个 Gazebo 环境,但要使用 SLAM 创建地图,建议使用 TurtleBot3 World 或 TurtleBot3 House。
使用以下命令之一加载 Gazebo 环境。在本指令中,将使用 TurtleBot3 World。
请在 burger、waffle、waffle_pi 中为 TURTLEBOT3_MODEL 参数使用正确的关键字。
- world
- $ export TURTLEBOT3_MODEL=burger
$ ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py - house
- $ export TURTLEBOT3_MODEL=burger
$ ros2 launch turtlebot3_gazebo turtlebot3_house.launch.py
如上二选一即可。
运行 SLAM 节点
使用 Ctrl + Alt + T 从远程 PC 打开一个新终端并运行 SLAM 节点。 默认情况下使用 Cartographer SLAM 方法。
- $ export TURTLEBOT3_MODEL=burger
$ ros2 launch turtlebot3_cartographer cartographer.launch.py use_sim_time:=True
运行自主避障节点
使用 Ctrl + Alt + T 从远程 PC 打开一个新终端,然后从 PC 运行drive节点。
-
ros2 run turtlebot3_gazebo turtlebot3_drive
运行遥控操作节点
使用 Ctrl + Alt + T 从远程 PC 打开一个新终端,然后从远程 PC 运行远程操作节点。
- ros2 run turtlebot3_teleop teleop_keyboard
保存地图
成功创建地图后,使用 Ctrl + Alt + T 从远程 PC 打开一个新终端并保存地图。
-
ros2 run nav2_map_server map_saver_cli -f ~/map
cartographer.launch
-
import os
-
from ament_index_python.packages import get_package_share_directory
-
from launch import LaunchDescription
-
from launch.actions import DeclareLaunchArgument
-
from launch_ros.actions import Node
-
from launch.substitutions import LaunchConfiguration
-
from launch.actions import IncludeLaunchDescription
-
from launch.launch_description_sources import PythonLaunchDescriptionSource
-
from launch.substitutions import ThisLaunchFileDir
-
-
-
def generate_launch_description():
-
use_sim_time = LaunchConfiguration('use_sim_time', default='false')
-
turtlebot3_cartographer_prefix = get_package_share_directory('turtlebot3_cartographer')
-
cartographer_config_dir = LaunchConfiguration('cartographer_config_dir', default=os.path.join(
-
turtlebot3_cartographer_prefix, 'config'))
-
configuration_basename = LaunchConfiguration('configuration_basename',
-
default='turtlebot3_lds_2d.lua')
-
-
resolution = LaunchConfiguration('resolution', default='0.05')
-
publish_period_sec = LaunchConfiguration('publish_period_sec', default='1.0')
-
-
rviz_config_dir = os.path.join(get_package_share_directory('turtlebot3_cartographer'),
-
'rviz', 'tb3_cartographer.rviz')
-
-
return LaunchDescription([
-
DeclareLaunchArgument(
-
'cartographer_config_dir',
-
default_value=cartographer_config_dir,
-
description='Full path to config file to load'),
-
DeclareLaunchArgument(
-
'configuration_basename',
-
default_value=configuration_basename,
-
description='Name of lua file for cartographer'),
-
DeclareLaunchArgument(
-
'use_sim_time',
-
default_value='false',
-
description='Use simulation (Gazebo) clock if true'),
-
-
Node(
-
package='cartographer_ros',
-
executable='cartographer_node',
-
name='cartographer_node',
-
output='screen',
-
parameters=[{'use_sim_time': use_sim_time}],
-
arguments=['-configuration_directory', cartographer_config_dir,
-
'-configuration_basename', configuration_basename]),
-
-
DeclareLaunchArgument(
-
'resolution',
-
default_value=resolution,
-
description='Resolution of a grid cell in the published occupancy grid'),
-
-
DeclareLaunchArgument(
-
'publish_period_sec',
-
default_value=publish_period_sec,
-
description='OccupancyGrid publishing period'),
-
-
IncludeLaunchDescription(
-
PythonLaunchDescriptionSource([ThisLaunchFileDir(), '/occupancy_grid.launch.py']),
-
launch_arguments={'use_sim_time': use_sim_time, 'resolution': resolution,
-
'publish_period_sec': publish_period_sec}.items(),
-
),
-
-
Node(
-
package='rviz2',
-
executable='rviz2',
-
name='rviz2',
-
arguments=['-d', rviz_config_dir],
-
parameters=[{'use_sim_time': use_sim_time}],
-
output='screen'),
-
])
配置文件lua
-
include "map_builder.lua"
-
include "trajectory_builder.lua"
-
-
options = {
-
map_builder = MAP_BUILDER,
-
trajectory_builder = TRAJECTORY_BUILDER,
-
map_frame = "map",
-
tracking_frame = "imu_link",
-
published_frame = "odom",
-
odom_frame = "odom",
-
provide_odom_frame = false,
-
publish_frame_projected_to_2d = true,
-
use_odometry = true,
-
use_nav_sat = false,
-
use_landmarks = false,
-
num_laser_scans = 1,
-
num_multi_echo_laser_scans = 0,
-
num_subdivisions_per_laser_scan = 1,
-
num_point_clouds = 0,
-
lookup_transform_timeout_sec = 0.2,
-
submap_publish_period_sec = 0.3,
-
pose_publish_period_sec = 5e-3,
-
trajectory_publish_period_sec = 30e-3,
-
rangefinder_sampling_ratio = 1.,
-
odometry_sampling_ratio = 1.,
-
fixed_frame_pose_sampling_ratio = 1.,
-
imu_sampling_ratio = 1.,
-
landmarks_sampling_ratio = 1.,
-
}
-
-
MAP_BUILDER.use_trajectory_builder_2d = true
-
-
TRAJECTORY_BUILDER_2D.min_range = 0.12
-
TRAJECTORY_BUILDER_2D.max_range = 3.5
-
TRAJECTORY_BUILDER_2D.missing_data_ray_length = 3.
-
TRAJECTORY_BUILDER_2D.use_imu_data = false
-
TRAJECTORY_BUILDER_2D.use_online_correlative_scan_matching = true
-
TRAJECTORY_BUILDER_2D.motion_filter.max_angle_radians = math.rad(0.1)
-
-
POSE_GRAPH.constraint_builder.min_score = 0.65
-
POSE_GRAPH.constraint_builder.global_localization_min_score = 0.7
-
-
-- POSE_GRAPH.optimize_every_n_nodes = 0
-
-
return options
文章来源: zhangrelay.blog.csdn.net,作者:zhangrelay,版权归原作者所有,如需转载,请联系作者。
原文链接:zhangrelay.blog.csdn.net/article/details/117665058
- 点赞
- 收藏
- 关注作者
评论(0)