2021SC@SDUSC
1. 本周工作目标
本周正式开始阅读ROS(ROS 1 Noetic)的源码。按照综述的计划,本周着手开始阅读ROS Master部分的源码。结合实际情况,本周的工作目标如下:
-
寻找一些专业书籍,了解更多的详细信息
-
下载ros源码,了解源码结构
-
从源码编译ROS Master,为后续调试阅读做准备
关于ROS1和ROS2,有点像Python2和Python3的过渡,二者并不兼容,后者将是前者的替代。ROS1最后一个LTS版本(Noetic)将在2025年结束支持,ROS2的第一个LTS版本(Foxy Fitzroy)已经与2020年发布,支持3年,现在(2021.10月)处于一个二者并存的过渡期。
ROS2有很多地方进行了改进,比如在ROS2中没有ROS Master!更多比对在下面这个链接:
ROS1 vs ROS2, Practical Overview For ROS Developers - The Robotics Back-End
2. 找书
学习一门课程,最重要的知识来源就是书本。找了一圈,最好的书籍应该是动物园系列的《Programming Robots with ROS》,而中文书籍里相对不错的是《机器人操作系统ROS原理与应用》,但是都是“入门书籍”,似乎没有深入讲解源码的书籍。
3. ros源码结构分析
那么还是得自己看源码。先在官网找到一下两个wiki:
http://wiki.ros.org/Source code
RecommendedRepositoryUsage/CommonGitHubOrganizations - ROS Wiki
通过上述wiki,我们知道了两个事实:
-
2013年以后,ROS的源码通过github、bitbucket等代码托管仓库进行托管和分发。
-
在github上,ROS的源码分布在不同账号下的不同仓库。比如核心组件通过https://github.com/ros这个账号发布,控制导航库通过https://github.com/ros-planning这个账号发布,还有一个账号(https://github.com/ros-gbp)专门用于发布打包的源码。
那么,我们去ros账号下看看有什么仓库。我们在这里找到了
-
https://github.com/ros/ros:ros核心仓库。
-
https://github.com/ros/ros_comm:ros通信核心组件,实现了roscpp、rospy等库。ros master的实现也在这里,而不是上面的ros仓库!
-
https://github.com/ros/catkin:编译工具catkin的实现。实际上按照仓库的描述,catkin is just a collection of cmake macros。
-
还有roscpp_core、std_msgs等仓库。
我们仔细研究一下这些仓库,比如把https://github.com/ros/ros仓库克隆到本地,观察(noetic-devel分支)的目录结构,结果在源码的第二层目录下发现了两个熟悉的文件:CMakelist.txt和package.xml!也就是说ROS的源码本身也是一些package,也使用catkin来管理、编译。一个git代码仓库里面有一系列相互联系的包,共同完成一个大功能。至此,我们大致了解了ros的源码组织结构。
P.S. 特别有意思的一点是,catkin的源码也是catkin包,也用catkin管理。
4. 从源码编译ROS
大致了解源码结构之后,我们先按照官网教程,从源码编译ROS一套流程走下来再说。官网wiki链接如下:
http://wiki.ros.org/Installation/Source
先跟着做完,做完再回头看道理。
官网教程写得很详细,自己跟着做的过程中只遇到了一些需要注意的小点:
-
要在apt源配置里增加ros源
-
rosdep update
的时候需要良好的国际网络连接 -
虚拟机内存不能给太小,至少要3G,建议4G,否则编译一些大文件的时候会用光内存,然后系统卡死,如下图所示 。
编译完成之后,我们就可以像source /opt/ros/noetic/setup.bash
一样,source ~/ros_catkin_ws/install_isolated/setup.bash
,然后正常使用roscore等工具链了。至此,编译结束!
我们回头过来看看刚刚执行的操作的含义和原理。
他首先让我们安装了一些bootstrap dependencies,这是一些用来下载源码、管理源码依赖的元工具,实际上就是一些Python脚本。
然后他教我们开始下载ros的源代码。这里需要关注的就是他下载源代码的方式,上文我们了解了ros发布代码的方式,如果要我们一个一个地git clone各个仓库来下载我们所需的代码,那是会累死人的!所以,他使用了刚刚安装的rosinstall_generator
工具获取了ROS noetic发行版的所有git仓库的下载链接,然后用vcs
工具批量下载了所有源码。也就是说,执行完vcs import --input noetic-desktop.rosinstall ./src
之后,所有的源码都下载到了工作区里./src
文件夹下了。
下载到源码之后,我们就准备要编译了。首先要解决的是源码依赖的问题,这里他用的是rosdep工具分析源码,该工具自动调用apt install在Ubuntu里安装所需依赖。然后就正式开始编译了,这里调用的是./src/catkin/bin/catkin_make_isolated
进行编译。没错,用下载的源码里的catkin工具编译整个工程!(这算是某种程度的自举了。)
catkin_make_isolated实际上也是用Python写的。
他这里用的是catkin_make_isolated,而不是catkin_make,这是为什么呢?二者的区别是什么呢?简答说来就是catkin_make把整个工程的所有包视作同一个项目,把各个包的CMakelist.txt和顶层的CMakelist.txt合并在一起生成一个总的CMakelist.txt,然后一次性编译。
catkin_make
treats the entire workspace as a single cmake project, and builds it with a single invocation of cmake.
catkin_make_isolated
treats each package as a separate cmake project, and builds and installs each separately, in dependency order.catkin_make vs catkin_make_isolated, which is preferred? - ROS Answers: Open Source Q&A Forum
另一个佐证是,如果细心观察的话,你会发现./src目录下是没有顶层CMakelist.txt文件的。也就是说,这个workspace并不是一个整体的project。
5. 总结
万事开头难(,然后中间难,最后结尾难),这周总算大致把源码的阅读环境建立起来了,留待下周开始阅读。