写这一篇文章的原因是随着相关内容的不断维护,这部分网上的一些资料都已经比较老了,配置起来走了一些弯路。不过,想当年实习配置SLAM算法库的时候什么依赖的报错没有调好过?哈哈,在今天配置完以后,特意总结此文章,把过程记录一下。方便我之后再配,还有就是给大家提供一些方便,不要把精力都花在像这种乱七八糟的事情上。



安装Cartographer

首先,Cartographer怎么安装我就不写了,这种链接网上多的是,搬来搬去也没什么意义。要写就写一些有价值,稀缺的内容。我这人很讨厌复制粘贴,尤其是复制粘贴了几个版本以后,格式都乱了,缺斤少量的浪费读者时间。比如看到什么“博客园”之类的网站上复制粘贴的垃圾内容,格式排版都错了,还赖在百度页面上关了以后重新打开一个又是它,这种一看我就气不打一处来。所以我就默认你的Cartographer已经装好了。要是你还没有装,我就随便放一个链接了cartographer ros使用指南-安装,请读者自行安装。假设安装完以后,文件夹名字叫cat_ws。


下载3D包

首先,Cartographer官方提供了一个3D demo包,通过如下指令可以把它下载下来:

wget -P ~/Downloads https://storage.googleapis.com/cartographer-public-data/bags/backpack_3d/with_intensities/b3-2016-04-05-14-14-00.bag

下载完以后,这个包会被下载到Downloads这个文件夹下。我把它挪到cartographer的安装目录cat_ws下。

那么,现在把这个包跑起来:

roslaunch cartographer_ros demo_backpack_3d.launch bag_filename:=/home/zhaokai/cat_ws/b3-2016-04-05-14-14-00.bag

在跑的过程中,我要把相关的点云信息保存下来,因此我另起一个终端,调用命令:

rosservice call /finish_trajectory 0
rosservice call /write_state ${HOME}/Downloads/b3-2016-04-05-14-14-00.bag.pbstream

这样就会在Downloads下生成一个叫b3-2016-04-05-14-14-00.bag.pbstream的文件


保存点云数据

我们可以发现,在Cartographer3D运行过程中,机器人坐标系离开某个区域以后,那里就剩下了一块灰黑交杂的所谓“栅格地图”,和2Dslam的质量完全没法去比较。只有机器人坐标系附近才有匹配的点云以及实时扫描的点云。

那么,我们应该通过什么方式,把历史点云记录下来呢?

打开cat_ws/src/cartographer_ros/cartographer_ros/launch/assets_writer_backpack_3d.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.
 
VOXEL_SIZE = 5e-2
 
include "transform.lua"
 
options = {
  tracking_frame = "base_link",
  pipeline = {
    {
      action = "min_max_range_filter",
      min_range = 1.,
      max_range = 60.,
    },
    {
      action = "dump_num_points",
    },
 
    -- Gray X-Rays. These only use geometry to color pixels.
    {
      action = "write_xray_image",
      voxel_size = VOXEL_SIZE,
      filename = "xray_yz_all",
      transform = YZ_TRANSFORM,
    },
    {
      action = "write_xray_image",
      voxel_size = VOXEL_SIZE,
      filename = "xray_xy_all",
      transform = XY_TRANSFORM,
    },
    {
      action = "write_xray_image",
      voxel_size = VOXEL_SIZE,
      filename = "xray_xz_all",
      transform = XZ_TRANSFORM,
    },
 
    -- Now we recolor our points by frame and write another batch of X-Rays. It
    -- is visible in them what was seen by the horizontal and the vertical
    -- laser.
    {
      action = "color_points",
      frame_id = "horizontal_vlp16_link",
      color = { 255., 0., 0. },
    },
    {
      action = "color_points",
      frame_id = "vertical_vlp16_link",
      color = { 0., 255., 0. },
    },
 
    {
      action = "write_xray_image",
      voxel_size = VOXEL_SIZE,
      filename = "xray_yz_all_color",
      transform = YZ_TRANSFORM,
    },
    {
      action = "write_xray_image",
      voxel_size = VOXEL_SIZE,
      filename = "xray_xy_all_color",
      transform = XY_TRANSFORM,
    },
    {
      action = "write_xray_image",
      voxel_size = VOXEL_SIZE,
      filename = "xray_xz_all_color",
      transform = XZ_TRANSFORM,
    },
  }
}
 
return options

我们在屁股后面插入一句:

 
    {
      action = "write_ply",
      filename = "points.ply",
    },
  }
}
 
return options

