ros services client
services vs actions vs topic
topic 因为话题对整个ros系统可见,当某种信息流需要总是能被其他节点获知,那么可以将其发布到话题中去
services: 服务是一种同步消息处理机制,只有当services中结果处理完毕返回值之后才会继续执行下面的程序。
actions: 是一种异步处理机制。就好比开了另外一个线程,我们可以将一个任务放到actions中去,在执行该任务的同时可以继续执行其他任务。
可见,当需要串行处理时使用services,可以并行处理时使用actions.
例子1
我们启动一个机械臂仿真环境
roslaunch iri_wam_aff_demo start_demo.launch
这个launch文件如下:
<launch>
<include file="$(find iri_wam_reproduce_trajectory)/launch/start_service.launch"/>
<node pkg ="iri_wam_aff_demo"
type="iri_wam_aff_demo_node"
name="iri_wam_aff_demo"
output="screen">
</node>
</launch>
可以看到其中包含了一个launch文件引用,也就是说我们可以使用include
标签实现一个launch文件启动多个节点。
接下来主要考察rosservice的使用方法及service类型数据结构。
使用命令查看service消息信息:
user ~ $ rosservice info /execute_trajectory
Node: /iri_wam_reproduce_trajectory
URI: rosrpc://ip-172-31-17-169:35175
Type: iri_wam_reproduce_trajectory/ExecTraj
Args: file
可以看出service也是依附于某一个节点的,具有URI和Args两个有意思的属性值。URI用于确定service的发出地址,Args是该项service所需要的参数。
需要注意的是,service虽然也有type类型,并且看上去跟msg挺像,但是并不是msg,也就是说使用rosmsg show
是看不到具体结构的,这是因为service的type对应的是srv文件(service缩写)。srv文件跟msg文件都被放在xxx_msgs包中,因为他两的结构与功能确实很像。
查看service的type文件使用如下命令:
user:~$ rossrv show DeleteModel
[gazebo_msgs/DeleteModel]:
string model_name
---
bool success
string status_message
srv文件的结构如下:
REQUEST
---
RESPONSE
#example
string model_name
---
bool success
string status_message
REQUEST
是service所需要的传入参数,RESPONSE
为返回参数
例子2:删除仿真环境中模型
使用如下命令可以删除环境中模型
rosservice call /gazebo/delete_model [TAB]+[TAB]
其中[TAB]+[TAB]
意思是可以通过短暂时间内双击自动补全可输入参数名称。
要删除环境中物体首先需要知道环境中都有那些物体,这通过如下命令实现:
rostopic echo /gazebo/model_states -n1
说白了就是输出一次模型状态topic的值,这样返回来一个字典,关键子name对应的list中就是环境中物体的名字。要删除哪个敲入哪个就可以。
那如何使用脚本删除物体呢?
#! /usr/bin/env python
import rospy
from gazebo_msgs.srv import DeleteModel, DeleteModelRequest # Import the service message used by the service /gazebo/delete_model
import sys
rospy.init_node('service_client') # Initialise a ROS node with the name service_client
rospy.wait_for_service('/gazebo/delete_model') # Wait for the service client /gazebo/delete_model to be running
delete_model_service = rospy.ServiceProxy('/gazebo/delete_model', DeleteModel) # Create the connection to the service
kk = DeleteModelRequest() # Create an object of type DeleteModelRequest
kk.model_name = "bowl_1" # Fill the variable model_name of this object with the desired value
result = delete_model_service(kk) # Send through the connection the name of the object to be deleted by the service
print result # Print the result given by the service called
其返回结果如下
s