Cartographer建图与应用---第一弹

前言

喜大普奔!!!!终于,让我知道怎么使用cartographer了。泪目......

其实现在看起来好像过程也就那么回事,但是因为在使用之前我对于很多东西不知道为什么要这样做,所以会想得比较多,不会立刻去实践,所以等到全部搞的差不多清楚了之后就拖的比较久了...

不管怎么样,今天上午终于把初步的实践应用搞定了,下面就继续记录吧!

个人思路

在开始具体的操作步骤之前,我要把使用cartographer的具体流程重新捋一遍。因为后续可能会换到高版本的Ubuntu去,有些具体的操作可能会不同,但是整体思路是大概一致的。

Question 1:是否需要分开两个工作空间?

这个问题是困扰我最久的,因为cartographer有点特殊,它是用一个单独的工作空间的形式下载下来的。那么要将carto算法运用到个人机器人模型上,我是在carto工作空间中进行编写代码呢,还是在个人机器人模型的工作空间中调用carto算法呢?
但是查了很久,网上也没有很详细的专门讨论这个问题的帖子。我询问的Chatgpt,它的回答是:使用cartographer算法,可以将个人机器人模型集成到cartographer工作空间中,也可以分开两个工作空间进行使用,其实说了和没说也差不多...

下面是我个人的理解:

  1. 在carto工作空间中进行launch文件和lua文件的编写时(至于launch文件和lua文件是什么东西,后面会有讲解),相当于将carto工作空间当作一个纯粹的导航算法包来使用,而个人的机器人工作空间下面存储的就是机器人模型(URDF)、Gazebo仿真环境等其他方面的配置。也就是说,我们将carto工作空间当作一个独立的导航算法模块包来使用,和机器人的接口就是通过/scan激光雷达话题、/odom里程计话题等来进行通讯,因为carto导航也是只需要这些传感器来进行建图,和其他的结构没有太大关系

  2. 如果在机器人工作空间中编写launch文件和lua文件的时候,就是真正的把carto算法和个人机器人结构完全分离开了,然后在个人工作空间下使用carto的时候就需要将路径引到carto的工作空间的配置文件进行处理。

  3. 也就是说,这两种方法的区别大概就是carto引用路径的不同,第一种方法是直接在本地工作空间进行引用,通过话题接口进行建图,第二种方法是通过设置相对路径来对本地机器人的导航建图进行操作。(其实我对第二种方法的理解还不是很清楚,可能也有错误,如有勘误欢迎大佬指出~)

所以比较两种方法,第一种方法相较于第二种方法更不容易出乱子也更容易理解,所以在后面的操作中我就使用第一中方法来进行操作的。

Question 2:需要配置什么文件?

正因为carto是用一个单独的工作空间来存放它的算法导航代码和实现,所以在独立性和模块化这一方面它做的特别好。也就是说在使用carto的时候我们只需要修改几个配置文件即可使用。那么需要哪几个文件呢?分别是URDF、Launch、Lua,至于它们分别是什么意思,下面一个一个来介绍。

URDF文件

URDF文件是描述机器人模型结构的文件,可以把它类比为Solidwork,也就是指出机器人模型是什么样子的,由什么结构构成等,也包括惯性矩阵、动力学参数等。所以它就是构成了机器人,机器人是什么样子的由他来编写决定。

在carto工作空间下是有一个专门的URDF文件夹,可以用来存储机器人结构模型文件。但是这有点不方便,容易把carto的源代码弄得很乱,所以一般还是将机器人URDF文件在个人的工作空间中存储。

Launch文件

launch文件很简单,就是同时启动多个节点的文件。在个人机器人工作空间中负责将机器人模型参数、Gazebo、rviz同时启动,以实现仿真环境,为carto算法作准备;在carto工作空间中负责将carto算法唤醒,并指出使用carto和机器人通讯的接口

Lua文件

lua文件在使用carto算法中就比较关键了,它的作用是对carto算法的可选项进行配置,比如机器人的基座标、激光雷达的话题,以及一大堆可配置参数(调参也就是在这里...),也就是作为carto的配置文件(config)进行使用,在launch文件中也需要对它进行引用。

Question 3:配置之后如何做到建图?

当文件配置好之后,我们就要准备来建图了。但是要怎么建图呢?carto又不像普通的gmapping等,直接在launch中调用就可以同时启动Gazebo、rviz和导航算法。

这个时候其实很容易就可以想到了,前面我们说过carto工作空间和机器人工作空间的联系,是通过laser话题和odom话题等传感器来进行通讯计算的。所以我们要使用carto首先得把这些话题发布出来吧!很容易想到,我们要先启动机器人,让他发布话题,然后启动carto,订阅这些话题进行建图。那么整个流程就一目了然了。

