MATLAB - ROS 2 工具箱入门教程

系列文章目录


文章目录

  • 系列文章目录
  • 前言
  • 一、ROS 2 入门
    • 1.1 ROS 2 术语
    • 1.2 启动 ROS 2 网络
    • 1.3 话题和服务质量策略
    • 1.4 消息
    • 1.5 从 ROS 2 网络断开连接
    • 1.6 DDS 和 RMW 实施
  • 二、连接到 ROS 2 网络
    • 2.1 在默认域中创建 ROS 2 节点
    • 2.2 在不同域上创建 ROS 2 节点
    • 2.3 更改默认域 ID
    • 2.4 ROS 2 网络通信
    • 2.5 子网外的 ROS 通信
  • 三、与 ROS 2 发布者和订阅者交换数据
    • 3.1 订阅并等待信息
    • 3.2 使用回调函数订阅
    • 3.3 发布消息
    • 3.4 断开 ROS 2 网络连接


前言

ROS 工具箱提供了一个连接 MATLAB® 和 Simulink® 与机器人操作系统(ROS 和 ROS 2)的接口。利用该工具箱,您可以设计 ROS 节点网络,并将 MATLAB 或 Simulink 生成的 ROS 节点与现有的 ROS 网络相结合。

工具箱包括 MATLAB 函数和 Simulink 块,可通过记录、导入和回放 rosbag 文件来可视化和分析 ROS 数据。您还可以连接到实时 ROS 网络,访问 ROS 消息。

该工具箱可让你通过桌面仿真和连接外部机器人仿真器(如 Gazebo)或硬件来验证 ROS 节点。ROS 工具箱支持 C++ 和 CUDA® 代码生成(使用 MATLAB Coder™、Simulink Coder 和 GPU Coder™),使您能够从 MATLAB 脚本或 Simulink 模型自动生成 ROS 节点,并部署到模拟或物理硬件上。支持 Simulink 外部模式后,当模型在硬件上运行时,你可以查看信息并更改参数。

在这里插入图片描述


一、ROS 2 入门

本示例展示了如何在 MATLAB 中设置 ROS 2,并获取有关 ROS 2 网络和 ROS 2 消息的信息。

机器人操作系统 2(ROS 2)是 ROS 的第二个版本,它是一个通信接口,可以让机器人系统的不同部分发现、发送和接收数据。支持 ROS 2 的 MATLAB® 是一个函数库,可让您与支持 ROS 2 的物理机器人或机器人模拟器(如 Gazebo®)交换数据。ROS 2 建立在数据分发服务(DDS)的基础上,这是一个端到端的中间件,具有发现、序列化和传输等功能。这些功能符合 ROS 2 的设计原则,如分布式发现和控制不同的传输 "服务质量 "选项。DDS 使用实时发布-订阅(RTPS)协议,可通过 UDP 等不可靠的网络协议进行通信。如需了解更多信息,请参阅 RTPS。

要了解 ROS,请参阅 ROS 入门。

1.1 ROS 2 术语

  • ROS 2 网络由通过 ROS 2 网络进行通信的机器人系统不同部分(如规划器或摄像头接口)组成。网络可以分布在多台机器上。

  • ROS 2节点是一个包含相关ROS 2能力(如发布者和订阅者)集合的实体。一个 ROS 2 网络可以有多个 ROS 2 节点。

  • 发布者和订阅者是处理数据的不同类型的 ROS 2 实体。它们使用消息交换数据。

  • 发布者向特定话题(如 “里程计”)发送消息,该话题的订阅者接收这些消息。一个话题可以关联多个发布者和订阅者。

  • 域是网络的物理分段。它由一个称为域 ID 的唯一整数值标识。默认情况下,域 ID 为 0。

  • ROS 2 网络中的每个节点在创建时都会向同一域 ID 中的其他节点公布自己的存在。

  • ROS 2 网络建立在数据分发服务(DDS)基础上,因此可以在分布式网络中连接多个节点。更多信息,请参阅在 ROS 中间件实现之间切换。

  • RTPS(实时发布者-订阅者)协议为 ROS 2 网络提供了在不可靠网络条件下发送信息的功能。

  • ROS 2 提供各种服务质量(QoS)策略,让你可以调整节点之间的通信。如需了解更多信息,请参阅管理 ROS 2 中的服务质量策略。

