• 【ROS】服务通信、话题通信的应用


    在这里插入图片描述

    Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法…感兴趣就关注我吧!你定不会失望。


    在这里插入图片描述

    本章将来学习如何利用话题通信,服务通信两种种方式对turtlesim进行一个控制

    0. 话题发布

    利用话题通信发布一个位姿信息,让乌龟一直做圆周运动

    首先,先启动 turtlesim这个节点
    在这里插入图片描述

    rosrun turtlesim    turtlesim_node
    rosrun turtlesim turtle_teleop_key
    
    • 1
    • 2

    现在可以直接使用键盘来控制乌龟运动了
    我们在另一个窗口查看下当前节点关系

    rqt_graph
    
    • 1

    在这里插入图片描述

    键盘节点通过 turtle1/cmd_vel这个话题向turtlesim发送速度控制消息,我们查看一下这个话题所使用的消息类型,方便进行下一步的修改

    rostopic info /turtle1/cmd_vel
    
    • 1

    可以得到该话题的消息类型为 geometry_msgs/Twist
    查看下该消息类型具体有什么参数

    rosmsg show geometry_msgs/Twist
    
    • 1

    其具有两类参数 linear、angular分别为角速度与线速度,对应xyz上的值
    请添加图片描述

    因为乌龟是一个2d的,所以linear中z值为0,而angular中只有z值是有效的,其余都为0

    geometry_msgs/Vector3 linear
      float64 x
      float64 y
      float64 z
    geometry_msgs/Vector3 angular
      float64 x
      float64 y
      float64 z
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    知道了乌龟的消息类型与控制节点我们可以直接使用命令来控制乌龟的运动

    rostopic pub /turtle1/cmd_ geometry_msgs/Twist "linear:
      x: 0.0
      y: 0.0
      z: 0.0
    angular:
      x: 0.0
      y: 0.0
      z: 0.0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    当然我们不想要这样,还可以通过python代码的方式来实现这段功能

    import rospy
    
    from geometry_msgs.msg import Twist
    
    rospy.init_node("twist_pub")
    
    pub=rospy.Publisher("/turtle1/cmd_vel",Twist,
    
    queue_size=10)
    
    rate=rospy.Rate(10)
    
    twist=Twist()
    
    twist.linear.x=1
    
    twist.angular.z=1
    
    while not rospy.is_shutdown():
    
        pub.publish(twist)
    
        rate.sleep()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    这段代码创建了一个节点 twist_pub,实例化消息对象为twist,将其中的值设置后调用pub.publish发出即可。与之前所讲的没有什么差别。
    引用msg消息时格式为:主消息包.msg/Twist
    接下来,乌龟就会进行一个圆周运动。

    1.话题订阅

    实时订阅乌龟的位姿信息
    先查看下当前话题下有什么话题与这个功能相关

    rostopic list
    
    • 1

    会找到一个这样的话题 turtle1/pose,很明显,其就为发布乌龟位姿的话题。
    我们可以直接订阅来看看

    rostopic echo /turtle1/pose
    
    • 1

    就会在屏幕上显示出来乌龟的实时位姿。 说明我们找的方向是没有错的

    接下来就是看看他的消息类型与消息内容了

    rostopic info /turtle1/pose 
    
    • 1

    其消息类型为:turtlesim/Pose

    rosmsg show turtlesim/Pose
    
    • 1

    其由五个数据组成

    float32 x
    float32 y
    float32 theta
    float32 linear_velocity
    float32 angular_velocity
    
    • 1
    • 2
    • 3
    • 4
    • 5

    接下来就是编写接收方节点即可

    import rospy
    
    from turtlesim.msg import Pose
    
    def doMsg(msg):
    
        rate.sleep()
    
        rospy.loginfo("乌龟x:%fm乌龟y:%f,乌龟角度:%f,乌龟线速度:%f,乌龟角速度:%f",msg.x,msg.y,msg.theta,msg.linear_velocity,msg.angular_velocity)
    
    rospy.init_node("sub_turtle")
    
    sub=rospy.Subscriber("turtle1/pose",Pose,
    queue_size=10,callback=doMsg)
    
    rate=rospy.Rate(1)
    
    rospy.spin()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2.服务调用

    利用代码生成新的乌龟
    首先先查看下当前的服务列表。

    rosservice list
    
    • 1

    会出现一个 /spawn 的节点其中文翻译为产卵,所以很明显就是我们需要的service

    利用

    rosservice type /spawn
    
    • 1

    查看下其srv类型 为: turtlesim/Spawn
    在查看下具体参数

    rossrv show turtlesim/Spawn
    
    • 1

    传入参数为坐标与名字,服务器返回值为名字

    float32 x
    float32 y
    float32 theta
    string name
    ---
    string name
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    我们直接进行调用试试

    rosservice call /spawn "x: 0.0 
    y: 4.0
    theta: 0.0
    name: 'dsa'" 
    name: "dsa"
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    成功出现了新的一只小乌龟
    在这里插入图片描述

    接下来看看代码如何编写

    import rospy
    
    from turtlesim.srv import *
    
    rospy.init_node("tospawn")
    
    client=rospy.ServiceProxy("/spawn",Spawn)
    
    request=SpawnRequest()
    
    request.x=5
    
    request.y=4
    
    request.theta=50
    
    request.name="dfg"
    
    #client.wait_for_service()
    rospy.wait_for_service("spawn")
    
    try:
        response=client.call(request)
    
        rospy.loginfo("乌龟的名字%s",response.name)
    
    except:
    
        rospy.loginfo("异常")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    3.话题通信与服务通信的比较

    1. Topic:多对多,异步,适用于连续高频发布消息与接受:雷达等

    2. Service: 一(service)对多,同步,适用于偶尔调用的某一特定功能:拍照等

  • 相关阅读:
    二分查找常见需求(持续更新中)
    内存寻址方式
    pytorch梯度累积
    【回归预测-LSTM预测】基于布谷鸟算法优化LSTM实现数据回归预测含Matlab代码
    使用CompletableFuture多线程异步任务优化查询接口性能
    令人愉快的 Nuxt3 教程 (一): 应用的创建与配置
    【Android】UI布局之布局(帧布局、表格布局)
    字符串-模板编译
    C# WPF入门学习主线篇(三十)—— MVVM(Model-View-ViewModel)模式
    SQL使用场景解决一对多查询、分页、复杂排名等问题之ROW_NUMBER、DENSE_RANK、RANK用法
  • 原文地址:https://blog.csdn.net/qq_62839589/article/details/130912978