动手学ROS2-2节点通信-服务之RCLPY实现

本文介绍了如何在Ubuntu22.04和ROS2Humble环境下,利用RCLPY创建服务功能包和节点,包括服务端和客户端的实现。服务端接收AddTwoInts服务请求并返回计算结果,客户端发送请求并接收异步响应。
摘要由CSDN通过智能技术生成

说明:本文基于ubuntu22.04和ros2 humble版本

三、服务之RCLPY实现

1.创建功能包和节点

创建功能包其实还可以加上一些参数,让这个过程变得更简单

cd chapt3_ws/src

ros2 pkg create example_service_rclpy --build-type ament_python --dependencies rclpy example_interfaces --node-name service_server_02

 --node-name service_server_02会帮助创建好节点文件和在setup.py中添加执行文件。

但是也有一些限制,比如只支持一个节点文件,所以还需要手动创建一个。

cd example_service_rclpy/example_service_rclpy/

touch service_client_02.py

修改setup.py文件 

    entry_points={
        'console_scripts': [
            "service_client_02 = example_service_rclpy.service_client_02:main",
            "service_server_02 = example_service_rclpy.service_server_02:main"
        ],
    },

2.服务端实现

#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
# 导入接口
from example_interfaces.srv import AddTwoInts


class ServiceServer02(Node):
    def __init__(self,name):
        super().__init__(name)
        self.get_logger().info("节点已启动:%s!" % name)
        self.add_ints_server_ = self.create_service(AddTwoInts,"add_two_ints_srv",
                    self.handle_add_two_ints) 
                    
    def handle_add_two_ints(self,request, response):
        self.get_logger().info(f"收到请求,计算{request.a} + {request.b}")
        response.sum = request.a + request.b
        return response
        
        
def main(args=None):
    rclpy.init(args=args) # 初始化rclpy
    node = ServiceServer02("service_server_02")  # 新建一个节点
    rclpy.spin(node) # 保持节点运行,检测是否收到退出指令(Ctrl+C)
    rclpy.shutdown() # 关闭rclpy

3.客户端实现

#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from example_interfaces.srv import AddTwoInts

class ServiceClient02(Node):
    def __init__(self,name):
        super().__init__(name)
        self.get_logger().info("节点已启动:%s!" % name)
        self.client_ = self.create_client(AddTwoInts,"add_two_ints_srv") 

    def result_callback_(self, result_future):
        response = result_future.result()
        self.get_logger().info(f"收到返回结果:{response.sum}")
    
    def send_request(self, a, b):
        while rclpy.ok() and self.client_.wait_for_service(1)==False:
            self.get_logger().info(f"等待服务端上线....")
            
        request = AddTwoInts.Request()
        request.a = a
        request.b = b
        self.client_.call_async(request).add_done_callback(self.result_callback_)

def main(args=None):
    rclpy.init(args=args) # 初始化rclpy
    node = ServiceClient02("service_client_02")  # 新建一个节点
    # 调用函数发送请求
    node.send_request(3,4)
    rclpy.spin(node) # 保持节点运行,检测是否收到退出指令(Ctrl+C)
    rclpy.shutdown() # 关闭rclpy

同样是异步请求,rclpy客户端库定义的是call_async并且使用add_done_callback添加回调函数。

4.服务测试

工作空间目录下,开启客户端

colcon build --packages-select example_service_rclpy

source install/setup.bash

ros2 run example_service_rclpy service_client_02

#打开新的终端运行

source install/setup.bash

ros2 run example_service_rclpy service_server_02

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ROS2中,节点之间的通信可以通过发布者(Publisher)和订阅者(Subscriber)来实现。具体的实现步骤如下: 1. 创建节点 首先,需要创建节点并且初始化ROS2系统,代码如下: ```python import rclpy rclpy.init() node = rclpy.create_node('my_node') ``` 2. 创建发布者 接下来,需要创建一个发布者对象并且指定发布的主题名称、消息类型等信息,代码如下: ```python from std_msgs.msg import String publisher = node.create_publisher(String, 'my_topic', 10) ``` 其中,String是消息类型,'my_topic'是发布的主题名称,10是队列的大小。 3. 发布消息 发布消息时,需要构造一个消息对象并且调用发布者对象的publish()方法,代码如下: ```python msg = String() msg.data = 'Hello, World!' publisher.publish(msg) ``` 这里构造了一个String类型的消息,将其data属性设置为'Hello, World!',然后调用publish()方法将消息发布出去。 4. 创建订阅者 创建订阅者的代码与创建发布者类似,需要指定订阅的主题名称、消息类型等信息,代码如下: ```python subscriber = node.create_subscription(String, 'my_topic', callback, 10) ``` 其中,callback是当订阅到消息时要执行的回调函数,10是队列的大小。 5. 定义回调函数 回调函数的作用是处理订阅到的消息,代码如下: ```python def callback(msg): print('I heard: [%s]' % msg.data) ``` 这里的回调函数将订阅到的消息打印出来。 6. 运行节点 最后,需要调用rclpy.spin()方法来运行节点,代码如下: ```python rclpy.spin(node) ``` 完整的代码如下: ```python import rclpy from std_msgs.msg import String def callback(msg): print('I heard: [%s]' % msg.data) def main(args=None): rclpy.init(args=args) node = rclpy.create_node('my_node') publisher = node.create_publisher(String, 'my_topic', 10) subscriber = node.create_subscription(String, 'my_topic', callback, 10) msg = String() msg.data = 'Hello, World!' publisher.publish(msg) rclpy.spin(node) node.destroy_node() rclpy.shutdown() if __name__ == '__main__': main() ``` 这个例子中创建了一个节点,同时创建了一个发布者和一个订阅者,发布了一条消息,然后运行节点并且等待订阅到消息。当订阅到消息时,会执行回调函数并且打印消息内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值