更多信息,请参阅机器人操作系统2(ROS 2)和 ROS 2 网站上的概念部分。

1.2 启动 ROS 2 网络

与 ROS 不同,ROS 2 无需在 MATLAB 中进行初始化。ROS 2 网络会自动从创建节点开始。

使用 ros2node 创建节点。

test1 = ros2node("/test1")
test1 = 
  ros2node - 属性:

    Name: '/test1'
      ID: 0

使用 ros2 node list 查看 ROS 2 网络中的所有节点。

ros2 node list
/test1

使用 clear 关闭 ROS 2 网络中的节点。

clear test1

使用 exampleHelperROS2CreateSampleNetwork 为 ROS 网络添加三个节点,其中包括样本发布者和订阅者。

exampleHelperROS2CreateSampleNetwork

使用 ros2 node list 查看 ROS 2 网络中的所有节点。

ros2 node list
/tp367a7a03_c5b6_46f8_962
/tp3cbf47a7_c1c8_474c_bb
/tp6bb8a4e5_2f37_

这是创建样本节点后 ROS 2 网络的可视化表示。在本示例的其余部分中,请将其作为探索 ROS 2 网络的参考。

在这里插入图片描述

1.3 话题和服务质量策略

运行命令 ros2 topic list 查看 ROS 2 网络中的可用话题。该命令会返回三个活动话题: /pose、/parameter_events/scan。话题 /parameter_events 是 ROS 2 网络中始终存在的全局话题。节点使用 /paramater_events 话题监控或更改网络中的参数。您创建的 /scan/pose 话题是示例网络的一部分。

ros2 topic list
/parameter_events
/pose
/rosout
/scan

每个主题都与一种信息类型相关联。运行命令 ros2 topic list -t 可以查看每个主题的信息类型。

ros2 topic list -t
            Topic                       MessageType           
    _____________________    _________________________________

    {'/parameter_events'}    {'rcl_interfaces/ParameterEvent'}
    {'/pose'            }    {'geometry_msgs/Twist'          }
    {'/rosout'          }    {'rcl_interfaces/Log'           }
    {'/scan'            }    {'sensor_msgs/LaserScan'        }

服务质量(QoS)策略选项可改变发布者和订阅者处理和交换信息的方式。

  1. 使用 HistoryDepth QoS 策略,可根据在处理队列中放置报文的方式确定通信对象的行为。将 History 指定为以下选项之一。

    • “keeplast” - 删除信息,只保留最新信息。

    • “keepall”(全部保留)- 保留队列中收到的所有报文,直到处理完毕。

  2. 使用 Reliability QoS 策略保证向用户发送信息。将可靠性指定为以下选项之一。

    • “reliable”- 确保发布者持续向订户发送信息,直到订户确认收到信息。

    • “besteffort”- 允许发布者只发送一次信息。

  3. 使用 Durability QoS 策略和 Depth 输入来控制晚加入连接的信息持久性。将 Durability 指定为以下选项之一。

    • “transientlocal”(临时)- 如果订阅者在发布者首次发送信息后加入网络,则发布者会向订阅者发送持久化信息。

    • “volatile”(易失性)- 发布者在发送信息后不会持久化信息。订阅者不会向发布者请求持久化信息。

1.4 消息

发布者和订阅者使用 ROS 2 消息交换信息。每条 ROS 2 消息都有一个相关的消息类型,它定义了消息中的数据类型和信息布局。更多信息,请参阅 “使用基本 ROS 2 消息”。

使用 ros2 msg show 查看消息类型的属性。geometry_msgs/Twist 消息类型有两个属性:Linear 和角度 Angular 。每个属性都是 geometry_msgs/Vector3 类型的信息,而 geometry_msgs/Vector3 又有三个 double 类型的属性。

ros2 msg show geometry_msgs/Twist
# This expresses velocity in free space broken into its linear and angular parts.

