代码层级图

|- usbacn_ws
    |- build
    |- devel
    |- src
        |- CMakeLists.txt       
        |- usbcan_test
            |- include
                |- .h*
            |- lib
                |- .so*
            |- msg
                |- test.msg
            |- main.cpp
            |- CmakeLists.txt
            |- package.xml

 

步骤

1、新建功能包

首先创建一个空的package单独存放msg类型(当然也可以在任意的package中自定义msg类型) 这里为便于说明,建立一个名为usbcan_test的包,用于对自定义msg类型的用法举例

$ cd usbacn_ws/src
$ catkin_create_pkg usbcan_test

 

2、新建msg文件

usbcan_test中创建msg文件夹,在msg文件夹其中新建一个名为test.msg消息类型文件

$ cd usbcan_test
$ mkdir msg
$ gedit test.msg
# 内容如下:
std_msgs/Header header
int16 id
int16 len
int32[8] data

 

3、修改package.xml

需要message_generation生成C++或Python能使用的代码,即将将.msg文件编译生成.h文件,需要message_runtime提供运行时的支持,所以package.xml中添加以下两句(一般生成的文件中都有了,去注释就行)

<build_depend>message_generation</build_depend>
<run_depend>message_runtime</run_depend>
# 或者这一句
<exec_depend>message_runtime</exec_depend>

 

如果还要ros支持,同样去注释

<build_depend>roscpp</build_depend>
<exec_depend>roscpp</exec_depend>

 

4、修改CMakeLists.txt

这个CMakeLists.txt是功能包下的,有几点注意: (1) 首先调用find_package查找依赖的包,必备的有roscpp 、rospy 、message_generation,其他根据具体类型添加,比如上面的msg文件中用到了std_msgs/Header header类型,那么必须查找std_msgs

find_package(catkin REQUIRED COMPONENTS
   roscpp
   rospy
   std_msgs
   message_generation
)

 

(2) 然后是add_message_files,指定msg文件

add_message_files(
    FILES
    test.msg
)

 

(3) 然后是generate_messages,指定生成消息文件时的依赖项,比如上面嵌套了其他消息类型std_msgs,那么必须注明

# generate_messages必须在catkin_package前面
generate_messages(
    DEPENDENCIES
    std_msgs  
)

 

(4) 然后是catkin_package设置运行依赖

catkin_package(
#    INCLUDE_DIRS include
    LIBRARIES usbcan_test
    CATKIN_DEPENDS roscpp message_runtime
    DEPENDS system_lib
)

 

到这里新的msg类型usbcan_test/test就可以使用了,下面编译这个包,然后利用rosmsg show指令查看

$ cd catkin_ws
$ catkin_make
$ rosmsg show usbcan_test/test
std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
int16 id
int16 len
int32[8] data

 

5、调用自定义msg类型

如果是在usbcan_test包内的节点中调用usbcan_test/test类型,只需要在.cpp文件中如下调用即可

#include "usbcan_test/test.h"

usbcan_test::test msg;
// (usbcan_test文件夹)::(test.msg) (随便一个名称)

 

然后修改CMakeLists.txt

# add_executable(${PROJECT_NAME}_node src/usbcan_test_node.cpp)
add_executable(cantest /home/fu/usbcan_ws/src/usbcan_test/main.cpp)
# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
# 这个PROJECT_NAME就是你到时rosrun的节点名
add_dependencies(cantest ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

# 动态库依赖(如果需要的话)
target_link_libraries(cantest ${catkin_LIBRARIES}
    /usr/lib/libECanVci.so
    /usr/lib/libusb.so
    /usr/lib/libusb-1.0.so
)

 

因为还用到include文件夹里的头文件,所以CMakeLists.txt要去注释

include_directories(
    include
    ${catkin_INCLUDE_DIRS}
)

 

6、其他包调用自定义msg类型

如果是在其他包调用usbcan_test/test类型则需要修改package.xmlCMakeLists.txt,比如同样在工作空间usbacn_ws内有一个名为test的包,我们可以在这个包内写一个节点,使用我们刚才自定义的消息类型usbcan_test/test,如下: (1) 修改package.xml 养成好习惯,维护软件包清单的更新,以便于别人使用你的软件前安装各种依赖项,当然这个文件不影响程序编译

<build_depend>roscpp</build_depend>
<run_depend>roscpp</run_depend>

<build_depend>usbcan_test</build_depend>
<run_depend>usbcan_test</run_depend>

 

(2) 修改CMakeLists.txt调用自定义消息类型主要修改两个地方,以下是重点: 一是find_package中需要声明查找包含该消息类型的包; 二是add_dependencies要注明该消息的依赖,其他地方和普通节点一样

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  message_generation
  usbcan_test
)

add_dependencies(test1 usbcan_test_gencpp)#调用同一工作空间的自定义消息类型时注明依赖关系,防止发生头文件找不到的报错

 

完整工程参考