创建package后,package.xml
不需要再修改
创建package命令是catkin_create_pkg nodeName
package名称
package的名称对应CMakeLists
中的project(package)
和package.xml
中的<name>package</name>
package的命名是有官方规范的,我意外地发现test
这个名字往往会带来问题,可能是因为带test
的package都是用于测试的,所以要避免使用。基本规则如下:
- 只能使用字母数字下划线
- 字母只能用小写,开头必须是字母
- 至少有两个字符长度
- 只做消息的package以_msg结尾,只含launch的以_launch结尾,以此类推
不要轻易用msg
, launch
, test
这样的字符串做名称,容易出问题。如果命名不规范,编译时会告警,影响编译时间。查看官方package列表,发现除了tf这样一个单词做名称的例子外,其他基本都是a_b
或a_b_c
这样的名称,例如tuw_geometry_rviz
,所以这样命名比较稳妥。
package.xml
每个package.xml文件必须包含的标签包括:
<package>
: 最高级tag,属性:format,用于指定格式<name>
:package名称<version>
:当前版本<description>
:package的基本描述<maintainer>
(至少一个):维护者<license>
(至少一个):协议<buildtool_depend>
(至少一个): 一般情况下只需要指定catkin作为编译工具, 在需要交叉编译的情况下需要增加目标机器的编译工具
可选标签包括:
<build_depend>
(多个):编译时需要依赖的其它package,适用于静态库<exec_depend>
(多个):运行时需要依赖的其它package,适用于静态库build_export_depend
: 编译时需要链接(build against)的package<export>
:用于添加额外的信息,比如需要嵌入的其它package的插件,或者一些说明信息。
使用depend
可以表示同时包括build
和exec
依赖,也就是说<depend>roscpp</depend>
相当于1
2<build_depend>roscpp</build_depend>
<exec_depend>roscpp</exec_depend>
一般都包括的几个是1
2
3
4
5
6<buildtool_depend>catkin</buildtool_depend>
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
<!-- 可能还有其他msgs类型 -->
<depend>std_msgs</depend>
<build_export_depend>std_msgs</build_export_depend>
几个重要路径
4个ROS的重要路径,可在CMakeLists中用message函数查看:
CATKIN_PACKAGE_LIB_DESTINATION
: lib库的路径CATKIN_PACKAGE_BIN_DESTINATION
: 可执行文件的路径CATKIN_PACKAGE_SHARE_DESTINATION
:共享文件的路径,就是CMakeLists中的INSTALL生成的两个cmake文件的路径catkin_INCLUDE_DIRS
: 跟catkin有关文件的路径,不仅仅是ROS相关的
在代码中包含另一个package的头文件时,经常写成#include<robot_api/robot_api.h>
,注意程序目录结构必须是这样:
多工作空间的问题
尽量只用一个工作空间,如果用到两个以上,不要出现同名package,也不要出现不同工作空间的包有依赖的情况 |
如果在/opt/ros/kinetic/
之外,如果我们创建了多个工作空间且需要在多个工作空间中来回地工作,比如/home/user/catkin_ws1
和 /home/user/catkin_ws2
ROS_PACKAGE_PATH
环境变量中的多个目录是有先后顺序的。如果工作空间1和2中的所有包之间没有依赖关系,那么将下面两句话放在bashrc
文件中合适的位置(至少应该放在source /opt/ros/kinetic/setup.*sh
后)。1
2source /home/user/catkin_ws1/devel/setup.*sh --extended
source /home/user/catkin_ws2/devel/setup.*sh --extended
后面source的工作空间会遮蔽之前工作空间的同名包,比如opt/ros/indigo/share/
中安装了move_base包,又在/home/user/catkin_ws1
中通过下载源代码的方式安装了move_base,由于ROS_PACKAGE_PATH
环境变量的遮蔽效果,我实际用的是/home/user/catkin_ws1/
中的move_base
,这正是我们常常的目的
环境变量中这样设置:1
2source /opt/ros/kinetic/setup.zsh
source /home/xiaoqiang/catkin_ws/devel/setup.zshROS_PACKAGE_PATH
结果是/home/xiaoqiang/catkin_ws/src:/opt/ros/kinetic/share
,也就是说后source的工作空间会排在ROS_PACKAGE_PATH
的靠前部分,也就是优先级高
source工作空间的顺序会影响链接的so文件
先source devel/setup.bash
,再source /opt/ros/melodic/setup.bash
,没有source install/setup.bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19# libmove_base.so 所链接的 libcostmap_2d.so 是deve/lib里的
user@user:~/catkin_ws/install/lib$ ldd libmove_base.so | grep user
libcostmap_2d.so => /home/user/my_ws/devel/lib/libcostmap_2d.so (0x00007f1d87062000)
user@user:~/catkin_ws/install/lib$ locate libcostmap_2d
# 有5个 libcostmap_2d.so
/home/user/catkin_ws/devel/lib/libcostmap_2d.so
/home/user/catkin_ws/install/lib/libcostmap_2d.so
/home/user/my_ws/devel/lib/libcostmap_2d.so
/home/user/my_ws/install/lib/libcostmap_2d.so
/opt/ros/melodic/lib/libcostmap_2d.so
# 删除 devel/lib/libcostmap_2d.so
user@user:~/catkin_ws/install/lib$ rm /home/user/my_ws/devel/lib/libcostmap_2d.so
# 此时就会链接到 ros 自带的 libcostmap_2d.so
# 如果ros自带的也被删除,就会链接失败,不去链接其他的 libcostmap_2d.so
user@user:~/catkin_ws/install/lib$ ldd libmove_base.so | grep cost
libcostmap_2d.so => /opt/ros/melodic/lib/libcostmap_2d.so (0x00007f15a177a000)
编译时寻找其他工作空间的包
很奇怪,我编译的工作空间已经有voxel_grid
,结果会去另一个工作空间找同名的包,但那个包已经被我删了,所以找不到,结果报错。
看catkin_make开头的信息,发现这里就涉及到了xju_ws
这个包了
发现build
文件夹里的几个文件涉及了xju_ws
,但是如果删除再编译,还是会生成一模一样的文件。
最后只有重建一个工作空间,执行catkin_init_workspace
,再编译,问题解决。