Vector3  linear
Vector3  angular
ros2 msg show geometry_msgs/Vector3
# This represents a vector in free space.

# This is semantically different than a point.
# A vector is always anchored at the origin.
# When a transform is applied to a vector, only the rotational component is applied.

float64 x
float64 y
float64 z

使用 ros2 msg list 查看 MATLAB 中可用消息类型的完整列表。

1.5 从 ROS 2 网络断开连接

使用 exampleHelperROS2ShutDownSampleNetwork 可从 ROS 2 网络中移除样本节点、发布者和订阅者。要移除自己的节点,请在节点、发布者或订阅者对象中使用 clear

exampleHelperROS2ShutDownSampleNetwork

1.6 DDS 和 RMW 实施

在 MATLAB® 和 Simulink® 中使用 ROS 2 时,您可以切换 RMW 实现来使用数据分发服务(DDS)。要配置所需的 RMW 实现,请按照以下步骤操作。

  1. 在 MATLAB 工具条 "环境 "部分的 "主页 "选项卡下,打开 “首选项”。

  2. 在 ROS 工具箱首选项对话框中配置 Python™ 环境,并从 ROS 中间件 (RMW) 实现下拉列表中选择一个实现。默认实现为 rmw_fastrtps_cpp

在这里插入图片描述

  1. 单击 “配置并切换到自定义 RMW 实现”,启动 ROS 中间件配置对话框,切换到自定义 RMW 实现。

  2. 安装并构建自定义 RMW 实现软件包,以验证使用所选自定义 RMW 实现创建 ROS 2 节点。

二、连接到 ROS 2 网络

ROS 2 网络由多个 ROS 2 节点组成。与 ROS 不同,ROS 2 基于数据分发标准(DDS),这是一个端到端的中间件,可提供发现、序列化和传输等功能。这些功能符合 ROS 2 的设计原则,如分布式发现和控制不同的传输 "服务质量 "选项。

要连接到 ROS 1 网络,请参阅连接到 ROS 网络。

使用 ROS 2 时,通常需要遵循以下步骤:

  • 连接到 ROS 2 网络 - 要连接到 ROS 2 网络,必须在 MATLAB 中创建一个 ROS 2 节点,并指定网络域 ID。

  • 交换数据–连接后,MATLAB 将通过发布者和订阅者与同一域 ID 中的其他 ROS 2 节点交换数据。

  • 从 ROS 2 网络断开连接 - 从 ROS 2 网络断开 MATLAB ROS 2 节点、发布者和订阅者的连接。

2.1 在默认域中创建 ROS 2 节点

使用 ros2node 在默认域中创建一个节点,其 ID 为 0。 节点与同一域中的其他节点通信,但不知道其他域中的节点。

defaultNode = ros2node("/default_node")
defaultNode = 
  ros2node - 属性:

    Name: '/default_node'
      ID: 0

使用 clear 删除对节点的引用,从而将其从 ROS 2 网络中删除。

clear defaultNode

2.2 在不同域上创建 ROS 2 节点

要在非默认域中创建节点,请明确指定域 ID 作为 ros2node 的第二个输入参数。下面的 newDomainNode 将在 ID 25 指定的域中创建。

newDomainNode = ros2node("/new_domain_node",25)
newDomainNode = 
  ros2node - 属性:

    Name: '/new_domain_node'
      ID: 25

要查看特定域的网络信息,请将 ID 作为参数提供给 ros2 函数。以下命令将显示域 ID 为 25 的所有节点。

ros2("node","list","DomainID",25)
/new_domain_node

2.3 更改默认域 ID

如果没有向 node 或 ros2 命令明确提供域 ID,它们默认使用 ROS_DOMAIN_ID 环境变量的值。使用 getenv 查看当前值。如果该环境变量未设置或未设置为有效值,则将使用默认的 0 域名 ID。

getenv("ROS_DOMAIN_ID")
ans =

  空的 0×0 char 数组

可以使用 setenv 命令设置 ROS_DOMAIN_ID

