0.说明
-
教程说明: ROS官网上有官方的教程:Installing ROS Kinetic on the Raspberry Pi,本教程是在其基础上,填了几处坑,使之可以顺利执行(第2.3和2.5节)。有一些地方变得详细,但也有一些地方做了简化处理,大家可以对照来看。
-
安装环境: Raspberry Pi Zero W+Raspbian buster+32G TF卡。
说明: 可用
cat /etc/os-release
命令查看Raspbian的版本。16G的TF卡理论上应该够用,但是比较极限,推荐使用32G的TF卡。如果使用的是Raspberry Pi 2,3,4,推荐直接安装ubuntu系统,从源直接安装ROS。 -
安装说明: 本教程安装的Desktop版的ROS,解决了常见的opencv和pluginlib等包无法编译的问题,只有rviz一个包无法正常安装,但是也会将其移除,避免导致安装失败。有关rviz的问题在最后我还会提到,不过就一般而言,在树莓派上做图像处理比较常见 ,但是用rviz做仿真的需求不大。
1.准备工作
1.初始化ROS仓库
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
sudo apt-get update
sudo apt-get upgrade
2.安装引导程序所需依赖
sudo apt-get install -y python-rosdep python-rosinstall-generator python-wstool python-rosinstall build-essential cmake
3.初始化rosdep
sudo rosdep init
rosdep update
这里由于一些原因sudo rosdep init
可能会失败,解决方法可以参考我的这一篇教程:rosdep init时website may be down解决方案。在确保DNS没有问题的情况下,可以先用手机热点碰碰运气,不行的话直奔教程中的方法三,手动进行rosdep init
。
2.开始编译
1.创建catkin工作空间
首先我们要创建一个工作空间,方便我们接下来编译ROS。
mkdir -p ~/ros_catkin_ws
cd ~/ros_catkin_ws
在执行下面的语句之前,首先要确保DNS解析没有问题,建议直接添加Google的DNS服务器,将下面两行内容添加进/etc/resolv.conf
。
nameserver 8.8.8.8
nameserver 8.8.4.4
接下来我们要使用wstool来安装Desktop版本的ROS了,首先先要生成rosinstall文件,该文件中包含了ROS Package的链接。如果成功执行了下面这条语句,则应该在当前目录下可以找到名为kinetic-desktop-wet.rosinstall
的非空文件。
rosinstall_generator desktop --rosdistro kinetic --deps --wet-only --exclude rviz rqt_rviz visualization_tutorials --tar > kinetic-desktop-wet.rosinstall
需要说明的是,因为我们无法编译rviz,所以我们在这一步排除了rviz包和依赖rviz环境的包的下载。
接下来我们就要从kinetic-desktop-wet.rosinstall
文件包含的网址中下载ROS的包了。该命令会把源代码下载进~/ros_catkin_ws/src
文件夹中。
wstool init src kinetic-desktop-wet.rosinstall
如果wstool init
失败或者被打断,可以输入以下命令继续下载。
wstool update -j4 -t src
如果出现以下提示ERROR in config: Error processing 'opencv3'
,证明opencv3下载失败。我们需要根据kinetic-desktop-wet.rosinstall
中的网址手动下载opencv,并放入到相应位置去。如果还有其他包裹下载失败,解决方法相同。
cd ~/Downloads
wget https://github.com/ros-gbp/opencv3-release/archive/release/kinetic/opencv3/3.3.1-5.tar.gz
tar -zxvf opencv3-release-release-kinetic-opencv3-3.3.1-5.tar.gz
mkdir -p ~/ros_catkin_ws/src/opencv
cp -r opencv3-release-release-kinetic-opencv3-3.3.1-5/* ~/ros_catkin_ws/src/opencv
当然,我们也可以在PC上下载好文件,然后通过FTP传输到树莓派上,如果没有代理的话,这样应该会快一些。
2.配置依赖
为了避免collada_urdf
包编译出现问题,我们需要手动编译Assimp。
mkdir -p ~/ros_catkin_ws/external_src
cd ~/ros_catkin_ws/external_src
wget http://sourceforge.net/projects/assimp/files/assimp-3.1/assimp-3.1.1_no_test_models.zip/download -O assimp-3.1.1_no_test_models.zip
unzip assimp-3.1.1_no_test_models.zip
cd assimp-3.1.1
cmake .
make
sudo make install
如果编译出现困难,也可以选择不构建collada_urdf
包,就像我们上面的rviz一样。
rosinstall_generator desktop --rosdistro kinetic --deps --wet-only --exclude collada_parser collada_urdf --tar > kinetic-desktop-wet.rosinstall
下面我们将用rosdep递归的安装所有依赖项,注意这时候一定要看好Raspbian的版本。
cd ~/ros_catkin_ws
rosdep install -y --from-paths src --ignore-src --rosdistro kinetic -r --os=debian:buster
如果显示有部分依赖没有安装,可以尝试多次执行该语句。
3.修复错误
这部分是ROS官方教程没有的内容,在我的多次测试中,如果不执行这些操作,会导致oepncv3、tf2编译失败。
首先在~/ros_catkin_ws/src/geometry2/tf2/src/buffer_core.cpp
文件中加入以下内容,避免tf2编译报错。
#ifndef logError
#define logError CONSOLE_BRIDGE_logError
#endif
#ifndef logWarn
#define logWarn CONSOLE_BRIDGE_logWarn
#endif
然后将~/ros_catkin_ws/src/opencv/modules/python/src2/cv2.cpp
文件的第885行由char* str = PyString_AsString(obj);
修改为const char* str = PyString_AsString(obj);
,避免opencv3编译报错。
4.更改libboost与gcc版本
在Raspbian Buster上,如果不更改libboost版本和编译器版本的话,就会导致pluginlib编译失败。以下内容来自ROS官网教程。
sudo apt remove libboost1.67-dev
sudo apt autoremove
sudo apt install -y libboost1.58-dev libboost1.58-all-dev
sudo apt install -y g++-5 gcc-5
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 10
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 20
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 10
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 20
sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 30
sudo update-alternatives --set cc /usr/bin/gcc
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 30
sudo update-alternatives --set c++ /usr/bin/g++
sudo apt install -y python-rosdep python-rosinstall-generator python-wstool python-rosinstall build-essential cmake
**说明:**为什么要执行这么多的命令,原因是因为我们前面执行的这条命令rosdep install -y --from-paths src --ignore-src --rosdistro kinetic -r --os=debian:buster
会安装libboost1.67
,而ROS Kinetic中使用的rospack版本依赖于libboost1.58
。
并且我们不能简单的将1.58版本替换成1.67版本,因为libboost1.58
与gcc-8不兼容,所以我们现在有两种方案,一种是使用gcc-8从源码构建libboost1.58
,另外一种是使用早期的gcc版本编译整个ROS。整个的意思是说,如果你使用了gcc-8编译过一部分ROS,则需要把build_isolated
和devel_isolated
文件夹删掉,重新从头编译ROS。
ROS官网教程使用的是第二种方法,使用gcc-5与g+±5构建整个ROS。
5.分配交换空间
树莓派Zero只有512MB的内存,在编译opencv3时可能出现内存不够的问题:g++: internal compiler error: Killed (program cc1plus)
。所以我们需要先分配1G的交换空间,注意: 树莓派重启后,已经分配的空间会保存,但要重新激活成交换空间。
#count的大小就是增加的swap空间的大小,64M是块大小,所以空间大小是bs*count=1024MB
sudo dd if=/dev/zero of=/swapfile bs=64M count=16
sudo mkswap /swapfile #把空间格式化成swap格式
sudo swapon /swapfile #使用刚才创建的swap空间
sudo swapon --show #查看交换空间
在编译完成后可以使用如下命令释放已经分配的交换空间。
sudo swapoff /swapfile
sudo rm /swapfile
6.检查与构建
首先执行gcc -v
以及g++ -v
命令,查看编译器版本,我们需要使用gcc&g+±5.* 。然后执行free
命令,查看内存中是否有我们分配的1G的交换空间。如果都没问题的话,就可以运行下面的语句开始编译ROS了。
sudo ./src/catkin/bin/catkin_make_isolated --install -DCMAKE_BUILD_TYPE=Release --install-space /opt/ros/kinetic
如果仍然出现g++: internal compiler error: Killed (program cc1plus)
错误,可以将默认的参数-j4
改为-j2
。
sudo ./src/catkin/bin/catkin_make_isolated --install -DCMAKE_BUILD_TYPE=Release --install-space /opt/ros/kinetic -j2
我们需要准备24~36个小时的编译时间。
7.配置环境变量
运行以下命令:
source /opt/ros/kinetic/setup.bash
echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc
不出意外的话,执行完这两条指令以后,ROS已经被配置完毕,我们可以运行roscore
来查看效果。
3.补充说明
-
如果我们还需要什么添加什么包,或者要更新已经下载的包,可以参考ROS官网教程中的
4.Maintaining a Source Checkout
。但要注意的是,安装依赖的时候,有关系统的参数一定要是--os=debian:buster
。 -
rviz编译失败是因为其依赖于ogre图形库,而apt包管理器中的ogre-1.9依赖于libboost-thread-dev,libboost-thread-dev又依赖于libboost1.67-dev,而我们前面已经说了,ROS Kinetic中的rospack依赖于libboost1.58,与libboost1.67冲突。于是这便形成了一个死循环。
但我认为这并不是无解的情况,因为我去ogre官网查阅了一些资料,发现libboost-thread-dev其实不是必须的依赖项,只不过apt包管理器中的ogre-1.9需要该依赖,所以我们也许可以直接从源码构建ogre,进而构建rviz。
我尝试了几次从源码构建ogre,均以失败告终,有时间我会再次进行尝试,争取在Raspbian构建完整的ROS Kinetic Desktop。(如果Kinetic的维护期结束,Noetic的生态变得完善,那么我会放弃这个问题,转去使用Melodic或者是Noetic 😄)
4.参考资料
Installing ROS Kinetic on the Raspberry Pi
Trouble processing tf2 package
Compiling ROS on raspberry pi 4 with Buster, problem with libboost1.58