LT-mapper,LT-SLAM代码运行与学习

时间:2022-10-15 16:53:15

1 安装编译

系统:

ubuntu: 	| Description: Ubuntu 18.04.6 LTS
architecture: 	| 64-bit
gcc: 		| gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
cmake: 		| cmake version 3.10.2 CMake suite maintained and supported by Kitware (kitware.com/cmake).
ros-melodic

查看系统及软件版本脚本参考:https://blog.csdn.net/BIT_HXZ/article/details/125120168

1.1编译安装LT_mapper

cd xx/LT_mapper_ws/src
git clone https://github.com/gisbi-kim/lt-mapper.git
catkin_make

报错1:fatal error: filesystem: 没有那个文件或目录

/home/meng/subject/LT_mapper_ws/src/lt-mapper/ltslam/include/ltslam/utility.h:88:10: fatal error: filesystem: 没有那个文件或目录
 #include <filesystem> // requires gcc version >= 8

/home/meng/subject/LT_mapper_ws/src/lt-mapper/ltremovert/include/removert/utility.h:70:10: fatal error: filesystem: 没有那个文件或目录
 #include <filesystem> // requires gcc version >= 8

LT-mapper,LT-SLAM代码运行与学习

思路1,用#include <experimental/filesystem>替换#include <filesystem>

LT-mapper,LT-SLAM代码运行与学习

参考:https://*.com/questions/39231363/fatal-error-filesystem-no-such-file-or-directory
发现还是报错,报错如下:

/home/meng/subject/LT_mapper_ws/src/lt-mapper/ltremovert/include/removert/utility.h:73:21: error: ‘filesystem’ is not a namespace-name
 namespace fs = std::filesystem;
                     ^~~~~~~~~~
/home/meng/subject/LT_mapper_ws/src/lt-mapper/ltremovert/include/removert/utility.h:73:31: error: expected namespace-name before ‘;’ token
 namespace fs = std::filesystem;
--------------