setenv("ROS_DOMAIN_ID","25")
envDomainNode = ros2node("/env_domain_node")
envDomainNode = 
  ros2node - 属性:

    Name: '/env_domain_node'
      ID: 25

ros2 函数提供该环境变量指定的网络信息。使用 ros2 node list 查看域 ID 为 25 的节点。

ros2 node list
/env_domain_node
/new_domain_node

将 ROS_DOMAIN_ID 重置为默认值。

setenv("ROS_DOMAIN_ID","")

2.4 ROS 2 网络通信

要连接到现有的 ROS 2 网络,请在所需的域中创建一个节点。ROS 2 网络会通过一种名为 "发现 "的机制,自动检测在同一域中创建的任何新节点。

启动时,ROS 2 中的每个节点都会向同一域中的其他节点发出自己存在的广告。其他节点会响应这一广告,向新节点提供自己的信息。拥有通信对象(如发布者和订阅者)的节点,如果拥有服务质量(QoS)设置兼容的相应对象,就能与其他节点建立连接。有关 QoS 设置的更多信息,请参阅《ROS 2 中的服务质量策略管理》。

发现是一个持续的过程,它能让新节点在创建时加入网络。每个节点都在监控 ROS 2 网络,其作用类似于 ROS 网络中的 ROS 主节点。当节点离线时,也会向其他节点公布自己的缺席。

在这里插入图片描述

新的 ROS 2 节点向现有节点发送广告。现有节点响应广告,然后建立持续通信。

2.5 子网外的 ROS 通信

子网是将 IP 网络划分为多个较小网段的逻辑分区。ROS 2 节点可与同一子网内的其他节点通信。要检测子网外的节点,可创建一个 DEFAULT_FASTRTPS_PROFILE.xml 文件,配置 MATLAB 使用的特定 DDS 实现。在地址元素内添加要与之通信的子网外系统的 IP 地址列表。请注意,要进行通信,两个系统都必须在各自的 DEFAULT_FASTRTPS_PROFILE.xml 文件中指定对方的地址。将 domainId 元素设置为用于通信的网络的适当值。

将此文件保存在 MATLAB 当前工作目录中。在 MATLAB 之外使用 ROS 2 的系统应将此文件放在运行 ROS 2 应用程序的同一目录下。下面是 DEFAULT_FASTRTPS_PROFILES.xml 文件的示例。

<?xml version="1.0" encoding="UTF-8" ?>
<profiles>
    <participant profile_name="participant_win" is_default_profile="true">
        <rtps>
            <builtin>
                <metatrafficUnicastLocatorList>
                     <locator/>
                </metatrafficUnicastLocatorList>
                 <initialPeersList>
                     <locator>
                         <udpv4>
                         <address>192.34.17.36</address>
                         </udpv4>
                     </locator>
                     <locator>
                         <udpv4>
                         <address>182.30.45.12</address>
                         </udpv4>
                     </locator>
                     <locator>
                         <udpv4>
                         <address>194.158.78.29</address>
                         </udpv4>
                     </locator>
                 </initialPeersList>
             </builtin>
         </rtps>
     </participant>
</profiles> 

ROS 2 会向 DEFAULT_FASTRTPS_PROFILES.xml 中列出 IP 地址的系统中的节点发布信息。如果 DEFAULT_FASTRTPS_PROFILES.xml 不存在或不包含正确的 IP 地址,则不会收到来自子网外其他机器中节点的信息。

在这里插入图片描述

三、与 ROS 2 发布者和订阅者交换数据

本例展示了如何在 ROS 2 网络中发布和订阅主题。

ROS 2 节点交换数据的主要机制是发送和接收消息。消息在话题上传输,每个话题在 ROS 2 网络中都有一个唯一的名称。如果节点想共享信息,就必须使用发布者向话题发送数据。要接收信息的节点必须使用同一话题的订阅者。除了唯一的名称外,每个话题还有一个信息类型,它决定了允许在特定话题中传输的信息类型。

这种发布者与订阅者之间的通信具有以下特点:

  • 主题用于多对多通信。多个发布者可以向同一个主题发送信息,多个订阅者可以接收信息。

  • 发布者和订阅者通过话题解耦,可以任意顺序创建和销毁。即使没有活跃的订阅者,也可以向话题发布信息。

