ros2实现话题通信

ros2实现话题通信

一,创建工作空间

mkdir -p ros2_ws/src
cd ros2_ws/src

二,创建package

# 进到ros2_ws/src路径下
ros2 pkg create --build-type ament_python py_pubsub
# 解释
ros2 pkg create <package-name>  --build-type  {cmake,ament_cmake,ament_python}  --dependencies <依赖名字>

三,创建发布者节点

# 进到ros2_ws/src/py_pubsub/py_pubsub路径下(此处是直接下载demo代码)
wget https://raw.githubusercontent.com/ros2/examples/foxy/rclpy/topics/minimal_publisher/examples_rclpy_minimal_publisher/publisher_member_function.py

四,config

# 回到ros2_ws/src/py_pubsub/路径下
# 修改package.xml(package.xml文件是功能包被ROS系统识别的前提)
## 相关描述信息
<description>Examples of minimal publisher/subscriber using rclpy</description>
<maintainer email="you@email.com">Your Name</maintainer>
<license>Apache License 2.0</license>
## 追加声明此节点需要的依赖 rclpy 和 std_msgs(就是代码中import的包)
<exec_depend>rclpy</exec_depend>
<exec_depend>std_msgs</exec_depend>
# 修改 setup.py :对应 package.xml 里的修改
maintainer='YourName',
maintainer_email='you@email.com',
description='Examples of minimal publisher/subscriber using rclpy',
license='Apache License 2.0',
## 在 console_scripts 中添加注册节点
entry_points={
        'console_scripts': [
                'talker = py_pubsub.publisher_member_function:main',
        ],
},
# 检查 setup.cfg :此为环境变量, 不然运行节点时setuptools找不到,没有就手动添加
[develop]
script-dir=$base/lib/py_pubsub
[install]
install-scripts=$base/lib/py_pubsub

五,创建订阅者节点

# 回到 ros2_ws/src/py_pubsub/py_pubsub 路径下
wget https://raw.githubusercontent.com/ros2/examples/foxy/rclpy/topics/minimal_subscriber/examples_rclpy_minimal_subscriber/subscriber_member_function.py

六,追加config

# package.xml 和 setup.cfg 是一样的,不需要修改
# setup.py 追加listener节点信息
entry_points={
        'console_scripts': [
                'talker = py_pubsub.publisher_member_function:main',
                'listener = py_pubsub.subscriber_member_function:main',
        ],
},

七,编译执行

# ros2_ws路径下检查依赖项(用到的包啥的)是否缺失,缺失会自动安装(报错看下面拓展内容)
rosdep install -i --from-path src --rosdistro foxy -y
# 编译(colcon build --symlink-install 此参数很有用,相当于建立一个link, 以后改动python代码就不需要重新编译)
colcon build --packages-select py_pubsub --symlink-install
# 加载环境 :source install/setup.bash
. install/setup.bash
# 运行节点talker
ros2 run py_pubsub talker

[INFO] [minimal_publisher]: Publishing: "Hello World: 0"
[INFO] [minimal_publisher]: Publishing: "Hello World: 1"
[INFO] [minimal_publisher]: Publishing: "Hello World: 2"
[INFO] [minimal_publisher]: Publishing: "Hello World: 3"
[INFO] [minimal_publisher]: Publishing: "Hello World: 4"
...
# 开另一个终端加载环境并运行listener
. install/setup.bash
ros2 run py_pubsub listener

[INFO] [minimal_subscriber]: I heard: "Hello World: 10"
[INFO] [minimal_subscriber]: I heard: "Hello World: 11"
[INFO] [minimal_subscriber]: I heard: "Hello World: 12"
[INFO] [minimal_subscriber]: I heard: "Hello World: 13"
[INFO] [minimal_subscriber]: I heard: "Hello World: 14"

# 命令行发布话题测试listener, /topic 对应话题名称
ros2 topic pub /topic std_msgs/msg/String "{data: 10}" 为啥写data:10 思考一下

目录结构:

# 编译成功之后ros2_ws下有四个dir:build,install,log,src
# 其中src目录结构如下
.
└── py_pubsub
    ├── package.xml
    ├── py_pubsub
    │   ├── __init__.py
    │   ├── publisher_member_function.py
    │   └── subscriber_member_function.py
    ├── resource
    │   └── py_pubsub
    ├── setup.cfg
    ├── setup.py
    └── test
        ├── test_copyright.py
        ├── test_flake8.py
        └── test_pep257.py

八,拓展

# rosdep是什么
rosdep是ros的一个功能包,在安装ros时会自动安装.在使用时需要初始化.
ros包有两个不同类型的依赖项:build依赖项和run依赖项。rosdep就是用来检查包的丢失依赖项,并且完成下载和安装。
此命令会自动检测src下的所有包依赖,如果发现没有安装的依赖,直接安装。
rosdep是ros一个命令行,用于安装系统依赖,具体地说,就是ros包的依赖。
# rosdep初始化
rosdep使用前需要先进行初始化和更新,初始化也就是执行下面指令:
sudo rosdep init
# 使用
rosdep install -i --from-path src --rosdistro foxy -y
# rosdep初始化失败的情况
1.为什么叫rosdepc?
rosdepc,c指的是China中国,主要用于和rosdep区分。
2.rosdepc和rosdep功能一致吗?
rosdep官方最新版源码直接修改的,改动了名称和源地址,将其地址修改为国内gitee地址。
3.rosdepc为什么不会初始化失败?
因为rosdepc使用的是国内的源,rosdep初始化失败是因为其使用的是github,国内无法访问。
# rosdepc安装使用
安装
sudo pip install rosdepc
如果显示没有pip可以试试pip3
sudo pip3 install rosdepc
如果pip3还没有
sudo apt-get install python3-pip 
sudo pip install rosdepc
使用
sudo rosdepc init
rosdepc update

代码注释:publisher_member_function.py为例,订阅者代码类似原理

# Copyright 2016 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import rclpy
from rclpy.node import Node
# 导入消息类型
from std_msgs.msg import String


class MinimalPublisher(Node):
    """
    创建一个话题发布节点
    """
    def __init__(self):
        super().__init__('minimal_publisher')
        # 创建并初始化发布者成员属性publisher_,这里使用create_publisher方法来创建的发布者,该方法一共有三个参数,第一个是方法类型,第二个是话题名称,第三个是消息队列长度
        self.publisher_ = self.create_publisher(String, 'topic', 10)
        # 创建定时器成员属性timer
        timer_period = 0.5  # seconds
        self.timer = self.create_timer(timer_period, self.timer_callback) # 启动一个定时装置,这个定时器的作用就是根据传入的timer_period时间周期,每隔一个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) # 发布,每隔0.5秒发一次
        self.get_logger().info('Publishing: "%s"' % msg.data) # 打印一下发布的数据
        self.i += 1 # 编号+1


def main(args=None):
    """
    ros2运行该节点的入口函数,可配置函数名称
    """
    rclpy.init(args=args) # 初始化rclpy

    minimal_publisher = MinimalPublisher() # 新建一个节点

    rclpy.spin(minimal_publisher) # 保持节点运行,检测是否收到退出指令(Ctrl+C)

    # 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() # rcl关闭


if __name__ == '__main__':
    main()

posted @ 2023-03-24 11:45  阿木古冷  阅读(178)  评论(0编辑  收藏  举报