ROS Service的使用_Python

ROS Service的使用_Python

  • ROS Service的使用_Python
    • Ros的Service和Topic
    • Python Server
    • Python Client

Ros的Service和Topic

二者都是ROS中节点间进行通信的方法。Topic采用的是广播/订阅的模式,没有反馈值,也就是发送的节点不知道谁会接收或者接收到没有。Service则采用request/response的模式,即客户端发送request,服务端处理request并给出response,客户端继而接收到response,这种方式可以实现客户端的阻塞,也能保证消息通信的反馈。

Python Server

ROS Service 官方python教程

#!/usr/bin/env python
#-*- coding:utf-8 -*-
############################
#File Name: server.py
#Author: Wang
#Mail: [email protected]
#Created Time:2017-09-25 15:17:38
############################

import rospy
from std_srvs.srv import *

def fun1(req):
    print "%s"%req.data
    return [True, "dsdf"]

def main():
    rospy.init_node('server_test', anonymous = True)
    rospy.Service('test', SetBool, fun1)
    rospy.spin()

if __name__ == '__main__':
    main()

这里有几点需要说明:
1. 使用Service时必须要有对应的srv文件描述request/response。以SetBool.srv文件为例,其源码位于/opt/ros/kinetic/share/std_srvs/srv/SetBool.srv,所以在导入时需要用:

from std_srvs.srv import *  #or
from std_srvs.srv import SetBool

注意这里的std_srvs.srv实际上是两层文件夹的名字,而import里面的内容不需要带.srv。这个规则在导入Ros各种msg的时候也被广泛的用到。
2. 再看srv文件的源码:

bool data # e.g. for hardware enabling / disabling
---
bool success   # indicate successful run of triggered service
string message # informational, e.g. for error messages

中间的- - -用于隔开srv文件,上面部分是request部分,下面部分是response部分。
3. 启动一个rosnode后可以添加很多Service,每个service中指明回调函数。
4. 回调函数中传入参数是srv文件的request部分,返回的是response部分,这里的return [True, “dsdf”]就是对应response部分的success和message。这个地方我试了很久。
测试service:

rosservice call /test "data: false"
#feedback:
    #success: True
    #message: dsdf

Python Client

#!/usr/bin/env python
#-*- coding:utf-8 -*-
############################
#File Name: client.py
#Author: Wang
#Mail: [email protected]
#Created Time:2017-09-25 18:25:25
############################

import rospy
from std_srvs.srv import SetBool

def main():
    rospy.wait_for_service('test')
    try:
        val = rospy.ServiceProxy('test', SetBool)
    resp1 = val(False)
        print resp1.success, resp1.message
    except rospy.ServiceException, e:
        print e

if __name__ == "__main__":
    main()

#feedback:
    #True dsdf

这里需要说明:
1. client不需要单独创建ros节点,这和publisher/subscriber的模式不同。
2. client的request变量内容通过Proxy的参数直接发给server,见代码。

c++版的和Python大同小异,有机会后续再补充。

你可能感兴趣的:(python,ros)