/home/meng/subject/LT_mapper_ws/src/lt-mapper/ltremovert/src/Session.cpp:87:24: error: ‘fs’ has not been declared
     for(auto& _entry : fs::directory_iterator(_scan_dir)) {

--------------
/home/meng/subject/LT_mapper_ws/src/lt-mapper/ltremovert/src/Removerter.cpp:8:10: error: ‘fs’ has not been declared
     if (!fs::is_directory(_path) || !fs::exists(_path))

LT-mapper,LT-SLAM代码运行与学习

解决思路与解决方案,按上面的报错逻辑来看,应该是filesystem这个命令空间及空间内的函数没有引用对,前面不是用#include <experimental/filesystem>替换#include <filesystem>嘛,这里也尝试用替换如下所示,这里仅仅修改下面的位置:

// namespace fs = std::filesystem;
namespace fs = std::experimental::filesystem;//hxz

编译通过

思路2:尝试升级G++到8以上,我没有尝试

1.2 编译安装file_player_mulran

cd xx/LT_mapper_ws/src
git clone https://github.com/irapkaist/file_player_mulran.git
catkin_make

1.3 编译安装SC-LIO-SAM

cd xx/LT_mapper_ws/src
git clone https://github.com/gisbi-kim/SC-LIO-SAM.git
catkin_make

1.4 安装CloudCompare

github地址:https://github.com/CloudCompare/CloudCompare
安装参考:https://blog.csdn.net/magic_ll/article/details/120780593

安装:

sudo apt-get update
sudo apt install snap
sudo snap install cloudcompare

LT-mapper,LT-SLAM代码运行与学习

运行参考命令:

cloudcompare.CloudCompare
loudcompare.ccViewer 

卸载:

sudo snap remove cloudcompare

2 LT-SLAM 流程

2.0准备数据序列

LT-mapper ParkingLot 数据集包含在三天内的六个序列,用于同一空间地点,但初始姿势不同。LT-SLAM 自动将它们对齐在共享坐标中。

LT-mapper,LT-SLAM代码运行与学习

下载链接:https://drive.google.com/drive/folders/1FNIU691AR2g04NlKBFCDL4APpxpzkfQp
全部下载即可

LT-mapper,LT-SLAM代码运行与学习

下载如下:

LT-mapper,LT-SLAM代码运行与学习

解压到任意一个文件夹,这里命名为data文件夹下:

LT-mapper,LT-SLAM代码运行与学习

使用MulRan player从数据目录中发布雷达和点云话题

cd xx/LT_mapper_ws
source devel/setup.bash
roslaunch file_player file_player.launch

launch启动出现软件界面:LT-mapper,LT-SLAM代码运行与学习

点击load,加载数据:

LT-mapper,LT-SLAM代码运行与学习

点击play会播放话题,点击end会结束播放话题

LT-mapper,LT-SLAM代码运行与学习

2.1 通过SC-LIUO-SLAM为每一个段生成一个段数据

2.1.1 由01数据生成一个段

需要设置文件保存路径:
修改:xx/LT_mapper_ws/src/SC-LIO-SAM/SC-LIO-SAM/config/params_mulran.yaml 文件内路径为自己创建的路径:

  # savePCDDirectory: "/home/user/Desktop/scliosam/data/"  # use global path, and end with "/" 
  savePCDDirectory: "/media/meng/T7/dataset/LT_mapper/data_parsed/01/"  # use global path, and end with "/"   

启动lio-sam:

cd xx/LT_mapper_ws
source devel/setup.bash
roslaunch lio_sam run_mulran.launch

第一次启动可能会遇到这个,应该不影响:

LT-mapper,LT-SLAM代码运行与学习

接着发布话题数据:

cd xx/LT_mapper_ws
source devel/setup.bash
roslaunch file_player file_player.launch

效果如下,如果rviz不显示,可以再启动一次run_mulran.launch;如果中间出现定位崩了,重新启动上面两个launch
LT-mapper,LT-SLAM代码运行与学习LT-mapper,LT-SLAM代码运行与学习LT-mapper,LT-SLAM代码运行与学习

结果保存在:
LT-mapper,LT-SLAM代码运行与学习
LT-mapper,LT-SLAM代码运行与学习

批量化查看pcd文件:https://blog.csdn.net/BIT_HXZ/article/details/122090880

2.1.2 由02数据生成一个段

01和02数据起点具有不同的位姿。
参考上面的操作,重新来一遍。效果如下:
LT-mapper,LT-SLAM代码运行与学习LT-mapper,LT-SLAM代码运行与学习

2.1.3 比较轨迹

打开cloudcompare软件,终端输入:
cloudcompare.CloudCompare

LT-mapper,LT-SLAM代码运行与学习

将01、02数据的trajectory.pcd文件用cloudcompare软件打开,进行轨迹比较

LT-mapper,LT-SLAM代码运行与学习

可以看出,01和02的起始位姿不同,所以轨迹并没有对齐。

注:如果trajectory.pcd文件在外接硬盘上,我这里在三星T7硬盘上,直接用cloudcompare打开会出现包权限不允许的错误,如下所示:

[pcl::PCDReader::readHeader] Could not open file '/media/meng/T7/dataset/LT_mapper/data_parsed/01/trajectory.pcd'! Error : Permission denied
[pcl::PassThrough::applyFilter] Input dataset doesn't have x-y-z coordinates!

LT-mapper,LT-SLAM代码运行与学习

解决办法为将两个trajectory.pcd文件复制到自己电脑硬盘的文件加下,如/home/Desktop/

2.1.4 在共享的中心坐标系中使用LT-SLAM对齐两个轨迹

指定需要对齐数据序列的路径,打开xx/LT_mapper_ws/src/lt-mapper/ltslam/config/params.yaml,修改对应路径,下面的修改应该是让02数据的轨迹向01数据对齐

ltslam:

  # sessions_dir: "/home/user/Documents/catkin2021/catkin_LTslam/data_kitti/in/" # end with / 
  sessions_dir: "/media/meng/T7/dataset/LT_mapper/data_parsed/" # end with /    ###hxz


  central_sess_name: "01" # should be same as the directory name of that session   ##hxz
  query_sess_name: "02" # should be same as the directory name of that session    ##hxz
  
  # save_directory: "/home/user/Documents/catkin2021/catkin_LTslam/data_kitti/out/011-02-manyloops/" # end with "/"
  save_directory: "/media/meng/T7/dataset/LT_mapper/data_ltslam/0102/" # end with "/"    ##hxz

  is_display_debug_msgs: false

  loopFitnessScoreThreshold: 0.7

  kNumSCLoopsUpperBound: 1000 # if you use an enough number, use all the detected loops 
  kNumRSLoopsUpperBound: 0 # if you use an enough number, use all the detected loops 

  numberOfCores: 16 # currently hard-coded in the utility.cpp
cd xx/LT_mapper_ws
source devel/setup.bash
roslaunch ltslam run.launch

LT-mapper,LT-SLAM代码运行与学习

LT-SLAM首先检测并缝合(detect and sticth)基于背景扫描的回环(scan context-based loops),并得到大致的初始位姿转换。然后,使用基于半径(radius-search)的搜索精细地缝合两个轨迹。
最终输出:

/media/meng/T7/dataset/LT_mapper/data_ltslam/0102/01_central_aft_intersession_loops.txt
/media/meng/T7/dataset/LT_mapper/data_ltslam/0102/02_central_aft_intersession_loops.txt

LT-mapper,LT-SLAM代码运行与学习

2.1.5 比较使用LT-SLAM对齐的两个轨迹

注意:上一步得到的最终文件01_central_aft_intersession_loops.txt02_central_aft_intersession_loops.txt如果在移动硬盘上,也需要移动到电脑本机硬盘上,否则可能打不开或打开失败。
直接拖如cloudcompare软件即可。

LT-mapper,LT-SLAM代码运行与学习

调整第1、4、8、12列的属性,点击apply all(这样拖入另一个txt时就不用调整了)
LT-mapper,LT-SLAM代码运行与学习LT-mapper,LT-SLAM代码运行与学习

发现01和02数据对应的轨迹被很好地对齐了。

LT-mapper,LT-SLAM代码运行与学习

2.1.6 使用在中心坐标系上优化的位姿对齐每一段点云

注:python环境:python3.7,之前配置的环境:https://blog.csdn.net/BIT_HXZ/article/details/123444769
注:出现报错查看目录3 找到对应的报错
分别将01_central_aft_intersession_loops.txt02_central_aft_intersession_loops.txt放在xx/data_parsed/01xx/data_parsed/02
使用SL-LIO-SLAM的python工具xx/LT_mapper_ws/src/SC-LIO-SAM/SC-LIO-SAM/tools/python/makeMergedMap.py,修改该py文件的下面4处:

# data_dir = "/home/user/Desktop/data/scliosam/mytest1/" # should end with / 
# scan_idx_range_to_stack = [0, 100] # if you want a whole map, use [0, len(scan_files)]
data_dir = "/media/meng/T7/dataset/LT_mapper/data_parsed/01/" # should end with /   ##hxz
scan_idx_range_to_stack = [0, 571] # if you want a whole map, use [0, len(scan_files)] ##hxz

# f = open(data_dir+"optimized_poses.txt", 'r')  ##hxz
f = open(data_dir+"01_central_aft_intersession_loops.txt", 'r')

# if( nodes_count % node_skip is not 0): 
if( nodes_count % node_skip != 0):  ##hxz         

第4行的571是Scans文件夹里面的项目数目

LT-mapper,LT-SLAM代码运行与学习

终端输入:

cd xx/LT_mapper_ws/src/SC-LIO-SAM/SC-LIO-SAM/tools/python
python3 makeMergedMap.py

LT-mapper,LT-SLAM代码运行与学习LT-mapper,LT-SLAM代码运行与学习

open3d中鼠标滚轮前滑是缩小,后滑是放大,按住滚轮移动鼠标是移动,鼠标左键可以移动视角

LT-mapper,LT-SLAM代码运行与学习

同样,针对02数据,修改xx/LT_mapper_ws/src/SC-LIO-SAM/SC-LIO-SAM/tools/python/makeMergedMap.py中对应位置,参考如上,输入命令python3 makeMergedMap.py
LT-mapper,LT-SLAM代码运行与学习

直接看的话,需要放大才可以看出区别
现在我们得到了在相同坐标系下的两个点云地图

运行python3 makeMergedMap.py时,在程序执行到保存pcd地图阶段时可能会报错:三个报错对应三个位置,相应修改如下。

TypeError: sequence item 0: expected str instance, bytes found

LT-mapper,LT-SLAM代码运行与学习

        # uncompressed = ''.join(uncompressed_lst)
        uncompressed = ''.join(str(uncompressed_lst))         #hxz

TypeError: write() argument must be str, not bytes

LT-mapper,LT-SLAM代码运行与学习

        # fileobj.write(struct.pack(fmt, compressed_size, uncompressed_size))
        fileobj.write(str(struct.pack(fmt, compressed_size, uncompressed_size)) )  ##hxz      

TypeError: write() argument must be str, not bytes

LT-mapper,LT-SLAM代码运行与学习

        # fileobj.write(buf)
        fileobj.write(str(buf))  ##hxz      

解决完报错后,终端打印输出如下,对齐后的点云地址如下
LT-mapper,LT-SLAM代码运行与学习

makeMergedMap.py文件中保存pcd的相关代码如下

LT-mapper,LT-SLAM代码运行与学习

最终01和02序列数据分别得到:map_0_to_609_with_intensity.pcdmap_0_to_571_with_intensity.pcd,但二者都比较大

LT-mapper,LT-SLAM代码运行与学习

2.1.7 使用cloudcompare比较每一段点云对齐后的效果

数据量比较大,暂时先不再ubuntu下用cloudcompare打开,如果用cloudcompare打开会报错,如下所示:

[pcl::PCDReader::read] The estimated cloud.data size (377341728) is different than the saved uncompressed value (1550071928)! Data corruption?
[pcl::PCDReader::read] Size of decompressed lzf data (0) does not match value stored in PCD header (1550071928). Errno: 22

LT-mapper,LT-SLAM代码运行与学习

注:如果可以打开比较观察,会发现有动态鬼点和较小的偏移,在使用LT-removert处理完动态鬼点后,LT-removert通过检查变化进行偏差对齐

3 报错及相关解决办法

3.1:ModuleNotFoundError: No module named 'pypcd'

解决步骤:

(1)pip install pypcd

我这里pypcd.py文件安装在/home/meng/anaconda3/envs/yolov5py37/lib/python3.7/site-packages/pypcd/pypcd.py

(2)替换pypcd.py文件

下面这个github代码针对篇pypcd在python3.x版本上的兼容性,写了针对python3.6的版本的pypcd,感谢感谢感谢。
https://github.com/weidezhang/pypcd_python3.6

LT-mapper,LT-SLAM代码运行与学习

将上面pip安装的/home/meng/anaconda3/envs/yolov5py37/lib/python3.7/site-packages/pypcd/pypcd.py备份后直接全部替换,备份参考命令如下:
cp /home/meng/anaconda3/envs/yolov5py37/lib/python3.7/site-packages/pypcd/pypcd.py /home/meng/anaconda3/envs/yolov5py37/lib/python3.7/site-packages/pypcd/pypcd.py.old

(3)如果没有进行(2)的替换,可能会报错;替换的话就基本没问题了:

报错1:ModuleNotFoundError: No module named 'cStringIO'

LT-mapper,LT-SLAM代码运行与学习

原因在于python3.X已经取消了cStringIO模块,但是可以在io模块中找到StringIO。参考:https://blog.csdn.net/S20144144/article/details/100518249

gedit /home/meng/anaconda3/envs/yolov5py37/lib/python3.7/site-packages/pypcd/pypcd.py
观察pypcd.py文件,相关调用函数的语句如下所示:

    fileobj = sio.StringIO(buf)
--------------
    fileobj = sio.StringIO()    

且StringIO()函数在python3中在io头文件中,故修改如下:

# import cStringIO as sio
import io as sio   #hxz

报错2:TypeError: startswith first arg must be bytes or a tuple of bytes, not str

参考:https://github.com/ansible/tower-cli/issues/300

LT-mapper,LT-SLAM代码运行与学习

修改如下:

        # if ln.startswith('DATA'):
        if ln.startswith(b'DATA'):  ##hxz          

LT-mapper,LT-SLAM代码运行与学习

        # if ln.startswith('#') or len(ln) < 2:
        if ln.startswith(b'#') or len(ln) < 2:  ##hxz          

报错3:TypeError: cannot use a string pattern on a bytes-like object

LT-mapper,LT-SLAM代码运行与学习

修改如下:

        # match = re.match('(\w+)\s+([\w\s\.]+)', ln)
        match = re.match('(\w+)\s+([\w\s\.]+)'.decode('utf-8'), ln) ##hxz

报错*n,会有很多报错。。。,我没解决完

3.2:ModuleNotFoundError: No module named 'open3d'

(注:之前尝试时,在python3.10的环境下一直安装不进去open3d,调整为python3.7环境就安装进去了。)
直接安装:pip install open3d

ERROR: Could not find a version that satisfies the requirement open3d (from versions: none)
ERROR: No matching distribution found for open3d

使用conda安装:
conda install open3d
报错:
PackagesNotFoundError: The following packages are not available from current channels:
到anaconda(https://anaconda.org/) 查看open3d这个包的下载链接:
LT-mapper,LT-SLAM代码运行与学习LT-mapper,LT-SLAM代码运行与学习LT-mapper,LT-SLAM代码运行与学习

输入命令:
conda install -c open3d-admin open3d,安装成功

3.3:ModuleNotFoundError: No module named 'addict'

pip install addict