ROS系统基础知识梳理(二)节点通信

ros基础知识梳理(二)——节点通信

publisher and subscriber

ros节点之间的基础通信方式,不同节点之间分别饰演publisher和subscriber的角色,由publisher发布某话题的通信消息,各个订阅了该话题的subscriber接收发布者发布的数据,以此实现节点之间的通信。

publisher编写流程

  1. 初始化publisher节点。
  2. 创建ros节点句柄;创建的第一个句柄将初始化整个节点,删除的最后一个句柄将释放节点所占用的所有资源。
  3. 通知topic master话题管理器,该节点将要发布话题的名称,数据类型,以及缓区大小,未来及被接受的数据将被自动抛弃。
  4. 调用rate函数,设置节点消息的发布频率。
  5. 进入发布话题消息循环,发布数据。
  6. 调用sleep函数实现对发布频率的把控。

subscriber编写流程

  1. 初始化subscriber节点。
  2. 创建ros节点句柄。
  3. 在topic master上订阅需要的topic,当有消息发布时,执行相应的回调函数。
#例程
# publisher.py
import rospy
from std_msgs.msg import String

def talker():
    rospy.init_node('publisher', anonymous=True)
    pub = rospy.Publisher('chatter', String, queue_size=10)
    rate = rospy.Rate(10) # 10hz
    while not rospy.is_shutdown():
        hello_str = "hello world %s" % rospy.get_time()
        rospy.loginfo(hello_str)
        pub.publish(hello_str)
        rate.sleep()

if __name__ == '__main__':
    try:
        talker()
    except rospy.ROSInterruptException:
        pass

#subscriber.py
import rospy
from std_msgs.msg import String

def callback(data):
    rospy.loginfo(rospy.get_caller_id() + 'I heard %s', data.data)

def subscriber():
    rospy.init_node('subscriber', anonymous=True)

    rospy.Subscriber('chatter', String, callback)

    rospy.spin()

if __name__ == '__main__':
    subscriber()

service and client

在使用service和client通信时,应先定义参数及返回值类型,并编写相应的msg和srv文件。

service 编写流程

  1. 编写服务函数,函数内容为该服务所提供的功能。
  2. 主函数,初始化节点。
  3. 建立节点句柄。
  4. 在ros内发布服务,等待其他节点调用。

client 编写流程

  1. 初始化节点,并创建节点句柄。
  2. 为调用的service创建client对象,用于调用srv函数。
  3. 按照srv格式整理好要处理的数据,并调用srv函数,存储好返回结果。

注:service调用过程为模态过程,在调用时会阻断其他代码的执行,调用完成,client.call将返回True,反之则返回False。

//例程
//service

 #include "ros/ros.h"
 #include "beginner_tutorials/AddTwoInts.h"
 
 bool add(beginner_tutorials::AddTwoInts::Request  &req,
          beginner_tutorials::AddTwoInts::Response &res)
 {
   res.sum = req.a + req.b;
   ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
   ROS_INFO("sending back response: [%ld]", (long int)res.sum);
   return true;
 }
 
 int main(int argc, char **argv)
 {
   ros::init(argc, argv, "add_two_ints_server");
   ros::NodeHandle n;
 
   ros::ServiceServer service = n.advertiseService("add_two_ints", add);
   ROS_INFO("Ready to add two ints.");
   ros::spin();
 
   return 0;
 }

//client

#include "ros/ros.h"
 #include "beginner_tutorials/AddTwoInts.h"
 #include <cstdlib>
 
 int main(int argc, char **argv)
 {
   ros::init(argc, argv, "add_two_ints_client");
   if (argc != 3)
   {
     ROS_INFO("usage: add_two_ints_client X Y");
     return 1;
   }
 
   ros::NodeHandle n;
   ros::ServiceClient client = n.serviceClient<beginner_tutorials::AddTwoInts>("add_two_ints");
   beginner_tutorials::AddTwoInts srv;
   srv.request.a = atoll(argv[1]);
   srv.request.b = atoll(argv[2]);
   if (client.call(srv))
   {
     ROS_INFO("Sum: %ld", (long int)srv.response.sum);
   }
   else
   {
     ROS_ERROR("Failed to call service add_two_ints");
     return 1;
   }
 
   return 0;
 }

