Service Node 教程中的例子,server接收两个整数,求和并返回。在这之前需要创建srv消息类型, 参考工具使用-ROS中创建和配置msg及srv
1 2 roscd beginner_tutorials/srv vim AddTwoInts.srv
消息内容定义
1 2 3 4 int64 a int64 b --- int64 sum
然后定义services
1 2 roscd beginner_tutorials/scripts vim add_two_ints_server.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import rospyfrom beginner_tutorials.srv import AddTwoIntsdef handle_add_two_ints (req) : print("Returning [%s + %s = %s]" %(req.a, req.b, (req.a+req.b))) return AddTwoIntsResponse(req.a + req.b) def add_two_ints_server () : rospy.init_node("add_two_ints_server" , anonymous=True ) s = rospy.Service('add_two_ints' , AddTwoInts, handle_add_two_ints) print("Ready to add two ints" ) rospy.spin() if __name__ == '__main__' : add_two_ints_server()
Client 由于请求-响应
server是一直等待请求的,但是client并不需要循环请求,所以client可以是node,也可以只是一次执行的任务。这里教程定义的是一次执行任务。
1 2 roscd beginner_tutorials/script vim add_two_ints_client.py
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 import sysimport rospyfrom beginner_tutorials.srv import AddTwoIntsdef add_two_ints_client (x, y) : rospy.wait_for_service("add_two_ints" ) try : add_two_ints = rospy.ServiceProxy("add_two_ints" , AddTwoInts) resp1 = add_two_ints(x, y) return resp1.sum except rospy.ServiceException, e: print("Service call failed: %s" %e) if __name__=="__main__" : if len(sys.argv) == 3 : x = int(sys.argv[1 ]) y = int(sys.argv[2 ]) else : print usage() sys.exit(1 ) print("Requesting %s + %s" %(x, y)) print("%s + %s = %s" %(x, y, add_two_ints_client(x, y)))
Request和Response 在本地调用服务的句柄时,相当于发送的XXXRequest,XXX表示srv类型,比如AddTwoIntsRequest。而server返回的则是XXXResponse, 如AddTwoIntsResponse。
Building nodes 已经配置好依赖项 message_generation
和 message_runtime
, 这里需要添加的只是srv文件, 在CMakeLists文件中修改
add_service_files(
FILES
AddTwoInts.srv
)
然后编译
1 2 cd ~/catkin_wscatkin_make
运行
新开两个终端,分别执行两个代码
1 rosrun beginner_tutorials add_two_ints_server.py
1 rosrun beginner_tutorials add_two_ints_client.py
输出:
思考 教程中,包括很多网上的资料都没提到如果srv返回多个变量该怎么办?
然后对上面的例子
1 2 3 4 5 6 # File: srv/AddTwoInts.srv int64 a int64 b --- int64 sum int64 subtract
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 from beginner_tutorials.srv import *import rospydef handle_add_two_ints (req) : print("Return [%s + %s = %s]" %(req.a, req.b, (req.a+req.b))) s1 = req.a+req.b print("return [%s - %s = %s]" %(req.a, req.b, req.a-req.b)) s2 = req.a - req.b return AddTwoIntsResponse(s1, s2) def add_two_ints_server () : rospy.init_node('add_two_ints_server' ) s = rospy.Service("add_two_ints" , AddTwoInts, handle_add_two_ints) print("Ready to add two ints" ) rospy.spin() if __name__=="__main__" : add_two_ints_server()
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 30 31 32 import sysimport rospyfrom beginner_tutorials.srv import *def add_two_ints_client (x, y) : rospy.wait_for_service('add_two_ints' ) try : add_two_ints = rospy.ServiceProxy("add_two_ints" , AddTwoInts) resp1 = add_two_ints(x, y) return resp1.sum, resp1.subtract except rospy.ServiceException, e: print("Service call failed: %s" %e) def usage () : return "%s [x, y]" %sys.argv[0 ] if __name__=="__main__" : if len(sys.argv) == 3 : x = int(sys.argv[1 ]) y = int(sys.argv[2 ]) else : print(usage()) sys.exit(1 ) print("Requesting %s + %s" %(x, y)) s1, s2 = add_two_ints_client(x, y) print("%s + %s = %s" %(x, y, s1)) print("%s - %s = %s" %(x, y, s2))
然后重新编译执行:
结果如下: