ROS 的编程教程虽然详细但是有些零散,总结一下编写的ROS程序的程序框架结构,参考资料会放在后面。
假设我们要编写一个这样的ROS package:
- 有一个C++的lib库 libA,可以提供给其他包和自己使用
- 有在package中自定义的message,msgA,
- 有一个C++结点 node1,依赖于本package中自定义的msgA和libA,以及外部的库
- 有一个Python module,pymodA ,可以提供给其他包使用
- 有一个python 的脚本 pynodeA,可以通过rosrun和roslaunch进行执行,依赖于ModA
整个package的文件目录结构如下
.
├── CMakeLists.txt
├── include
│ ├── libA
│ │ └── libA.h
│ └── nodeA
│ └── nodeA_class.h
├── launch
│ └── test.launch
├── msg
│ └── msgA.msg
├── nodes
│ └── nodeA.cpp
├── package.xml
├── script
│ └── pynodeA_pub.py
├── setup.py
├── src
│ ├── libA
│ │ └── libA.cpp
│ ├── nodeA
│ │ └── nodeA_class.cpp
│ ├── pymodA
│ │ ├── hello.py
│ │ └── __init__.py
│ └── pymodB
│ ├── hello.py
│ └── __init__.py
└── tree.txt
下面来详细的进行各个部分的介绍
include 文件夹
include文件夹主要存放创建的lib以及和node相关的头文件的路径,为了结构清晰,在include文件夹下面建子目录来存放相关文件,比如libA和nodeA两个文件夹
msg文件夹
存放自定义的message
nodes文件夹
存放可执行的node的C++文件
script文件夹
存放python的可执行脚本
src文件夹
存放lib的源文件以及C++可执行文件的源文件
setup.py
根据 ROS rospy 教程中所说,setup.py可以使得你的project中的python脚本使用你在该project中自定义的包,比如上面pynodeA_pub.py可以使用pymodA和pymodB中的函数,在pynodeA_pub文件中只需要添加
import pymodA
import pymodB
需要对cmake文件进行相应的修改,后面会进行介绍,注意setup.py文件要和package的cmakelist文件在同一目录下,setup.py文件主要就是给cmake使用的配置文件
其他参考资料:ROS Handling of setup.py
cmakelists.txt
这个文件是最最重要的,接下来会详细的介绍cmakelist的结构和参数
首先ROS 的package的编译有两种模式,一种直接使用catkin_make ,这是develop模式,生成devel文件夹,一种是使用catkin_make install , 安装package,这个主要是为了你的包给别人使用。那么我们就分两种模式来看
catkin_make
首先可以明确使用这个命令在devel文件夹里面能够得到哪些:
- include 文件夹下的包名目录下只有msgA.h一个文件
- lib文件夹下的包名目录下有可执行文件nodeA,以及动态链接库libA.so,但是没有libA.h这个头文件
- lib/python/dist-packages目录下有包目录package/,里面有msg/目录,存放所有的生成的msg的python model. python的module目录pymodA/和pymodB/
你在project里面可以直接使用:
# 对C++ 源文件,可以使用
# include "nodeA/nodeA_class.h"
# include "libA/libA.h"
# include "package/msgA.h"
# 对 python 脚本,可以
import pymodA
import pymodB
from package.msg import msgA
想要实现这些,cmakelist文件的对应语句如下:
1.首先是生成消息模板的部分,直接参考 ROS CreatingMsgAndSrv
2.生成了消息之后,要使得其能够在project内部使用,所以cmakelist文件中有
include_directories(
include ${catkin_INCLUDE_DIRS} # 将头文件include进去
)
3.生成lib和可执行文件
add_library(libA src/libA/libA.cpp)
target_link_libraries(libA
${catkin_LIBRARIES}
)
add_dependencies(libA ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
FILE(GLOB_RECURSE SOURCE_FILES src/*.cpp) # 抓取子目录对应源文件,我这里用到了src 里面的所有
add_executable(nodeA
nodes/nodeA.cpp ${SOURCE_FILES} # add all relative cpp files
)
add_dependencies(nodeA ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(nodeA
libA
${catkin_LIBRARIES}
)
这里面除了带有我们自己命名的那些是自定义之外,其余都是默认的值,一般不需要进行改动
写了这些语句,那么catkin_make基本没问题了,如果想要其他包使用,要进行install,下面还有补充的几点注意:
- devel 下编译得到的只有libA.so和msgA.h,所以其他的包只能用到msg.h,想要使用libA需要Cmake进行install
- 对于python,如果有依赖的包建议使用requirements.txt来安装Python文件中依赖的包,虽然ros有通过package.xml定义的方法来解决,但是没法设置参数,所以不是很方便
catkin_make install
这个主要得到install文件夹,这个和devel文件夹几乎一个结构模式,不同的是里面的内容比devel文件夹多的多。
install文件夹中主要有
1.include 文件夹的package目录下有msgA.h,libA文件夹和nodeA文件夹,分别存放libA.h和nodeA.h
2.lib/package文件夹下有可执行文件nodeA以及pynodeA_pub.py可执行脚本
3.lib/python/dist-packages目录下和devel相同
cmakelist文件中的相应的参数设置如下
## Mark executable scripts (Python etc.) for installation
## in contrast to setup.py, you can choose the destination
install(PROGRAMS # python 可执行脚本
script/pynodeA_pub.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
## Mark executables for installation
## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html
install(TARGETS nodeA # 可执行文件
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
## Mark libraries for installation 库文件
## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html
install(TARGETS libA
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} # .so
)
## Mark cpp header files for installation 头文件
install(DIRECTORY include/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
FILES_MATCHING PATTERN "*.h"
PATTERN ".svn" EXCLUDE
)
# launch 文件
install(DIRECTORY launch/
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch
PATTERN ".svn" EXCLUDE)
执行完catkin_make install 之后,会在工作空间目录得到install 文件夹,当你需要在其他地方使用是,使用source install/setup.bash