文章目录
- 一、基础环境搭建
- 二、克隆并安装依赖仓库
- 三、安装 Python 依赖
- 四、编译项目
- 五、运行
- 六、Bug
- 1、Error: the value of ‘NrDims’ is not usable in a constant expression
- 2、The keyword signature for target_link_libraries has already been used with
- 3、usr/bin/env: ‘python’: No such file or directory
- 4、AttributeError: 'gtsam.gtsam.Rot3' object has no attribute 'quaternion'
- 5、AttributeError: module 'numpy' has no attribute 'bool'
https://github.com/jake3991/sonar-SLAM/
下面是一份中文的详细步骤指南,帮助你在 Ubuntu 20.04 + ROS Noetic 环境下复现 sonar-SLAM (BlueRov SLAM) 项目所需的安装与运行过程。该项目主要使用成像声呐(Imaging Sonar)与 DVL+IMU 等作为里程推算(Dead Reckoning),再通过图优化 (ISAM2, GTSAM) 完成 3DOF 水平平面内的 SLAM。请根据自身环境做适当的调整。
-
Ensure all python dependencies are installed
-
Check ros distro
-
clone this repo into your catkin workspace
-
clone git clone https://github.com/ethz-asl/libnabo.git into your catkin workspace
-
clone https://github.com/ethz-asl/libpointmatcher.git into your catkin workspace
-
Make sure to use our specific tested version of libpointmatcher by using the following command in the libpointmatcher folder
git checkout d478ef2eb33894d5f1fe84d8c62cec2fc6da818f
-
clone https://github.com/jake3991/Argonaut.git into your catkin workspace
-
build your workspace with catkin build NOT catkin_make
一、基础环境搭建
1. 安装 ROS Noetic
如果你已经在 Ubuntu 20.04 上安装好了 ROS Noetic,并且确保命令 rosversion -d
输出 noetic
,可以跳过本节。若你尚未安装,请参见ROS Noetic官方安装教程。安装完成后,务必在 ~/.bashrc
中加入:
source /opt/ros/noetic/setup.bash
以便让所有新打开的终端都有 ROS 环境变量。
2. 安装 catkin 工具
本项目强烈建议使用 catkin build
(来自 catkin_tools
),而不是默认的 catkin_make
。如果未安装,可以执行:
sudo apt update
sudo apt install python3-catkin-tools
安装成功后,即可在终端中使用 catkin build
指令。
3. 创建工作空间
在你的 Home 目录下创建一个新的 catkin 工作空间,例如 catkin_ws_sonar
:
mkdir -p ~/catkin_ws_sonar/src
cd ~/catkin_ws_sonar
catkin init
catkin build
这样就初始化了一个可使用 catkin build
的工作空间。
二、克隆并安装依赖仓库
1. 克隆 sonar-SLAM(BlueRov SLAM)仓库
在 catkin_ws_sonar/src
中进行以下操作:
cd ~/catkin_ws_sonar/src
git clone https://github.com/jake3991/sonar-SLAM.git
其目录名默认为 sonar-SLAM
或 bruce_slam
,具体以你克隆后显示为准。
2. 依赖库 1:libnabo
还需要克隆 libnabo:
cd ~/catkin_ws_sonar/src
git clone https://github.com/ethz-asl/libnabo.git
3. 依赖库 2:libpointmatcher
克隆 libpointmatcher:
cd ~/catkin_ws_sonar/src
git clone https://github.com/ethz-asl/libpointmatcher.git
注意:该项目特定推荐使用某个已测试的版本,故需要在 libpointmatcher
文件夹内 checkout 该 commit:
cd libpointmatcher
git checkout d478ef2eb33894d5f1fe84d8c62cec2fc6da818f
这样可以避免因代码更新而造成兼容性问题。
4. 依赖库 3:Argonaut
根据文档,还需要克隆 Argonaut:
cd ~/catkin_ws_sonar/src
git clone https://github.com/jake3991/Argonaut.git
该仓库包含 BlueROV 相关的硬件配置、launch 文件以及一些辅助工具。
三、安装 Python 依赖
该项目基于 Python 3 环境,需要以下包(原文提到):
cv_bridge
gtsam
matplotlib
message_filters
numpy
opencv_python
rosbag
rospy
scikit_learn
scipy
sensor_msgs
Shapely
tf
tqdm
pyyaml
# 清华镜像
pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple
# 阿里云镜像
pip install numpy -i https://mirrors.aliyun.com/pypi/simple/
# 永久配置阿里云镜像源
pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
1. 直接使用 pip 安装
先确保你的系统 Python 3 环境可用,然后在终端下执行:
python3 -m pip install --upgrade pip # 更新 pip
python3 -m pip install gtsam matplotlib message_filters numpy opencv-python rosbag rospkg scikit-learn scipy shapely tqdm pyyaml
(1)安装 cv_bridge
cv_bridge
通常通过 ROS 的方式进行安装或编译,常规做法是:
sudo apt install ros-noetic-cv-bridge
或者在工作空间内二次编译源代码,但一般使用 apt
安装足够。
(2)安装 Python ROS 相关包
-
rospy
,sensor_msgs
,tf
,message_filters
等通常都由ros-noetic-...
中自带,无需单独安装。 -
如果遇到报错,可再执行:
sudo apt install python3-rospy python3-catkin-pkg python3-rospkg sudo apt install ros-noetic-tf ros-noetic-tf-conversions ros-noetic-sensor-msgs
来补充安装。
2. 确认 Python 依赖已安装
在安装完成后,你可以使用以下命令确认包是否可用:
python3 -c "import gtsam; import numpy; import cv2; print('OK')"
如果不报错,说明基本正常。
四、编译项目
-
进入工作空间根目录:
cd ~/catkin_ws_sonar
-
进行编译(注意要用
catkin build
-
等待所有包编译完成,若出现错误请先查看缺少哪些依赖,再进行安装。
编译完成后,执行:
source ~/catkin_ws_sonar/devel/setup.bash
以保证编译生成的可执行文件与脚本被系统识别。
五、运行
-
启动 SLAM
source ~/catkin_ws_sonar/devel/setup.bash cd ~/catkin_ws_sonar roslaunch bruce_slam slam.launch
这时会启动核心 SLAM 节点,并在后台等待传感器话题数据。
-
回放 rosbag
在另一终端同样source ~/catkin_ws/devel/setup.bash
后:cd ~/catkin_ws_sonar/bag rosbag play sample_data.bag
这样就把包里的声呐图像、IMU、DVL 等数据话题发布到 ROS 中,SLAM 节点便会开始处理并进行姿态/地图的更新。
六、Bug
1、Error: the value of ‘NrDims’ is not usable in a constant expression
/usr/include/pcl-1.10/pcl/point_representation.h: In instantiation of ‘void pcl::DefaultFeatureRepresentation<PointDefault>::NdCopyPointFunctor::operator()() [with Key = pcl::fields::alpha_m; PointDefault = pcl::PPFSignature]’:
/usr/include/pcl-1.10/pcl/for_each_type.h:87:51: recursively required from ‘static void pcl::for_each_type_impl<false>::execute(F) [with Iterator = boost::mpl::v_iter<boost::mpl::vector<pcl::fields::f1, pcl::fields::f2, pcl::fields::f3, pcl::fields::f4, pcl::fields::alpha_m>, 1>; LastIterator = boost::mpl::v_iter<boost::mpl::vector<pcl::fields::f1, pcl::fields::f2, pcl::fields::f3, pcl::fields::f4, pcl::fields::alpha_m>, 5>; F = pcl::DefaultFeatureRepresentation<pcl::PPFSignature>::NdCopyPointFunctor]’
/usr/include/pcl-1.10/pcl/for_each_type.h:87:51: required from ‘static void pcl::for_each_type_impl<false>::execute(F) [with Iterator = boost::mpl::v_iter<boost::mpl::vector<pcl::fields::f1, pcl::fields::f2, pcl::fields::f3, pcl::fields::f4, pcl::fields::alpha_m>, 0>; LastIterator = boost::mpl::v_iter<boost::mpl::vector<pcl::fields::f1, pcl::fields::f2, pcl::fields::f3, pcl::fields::f4, pcl::fields::alpha_m>, 5>; F = pcl::DefaultFeatureRepresentation<pcl::PPFSignature>::NdCopyPointFunctor]’
/usr/include/pcl-1.10/pcl/for_each_type.h:98:92: required from ‘void pcl::for_each_type(F) [with Sequence = boost::mpl::vector<pcl::fields::f1, pcl::fields::f2, pcl::fields::f3, pcl::fields::f4, pcl::fields::alpha_m>; F = pcl::DefaultFeatureRepresentation<pcl::PPFSignature>::NdCopyPointFunctor]’
/usr/include/pcl-1.10/pcl/point_representation.h:310:40: required from ‘void pcl::DefaultFeatureRepresentation<PointDefault>::copyToFloatArray(const PointDefault&, float*) const [with PointDefault = pcl::PPFSignature]’
/usr/include/pcl-1.10/pcl/point_representation.h:308:7: required from here
/usr/include/pcl-1.10/pcl/point_representation.h:252:48: error: the value of ‘NrDims’ is not usable in a constant expression
/usr/include/pcl-1.10/pcl/point_representation.h:251:19: note: ‘NrDims’ was not initialized with a constant expression
251 | const int NrDims = pcl::traits::datatype<PointDefault, Key>::size;
| ^~~~~~
/usr/include/pcl-1.10/pcl/point_representation.h:252:48: note: in template argument for type ‘int’
252 | Helper<Key, FieldT, NrDims>::copyPoint (p1_, p2_, f_idx_);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
make[2]: *** [CMakeFiles/pcl.dir/build.make:63: CMakeFiles/pcl.dir/src/bruce_slam/cpp/pcl.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:1052: CMakeFiles/pcl.dir/all] Error 2
make: *** [Makefile:141: all] Error 2
# cmake_minimum_required(VERSION 2.8.3)
cmake_minimum_required(VERSION 3.1)
project(bruce_slam)
set(CMAKE_CXX_STANDARD 14)
2、The keyword signature for target_link_libraries has already been used with
the target “pcl”
Errors << bruce_slam:check /home/zhanyong/catkin_ws_sonar/logs/bruce_slam/build.check.000.log
** WARNING ** io features related to pcap will be disabled
** WARNING ** io features related to png will be disabled
** WARNING ** io features related to libusb-1.0 will be disabled
CMake Error at /home/zhanyong/catkin_ws_sonar/src/sonar-SLAM/bruce_slam/CMakeLists.txt:33 (target_link_libraries):
The keyword signature for target_link_libraries has already been used with
the target "pcl". All uses of target_link_libraries with a target must be
either all-keyword or all-plain.
The uses of the keyword signature are here:
* /opt/ros/noetic/share/pybind11_catkin/cmake/pybind11Tools.cmake:179 (target_link_libraries)
* /opt/ros/noetic/share/pybind11_catkin/cmake/pybind11Tools.cmake:211 (target_link_libraries)
make: *** [Makefile:1052: cmake_check_build_system] Error 1
根据错误信息,问题出在 target_link_libraries
的语法不一致,导致对同一个目标(如 pcl
)的链接方式混用了关键字(如 PRIVATE
)和旧式语法。
使用关键字语法加上PRIVATE
即可
# 错误示例(旧式语法)
target_link_libraries(pcl some_lib) # ❌ 旧式语法
target_link_libraries(pcl PRIVATE another_lib) # ✅ 关键字语法
# 修改为统一使用关键字语法
target_link_libraries(pcl PRIVATE some_lib) # ✅
target_link_libraries(pcl PRIVATE another_lib) # ✅
修复后可通过编译
3、usr/bin/env: ‘python’: No such file or directory
# 对所有文件进行
chmod -R a+rwx .
# 或者对python文件
find . -type f -name "*.py" -exec chmod +x {} \;
setting /run_id to 705e069e-0554-11f0-a68e-5ddd692a4939
process[rosout-1]: started with pid [15944]
started core service [/rosout]
process[bruce/slam/gyro_fusion-2]: started with pid [15951]
/usr/bin/env: ‘python’: No such file or directory
process[bruce/slam/dead_reckoning-3]: started with pid [15952]
/usr/bin/env: ‘python’: No such file or directory
process[bruce/slam/feature_extraction-4]: started with pid [15953]
/usr/bin/env: ‘python’: No such file or directory
process[bruce/slam/slam-5]: started with pid [15954]
/usr/bin/env: ‘python’: No such file or directory
process[bruce/map_to_world_tf_publisher-6]: started with pid [15955]
[bruce/slam/gyro_fusion-2] process has died [pid 15951, exit code 127, cmd /home/zhanyong/catkin_ws_sonar/src/sonar-SLAM/bruce_slam/scripts/gyro_node.py __name:=gyro_fusion __log:=/home/zhanyong/.ros/log/705e069e-0554-11f0-a68e-5ddd692a4939/bruce-slam-gyro_fusion-2.log].
log file: /home/zhanyong/.ros/log/705e069e-0554-11f0-a68e-5ddd692a4939/bruce-slam-gyro_fusion-2*.log
[bruce/slam/dead_reckoning-3] process has died [pid 15952, exit code 127, cmd /home/zhanyong/catkin_ws_sonar/src/sonar-SLAM/bruce_slam/scripts/dead_reckoning_node.py __name:=dead_reckoning __log:=/home/zhanyong/.ros/log/705e069e-0554-11f0-a68e-5ddd692a4939/bruce-slam-dead_reckoning-3.log].
log file: /home/zhanyong/.ros/log/705e069e-0554-11f0-a68e-5ddd692a4939/bruce-slam-dead_reckoning-3*.log
[bruce/slam/feature_extraction-4] process has died [pid 15953, exit code 127, cmd /home/zhanyong/catkin_ws_sonar/src/sonar-SLAM/bruce_slam/scripts/feature_extraction_node.py __name:=feature_extraction __log:=/home/zhanyong/.ros/log/705e069e-0554-11f0-a68e-5ddd692a4939/bruce-slam-feature_extraction-4.log].
log file: /home/zhanyong/.ros/log/705e069e-0554-11f0-a68e-5ddd692a4939/bruce-slam-feature_extraction-4*.log
[bruce/slam/slam-5] process has died [pid 15954, exit code 127, cmd /home/zhanyong/catkin_ws_sonar/src/sonar-SLAM/bruce_slam/scripts/slam_node.py __name:=slam __log:=/home/zhanyong/.ros/log/705e069e-0554-11f0-a68e-5ddd692a4939/bruce-slam-slam-5.log].
log file: /home/zhanyong/.ros/log/705e069e-0554-11f0-a68e-5ddd692a4939/bruce-slam-slam-5*.log
从报错信息/usr/bin/env: ‘python’: No such file or directory
可见,系统在调用#!/usr/bin/env python
时找不到python
解释器。这通常是因为当前环境里并没有安装或配置名为“python”的可执行文件。
在较新的 Linux 发行版(例如 Ubuntu 20.04+)里,默认只提供了python3
而没有python
(指向 Python2)的符号链接。如果脚本里使用了#!/usr/bin/env python
,却没有在系统中安装 python
,就会导致No such file or directory
的错误。
如果需要 python3 并希望将其软链接为 python
,可以在 Debian/Ubuntu 系列上安装 python-is-python3
:
sudo apt-get update
sudo apt-get install python-is-python3
重新进行编译
4、AttributeError: ‘gtsam.gtsam.Rot3’ object has no attribute ‘quaternion’
这个错误说明在你的代码中调用了不存在的方法 quaternion()
。在当前的 gtsam 版本中,gtsam.Rot3
对象并没有提供 quaternion()
方法,而是应该使用 toQuaternion()
方法来获取四元数表示。
-
修改代码
找到conversions.py
文件中的第 202 行,把:qw, qx, qy, qz = pose.rotation().quaternion()
修改为:
q = pose.rotation().toQuaternion() qw, qx, qy, qz = q.w(), q.x(), q.y(), q.z()
这样就通过
toQuaternion()
方法获得了四元数对象,再通过w()
,x()
,y()
,z()
分别提取各个分量。
5、AttributeError: module ‘numpy’ has no attribute ‘bool’
错误信息指出,在调用
sel = np.zeros(len(target_points), np.bool)
时出现了异常。原因在于,从 NumPy 1.20 版本开始,np.bool
已经被废弃,不再可用(替代方案是使用内置的 bool
或 NumPy 的 np.bool_
)。这就是导致 AttributeError: module 'numpy' has no attribute 'bool'
的原因。
如何修复
sel = np.zeros(len(target_points), dtype=bool)