欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

玩转ROS2系列04--在功能包中实现一个订阅节点和发布节点

程序员文章站 2022-07-14 22:09:29
...

玩转ROS2系列:

玩转ROS2系列01–Ubuntu下ROS 2 版本选择和安装
玩转ROS2系列02–创建一个工作空间并编译功能包
玩转ROS2系列03–创建并运行一个你自己的功能包
玩转ROS2系列04–在功能包中实现一个订阅节点和发布节点

在上一篇博文中,我们已经创建好了我们自己的功能包,现在我们要往功能包中添加一些节点,我们将在这个功能包中编写一个发布节点和一个订阅节点,实现两个节点之间的互相通讯。
主要过程和代码参考官网教程Writing a simple publisher and subscriber (Python)

Step 1
首先进入我们创建的功能包的源码目录下,然后新创建一个python文件publisher_member_function.py

cd ros2_example_ws/src/my_package/my_package/

Step 2
编写发布节点的代码,然后保存退出

vim publisher_member_function.py
import rclpy
from rclpy.node import Node

from std_msgs.msg import String


class MinimalPublisher(Node):

    def __init__(self):
        super().__init__('minimal_publisher')
        self.publisher_ = self.create_publisher(String, 'topic', 10)
        timer_period = 0.5  # seconds
        self.timer = self.create_timer(timer_period, self.timer_callback)
        self.i = 0

    def timer_callback(self):
        msg = String()
        msg.data = 'Hello World: %d' % self.i
        self.publisher_.publish(msg)
        self.get_logger().info('Publishing: "%s"' % msg.data)
        self.i += 1


def main(args=None):
    rclpy.init(args=args)

    minimal_publisher = MinimalPublisher()

    rclpy.spin(minimal_publisher)

    # Destroy the node explicitly
    # (optional - otherwise it will be done automatically
    # when the garbage collector destroys the node object)
    minimal_publisher.destroy_node()
    rclpy.shutdown()


if __name__ == '__main__':
    main()

Step 3
编写订阅节点的代码,然后保存退出

vim subscriber_member_function.py
import rclpy
from rclpy.node import Node

from std_msgs.msg import String


class MinimalSubscriber(Node):

    def __init__(self):
        super().__init__('minimal_subscriber')
        self.subscription = self.create_subscription(
            String,
            'topic',
            self.listener_callback,
            10)
        self.subscription  # prevent unused variable warning

    def listener_callback(self, msg):
        self.get_logger().info('I heard: "%s"' % msg.data)


def main(args=None):
    rclpy.init(args=args)

    minimal_subscriber = MinimalSubscriber()

    rclpy.spin(minimal_subscriber)

    # Destroy the node explicitly
    # (optional - otherwise it will be done automatically
    # when the garbage collector destroys the node object)
    minimal_subscriber.destroy_node()
    rclpy.shutdown()


if __name__ == '__main__':
    main()

Step 4
修改功能包的package.xml文件

vim  ../package.xml

<buildtool_depend>ament_python</buildtool_depend>后面新增2行,然后保存退出

<exec_depend>rclpy</exec_depend>
<exec_depend>std_msgs</exec_depend>

Step 5
修改功能包的setup.py文件

vim  ../setup.py

编辑entry_points括号内的内容,编辑完成后如下

    entry_points={
        'console_scripts': [
            'my_node = my_package.my_node:main',
            'talker = my_package.publisher_member_function:main',
            'listener = my_package.subscriber_member_function:main',
        ],
    },

Step 6
编译功能包

sudo rosdep install -i --from-path src --rosdistro $ROS_DISTRO -y
colcon build --packages-select my_package

这里所使用到的rclpy和std_msgs两个包在ROS2中是默认包含的,所以rosdep 这一步的操作并未起到任何作用,但是以后我们在编写自己的包中可能会依赖ROS2默认不包含的包,所以作为习惯,我们在以后编译包时还是默认执行rosdep的操作
Step 7
运行功能包中发布和订阅节点
在两个终端中分别运行talker和listener节点

ros2 run my_package talker
ros2 run  my_package listener

可以看到,发布和订阅节点已经正常的运行起来了
玩转ROS2系列04--在功能包中实现一个订阅节点和发布节点

相关标签: ROS2