ROS之使用自定义msg

代码层级图

|- 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)#调用同一工作空间的自定义消息类型时注明依赖关系,防止发生头文件找不到的报错

 

完整工程参考

<think>嗯,用户想了解如何在ROS使用自定义消息类型进行话题通信。我之前整理过一些关于ROS话题通信的引用资料,现在需要结合这些资料来回答。 首先,根据引用[1],自定义msg的流程包括创建msg文件、配置package.xml和CMakeLists.txt,然后是编写发布方和订阅方的代码。引用[2]提到msg文件中可以使用Header类型,所以可能需要包含Header标头。引用[3]强调了发布方、接收方和数据(自定义消息)三个关键点,以及vscode的配置。 用户的问题需要分步骤的教程。应该先讲创建msg文件的步骤,包括在功能包下新建msg目录,编写msg文件的内容,比如加入Header和其他字段。接着是配置package.xml,添加对message_generation和message_runtime的依赖。然后配置CMakeLists.txt,添加msg文件,生成消息代码。 然后需要说明如何编写发布者和订阅者的Python代码,注意导入自定义的消息类型。同时要提醒用户可能遇到的路径问题,比如需要source devel/setup.bash,或者配置vscode的环境。这部分可以引用[3]提到的vscode配置注意事项。 最后,测试部分需要编译和运行节点,使用rostopic命令查看消息是否正确发布。可能还要提到常见错误,比如消息未生成导致导入失败,或者环境变量未设置正确。 生成的相关问题应该围绕步骤展开,比如如何定义复杂消息,如何处理依赖,以及调试方法。这样用户可以根据问题进一步深入学习。</think>### ROS自定义消息实现话题通信教程 #### 一、创建自定义消息 1. 在功能包目录下新建`msg`文件夹,创建`Person.msg`文件: ```msg Header header string name uint8 age float32 height ``` 注意:第一行的`Header`类型需要包含`std_msgs/Header`声明[^2] #### 二、配置编译规则 1. 修改`package.xml`添加依赖: ```xml <build_depend>message_generation</build_depend> <exec_depend>message_runtime</exec_depend> ``` 2. 修改`CMakeLists.txt`: ```cmake find_package(catkin REQUIRED COMPONENTS roscpp std_msgs message_generation ) add_message_files( FILES Person.msg ) generate_messages( DEPENDENCIES std_msgs ) catkin_package( CATKIN_DEPENDS message_runtime ) ``` #### 三、编写发布者节点(publisher.py) ```python #!/usr/bin/env python import rospy from std_msgs.msg import Header from your_pkg.msg import Person # 替换为实际包名 def talker(): pub = rospy.Publisher('person_info', Person, queue_size=10) rospy.init_node('person_publisher', anonymous=True) rate = rospy.Rate(1) # 1Hz while not rospy.is_shutdown(): msg = Person() msg.header.stamp = rospy.Time.now() msg.name = "Alice" msg.age = 25 msg.height = 1.68 pub.publish(msg) rate.sleep() if __name__ == '__main__': try: talker() except rospy.ROSInterruptException: pass ``` #### 四、编写订阅者节点(subscriber.py) ```python #!/usr/bin/env python import rospy from your_pkg.msg import Person # 替换为实际包名 def callback(data): rospy.loginfo(f"Received: {data.name}, Age: {data.age}, Height: {data.height}") def listener(): rospy.init_node('person_subscriber') rospy.Subscriber("person_info", Person, callback) rospy.spin() if __name__ == '__main__': listener() ``` #### 五、编译与测试 1. 执行编译: ```bash catkin_make source devel/setup.bash ``` 2. 运行测试: ```bash # 终端1 roscore # 终端2 rosrun your_pkg publisher.py # 终端3 rosrun your_pkg subscriber.py # 终端4 rostopic echo /person_info ``` #### 六、常见问题处理 1. **消息未生成**:检查`CMakeLists.txt`的`generate_messages()`是否配置正确 2. **导入失败**:确认已执行`source devel/setup.bash`[^3] 3. **字段不匹配**:修改msg文件后需要重新编译
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值