第5天 ROS 《Service 通信实验指导书》

一、实验目标

  1. 理解 ROS Service 的通信机制,包括请求(Request)与响应(Response)。
  2. 掌握创建 .srv 文件并在 ROS 中使用 Service。
  3. 能够实现两个示例 Service:
    • 计算器服务:实现加、减、乘、除运算。
    • 整形数组排序服务:对输入的整形数组进行排序并返回结果。
  4. 掌握 Service Server 和 Client 的实现流程

二、实验原理

1. ROS Service 机制

  • Server:提供服务,等待 Client 请求。
  • Client:发起请求,接收 Server 响应。
  • Service 通过 .srv 文件定义 请求字段 与 响应字段。

示意图:

Client --------> Server
Request Response

2. Service 文件

  • .srv 文件结构:
python 复制代码
# 请求字段
int32 a
int32 b
string op
---
# 响应字段
float32 result
string status
  • 请求与响应之间使用 --- 分隔。

三、实验准备

  1. 软件环境
    • Ubuntu 20.04
    • ROS Noetic
    • Python 3
    • RViz(可选)
  2. ROS 工作空间
bash 复制代码
cd ~/catkin_ws/src
catkin_create_pkg my_service_pkg rospy std_msgs
cd ~/catkin_ws
catkin_make
source devel/setup.bash

四、实验内容与步骤

实验1:计算器服务

第五天ROS Service 通信实验1

1. 创建 Service 文件

bash 复制代码
cd ~/catkin_ws/src/my_service_pkg

mkdir srv

cd srv

gedit Calculator.srv

路径:~/catkin_ws/src/my_service_pkg/srv/Calculator.srv

内容:

python 复制代码
float32 a
float32 b
string op
---
float32 result
string status

2. 编写 Server 节点

bash 复制代码
cd ~/catkin_ws/src/my_service_pkg/

mkdir scripts

cd scripts

gedit calculator_server.py

文件:calculator_server.py

python 复制代码
#!/usr/bin/env python3
import rospy
from my_service_pkg.srv import Calculator, CalculatorResponse

def handle_calculator(req):
    try:
        if req.op == '+':
            res = req.a + req.b
        elif req.op == '-':
            res = req.a - req.b
        elif req.op == '*':
            res = req.a * req.b
        elif req.op == '/':
            res = req.a / req.b
        else:
            return CalculatorResponse(0, "Unsupported operation")
        return CalculatorResponse(res, "OK")
    except Exception as e:
        return CalculatorResponse(0, str(e))

def calculator_server():
    rospy.init_node('calculator_server')
    s = rospy.Service('calculator', Calculator, handle_calculator)
    rospy.loginfo("Calculator Service Ready...")
    rospy.spin()

if __name__ == "__main__":
    calculator_server()

3. 编写 Client 节点

文件:calculator_client.py

cd ~/catkin_ws/src/my_service_pkg/scripts

gedit calculator_client.py

python 复制代码
#!/usr/bin/env python3
import rospy
from my_service_pkg.srv import Calculator

def calculator_client(a, b, op):
    rospy.wait_for_service('calculator')
    try:
        calc = rospy.ServiceProxy('calculator', Calculator)
        resp = calc(a, b, op)
        return resp.result, resp.status
    except rospy.ServiceException as e:
        print("Service call failed: %s"%e)
        return None, str(e)

if __name__ == "__main__":
    rospy.init_node('calculator_client')
    
    # 手动输入
    try:
        a = float(input("请输入第一个数字: "))
        b = float(input("请输入第二个数字: "))
        op = input("请输入运算符 (+, -, *, /): ")
    except ValueError:
        print("输入无效,请输入数字!")
        exit(1)
    
    result, status = calculator_client(a, b, op)
    print("计算结果:", result, "状态:", status)

实验2:整形数组排序服务

1. 创建 Service 文件

路径:~/catkin_ws/src/my_service_pkg/srv/SortArray.srv

内容:

bash 复制代码
int32[] array
---
int32[] sorted_array
string status

2. 编写 Server 节点

文件:sort_array_server.py

python 复制代码
#!/usr/bin/env python3
import rospy
from my_service_pkg.srv import SortArray, SortArrayResponse

def handle_sort_array(req):
    try:
        sorted_arr = sorted(req.array)
        return SortArrayResponse(sorted_arr, "OK")
    except Exception as e:
        return SortArrayResponse([], str(e))