然后切换到根目录下,重新编译(我这里不重新编译的话,貌似修改无效):

catkin_make_isolated --install --use-ninja
source devel_isolated/setup.bash 

然后就要调用另一个launch文件,生成ply文件:

roslaunch cartographer_ros assets_writer_backpack_3d.launch    bag_filenames:=${HOME}/cat_ws/b3-2016-04-05-14-14-00.bag    pose_graph_filename:=${HOME}/Downloads/b3-2016-04-05-14-14-00.bag.pbstream

注意,bag和pose_graph的文件路径,要写成自己放置的文件路径。

这句指令运行结束以后,会有红色提示,但并不代表报错了:

那么现在观察/cat_ws目录下,除了刚刚下载好的b3-2016-04-05-14-14-00.bag,还多了一堆文件(第一行):

这里要注意两点:第一,如果之前这个bag文件你之前下载好以后就没有动,仍然放在downloads文件夹下,那么这些新生成的文件也应该去downloads文件夹下面去找。第二,会产生一个叫b3-2016-04-05-14-14-00.bag_points.ply的文件(图里面的第一行第二个)。第三,如果之前修改那个lua文件以后没有重新编译,那么就只有一堆图片(第一行3-8个文件),而没有第二个b3-2016-04-05-14-14-00.bag_points.ply文件。一定要生成b3-2016-04-05-14-14-00.bag_points.ply才能后续可视化。


可视化点云数据

编译point_cloud_viewer库

网上就是这部分的内容有一些过时了,因此在配置这一块内容的时候遇到了一些问题。当然我的内容也可能有过时的一天,起码截至今天2021-04-13的时候是可以用的。所以可以先按我的来。

首先,应该下载配置Cartographer的点云可视化库。github链接:GitHub - cartographer-project/point_cloud_viewer: View billions of points in your browser. 。这里注意,我的代码版本是12 Oct 2020 ,目前来看是最新的版本。之后如果更新了,大家又有配置问题,可以回退这个版本,用我如下的方式进行成功配置。

不过链接里面readme的内容貌似不是很适合直接在ubuntu下装载,所以我接下来把我的过程详细记录一下:

mkdir ~/tools/
cd ~/tools/
git clone https://github.com/googlecartographer/point_cloud_viewer
curl https://sh.rustup.rs -sSf | sh

成功以后会提示:

然后调用:

echo "export PATH=$HOME/.cargo/bin:$PATH" >> ~/.bashrc
source ~/.bashrc
git submodule update --init --recursive

注意第三句话git submodule update --init --recursive,如果不用的话后续会报错:error: failed to run custom build command for `protobuf_provider v0.1.0 (/home/zhaokai/tools/point_cloud_viewer/protobuf_provider)`

然后开始编译其中的内容:

cd ~/tools/point_cloud_viewer
cargo build --release 

生成OctreeStructure

这里需要把之前生成的ply文件,给转化成可视化需要的点云图文件结构。

cd ~/tools/point_cloud_viewer
target/release/build_octree /home/zhaokai/cat_ws/b3-2016-04-05-14-14-00.bag_points.ply --output-directory /home/zhaokai/cat_ws/cloud

注意以上的指令,/home/zhaokai/cat_ws/b3-2016-04-05-14-14-00.bag_points.ply是之前生成的ply文件,--output-directory后面跟着的是输出路径,这里建议最好用一个空闲的文件夹保存,比如我在cat_ws下面新建了一个cloud文件,命令运行结束后,会产生一大堆文件:

那么接下来,就需要根据这个cloud文件夹里生成的内容,对点云进行可视化了!之后我要介绍的内容,网上其他的就比较过时了,按他们的配置可能就会出问题。

可视化点云有两种方式,第一种,叫sdl_viewer。第二种,叫Web_viewer。下面我依次讲这两者的配置方法。

Sdl_viewer

这一种是比较好配置的,基本不会报什么错误。

cd ~/tools/point_cloud_viewer/sdl_viewer/
cargo build --release

我看到网上的相关教程,例如https://www.ncnynl.com/archives/201811/2789.html,3D激光slam,cartographer的使用,第一视角点云_Nksjc的博客-CSDN博客 等都没有提这种sdl_viewer方式,我不是很知道为什么,明明这种感觉更方便一点。

使用命令则是:

../target/release/sdl_viewer /home/zhaokai/cat_ws/cloud

