3. 服务通信实现
任务目标
本案例实现一个ROS2加法服务:服务端节点接收两个整数请求,返回其和;客户端节点发送请求并等待响应,验证ROS2服务通信的同步请求-响应机制。
环境准备
需要已安装ROS2(Humble或更新版本),并创建好工作空间。本案例使用Python编写,无需额外依赖包。
实现步骤
在功能包中创建两个Python文件:add_service.py(服务端)和add_client.py(客户端)。服务端使用rclpy创建服务,客户端使用rclpy创建客户端并同步调用服务。
关键完整代码
# add_service.py
import rclpy
from rclpy.node import Node
from example_interfaces.srv import AddTwoInts
class AddService(Node):
def __init__(self):
super().__init__('add_service')
self.srv = self.create_service(AddTwoInts, 'add_two_ints', self.add_callback)
self.get_logger().info('服务端已启动,等待请求...')
def add_callback(self, request, response):
response.sum = request.a + request.b
self.get_logger().info(f'收到请求: {request.a} + {request.b} = {response.sum}')
return response
def main(args=None):
rclpy.init(args=args)
node = AddService()
try:
rclpy.spin(node)
except KeyboardInterrupt:
pass
finally:
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
# add_client.py
import rclpy
from rclpy.node import Node
from example_interfaces.srv import AddTwoInts
class AddClient(Node):
def __init__(self):
super().__init__('add_client')
self.cli = self.create_client(AddTwoInts, 'add_two_ints')
while not self.cli.wait_for_service(timeout_sec=1.0):
self.get_logger().info('等待服务端启动...')
self.req = AddTwoInts.Request()
def send_request(self, a, b):
self.req.a = a
self.req.b = b
future = self.cli.call_async(self.req)
rclpy.spin_until_future_complete(self, future)
if future.result() is not None:
return future.result().sum
else:
self.get_logger().error('服务调用失败')
return None
def main(args=None):
rclpy.init(args=args)
client = AddClient()
result = client.send_request(3, 5)
if result is not None:
client.get_logger().info(f'调用结果: 3 + 5 = {result}')
client.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
编译与运行
- 将上述两个文件放入功能包的
scripts目录,并赋予执行权限:chmod +x scripts/add_service.py scripts/add_client.py - 在
setup.py的entry_points中添加:
entry_points={
'console_scripts': [
'add_service = scripts.add_service:main',
'add_client = scripts.add_client:main',
],
},
- 编译并source环境:
cd ~/ros2_ws
colcon build --packages-select your_package_name
source install/setup.bash
验证方法
打开两个终端,分别运行以下命令:
# 终端1
ros2 run your_package_name add_service
# 终端2
ros2 run your_package_name add_client
通过条件:
- 终端1显示“收到请求: 3 + 5 = 8”
- 终端2显示“调用结果: 3 + 5 = 8”
- 预期输出为8,与代码逻辑严格一致
也可使用命令行工具验证服务通信:
ros2 service list # 应看到 /add_two_ints
ros2 service call /add_two_ints example_interfaces/srv/AddTwoInts "{a: 10, b: 20}"
预期返回sum: 30。
常见问题
- 找不到服务:确认服务端已启动且服务名一致,使用
ros2 service list检查。 - 客户端阻塞:确保服务端正在运行,客户端
wait_for_service会等待服务出现。 - 编译错误:检查
setup.py中scripts路径是否正确,以及是否已安装example_interfaces包。