在这里插入图片描述

除了如何在 ROS 2 网络中发布和订阅主题外,本示例还展示了如何

  • 等待收到新消息,或

  • 使用回调在后台处理新消息

先决条件 开始使用 ROS 2,连接到 ROS 2 网络。

3.1 订阅并等待信息

创建一个包含多个发布者和订阅者的 ROS 2 示例网络。

exampleHelperROS2CreateSampleNetwork

使用 ros2 topic list 查看哪些话题可用。

ros2 topic list
/parameter_events
/pose
/rosout
/scan

假设你想订阅 /scan 主题。使用 ros2subscriber 订阅 /scan 主题。指定订阅节点的名称。如果 ROS 2 网络中已经存在该主题,ros2subscriber 会自动检测其消息类型,因此无需指定。

detectNode = ros2node("/detection");
pause(5)
laserSub = ros2subscriber(detectNode,"/scan");
pause(5)

使用 receive 等待新信息。指定超时时间为 10 秒。输出 scanData 包含接收到的报文数据,status 表示是否成功接收到报文,stustext 则提供有关状态的其他信息。

[scanData,status,statustext] = receive(laserSub,10);

现在,您可以订阅者 laserSub 及其关联节点。

clear laserSub
clear detectNode

3.2 使用回调函数订阅

您可以指定在收到新消息时调用的函数,而不是使用 receive 来获取数据。这样,其他 MATLAB 代码就可以在订阅者等待新消息时执行。如果要使用多个订阅者,回调是必不可少的。

使用回调函数 exampleHelperROS2PoseCallback 订阅 /pose 主题,该函数将收到的消息作为输入。在主工作区和回调函数之间共享数据的一种方法是使用全局变量。定义两个全局变量 posorient

controlNode = ros2node("/base_station");
pause(5)
poseSub = ros2subscriber(controlNode,"/pose",@exampleHelperROS2PoseCallback);
global pos
global orient

/pose 主题收到新的信息数据时,全局变量 posorient 将被分配到 exampleHelperROS2PoseCallback 函数中。

function exampleHelperROS2PoseCallback(message)    
    % Declare global variables to store position and orientation
    global pos
    global orient
    
    % Extract position and orientation from the ROS message and assign the
    % data to the global variables.
    pos = [message.linear.x message.linear.y message.linear.z];
    orient = [message.angular.x message.angular.y message.angular.z];
end

稍等片刻,等待网络发布另一条 /pose 消息。显示更新后的值。

pause(3)
disp(pos)
    0.0415   -0.0010   -0.0016
disp(orient)
   -0.0043   -0.0205    0.0338

如果在命令行中多次输入 posorient,就能看到数值在不断更新。

通过清除订阅者变量来停止姿势订阅者

clear poseSub
clear controlNode

注:除使用全局外,还有其他方法从回调函数中提取信息。例如,可以将句柄对象作为附加参数传递给回调函数。有关定义回调函数的更多信息,请参阅为图形对象创建回调函数文档。

3.3 发布消息

创建一个向 /chatter 主题发送 ROS 2 字符串信息的发布器。

chatterPub = ros2publisher(node_1,"/chatter","std_msgs/String");

创建并填充 ROS 2 消息,发送到 /chatter 主题。

chatterMsg = ros2message(chatterPub);
chatterMsg.data = 'hello world';

使用 ros2 topic list 验证 /chatter 主题在 ROS 2 网络中是否可用。

ros2 topic list
/chatter
/parameter_events
/pose
/rosout
/scan

exampleHelperROS2ChatterCallback 会在收到新消息时被调用,并显示消息中的字符串内容。

chatterSub = ros2subscriber(node_2,"/chatter",@exampleHelperROS2ChatterCallback)
chatterSub = 
  ros2subscriber - 属性:

        TopicName: '/chatter'
    LatestMessage: []
      MessageType: 'std_msgs/String'
    NewMessageFcn: @exampleHelperROS2ChatterCallback
          History: 'keeplast'
            Depth: 10
      Reliability: 'reliable'
       Durability: 'volatile'

