文章目录
- 第 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”,并按下回车,运行客户端节点。
- 运行客户端节点后,启动服务器节点的终端窗口会打印下图红框所示内容。