ROS话题通信案例(三)——自定义消息msg(c++和python)

参考视频:【奥特学园】ROS机器人入门课程《ROS理论与实践》零基础教程_哔哩哔哩_bilibili

参考文档:http://www.autolabor.com.cn/book/ROSTutorials/

需求:

  创建自定义消息,该消息包含人的信息:姓名、身高、年龄等。

流程:

  1. 按照固定格式创建 msg 文件
  2. 编辑配置文件
  3. 编译生成可以被 Python 或 C++ 调用的中间文件

1.定义msg文件

功能包下新建 msg 目录,添加文件 Person.msg

string name
uint16 age
float64 height

2.编辑配置文件

package.xml中添加编译依赖与执行依赖

  <build_depend>message_generation</build_depend>
  <exec_depend>message_runtime</exec_depend>
  <!-- 
  exce_depend 以前对应的是 run_depend 现在非法
  -->

CMakeLists.txt编辑 msg 相关配置

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)
# 需要加入 message_generation,必须有 std_msgs

## 配置 msg 源文件
add_message_files(
  FILES
  Person.msg
)

# 生成消息时依赖于 std_msgs
generate_messages(
  DEPENDENCIES
  std_msgs
)

#执行时依赖
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES demo02_talker_listener
  CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
#  DEPENDS system_lib
)

 

 

3.编译

编译后的中间文件查看:

C++ 需要调用的中间文件(.../工作空间/devel/include/包名/xxx.h)

Python 需要调用的中间文件(.../工作空间/devel/lib/python3/dist-packages/包名/msg)


 

C++实现

需求:

编写发布订阅实现,要求发布方以10HZ(每秒10次)的频率发布自定义消息,订阅方订阅自定义消息并将消息内容打印输出。

分析:

在模型实现中,ROS master 不需要实现,而连接的建立也已经被封装了,需要关注的关键点有三个:

  1. 发布方
  2. 接收方
  3. 数据(此处为自定义消息)

流程:

  1. 编写发布方实现;
  2. 编写订阅方实现;
  3. 编辑配置文件;
  4. 编译并执行

0.vscode 配置

为了方便代码提示以及避免误抛异常,需要先配置 vscode,将前面生成的 head 文件路径配置进 c_cpp_properties.json 的 includepath属性

"/xxx/yyy工作空间/devel/include/**" //配置 head 文件的路径 

1.发布方

#include "ros/ros.h"
#include "plumbing_pub_sub/Person.h"
/*
    发布者:发布人的消息
        1.包含头文件;
        2.初始化ROS节点
        3.创建节点句柄
        4.创建发布者对象
        5.编写发布者逻辑,发布数据。
*/
int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");
    ROS_INFO("这是消息发布方");
    // 2.初始化ROS节点
    ros::init(argc,argv,"banZhuanRen");
    // 3.创建节点句柄
    ros::NodeHandle nh;
    // 4.创建发布者对象
    ros::Publisher pub = nh.advertise<plumbing_pub_sub::Person>("Chat",10);
    // 5.编写发布者逻辑,发布数据。
    //5.1.被发布的数据
    plumbing_pub_sub::Person person;
    person.name = "张三";
    person.age = 1;
    person.height = 1.73;
    //5.2.设置发布的频率
    ros::Rate rate(1);
    //5.3.循环发布数据
    while (ros::ok())
    {
        //修改数据
        person.age += 1;
        //核心:数据发布
        pub.publish(person);
        ROS_INFO("发布的消息:%s,%d,%.2f",person.name.c_str(),person.age,person.height);
        //休眠
        rate.sleep();
        //建议
        ros::spinOnce();

    }
    return 0;
}
    

配置

执行

2.订阅方

#include "ros/ros.h"
#include "plumbing_pub_sub/Person.h"

/*
    订阅方:订阅消息
        1.包含头文件;
            #include "plumbing_pub_sub/Person.h"
        2.初始化ROS节点
        3.创建节点句柄
        4.创建订阅者对象
        5.处理订阅的数据
        6.调用spin()函数
*/
void doPerson (const plumbing_pub_sub::Person::ConstPtr& person){
    ROS_INFO("订阅人的信息:%s,%d,%.2f",person->name.c_str(),person->age,person->height);
}
int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");
    ROS_INFO("订阅方实现");
    // 2.初始化ROS节点
    ros::init(argc,argv,"jiaZhang");
    // 3.创建节点句柄
    ros::NodeHandle nh;
    // 4.创建订阅者对象
    ros::Subscriber sub = nh.subscribe("Chat",10,doPerson);
    // 5.处理订阅的数据
    // 6.调用spin()函数
    ros::spin();
    return 0;
}

配置

执行

 


python 实现

0.vscode配置

将自定义 msg 所在的文件夹配置进 settings.json

1.发布方

在 scripts 下新建 demo03_pub_person_p.py

#! /usr/bin/env python

import rospy
from plumbing_pub_sub.msg import Person
'''
    发布方:发布人的消息
        1.导包;
        2.初始化ROS节点;
        3.创建发布者对象;
        4.组织发布逻辑并发布数据。

'''

if __name__ == "__main__":
    # 2.初始化ROS节点;
    rospy.init_node("daMa")
    # 3.创建发布者对象;
    pub = rospy.Publisher("jiaoSheTou",Person,queue_size=10)
    # 4.组织发布逻辑并发布数据。
    # 4.1.创建 Person 数据
    p = Person()
    p.name = "奥特曼"
    p.age = 8
    p.height = 1.85
    # 4.2.创建 Rate 对象
    rate = rospy.Rate(1)
    # 4.3.循环发布数据
    while not rospy.is_shutdown():
        pub.publish(p)
        rospy.loginfo("发布的消息:%s,%d,%.2f",p.name,p.age,p.height)
        rate.sleep()

2.权限设置

给 py 文件增加可执行权限

cys@ubuntu:~/demo03_ws/src/plumbing_pub_sub/scripts$ chmod +x *.py

3.配置 CMakeLists.txt

更改 CMakeLists.txt 中的配置

 4.命令行测试

cys@ubuntu:~/demo03_ws$ source ./devel/setup.bash
cys@ubuntu:~/demo03_ws$ rosrun plumbing_pub_sub demo03_pub_person_p.py

cys@ubuntu:~/demo03_ws$ source ./devel/setup.bash
cys@ubuntu:~/demo03_ws$ rostopic echo jiaoSheTou

5.订阅方

 在 scripts 下新建 demo04_sub_person_p.py

#! /usr/bin/env python

import rospy
from plumbing_pub_sub.msg import Person
'''
    订阅方:订阅人的消息
        1.导包;
        2.初始化ROS节点;
        3.创建订阅者对象;
        4.处理订阅的数据;
        5.spin()。

'''
def doPerson(p):
    rospy.loginfo("小伙子的数据:%s,%d,%.2f",p.name,p.age,p.height)

if __name__ == "__main__":
    # 2.初始化ROS节点;
    rospy.init_node("daYe")
    # 3.创建订阅者对象;
    sub = rospy.Subscriber("jiaoSheTou",Person,doPerson)
    # 4.处理订阅的数据;
    # 5.spin()。
    rospy.spin()

修改权限和配置

 6.运行

启动发布方

启动订阅方

cys@ubuntu:~/demo03_ws$ source ./devel/setup.bash
cys@ubuntu:~/demo03_ws$ rosrun plumbing_pub_sub demo04_sub_person_p.py 

 7.绘制计算图

cys@ubuntu:~$ rqt_graph 

 

posted on 2021-07-13 19:35  蔡军帅  阅读(3484)  评论(0编辑  收藏  举报