ros2-如何创建一个简单的服务

服务通讯是ROS 2中节点通讯的另一种方式,与话题通讯不同,服务通讯具有反馈机制,即客户端发送请求后,服务器处理请求并返回结果。这在需要确认操作结果的场景中非常有用。以下是如何使用Python实现ROS 2节点之间的服务通讯的详细说明。

步骤概述

  1. 创建工作空间和包
  2. 编写服务端节点
  3. 编写客户端节点
  4. 配置和编译包
  5. 运行服务和客户端

1. 创建工作空间和包

首先,在你的工作目录中创建一个ROS 2工作空间:

# 复制代码

mkdir -p ~/ros2_ws/src cd ~/ros2_ws colcon build

然后,在工作空间中创建一个新的ROS 2包:

复制代码

cd ~/ros2_ws/src ros2 pkg create --build-type ament_python my_service_package

2. 编写服务端节点

my_service_package目录下,创建一个新的Python脚本,例如service_node.py

# my_service_package/my_service_package/service_node.py

import rclpy
from rclpy.node import Node
from example_interfaces.srv import AddTwoInts

class AddTwoIntsService(Node):

    def __init__(self):
        super().__init__('add_two_ints_service')
        self.srv = self.create_service(AddTwoInts, 'add_two_ints', self.add_two_ints_callback)

    def add_two_ints_callback(self, request, response):
        response.sum = request.a + request.b
        self.get_logger().info(f'Incoming request: a={request.a}, b={request.b}, sum={response.sum}')
        return response

def main(args=None):
    rclpy.init(args=args)
    service = AddTwoIntsService()
    rclpy.spin(service)
    service.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

3. 编写客户端节点

my_service_package目录下,创建另一个Python脚本,例如client_node.py

# my_service_package/my_service_package/client_node.py

import sys
import rclpy
from rclpy.node import Node
from example_interfaces.srv import AddTwoInts

class AddTwoIntsClient(Node):

    def __init__(self):
        super().__init__('add_two_ints_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('Service not available, waiting again...')
        self.req = AddTwoInts.Request()

    def send_request(self):
        self.req.a = int(sys.argv[1])
        self.req.b = int(sys.argv[2])
        self.future = self.cli.call_async(self.req)
        rclpy.spin_until_future_complete(self, self.future)
        return self.future.result()

def main(args=None):
    rclpy.init(args=args)
    client = AddTwoIntsClient()
    response = client.send_request()
    client.get_logger().info(f'Result of add_two_ints: {response.sum}')
    client.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

4. 配置和编译包

更新setup.py文件,添加入口点以便于启动节点:

from setuptools import setup

package_name = 'my_service_package'

setup(
    name=package_name,
    version='0.0.0',
    packages=[package_name],
    data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
    ],
    install_requires=['setuptools'],
    zip_safe=True,
    maintainer='Your Name',
    maintainer_email='yourname@example.com',
    description='Examples of ROS 2 service communication',
    license='Apache License 2.0',
    tests_require=['pytest'],
    entry_points={
        'console_scripts': [
            'service_node = my_service_package.service_node:main',
            'client_node = my_service_package.client_node:main',
        ],
    },
)

确保package.xml中包含以下依赖项:

<exec_depend>rclpy</exec_depend>
<exec_depend>example_interfaces</exec_depend>

在工作空间的根目录下编译包:

cd ~/ros2_ws colcon build

5. 运行服务和客户端

编译完成后,运行服务节点:

source ~/ros2_ws/install/setup.bash 
ros2 run my_service_package service_node

在另一个终端中,运行客户端节点:

source ~/ros2_ws/install/setup.bash
ros2 run my_service_package client_node 5 3

这里,client_node脚本会发送两个整数(5和3)到服务端,服务端将返回它们的和,并在客户端打印结果。

总结

通过以上步骤,你可以使用Python成功实现ROS 2中的服务通讯。服务端节点负责处理请求并返回结果,而客户端节点发送请求并接收结果。这种通讯方式适用于需要确认操作结果的场景,例如生成对象、计算任务等。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现一个ROS 2 C++节点修改另一个节点的参数,您需要使用ROS 2参数服务器。在ROS 2中,参数服务器是一个集中存储ROS节点参数的地方,节点可以通过参数服务器来获取和设置参数值。 在下面的示例中,我们将演示如何创建一个节点`node1`,并在运行时修改另一个节点`node2`的参数: ```cpp #include "rclcpp/rclcpp.hpp" int main(int argc, char **argv) { rclcpp::init(argc, argv); auto node1 = std::make_shared<rclcpp::Node>("node1"); // 获取 node2 节点的参数服务器 auto node2 = rclcpp::Node::make_shared("node2"); auto parameter_client = std::make_shared<rclcpp::AsyncParametersClient>(node2); // 修改 node2 节点的参数 auto set_parameter_results = parameter_client->set_parameters({ rclcpp::Parameter("my_parameter", "new_value") }); rclcpp::spin(node1); rclcpp::shutdown(); return 0; } ``` 在上面的代码中,我们创建了一个名为`node1`的节点,并获取了另一个节点`node2`的参数服务器。然后,我们使用`parameter_client`异步客户端来设置`node2`节点的参数。在上面的示例中,我们将参数“my_parameter”的值设置为“new_value”。 请注意,您需要先启动`node2`节点,然后才能在`node1`节点中修改其参数。另外,您需要确保`node2`节点已经设置了要修改的参数,否则会返回错误。 在实际应用中,您可能需要通过ROS 2话题或服务来实现节点之间的通信和协作。但是,如果只需要简单地修改节点的参数,使用参数服务器是一种简单有效的方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值