(这点注意要把路径写对,target文件夹是在~/tools/point_cloud_viewer目录下。而/home/zhaokai/cat_ws/cloud是上面生成的点云文件夹。

运行以后的截图:

从这个弹出的窗口里,可以切换各种角度,通过鼠标滑轮,左键拖动等方式查看点云数据。

Web_viewer

这个工具是通过网页来观察点云的。同样前置要求是,需要把点云生成到cloud文件夹当中。

首先要进入到对应文件夹当中,准备进行编译。

cd ~/tools/point_cloud_viewer/octree_web_viewer/client
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash

第二句运行结束以后,如图所示:

然后对bashrc进行source:

source ~/.bashrc

发现提示了一个新的错误:

既然人家让运行这个指令,那就老老实实运行:

nvm install 12.18.0

然后下一步接着运行:

nvm ls && nvm ls-remote && nvm install v**

结果提示v** not found:

那就再补一个指令:

nvm ls-remote
source ~/.bashrc

然后接着运行:

sudo apt install cmdtest
cargo build --release

结果发现有这两个报错,找不到/app_bundle.js和/app_bundle.js.map。

那么我们就应该想办法生成这两个文件。刚刚我们安装nvm就是这个作用。接下来的内容,以我目前的水平其实我并不太懂具体每一步的详细运行原因,所以可能有一些指令属于无用指令。但是我又不好确认哪些是无用的,只好按我配置的顺序记录下来了。

nvm install 8
nvm use 8
npm install

我们可以看到提示什么found 1 high severity vulnerability,高危漏洞,看起来好可怕的样子。

那么我就按它提示的来修复:

npm audit fix
npm install

这下我们看到漏洞没有力。然后运行:

npm run build

结果提示报错。说缺了个什么"three"。

我们运行这句话的目的是,生成/app_bundle.js和/app_bundle.js.map,结果这里报错了。那这个问题必须解决,否则没法对web_viewer接着进行编译。

但我们进入~/tools/point_cloud_viewer/octree_web_viewer/client/node_modules文件夹里面,明明看到有这个three文件夹的,在第三行最后一个。。

然后打开~/tools/point_cloud_viewer/octree_web_viewer/client/下面的tsconfig.json文件:

看到types里,有一个“three”。那把这个three删了行不行?重新用npm run build试了一下:

好家伙,这么多错,看来不能删。把tsconfig.json恢复原样。

经过查询以后,我发现可以使用这个命令:

npm install @types/three

这下没有报错了!然后再运行:

npm run build

这又是个什么错误?

/home/zhaokai/tools/point_cloud_viewer/octree_web_viewer/client/node_modules/rollup/dist/shared/loadConfigFile.js:494
        ? (await import(url.pathToFileURL(fileName).href)).default
                 ^^^^^^

经过一番查询,这里我就直接揭晓答案吧,这是因为版本不对。需要使用10以上的nvm版本。详见SyntaxError: Unexpected token import · Issue #3594 · rollup/rollup · GitHub

nvm use 11
nvm install 11
npm run build

(这也足以说明,链接cartographer ros使用指南-第一视角点云 里面讲的内容可能过时了。)

运行结束后,看到提示:

> point_viewer@0.1.0 build /home/zhaokai/tools/point_cloud_viewer/octree_web_viewer/client
> tsc && rollup -c
build/main.js → ../../target/app_bundle.js...
created ../../target/app_bundle.js in 1.8

我们可以看到,之前我们提到编译octree_web_viewer时缺少的 app_bundle.js等东西这下就有了。

cd ~/tools/point_cloud_viewer/octree_web_viewer
cargo build --release

运行结束后提示:

 Compiling octree_web_viewer v0.1.0 (/home/zhaokai/tools/point_cloud_viewer/octree_web_viewer)
    Finished release [optimized] target(s) in 5.18s

这下编译成功了! 然后就可以用web的方式来观察生成的点云:

cd ~/tools/point_cloud_viewer/target/release
./points_web_viewer /home/zhaokai/cat_ws/cloud

注意我们可以看到生成的可执行文件的名字也变了,叫points_web_viewer,而不是其他链接中提到的web_viewer。而/home/zhaokai/cat_ws/cloud是刚刚用ply生成的装了很多东西的文件夹。

运行提示:

Starting http server: 127.0.0.1:5433
Got 8 nodes with 94853 points (0.551338ms).

这时候打开浏览器,在地址栏里输入 http://localhost:5433 ,然后就可以以网页的形式查看生成的点云:

这种方式如果实在配置不好,我个人觉得就算了,不要强迫症了,就用sdl_viewer进行可视化就可以了。


更多内容请关注我的专栏,谢谢!