文章目录
- 第 10 课 服务数据的自定义与使用
-
- 1.自定义服务数据
- 2.服务数据的使用
-
- 2.1 创建服务器和客户端代码
- 2.2 运行服务器和客户端节点
第 10 课 服务数据的自定义与使用
1.自定义服务数据
注意:在自定义服务数据之前,需要先创建工作空间和功能包,具体操作过程可前往目录“第4课 创建工作空间与功能包”查看文档。
自定义服务数据的具体操作步骤如下:
- 打开命令行终端。
- 输入进入功能包所在目录的指令“roscd beginner_hiwonder”,并按下回车。
注意:若出现提示“No such package/stack ‘beginner_hiwonder’”,即功能包不存在于环境变量 ROS_PACKAGE_PATH 中,具体解决方法可前往目录“第 4 课 创建工作空间与功能包”查看文档,解决此问题后,请重复一次当前步骤的操作。
- 输入指令“mkdir srv”,并按下回车,新建用于存放文本文件的文件夹“srv”。
- 输入指令“vi Person.srv”编辑程序,复制下面程序。如需修改,再按下“i”即可修改。修改完成,按下“Esc”,输入“:wq”保存并退出。
string name int8 age int8 sex int8 unknown = 0 int8 male = 1 int8 female = 2 --- string result
5) 输入“cd ~/catkin_ws/src/beginner_hiwonder/”,按下回车。
6) 输入“vi package.xml”,复制下面程序,在下图所示位置添加功能包依赖。如需修改,再按下“i”即可修改。修改完成,按下“Esc”,输入“:wq”保存并退出。
<build_depend>message_generation</build_depend> <exec_depend>message_runtime</exec_depend>
7) 输入“vi CMakeLists.txt”,再按下“i”,修改“CMakeLists.txt”文件。
8) 在下图所示位置添加所需的编译选项“message_generation”。
9) 找到下图所示代码,将红框部分进行反注释,并添加所需的编译选项“Person.srv”。
10) 找到下图所示代码,将红框部分进行反注释,确保所需的编译选项生效。
11) 找 到 下 图 所 示 代 码 , 将 红 框 部 分 进 行 反 注 释 , 并 添 加 所 需 的 编 译 选 项“message_runtime”。
12) 修改完成,按下“Esc”,输入“:wq”保存并退出。
13) 输入指令“rossrv show beginner_hiwonder/Person”,并按下回车,查看写入的消息字段能否被系统识别。当出现下图红框所示字样,即代表识别成功。
2.服务数据的使用
2.1 创建服务器和客户端代码
- 打开Linux命令行终端。
- 输入指令“cd catkin_ws/src/beginner_hiwonder/scripts/”,并按下回车,进入用于存放Python脚本的文件夹“scripts”。
- 输入指令“vi person_server.py”编辑程序,复制下面程序。如需修改,再按下“i”即可修改。修改完成,按下“Esc”,输入“:wq”保存并退出。
#!/usr/bin/env python # -*- coding: utf-8 -*- # 该脚本定义了一个ROS服务,用于展示个人信息 # 服务数据类型为 beginner_hiwonder::Person,这是一个自定义的服务类型 # 导入rospy,这是一个Python库,用于ROS节点的编写 import rospy # 从beginner_hiwonder.srv包导入Person服务定义(这是自定义服务类型)及其响应PersonResponse from beginner_hiwonder.srv import Person, PersonResponse # 定义服务请求的处理函数,该函数将在客户端请求服务时被调用 def personCallback(req): # 打印请求数据,包括名字、年龄和性别 rospy.loginfo("Person: name:%s age:%d sex:%d", req.name, req.age, req.sex) # 服务响应,返回字符串"OK",表示成功接收到请求 return PersonResponse("OK") # 定义服务节点的主函数 def person_server(): # 初始化一个名为'person_server'的ROS节点 rospy.init_node('person_server') # 创建一个服务'/show_person',服务类型为Person,指定服务请求时的回调函数为personCallback s = rospy.Service('/show_person', Person, personCallback) # 打印消息,指示已准备好接收服务请求 print "Ready to show person information." # 进入循环,等待服务请求并调用回调函数处理 rospy.spin() # Python的标准模板,当该脚本被执行时,以下代码块将运行 if __name__ == "__main__": # 调用服务节点的主函数 person_server()
4) 输入指令“vi person_client.py”编辑程序,复制下面程序。如需修改,再按下“i”即可修改。修改完成,按下“Esc”,输入“:wq”保存并退出。
#!/usr/bin/env python # -*- coding: utf-8 -*- # 该脚本作为ROS服务客户端,请求/show_person服务,该服务的数据类型为beginner_hiwonder::Person # 导入sys模块,它提供了一系列有关Python运行环境的变量和函数 import sys # 导入rospy,用于ROS节点的编程 import rospy # 从beginner_hiwonder.srv包导入Person服务和PersonRequest消息类型 from beginner_hiwonder.srv import Person, PersonRequest # 定义服务客户端函数 def person_client(): # 初始化ROS节点,命名为'person_client' rospy.init_node('person_client') # 阻塞直到发现名为'/show_person'的服务 rospy.wait_for_service('/show_person') try: # 创建服务客户端,连接到'/show_person'服务,服务类型为Person person_client = rospy.ServiceProxy('/show_person', Person) # 使用PersonRequest的常量male表示性别,向服务发送请求 # 发送的请求数据是名字"Tom",年龄20,性别male(使用PersonRequest的male常量) response = person_client("Tom", 20, PersonRequest.male) # 返回响应结果 return response.result except rospy.ServiceException, e: # 如果服务调用失败,打印错误信息 print "Service call failed: %s" % e # 当该脚本被作为主程序运行时,而不是作为模块导入时 if __name__ == "__main__": # 调用服务并打印结果 print "Show person result : %s" % (person_client())
5) 输入指令“chmod +x person_server.py”和“chmod +x person_client.py”,并按下回车,赋予文件可执行权限
2.2 运行服务器和客户端节点
- 输入指令“cd ~/catkin_ws”,并按下回车,进入catkin工作空间。
- 输入指令“catkin_make”,并按下回车,构建目录中所有的功能包。
- 输入指令“source ./devel/setup.bash”,并按下回车,刷新工作空间的环境。
- 输入指令“roscore”,并按下回车,启动节点管理器。
若已开启,则会出现以下提示:
- 输入指令“rosrun beginner_hiwonder person_server.py”,并按下回车,运行服务器节点。如需停止节点的运行,可按下快捷键“Ctrl+C”。
- 打开一个新的命令行终端,输入指令“rosrun beginner_hiwonder person_client.py”,并按下回车,运行客户端节点。
- 运行客户端节点后,启动服务器节点的终端窗口会打印下图红框所示内容。