def sort_array_server():
    rospy.init_node('sort_array_server')
    s = rospy.Service('sort_array', SortArray, handle_sort_array)
    rospy.loginfo("Sort Array Service Ready...")
    rospy.spin()

if __name__ == "__main__":
    sort_array_server()

3. 编写 Client 节点

文件:sort_array_client.py

python 复制代码
#!/usr/bin/env python3
import rospy
from my_service_pkg.srv import SortArray

def sort_array_client(array):
    rospy.wait_for_service('sort_array')
    try:
        sort_srv = rospy.ServiceProxy('sort_array', SortArray)
        resp = sort_srv(array)
        return resp.sorted_array, resp.status
    except rospy.ServiceException as e:
        print("Service call failed: %s" % e)
        return None, str(e)

if __name__ == "__main__":
    rospy.init_node('sort_array_client')

    try:
        # 手动输入数组(用空格分隔)
        user_input = input("请输入一组整数(用空格分隔,例如:5 2 9 1 7):\n")
        
        # 转换为整数列表
        array = list(map(int, user_input.strip().split()))
        
    except ValueError:
        print("输入格式错误,请输入整数!")
        exit(1)

    sorted_array, status = sort_array_client(array)

    print("排序结果:", sorted_array)
    print("状态:", status)

4.实验步骤总结

1.创建 Service .srv 文件。
2.修改 CMakeLists.txt
bash 复制代码
find_package(catkin REQUIRED COMPONENTS

  rospy

  std_msgs

  message_generation

)





add_service_files(
    FILES
    Calculator.srv
    SortArray.srv
)

generate_messages(
    DEPENDENCIES std_msgs
)

catkin_package(
    CATKIN_DEPENDS rospy std_msgs message_runtime
)

3.修改package.xml:

bash 复制代码
<build_depend>message_generation</build_depend>

<exec_depend>message_runtime</exec_depend>  

<build_export_depend>message_runtime</build_export_depend>
4.编译工作空间:
bash 复制代码
cd ~/catkin_ws
catkin_make
source devel/setup.bash
5.给calculator_client.py和calculator_server.py添加可执行权限!
bash 复制代码
cd ~/catkin_ws/src/my_service_pkg/scripts

    chmod   +x calculator_client.py

    chmod   +x calculator_server .py
6.启动运行

1.启动 Server 节点。

rosrun my_service_pkg calculator_server.py

2.运行 Client 节点,观察结果。

rosrun my_service_pkg calculator_client.py

五、注意事项

  1. Service 名称应唯一,避免与已有节点冲突。
  2. 对除零等异常情况要进行处理。
  3. Client 发送请求前需等待 Service 可用:

rospy.wait_for_service('service_name')

相关推荐
广州虚拟动力-动捕&虚拟主播1 小时前
从视角一致性看具身智能:头戴式采集设备的不可替代性
机器人
xwz小王子6 小时前
Science Advances 让机器人触觉在重压下继续分辨微小变化
机器人·1024程序员节
GlobalInfo11 小时前
机器人线缆用无卤TPU料市场分析报告深度版:产业洞察、技术演进与路径
大数据·人工智能·机器人
AiNightVision12 小时前
电力巡检夜视方案选型指南——无人机/机器人/固定监测三种场景怎么选
人工智能·科技·车载系统·机器人·无人机·边缘计算·视频
咕泡科技13 小时前
AI前沿速递:Gemini双连发+混元双档落地!智元发布首个机器人工时KPI,具身智能分出工厂与客厅两条赛道
人工智能·机器人·腾讯混元·智元机器人·gemini4carbon·巴布机器人
天树星智源14 小时前
静态物理满分、交互 11.54%:3D 场景生成系统的幻觉
论文阅读·人工智能·3d·机器人
咬代码的兽14 小时前
智元创新日拆解:机器人开始按工时结算,Token之后有了Worken
机器人
趣味科技v14 小时前
具身智能从“演示”走向“部署”:智元把机器人送进真实工位
机器人·具身智能·智元
Wanda121414 小时前
机器人与机电一体化3D数字孪生机器-Day9
人工智能·3d·unity·机器人·数字孪生
超级架构师15 小时前
让 Fortran 模型自己调用 Agent:原生 Fortran 2008 实现深度剖析
人工智能·python·架构·机器人·开源·fortran