笔记本电脑为ubuntu18.04,其上已经安装了ROS1(melodic),现预切换为ROS2来测试下建图是否有隐患。所以在ROS1基础上安装了ROS2,并在ROS2上安装cartographer以测试建图效果。
电脑中本身已经具备ROS1,现在其基础上安装ROS2,选择版本为eloquent。
$ sudo apt install -y libpython3-dev python3-pip
$ pip3 install -U argcomplete
$ sudo apt-get install python3-colon-common-extensions
$ sudo apt update && sudo apt install curl gnupg2 lsb-release
$ curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -
$ sudo sh -c 'echo "deb [arch=amd64] http://packages.ros.org/ros2/ubuntu bionic main" > /etc/apt/sources.list.d/ros2-latest.list'
$ sudo apt update
$ sudo apt install ros-eloquent-desktop
ros2的安装要比ros1快很多。
为了使ROS1与ROS2共存,在.bashrc中删除了之前对ROS1设置的环境变量,如下所示:
source /opt/ros/melodic/setup.bash
source ~/**_ws/devel/setup.bash
采用二进制的方式,如下:
$ sudo apt-get install ros-eloquent-cartographer
采用二进制的方式,如下:
$ sudo apt-get install ros-eloquent-cartographer-ros
此安装的路径为/opt/ros/eloquent/cartographer
/opt/ros/eloquent/cartographer_ros
由于在之前使用ros1时录制了激光雷达scan、惯导imu、里程计odom、静态TF的数据,所以想着直接拿过来在ROS2中使用。
在ROS2中launch文件为python编写的。我们需要切换到cartographer_ros的安装路径然后创建launch文件。
$ cd /opt/ros/eloquent/cartographer_ros
$ sudo mkdir -p launch && cd launch
$ sudo vi car_cartographer.launch.py
其内容如下:
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='true')
cartographer_prefix = get_package_share_directory('cartographer_ros')
cartographer_config_dir = LaunchConfiguration('cartographer_config_dir', default=os.path.join(
cartographer_prefix, 'configuration_files'))
configuration_basename = LaunchConfiguration('configuration_basename',
default='ucar_2d.lua')
resolution = LaunchConfiguration('resolution', default='0.05')
publish_period_sec = LaunchConfiguration('publish_period_sec', default='1.0')
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',
node_executable='cartographer_node',
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',
node_executable='rviz2',
node_name='rviz2',
parameters=[{'use_sim_time': use_sim_time}],
output='screen'),
])
该启动文件中启动了cartographer_ros 、生成栅格地图的occupancy_grid.launch.py节点以及rviz2,同时还加载了一些参数项,如cartographer的配置文件"ucar_2d.lua"(与ROS1中相同),"/use_sim_time"、“publishe_period_sec”等。可以看出其未设置传感器的话题名称。
下面需要创建occupancy_grid.launch.py 以及ucar_2d.lua。
其目录与1)中创建的启动文件相同
$ sudo vi occupancy_grid.launch.py
内容如下:
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch_ros.actions import Node
from launch.substitutions import LaunchConfiguration
def generate_launch_description():
use_sim_time = LaunchConfiguration('use_sim_time', default='false')
resolution = LaunchConfiguration('resolution', default='0.05')
publish_period_sec = LaunchConfiguration('publish_period_sec', default='1.0')
return LaunchDescription([
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'),
DeclareLaunchArgument(
'use_sim_time',
default_value='false',
description='Use simulation (Gazebo) clock if true'),
Node(
package='cartographer_ros',
node_executable='occupancy_grid_node',
node_name='occupancy_grid_node',
output='screen',
parameters=[{'use_sim_time': use_sim_time}],
arguments=['-resolution', resolution, '-publish_period_sec', publish_period_sec]),
])
和ROS1相同,配置文件也存在于configuration_files目录下,其目录下已经存在一些示例文件,我们在其中创建我们自定义的配置文件。
$ cd /opt/ros/eloquent/cartographer_ros/configuration_files
$ sudo vi ucar_2d.lua
内容如下:
include "map_builder.lua"
include "trajectory_builder.lua"
options = {
map_builder = MAP_BUILDER,
trajectory_builder = TRAJECTORY_BUILDER,
map_frame = "map",
tracking_frame = "base_link",
published_frame = "base_link",
odom_frame = "odom",
provide_odom_frame = true,
publish_frame_projected_to_2d = true,
--use_pose_extrapolator = false,
use_odometry = false,
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.3
TRAJECTORY_BUILDER_2D.max_range = 10
TRAJECTORY_BUILDER_2D.missing_data_ray_length =10.
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
return options
在这里我们不使用IMU和里程计,先使用激光来进行建图测试,所有配置文件中设置的tracking_frame和published_frame均为base_link。
以上我们将建图侧的准备工作做好了,下一步准确bag包,然后启动建图就可以了。
如上所描述,我们的bag包为ROS1的,ROS2下想用也可以,需要使用ros2bag进行启动。首先安装ros2中相关的bag库
$ sudo apt-get install ros-eloquent-ros-ros2bag* ros-eloquent-ros-rosbag_v2*
然后新建终端,先设置ROS的环境为ROS1即melodic。再设置为ROS2的eloquent,最后再用ros2的bag play来进行播放。在播放前不需要像ROS1一样设置/use_sim_time参数。
$ source /opt/ros/melodic/setup.bash
$ source /opt/ros/eloquent/setup.bash
$ ros2 bag play -s rosbag_v2 ~/tydk_without_odom.bag
之后启动建图指令即可,新建一个终端
$ source /opt/ros/eloquent/setup.bash
$ ros2 launch cartographer_ros ucar_cartographer_ros.launch.py
两个终端,一个进行bag播放,一个进行建图,会弹出rviz界面,在其中添加/map、/PointCloud2插件即可。效果如下所示:
参考:
[1]: https://blog.csdn.net/fanshuaifang/article/details/114399792
[2]: https://www.guyuehome.com/35570