ROS通信机制(一)--话题通信

话题通信

话题通信是基于发布订阅模式的,即一个节点发布消息,另一个节点订阅该消息。
流程:编写发布方实现–编写订阅方实现–(用python实现时,为python文件编写可执行权限)–编写配置文件–编译执行

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

前期准备工作:创建一个ROS功能包–vscode中编译ros(修改.vscode/tasks.json 文件)
src目录下创建ros功能包、设置包名、添加依赖

话题发布

  1. C++实现
    –>在ros功能包下的src目录新建demo01_pub.cpp文件(必要时修改 .vscode/c_cpp_properties.json文件)
    发布者C++代码如下:
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>
/*
    发布方实现:
        1.包含头文件
        ROS中文本类型 -->std_msgs/String.h
        2.初始化ros节点
        3.创建节点句柄;
        4.创建发布者对象
        5.编写发布逻辑并发布数据
*/
int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");  //防止中文乱码
    //初始化ROS节点;
    ros::init(argc,argv,"ergouzi");
    //创建节点句柄;
    ros::NodeHandle nh;
    //创建发布者对象;
    ros::Publisher pub = nh.advertise<std_msgs::String>("fang",10);
    //编写发布逻辑并发布数据
    //要求以 10Hz 的频率发布数据,并且文本后添加编号
    //先创建被发布的消息
    std_msgs::String msg;
    //发布频率
    ros::Rate rate(10);
    //设置编号
    int count = 0;
    //编写循环,循环中发布数据
    while (ros::ok())
    {
        count++;
        //实现字符串拼接数字
        std::stringstream ss;
        ss << "hello --> " << count;
        //msg.data = "hello";
        msg.data = ss.str();

        pub.publish(msg);
        //添加日志;
        ROS_INFO("发布的数据是:%s",ss.str().c_str());
        rate.sleep();
    }
    return 0;
}

修改Cmakelist.txt文件并编译执行
执行:启动roscore
rosrun plumbing_pub_sub demo01_pub
发布话题完毕
2. Python实现

话题订阅

  1. C++实现

–>在ros功能包下的src目录新建demo02_sub.cpp文件(必要时修改 .vscode/c_cpp_properties.json文件)
订阅者C++代码如下:

#include "ros/ros.h"
#include "std_msgs/String.h"
/*
    发布方实现:
        1.包含头文件
        ROS中文本类型 -->std_msgs/String.h
        2.初始化ros节点
        3.创建节点句柄;
        4.创建订阅者对象
        5.处理订阅的数据
        6.声明一个spin()函数
*/ 
void doMsg(const std_msgs::String::ConstPtr &msg){
    //通过msg获取并操作订阅到的数据
    ROS_INFO("翠花订阅到的数据:%s",msg->data.c_str());
}
int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");
    //初始化ros节点
    ros::init(argc,argv,"cuihua");
    //创建节点句柄;
    ros::NodeHandle nh;
    //创建订阅者对象
    ros::Subscriber sub = nh.subscribe("fang",10,doMsg); 
    //处理订阅的数据

    ros::spin();

    return 0;
}

配置CMakeList.txt文件
ROS通信机制(一)--话题通信
执行:启动roscore
rosrun plumbing_pub_sub demo02_sub
话题订阅发布结果如下:
ROS通信机制(一)--话题通信

  1. Python实现
  • 1.在功能包下新建scripts文件夹,新建文件demo01_pub_p.py
    发布方代码
#! /usr/bin/env python
#1.导包 
import rospy
from std_msgs.msg import String

if __name__ == "__main__":
    #2.初始化ROS节点:命名(唯一)
    rospy.init_node("santai")
    #3.实例化发布者对象
    pub = rospy.Publisher("che",String,queue_size=10)
    #4.组织被发布的数据,并编写逻辑发布数据
    msg = String()  #创建 msg 对象
    msg_front = "hello"
    count = 0  #计数器 
    # 设置循环频率
rate = rospy.Rate(10)
rospy.sleep(3)
while not rospy.is_shutdown():
        count += 1
        #拼接字符串
        msg.data = msg_front + str(count)
        pub.publish(msg)
        rospy.loginfo("写出的数据:%s",msg.data)
        rate.sleep()
  • 2.在scripts目录下新建demo02_sub_p.py
    订阅方实现:
#! /usr/bin/env python
#1.导包 
import rospy
from std_msgs.msg import String
def doMsg(msg):
    rospy.loginfo("I heard:%s",msg.data)

if __name__ == "__main__":
    #2.初始化 ROS 节点:命名(唯一)
    rospy.init_node("huahua")
    #3.实例化订阅者对象
    sub = rospy.Subscriber("che",String,doMsg,queue_size=10)
    #4.处理订阅的消息(回调函数)
    #5.设置循环调用回调函数
   rospy.spin()
  • 3.为python代码添加可执行权限
chmod +x *.py
ll
  • 4.编译执行
    启动roscore
    启动发布节点:
source ./devel/setup.bash
rosrun plumbing_pub_sub demo01_pub_p.py

启动订阅节点:

source ./devel/setup.bash
rosrun plumbing_pub_sub demo02_sub_p.py

注:订阅者不能完全订阅发布者消息,解决办法:对发布代码加一行:rospy.sleep(3),休眠3秒钟

上一篇:配置ssh免密登录


下一篇:tornado中的协程是如何工作的