Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法…感兴趣就关注我吧!你定不会失望。
服务通信、话题通信的应用
本章将来学习如何利用话题通信,服务通信两种种方式对turtlesim进行一个控制
0. 话题发布
利用话题通信发布一个位姿信息,让乌龟一直做圆周运动
首先,先启动 turtlesim这个节点
rosrun turtlesim turtlesim_node rosrun turtlesim turtle_teleop_key
现在可以直接使用键盘来控制乌龟运动了
我们在另一个窗口查看下当前节点关系
rqt_graph
键盘节点通过 turtle1/cmd_vel这个话题向turtlesim发送速度控制消息,我们查看一下这个话题所使用的消息类型,方便进行下一步的修改
rostopic info /turtle1/cmd_vel
可以得到该话题的消息类型为 geometry_msgs/Twist
查看下该消息类型具体有什么参数
rosmsg show geometry_msgs/Twist
其具有两类参数 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
知道了乌龟的消息类型与控制节点我们可以直接使用命令来控制乌龟的运动
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
当然我们不想要这样,还可以通过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()
这段代码创建了一个节点 twist_pub,实例化消息对象为twist,将其中的值设置后调用pub.publish发出即可。与之前所讲的没有什么差别。
引用msg消息时格式为:主消息包.msg/Twist
接下来,乌龟就会进行一个圆周运动。
1.话题订阅
实时订阅乌龟的位姿信息
先查看下当前话题下有什么话题与这个功能相关
rostopic list
会找到一个这样的话题 turtle1/pose,很明显,其就为发布乌龟位姿的话题。
我们可以直接订阅来看看
rostopic echo /turtle1/pose
就会在屏幕上显示出来乌龟的实时位姿。 说明我们找的方向是没有错的
接下来就是看看他的消息类型与消息内容了
rostopic info /turtle1/pose
其消息类型为:turtlesim/Pose
rosmsg show turtlesim/Pose
其由五个数据组成
float32 x float32 y float32 theta float32 linear_velocity float32 angular_velocity
接下来就是编写接收方节点即可
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()
2.服务调用
利用代码生成新的乌龟
首先先查看下当前的服务列表。
rosservice list
会出现一个 /spawn 的节点其中文翻译为产卵,所以很明显就是我们需要的service
利用
rosservice type /spawn
查看下其srv类型 为: turtlesim/Spawn
在查看下具体参数
rossrv show turtlesim/Spawn
传入参数为坐标与名字,服务器返回值为名字
float32 x float32 y float32 theta string name --- string name
我们直接进行调用试试
rosservice call /spawn "x: 0.0 y: 4.0 theta: 0.0 name: 'dsa'" name: "dsa"
成功出现了新的一只小乌龟
接下来看看代码如何编写
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("异常")
3.话题通信与服务通信的比较
1.Topic:多对多,异步,适用于连续高频发布消息与接受:雷达等
2.Service: 一(service)对多,同步,适用于偶尔调用的某一特定功能:拍照等