本文以移植代码为例说明。目标是把一款云台SDK中的ROS代码部分抠出来移植到自己创建的工作空间中。记录下大致的流程。
目录
1、创建工作空间
mkdir -p pantilt_ws/src
cd pantilt_ws/src
catkin_init_workspace
pantilt_ws 文件夹是创建的工作空间,src 文件夹放置后面创建的功能包的源码。catkin_init_workspace 命令用来初始化工作空间,这个命令会在 src 文件夹中生成一个 CMakeLists.txt 的文件。
2、编译工作空间(可选)
在这里这个步骤不是必要的,完全可以放到最后完成。这个步骤放在这里只是用来说明工作空间为空的情况下也能编译,另外,为了展示运行了这个命令后工作空间会产生什么样的变化。
cd pantilt_ws
catkin_make
catkin_make 会在工作空间 pantilt_ws 中生成 devel、build 这两个文件夹:
devel:开发空间,放置开发过程中的可执行文件
build:编译过程中产生的中间文件
这两个文件及文件中的内容在开发过程中都是相关指令自行生成的,我们不用管。
3、设置环境变量(可选)
如果没有执行步骤 2,直接跳到步骤 4 即可。编译好工作空间后需要把工作空间添加到环境变量中去,可以使用下面的指令,把工作空间 devel 文件夹下的 setup.bash 文件的路径加到环境变量中。
source devel/setup.bash
这样做不方便的一点是每次运行都得重新 source 一下,我们可以把以下路径直接加到 ~/.bashrc 文件中
打开 ~/.bashrc 文件
gedit ~/.bashrc
添加路径
source ~/Desktop/pantilt_ws/devel/setup.bash
保存退出。
4、创建功能包
功能包必须放在工作空间的 src 文件夹下,另外所有源码必须放在功能包中。创建功能包的模板:
catkin_create_pkg <package_name> [depend1] [depend2] [depend3]
catkin_create_pkg 命令后跟功能包的名字,功能报名字后跟依赖项。
这里我创建一个名为 pantilt_ctl 的功能包:
cd pantilt_ws/src
catkin_create_pkg pantilt_ctl std_msgs rospy roscpp message_generation message_runtime
创建成功后在 pantilt_ws/src 文件夹下会多出一个 pantilt_ctl 的文件夹和一个名为 CMakeLists.txt 的文件
在 pantilt_ctl 文件夹下会新建 include 和 src 文件夹以及 CMakeLists.txt 和 package.xml 文件。
package.xml 文件的开始主要是使用 xml 语言记录的功能报的名字、版本、描述和开源协议等信息,然后 package.xml 后面还包含功能包的依赖信息。在创建功能包时的 std_msg/roscpp/rospy 等依赖包都会写在这里面,后面如果还有附加的依赖功能包就可以在这里面手动加入。
CMakeLists.txt 文件主要用来描述功能包在编译时的编译规则,即一些编译指令,使用的是 CMake 的语法。
5、编写源代码、修改 CMakeLists.txt 文件
如果是自己写代码的话那就是在功能包 pantilt_ctl 的 src 文件夹下新建 cpp 源文件,在 include 文件夹下新建 cpp 头文件即可。
这里直接将云台官方 SDK 源码中的有关文件拷贝过来,并做相应的类名、路径名等的修改。
然后是修改 CMakeLists.txt 文件的内容。
比如说我只有一个 read_write_node.cpp 的ROS节点源文件,那么需要在 CMakeLists.txt 文件中加入以下两条语句:
add_executable(read_write_node src/read_write_node.cpp)
target_link_libraries(read_write_node ${catkin_LIBRARIES})
add_executable 第一个参数是生成的可执行文件的名称,第二个参数是需要编译的代码。
target_link_libraries 设置的是生生成可执行文件的链接库。
对于其他的一些命令,CMakeLists.txt 文件中都有相应的注释来解释命令的作用。
例如,如果想让自己添加的msg文件(在功能包中创建 msg 文件夹,新建的 msg 文件都放在这里)起作用的话,就要加入下面的语句;
find_package(catkin REQUIRED COMPONENTS
。。。
message_generation
)
## Generate messages in the 'msg' folder
add_message_files(
FILES
your_msg_name.msg
)
## Generate added messages and services with any dependencies listed here
generate_messages(
DEPENDENCIES
std_msgs
)
catkin_package(
。。。
message_runtime
)
- find_package 添加的是依赖功能包。
- add_message_files 里面列出你的 msg 文件的名字,这样程序在编译时就会发现这个定义的消息接口,然后根据这个接口去做编译,并生成相应的头文件放在 devel/include/[your_package_name]/[your_msg_name].h 中,cpp代码中使用时直接通过下面的代码加入头文件:
#include "[your_package_name]/[your_msg_name].h"
- generate_messages 中列出编译生成 msg 时的依赖,这里是 std_msgs。
- catkin_package 中加入 msg 编译时的依赖,即 message_runtime。
还需要在 package.xml 文件中加入功能包依赖项:
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
build_depend 是编译依赖,在程序编译时需要的依赖项。
exec_depend 是执行依赖,在程序运行时需要的依赖项。
6、编译功能包
先回到工作空间的目录下执行编译
cd pantilt_ws
catkin_make
然后设置环境变量
source pantilt_ws/devel/setup.bash
7、启用节点
先使用命令 roscore 启动 rosmaster,然后新开一个终端使用 rosrun 命令启用功能包中的节点,语法为:
rosrun [your_package_name] [you_node_name]
rosrun 后面跟功能包的名字,功能包名后面跟在这个功能包中的节点的名字。
如:
rosrun pantilt_ctl read_write_node