QAProcess: 开发者指南 | Review Status | PackageProposalProcess | PackageDocumentation | APIReviewProcess | DocReviewProcess | CodeReviewProcess | StackDocumentation | StackVersionPolicy | 自动化测试 | WorkOnTrunkStack | 功能包集发布过程 | WritingTutorials | Graveyard
ROS开发者指南
ROS是一个庞大的系统,许多人协同开发。为了合理的管理,我们已经写好了开发指导说明。请按照下面的指导说明,合理布局你的代码。
参考:
源代码管理
支持使用Git,Mercurial,Subversion, 和Bazaar进行代码管理。由于ROS社区是分散的,欢迎你将代码托管到任何公共访问的地方(比如GitHub, Bitbucket, Google Code). 主要的ROS基础代码会被发布到github.com的几个组织单元several organization units下面。关于建议的仓库使用说明参考RecommendedRepositoryUsage
- 只添加手动编写的源代码文件,以及必须的构建功能包的相关文件. 不要添加机器自动生成的文件,比如目标文件(*.o),库文件(.a, .so, .dll), 或者自动配置脚本文件.
svn add 将会递归到子目录里添加所有文件. 在svn add之前先操作下 make clean .
- 不要添加大的二进制文件: 通过web服务器上传,下载到本地的构建文件夹去.
- 尽早且经常性提交自己的代码.不在源码管理范围内的任何文件都应该作为草稿(scratch)存储。
- 尽量保持每次的提交集中到一处特殊的更改,而不是一次提交多方面的更改,这样更容易回溯代码。
- 每一次的提交都写清更改说明.
- 不要打乱构建结构. 在check in之前确保你的代码能够顺利编译.
Bug追溯
针对每一个功能包,利用单独的bug tracker,实现bug报告,增强请求,和任务分配。经常性的,在本站的页面上,你会看的一些具体的bug tracker的相关链接。
对于代码的托管GitHub作为一个仓库的通用的bug tracker。
代码维护者将会为每个报告的问题创建一个里程式标记(milestone)。当问题被定位时,可以给报告者一个合适的反馈。这些里程标记就是ROS正式版(比如 Groovy or Hydro) 或者细分版本(比如 Hydro beta 1). 更多的是,当问题没被修复时,会赋以标记untargeted。这可能是由于开发者的时间紧迫或者可靠性的考虑。
为了让用户表达自己的想法,针对已发布的软件版本,测试是否已经修复bug,维护者应该要么,在关闭问题报告的时候,发布一个尝试版本,要么为每一个更细化的版本设置标记,在下个里程标记之前,标记问题报告。这样一来,对用户来说,让所包含的问题本身来决定发布版的bug是否已经被修复。
当你发现一个bug时,开启一个指派(ticket)。当你需要新功能的时候,打开一个指派。邮件或者发布到answers.ros.org或者邮件列表都有可能被遗忘。但是,指派的方式反而就不会那么容易忘记。
- 指派的时候尽量遵循这些原则.
- 尽量包含bug重现时,需要的指令。They should include instructions for reproducing the bug.
- 尽量描述问题出现时的,系统运行状态。(用的什么系统版本,涉及的功能包有哪些。
- 不要畏惧指派。许多开发者都会指派给他们自己,比如利用Trac。
如果你不确定出现问题时涉及的的功能包或者问题确实是一个bug,请首先访问answers.ros.org。
代码布局
package功能包由代码组织而成,而功能包组成一个单独的仓库responsitory。功能包是作为代码构建的基本单位。
尤其注意!建议,在GitHub上,在仓库的根目录创建一个README.md,用来向用户说明代码仓库的具体细节。建议,在ROS wiki页面设置链接到指定的包含的软件包。参照 this article 获取更多的帮助.
功能包
ROS功能包和系统的构建依赖于manifest.xml。
每一个功能包都必须,在功能包所在的顶层目录,存在一个manifest.xml文件.
- 最基本的,manifest必须包含下面的三部分
- description
- author
- license
下面举一个roscpp节点的一个模板例子:
<package> <description brief="BRIEF DESCRIPTION"> LONGER DESCRIPTION </description> <author>You/you@willowgarage.com</author> <license>BSD</license> <url>http://wiki/YOURPACKAGE</url> <depend package="roscpp"/> </package>
下面是rospy的一个例子:
<package> <description brief="BRIEF DESCRIPTION"> LONGER DESCRIPTION </description> <author>You/you@willowgarage.com</author> <license>BSD</license> <url>http://wiki/YOURPACKAGE</url> <depend package="rospy"/> </package>
GUI 工具包
我们已经移植了所有最新的GUI到rqt,这些GUI都是QT基础的GUI框架。在fuerte使用wxWidgets之前,因交叉编译的兼容性太差,大部分已有的代码被重建。 因此对于新的GUI设计,考虑使用rqt。开发说明从这里获取(including license consideration when writing in python)。
代码构建
基本的代码构建工具是CMake(more).
每一个创建的功能包的顶层目录都必须存在CMakeLists.txt .
现在,每一个功能包都必须有一个Makefile, 短而精巧.
- 那些没有经过构建步骤的功能包不需要任何的构建文件。
证书
ROS 是开源.旨在让来自五湖四海的不同的用户和开发者们,从学生到企业家们,都可以得到帮助获取支持。
- 我们倾向自由的开源证书,促进代码的商业化.
倾向建议使用证书BSD 证书. 尽可能,新的代码都应该在BSD证书下发布。所有的ROS代码都是BSD证书下发布的 选择BSD的原因
- The preference for BSD is based on many factors. Here are a few:
- BSD allows any kind of reuse, from academic to commercial, open or closed.
- BSD is compatible with all other OSI-approved licenses. (For example GPL v2 is not compatible with Apache 2).
BSD does not require that changes be contributed back but there are large thriving communities using the BSD license (e.g., http://www.openbsd.org, http://www.freebsd.org). Members of these communities frequently contribute improvements, without being required to do so.
- The preference for BSD is based on many factors. Here are a few:
其他任何的OSI促成的证书都是可接受的(for non-core code).
- 我们强烈建议使用非对称版权的证书(比如BSD),来进行ROS .msg和.srv文件的发布,所以不妨碍那些自动产生的源代码文件和数据结构.
- 工程中的所有文本状态的证书都应该放到顶层的LICENSES文件目录下。如果你天剑了一个并不包括在LICENSE目录下的证书,添加下证书状态即可。
- 每一个源代码文件,都应该在顶层,包含一个证书的简略版注释。方便的,LICENSES目录下也应该包含证书的简略说明,并且需要不同的语言书写。
- 对于我们发布的第三方的代码,证书和版权会被予以保护
- 我们将严格遵守第三方软件,例如:
如果库有证书GPL声明 or LGPL 声明,如果你修改了,则你必须发布修改后的代码。理想情况下,你必须发送一个补丁给库的维护者。保持如果修改后的代码的公共访问权限也是必要的.
如果你的功能包使用了GPL'd库,然后你的功能包也必须进行GPL声明。
如果你的功能包使用了GPL'd库,那么你就不能使用与GPL不兼容的授权协议GPL-incompatible license. 例如,Creative Commons Attribution-Noncommercial-Share Alike 证书是与GPL不兼容的,因为他强加了一些GPL不能做的约束条件(换句话说,就是要求的属性,禁止商业使用等).
- 尽可能的,每一个ROS功能包都以一种单一证书形式予以管理。
- 一般性的特殊案例:BSD证书代码(比如 ROS core),在一个功能包,也会用到GPL证书声明的代码。为了配合GPL,BSD声明的代码,是在BSD和GPL多证书下声明的,用户可以选择使用哪个证书协议。这当然也不是声明大问题,因为GPL增加了一些BSD不要求的一些限制条件。
ROS功能包和通信系统允许细致的证书协议。因为节点通过ROS消息进行通信,多节点通信的代码不是连接到一起。因此,功能包提供了一种“证书壁垒(license boundary)”。
- 例外:当一个功能包是库的形式,并且确实链接到其他的功能包。这种情况下,各个证书会被混合声明在目标代码里。
引用: Maintaining Permissive-Licensed Files in a GPL-Licensed Project: Guidelines for Developers
版权
遵循Berne Convention版权,作为作者自动拥有版权,而不管有没有一个正式的声明。无论如何,显式的版权声明有助于长期性项目的管理。
每一个源文件都应该在文件顶层上,包含一个版权说明注释,例如 Copyright 2008 Jim Bob. 这个就是一个证书的简概说明.
- 如果只自己使用,版权属于自己。
- 如果受雇于某些人,或者公司(比如Willow Garage),版权就属于公司。
调试
ROS里的调试工具,包括但不限于:
一般性建议:
如果一个程序,比如foo, crashes, 首先使用 GDB:
- 可以通过添加一些必要的参数:
(gdb) run arg1 arg2 arg3
当程序崩溃crashes时,利用gdb的bt指令来进行追溯和探究。
- 对于一些棘手的bug,尤其涉及到内存崩溃的。试着实用工具valgrind:
valgrind -v foo arg1 arg2 arg3
Valgrind可以追踪所有的内存访问呢,一把可以找到问题的原因。同样,可以发现你没有发现的其他问题。注意的就是,Valgrind会拖慢你程序运行的节奏,看起运行缓慢。
master和rospy的日志会默认创建到ROS_ROOT/log。但是,roscpp的客户端节点日志默认不会创建。如果你正在以nasty模式调试时,你可以设置构建的第二个参数WRITE_LOG_FILE(伴随其他的选项ANONYMOUS_NAME等)。其他选择是,如果你不想重新编译节点,你可以在命令行中添加log:=BLAHBLAH,BLAHBLAH可以是任何东西,也可以什么也不是。
测试
我们进行两个级别的测试:
库: 在库的层面上,我们使用用标准的单元测试框架。C++时,我们使用gtest.,Python时,我们使用unittest.
消息: 在消息层面上,我们使用rostest.建立系统节点,运行一个测试节点,然后逐步拆分系统。
我们已经构建了best practices and policies ,进行编写和运行测试test。
如果你在ROS系统下,开发ros-pkg 或者wg-ros-pkg,安装build farm 启动测试构代码搭建和自动测试在不同的芯片体系下。如果在你提交后,搭建或者测试停止工作,你应该获得一封邮件来告知相关的错误,希望来修复它。参考AutomatedTesting指导说明。
文档汇总
所有的代码都应该参照 QAProcess.进行文档汇总。包括:
- 所有外部的可见的代码级的API
- 所有外部的可见的ROS级的API
正式发布
ROS社区代码的发布流程参考release页面
标准化
弃用规则
一旦有人使用的你的代码,你就有责任不要对他们所谓的对代码大幅改动,进行釜底抽薪。相反的,使用deprecation,意味着,对于它的移除用清单的形式,标记指定的特性或者内容不再支持。给用户些时间去适应,作为一个发布版的过程循环,就和移除一样。
弃用发生在多级情况下,包括:
API features : 你想从库中,删除一个方法。首先需要再API文档中标记它被弃用了。在DOxgyen中,使用@deprecated. 如果语言支持相关语法,也可以在源码中标注。比如C/C++,利用 __attribute__ ((deprecated)). 在下一次的发布版中,就要注意弃用的标记在修改清单中,标有未来的发布版本中你希望删除的部分。如果代码未来会被广泛应用,将其标记的明显些,然后在后面附上注释。在未来的正式发布版中,删除即可。
Packages : 意思就是,你想删除一个功能包。在wiki文档中标记为弃用(比如吧DEPRECATED标记在文档开头),声明你想要什么时候删除。更改说明,包含那些弃用的声明,会被带到下一次的发布版中。当功能包被广泛使用的时候,你就应该使用email,尽量将警告发给那些使用的用户。
大数据文件,大测试文件
大文件(大小超过1MB)经常不属于*-ros-pkg仓库代码,尤其是他们一般仅仅用在单元测试时。不管某些人是否构建了你的功能包,大的文件会影响checkout的仓库的时间和效率。
大的数据文件应该被托管到公共的web主网页。在web服务器上,你也可以仅仅放置你所需要的文件。文件的托管可以在download.ros.org. 请联系ros-release@lists.ros.org 获取更多信息。在你打开上传请求之前,鼓励你去查找是否已存在你所需要的文件。
下载文件,请使用catkin_download_test_data. 如果,你在更早的rosbuild时候,使用 rosbuild_download_test_data(URL MD5SUM) 宏定义。比如:
catkin_download_test_data( ${PROJECT_NAME}_saloon.bag http://downloads.foo.com/bags/saloon.bag DESTINATION ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_SHARE_DESTINATION}/test MD5 01603ce158575da859b8afff5b676bf9) rosbuild_download_test_data(http://code.ros.org/svn/data/robot_pose_ekf/zero_covariance.bag test/zero_covariance.bag 0a51b4f5001f446e8466bf7cc946fb86)