/chatter 话题发布一条消息。观察订阅者回调显示的字符串。

send(chatterPub,chatterMsg)
pause(3)

当订阅者收到字符串消息时,exampleHelperROS2ChatterCallback 函数被调用。

3.4 断开 ROS 2 网络连接

从 ROS 2 网络中删除样本节点、发布者和订阅者。同时清除全局变量 pos 和 orient

clear global pos orient
clear 

该处使用的url网络请求的数据。


  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的 ROS 2 入门示例。 假设你已经安装好了 ROS 2 和相关的依赖包。我们将创建一个简单的 ROS 2 节点,该节点将发布一个名为 `/demo_topic` 的主题,其中包含一个字符串消息。我们还将创建一个订阅该主题的节点。 首先,在终端中创建一个工作空间: ``` mkdir -p ~/ros2_ws/src cd ~/ros2_ws/ colcon build ``` 接下来,创建一个 ROS 2 包: ``` cd ~/ros2_ws/src ros2 pkg create my_demo_pkg --build-type ament_cmake ``` 这将在 `~/ros2_ws/src` 目录下创建一个名为 `my_demo_pkg` 的 ROS 2 包。进入该包的目录: ``` cd my_demo_pkg/ ``` 在 `my_demo_pkg` 目录下创建一个名为 `publisher.cpp` 的 C++ 文件,并将以下代码复制到文件中: ```cpp #include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" using namespace std::chrono_literals; class PublisherNode : public rclcpp::Node { public: PublisherNode() : Node("publisher_node") { publisher_ = this->create_publisher<std_msgs::msg::String>("/demo_topic", 10); timer_ = this->create_wall_timer(1s, std::bind(&PublisherNode::timer_callback, this)); } private: void timer_callback() { auto message = std_msgs::msg::String(); message.data = "Hello, ROS 2!"; publisher_->publish(message); } rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_; rclcpp::TimerBase::SharedPtr timer_; }; int main(int argc, char **argv) { rclcpp::init(argc, argv); auto node = std::make_shared<PublisherNode>(); rclcpp::spin(node); rclcpp::shutdown(); return 0; } ``` 这个节点将创建一个名为 `/publisher_node` 的节点,并在 `/demo_topic` 主题上发布一个字符串消息。 接下来,在 `my_demo_pkg` 目录下创建一个名为 `subscriber.cpp` 的 C++ 文件,并将以下代码复制到文件中: ```cpp #include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" void callback(const std_msgs::msg::String::SharedPtr msg) { RCLCPP_INFO(rclcpp::get_logger("subscriber_node"), "Received message: '%s'", msg->data.c_str()); } int main(int argc, char **argv) { rclcpp::init(argc, argv); auto node = rclcpp::Node::make_shared("subscriber_node"); auto subscriber = node->create_subscription<std_msgs::msg::String>("/demo_topic", 10, callback); rclcpp::spin(node); rclcpp::shutdown(); return 0; } ``` 这个节点将创建一个名为 `/subscriber_node` 的节点,并订阅 `/demo_topic` 主题。当接收到消息时,它将打印消息内容。 现在,我们需要将这两个节点添加到 `CMakeLists.txt` 文件中: ``` add_executable(publisher_node src/publisher.cpp) ament_target_dependencies(publisher_node rclcpp std_msgs) add_executable(subscriber_node src/subscriber.cpp) ament_target_dependencies(subscriber_node rclcpp std_msgs) ``` 最后,编译并运行节点: ``` cd ~/ros2_ws/ colcon build --packages-select my_demo_pkg source install/setup.bash ros2 run my_demo_pkg publisher_node ``` 在另一个终端中运行以下命令: ``` ros2 run my_demo_pkg subscriber_node ``` 现在你应该能够在订阅节点的终端中看到如下输出: ``` [INFO] [subscriber_node]: Received message: 'Hello, ROS 2!' ``` 这就是一个简单的 ROS 2 入门示例。你可以尝试修改代码并探索更多高级功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值