通信过程中的函数解析(c++)

  1. n.advertise<>()函数
      例句:ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
      n–句柄名称,advertise<topic_message_type>()函数接受两个参数,第一个参数为要发布的topic名称,第二个参数为设置缓冲区的大小。<>内部为topic发布的数据类型。
      advertise()函数将会告知topic master要发布的话题名称。调用advertise()函数后,master node将master node将通知订阅该话题的subscriber,然后进行数据传输。
      advertise()返回一个Publisher的对象,调用该对象可以再此topic上发布消息。
  2. ros::Rate loop_rate(int)函数
      ros::Rate类可定制频率的函数,接受一个int型参数,通过调用主函数末尾的上来sleep()函数,将该参数置为发布频率。
  3. pub.publish(msg)函数
       publisher类的成员函数,接受一个消息对象的引用,利用此函数可以将消息对象msg里面的内容发布出去,消息对象msg的类型要和advertise<topic_message_type>()函数中标定的消息类型相一致。
  4. ros::Rate sleep()函数
      与loop_rate()函数成套使用,使程序能按照设定的频率发布数据。
  5. n.subscriber()函数
      例句:ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
      设置subscriber函数,该函数为一个topic生成subscriber,函数接受三个参数,第一个参数设置为订阅话题的名称,第二个参数为接受缓冲区的大小,第三个参数为接收到函数后需操作的调用函数。
  6. "beginner_tutorials/AddTwoInts.h"头文件
      该头文件在设置srv文件时由ros自动生成,头文件原型为<package_name>/<file_name>.h,头文件内定义了该service接收的每个参数的类型以及服务返回值的类型。
  7. n.advertiseService()函数
      例句:ros::ServiceServer service = n.advertiseService("add_two_ints", add);
      设置service函数,该函数将会在ros系统中生成一个service,函数接受两个参数,第一个参数将被设置为service的名称,第二个参数作为该service功能执行函数,供相应的client节点调用。
  8. n.serviceClient()函数
      例句:ros::ServiceClient client = n.serviceClient<beginner_tutorials::AddTwoInts>("add_two_ints");
      设置client函数,该函数将在ros中生成一个client,该函数接受一个服务名作为参数,向ros指明client要调用的服务。
  9. ros::ok()函数
      该函数会设置一个SIGINT监听,函数返回True,仅当以下四种情况发生时,该函数返回False:
       1. SIGINT被触发(Ctrl+c)
       2.被另一同名节点踢出
       3.函数ros::shutdown()被程序另一部分调用
       4.程序所有句柄被销毁
  10. ros::spin(),ros::spinOnce()函数
      ros回调程序,spin()不会执行原程序,spinOnce()会继续执行原程序
  • 3
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Ubuntu中,ROS(机器人操作系统)是一个常用的开源框架,用于构建机器人软件和控制系统。以下是一些Ubuntu中ROS相关的基础知识: 1. ROS版本:在Ubuntu 18.04中,对应的ROS版本是melodic。确保你安装的ROS版本与你的Ubuntu版本相匹配,以避免出现错误。\[2\] 2. 安装ROS:在Ubuntu中安装ROS可以按照以下步骤进行: - 设置系统软件源和ROS源 - 添加ROS的keys - 安装ROS - 初始化ROS - 配置ROS系统环境 - 进行ROS测试\[1\] 3. 基本概念:ROS中有一些基本概念需要了解,例如: - roscore:ROS的核心功能,用于管理ROS节点之间的通信。 - rosnodelist:用于查看当前运行的ROS节点列表。 - rostopic:用于查看和发布ROS主题(topic)的信息。 - rosrun:用于运行ROS节点。 - rqt_graph:用于可视化ROS节点和主题之间的关系图。 - rosbag:用于记录和回放ROS主题的数据。 - 等等\[1\] 这些是Ubuntu中ROS相关的一些基础知识,希望对你有所帮助。如果你有更具体的问题,请告诉我。 #### 引用[.reference_title] - *1* *2* [Ubuntu18.04 ROS](https://blog.csdn.net/weixin_43563233/article/details/109746851)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [ROS学习笔记01、安装Ubuntu18.04以及ROS环境](https://blog.csdn.net/cl939974883/article/details/126306805)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值