操作步骤

所以综上所述,把这些问题搞清楚之后,使用carto的全流程还是很简单的,大体如下:

  1. 新建个人机器人工作空间,在里面存放机器人结构文件URDF、Gazebo仿真环境文件World、rviz配置文件等,并编写launch文件使机器人模型可以在Gazebo、rviz中同时启动,也要进行测试;

  2. 在cartographer工作空间中,/carto_ws/src/cartographer_ros/cartographer_ros下有两个文件夹,launch文件夹和configuration_files文件夹,这里面有对应的文件模板demo_revo_lds.launchrevo_lds.lua,我们分别复制一份到文件夹中后对内容进行配置;

  3. 新建一个终端,进入个人机器人工作空间中,刷新环境变量后执行launch文件,让机器人在Gazebo和rviz中显示出来;

  4. 新建一个终端,进入carto工作空间中,进行编译catkin_make_isolated --install --use-ninja,完成后刷新环境变量source install_isolated/setup.bash,然后执行自己编写的launch文件,就可以开始建图了;

  5. 停止建图并保存地图,执行代码一套:

点击查看代码
rosservice call /finish_trajectory 0
//自己配置路径
rosservice call /write_state "{filename: '/home/cy/mymap.pbstream'}"
rosrun cartographer_ros cartographer_pbstream_to_ros_map -map_filestem=/home/cy/mymap.pbstream -pbstream_filename=/home/cy/mymap.pbstream -resolution=0.05 

后续要解决的问题

参数调整

由于是我自己随便做的机器人和地图,还有操作机器人移动也不是很熟练,所以建出来的图特别垃圾哈哈哈哈,跑了两下就停了。这里把我第一次用caro建的图甩出来,作为纪念!!

所以后续还是需要了解lua文件中参数的含义,然后开始调参漫漫长路~

停止建图命令集成

每次结束建图的时候要输入那么多命令其实很难受,后续我需要想想如何将它们放在一个sh命令脚本中,直接运行这个脚本就可以停止建图并转换为图片了~

控制机器人运动方法

这里我使用的是rosrun teleop_twist_keyboard teleop_twist_keyboard.py,确实很不好用hhhhhh,好奇怪的键盘方式...后面找找有没有比较直观简单的键盘操作方式。

代码

把这次的代码贴一下,以便后续对比学习:

launch文件

点击查看代码
<!--
  Copyright 2016 The Cartographer Authors

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->

<launch>
  <param name="/use_sim_time" value="true" />

  <node name="cartographer_node" pkg="cartographer_ros"
      type="cartographer_node" args="
          -configuration_directory $(find cartographer_ros)/configuration_files
          -configuration_basename myrobot.lua"  //指明配置文件
      output="screen">
    <remap from="scan" to="/scan" />  //激光雷达话题
    <remap from="odom" to="odom" />     //里程计话题
  </node>

  <node name="cartographer_occupancy_grid_node" pkg="cartographer_ros"
      type="cartographer_occupancy_grid_node" args="-resolution 0.05" />

</launch>

lua文件

具体的lua文件中的参数应该怎么调整,我后续会进一步学习,这里的是初步的,当作测试练习而已

点击查看代码
-- Copyright 2016 The Cartographer Authors
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.

include "map_builder.lua"
include "trajectory_builder.lua"

options = {
  map_builder = MAP_BUILDER,
  trajectory_builder = TRAJECTORY_BUILDER,
  map_frame = "map",

  tracking_frame = "base_footprint",       // 基座标
  published_frame = "odom",           //里程计
  odom_frame = "odom",
  provide_odom_frame = false,

  publish_frame_projected_to_2d = false,
  use_pose_extrapolator = true,
  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.submaps.num_range_data = 35
TRAJECTORY_BUILDER_2D.min_range = 0.3
TRAJECTORY_BUILDER_2D.max_range = 8.
TRAJECTORY_BUILDER_2D.missing_data_ray_length = 1.
TRAJECTORY_BUILDER_2D.use_imu_data = false
TRAJECTORY_BUILDER_2D.use_online_correlative_scan_matching = true
TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.linear_search_window = 0.1
TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.translation_delta_cost_weight = 10.
TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.rotation_delta_cost_weight = 1e-1

POSE_GRAPH.optimization_problem.huber_scale = 1e2
POSE_GRAPH.optimize_every_n_nodes = 35
POSE_GRAPH.constraint_builder.min_score = 0.65

return options

致谢

当然!!也离不开互联网大佬的帮助!!!特列致谢:

参数解释
命令使用

posted @ 2024-09-12 13:20  cyMessi  阅读(33)  评论(0编辑  收藏  举报