MATLAB - ROS 入门教程

发布时间:2024年01月22日

目录

一、开始使用 ROS

1.1 ROS 术语

1.2 初始化 ROS 网络

1.3 话题

1.4?服务

1.5 消息

二、连接到 ROS 网络

2.1 在 MATLAB 中创建 ROS 主站

2.2 连接外部 ROS 主站

2.3 节点主机规范

2.4 ROS 环境变量

2.5 验证连接

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

3.1 订阅和等待消息

3.2 使用回调函数订阅

3.3 发布消息

3.4 关闭 ROS 网络


一、开始使用 ROS

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

机器人操作系统(ROS)是一种通信接口,可使机器人系统的不同部分相互发现,并在它们之间发送和接收数据。MATLAB? 通过一个函数库支持 ROS,使您能够与支持 ROS 的物理机器人或机器人模拟器(如 Gazebo?)交换数据。

1.1 ROS 术语

  • ROS 网络由机器人系统中通过 ROS 进行通信的不同部分(如规划器或摄像头接口)组成。该网络可分布在多台机器上。
  • ROS 主站负责协调 ROS 网络的各个部分。它由主 URI(统一资源标识符)标识,该标识符指定了主站运行所在机器的主机名或 IP 地址。
  • 一个 ROS 节点包含一系列相关的 ROS 功能(如发布者、订阅者和服务)。一个 ROS 网络可以有多个 ROS 节点。
  • 发布者、订阅者和服务是处理数据的不同类型的 ROS 实体。它们使用信息交换数据。
  • 发布者向特定主题(如 "里程计")发送消息,该主题的订阅者接收这些消息。一个主题可以关联多个发布者和订阅者。

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

1.2 初始化 ROS 网络

使用 rosinit 初始化 ROS。默认情况下,rosinit 会在 MATLAB 中创建一个 ROS 主节点,并启动一个与主节点相连的全局节点。其他 ROS 功能会自动使用全局节点。

rosinit
Launching ROS Core...
.....Done in 5.7786 seconds.
Initializing ROS master on http://172.21.16.85:51063.
Initializing global node /matlab_global_node_13423 with NodeURI http://ah-avijayar:52604/ and MasterURI http://localhost:51063.

使用 rosnode list 查看 ROS 网络中的所有节点。请注意,唯一可用的节点是由 rosinit 创建的全局节点。

rosnode list
/matlab_global_node_13423

使用 exampleHelperROSCreateSampleNetwork 为 ROS 网络添加三个节点以及样本发布者和订阅者。

exampleHelperROSCreateSampleNetwork

再次使用 rosnode list 查看三个新节点(node_1、node_2 和 node_3)。

rosnode list
/matlab_global_node_13423
/node_1
/node_2
/node_3

图中显示了 ROS 网络的当前状态。MATLAB 全局节点是断开的,因为它目前没有任何发布者、订阅者或服务。

1.3 话题

使用 rostopic 列表查看 ROS 网络中的可用主题。目前有四个活动主题: /pose、/rosout、/scan 和 /tf。默认主题:rosout 和 tf 始终存在于 ROS 网络中。其他两个主题是作为样本网络的一部分创建的。?

rostopic list
/pose  
/rosout
/scan  
/tf    

使用 rostopic info <topicname> 获取特定主题的具体信息。下面的命令显示 /node_1 发布(向 /pose 主题发送消息),而 /node_2 订阅(接收来自该主题的消息)。更多信息请参阅 "与 ROS 发布者和订阅者交换数据"。

rostopic info /pose
Type: geometry_msgs/Twist
 
Publishers:
* /node_1 (http://ah-avijayar:52609/)
 
Subscribers:
* /node_2 (http://ah-avijayar:52614/)

使用 rosnode info <nodename> 获取特定节点的信息。下面的命令显示,node_1 向 /pose、/rosout 和 /tf 主题发布信息,订阅 /scan 主题并提供服务: /node_1/get_loggers 和 /node_1/set_logger_level。ROS 网络中创建的所有节点都提供默认日志服务:get_loggers 和 set_logger_level。

rosnode info /node_1
Node: [/node_1]
URI: [http://ah-avijayar:52609/]
 
Publications (3 Active Topics): 
 * /pose
 * /rosout
 * /tf
 
Subscriptions (1 Active Topics): 
 * /scan
 
Services (2 Active): 
 * /node_1/get_loggers
 * /node_1/set_logger_level

1.4?服务

ROS 服务为跨 ROS 网络的程序调用提供了一种机制。服务客户端向服务服务器发送请求信息,服务服务器会处理请求中的信息并返回响应信息(请参阅 "调用和提供 ROS 服务")。

使用 rosservice list 查看 ROS 网络中所有可用的服务服务器。下面的命令显示,有两个服务(/add 和 /reply)以及所有节点的默认日志记录器服务可用。

rosservice list
/add
/matlab_global_node_13423/get_loggers
/matlab_global_node_13423/set_logger_level
/node_1/get_loggers
/node_1/set_logger_level
/node_2/get_loggers
/node_2/set_logger_level
/node_3/get_loggers
/node_3/set_logger_level
/reply

使用 rosservice info <servicename> 获取特定服务的信息。

rosservice info /add
Node: /node_3
URI: rosrpc://ah-avijayar:52618
Type: roscpp_tutorials/TwoInts
Args: MessageType A B

1.5 消息

发布者、订阅者和服务使用 ROS 消息来交换信息。每个 ROS 消息都有一个相关的消息类型,它定义了消息中的数据类型和信息布局(请参阅 "使用基本 ROS 消息")。

使用 rostopic type <topicname> 查看主题使用的消息类型。下面的命令显示,/pose 主题使用的消息类型为 geometry_msgs/Twist。

rostopic type /pose
geometry_msgs/Twist

使用 rosmsg show <messagetype> 查看消息类型的属性。(geometry_msgs/Twist)消息类型有两个属性:线性(Linear)和角度(Angular)。每个属性都是几何_msgs/Vector3 类型的消息,而几何_msgs/Vector3 又有三个 double 类型的属性。

rosmsg show geometry_msgs/Twist
% This expresses velocity in free space broken into its Linear and Angular parts.
Vector3  Linear
Vector3  Angular
rosmsg show geometry_msgs/Vector3
% This represents a vector in free space. 
% It is only meant to represent a direction. Therefore, it does not
% make sense to apply a translation to it (e.g., when applying a 
% generic rigid transformation to a Vector3, tf2 will only apply the
% rotation). If you want your data to be translatable too, use the
% geometry_msgs/Point message instead.

double X
double Y
double Z

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

1.6 关闭 ROS 网络

使用 exampleHelperROSShutDownSampleNetwork 从 ROS 网络中删除样本节点、发布者和订阅者。只有在先前使用 exampleHelperROSStartSampleNetwork 创建了示例网络时,才需要使用此命令。

exampleHelperROSShutDownSampleNetwork

使用 rosshutdown 关闭 MATLAB 中的 ROS 网络。这将关闭由 rosinit 启动的 ROS 主节点,并删除全局节点。建议在完成 ROS 网络工作后使用 rosshutdown。

rosshutdown
Shutting down global node /matlab_global_node_13423 with NodeURI http://ah-avijayar:52604/ and MasterURI http://localhost:51063.
Shutting down ROS master on http://172.21.16.85:51063.

二、连接到 ROS 网络

ROS 网络由一个 ROS 主站和多个 ROS 节点组成。ROS 主节点通过跟踪所有活跃的 ROS 实体,促进 ROS 网络中的通信。每个节点都需要向 ROS 主站注册,才能与网络中的其他节点通信。MATLAB? 可以启动 ROS 主站,也可以在 MATLAB 外部(例如在另一台计算机上)启动主站。

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

  1. 连接到 ROS 网络。要连接到 ROS 网络,可以在 MATLAB 中创建 ROS 主站,也可以连接到现有的 ROS 主站。在这两种情况下,MATLAB 都会创建并注册自己的 ROS 节点(称为 MATLAB 全局节点)。rosinit 函数负责管理这一过程。
  2. 交换数据。连接后,MATLAB 将通过发布者、订阅者和服务与其他 ROS 节点交换数据。
  3. 断开 ROS 网络连接。调用 rosshutdown 函数断开 MATLAB 与 ROS 网络的连接。

本例向您展示了如何

  • 在 MATLAB 中创建 ROS 主站
  • 连接外部 ROS 主站

先决条件: 开始使用 ROS

2.1 在 MATLAB 中创建 ROS 主站

要在 MATLAB 中创建 ROS 主站,请调用 rosinit(不带任何参数)。该函数还创建了全局节点,MATLAB 使用它与 ROS 网络中的其他节点通信。

rosinit
Launching ROS Core...
Done in 0.36647 seconds.
Initializing ROS master on http://172.29.196.158:56952.
Initializing global node /matlab_global_node_23704 with NodeURI http://dcc427349glnxa64:33843/ and MasterURI http://localhost:56952.

MATLAB 外部的 ROS 节点现在可以加入 ROS 网络。它们可以使用 MATLAB 主机的主机名或 IP 地址连接到 MATLAB 中的 ROS 主节点。

您可以通过调用 rosshutdown 关闭 ROS 主节点和全局节点。

rosshutdown
Shutting down global node /matlab_global_node_23704 with NodeURI http://dcc427349glnxa64:33843/ and MasterURI http://localhost:56952.
Shutting down ROS master on http://172.29.196.158:56952.

2.2 连接外部 ROS 主站

你也可以使用 rosinit 命令连接外部 ROS 主站(例如运行在机器人或虚拟机上的 ROS 主站)。你可以通过两种方式指定主站的地址:IP 地址或主控程序运行计算机的主机名。

每次调用 rosinit 后,必须先调用 rosshutdown,然后再以不同语法调用 rosinit。为简洁起见,这些示例中省略了对 rosshutdown 的调用。

master_host "是主机名示例,"192.168.1.1 "是外部 ROS 主站的 IP 地址示例。请根据外部主站在网络中的位置调整这些地址。如果在指定地址找不到主控程序,这些命令将失效。

rosinit('192.168.1.1')
rosinit('master_host')

对 rosinit 的两次调用都假定主站接受 11311 端口的网络连接,这是标准的 ROS 主控端口。如果主控程序运行在其他端口上,可以将其指定为第二个参数。要连接到主机名为 master_host、端口为 12000 的 ROS 主站,请使用以下命令:

rosinit('master_host',12000)

如果知道主站的整个统一资源标识符(URI),则可以使用以下语法创建全局节点并连接到主控程序:

rosinit('http://192.168.1.1:12000')

2.3 节点主机规范

在某些情况下,您的计算机可能连接到多个网络并拥有多个 IP 地址。本图就是一个例子。

?

左下角的计算机运行 MATLAB,并连接到两个不同的网络。在一个子网中,它的 IP 地址是 73.195.120.50,而在另一个子网中,它的 IP 地址是 192.168.1.100。这台电脑希望连接到 TurtleBot? 电脑上 IP 地址为 192.168.1.1 的 ROS 主站。作为向主节点注册的一部分,MATLAB 全局节点必须指定其他 ROS 节点可以连接到它的 IP 地址或主机名。TurtleBot 上的所有节点都将使用该地址向 MATLAB 全局节点发送数据。

当使用主节点的 IP 地址调用 rosinit 时,它会尝试检测用于联系主节点的网络接口,并将其作为全局节点的 IP 地址。如果自动检测失败,可以在 rosinit 调用中使用 NodeHost 名-值对明确指定 IP 地址或主机名。NodeHost 名-值对可与已显示的任何其他语法一起使用。

这些命令向 ROS 网络公布的计算机 IP 地址为 192.168.1.100。

rosinit('192.168.1.1','NodeHost','192.168.1.100')
rosinit('http://192.168.1.1:11311','NodeHost','192.168.1.100')
rosinit('master_host','NodeHost','192.168.1.100')

一旦某个节点在 ROS 网络中注册,就可以使用命令 rosnode info <nodename> 查看它发布的地址。调用 rosnode list 可以查看所有已注册节点的名称。

2.4 ROS 环境变量

在高级使用情况下,您可能希望通过标准 ROS 环境变量来指定 ROS 主节点的地址和您发布的节点地址。前面几节所解释的语法应该足以满足大多数使用情况。

如果没有为 rosinit 提供参数,函数还会检查标准 ROS 环境变量的值。这些变量是 ROS_MASTER_URI、ROS_HOSTNAME 和 ROS_IP。你可以使用 getenv 命令查看它们的当前值:

getenv('ROS_MASTER_URI')
getenv('ROS_HOSTNAME')
getenv('ROS_IP')

你可以使用 setenv 命令设置这些变量。设置完环境变量后,调用不带参数的 rosinit。ROS 主节点的地址由 ROS_MASTER_URI 指定,全局节点的广告地址由 ROS_IP 或 ROS_HOSTNAME 指定。如果为 rosinit 指定了其他参数,它们将覆盖环境变量中的值。

setenv('ROS_MASTER_URI','http://192.168.1.1:11311')
setenv('ROS_IP','192.168.1.100')
rosinit

不必同时设置 ROS_HOSTNAME 和 ROS_IP。如果同时设置,则 ROS_HOSTNAME 优先。

2.5 验证连接

要使 ROS 连接正常工作,必须确保所有节点都能与主节点和节点间进行通信。各个节点必须与主节点通信,以注册订阅者、发布者和服务。它们还必须能够相互通信,以发送和接收数据。如果 ROS 网络设置不当,就有可能出现能发送数据却无法接收数据的情况(反之亦然)。

该图显示了一个 ROS 网络,其中有一个 ROS 主节点和两个向主节点注册的不同节点。每个节点都会联系主节点,查找 ROS 网络中另一个节点的广告地址。一旦每个节点都知道了对方的地址,就可以在没有主节点参与的情况下建立数据交换。

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

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

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

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

  • 话题用于多对多通信。许多发布者可以向同一个话题发送信息,许多订阅者也可以接收这些消息。
  • 发布者和订阅者通过话题解耦,可以任意顺序创建和销毁。即使没有活跃的订阅者,也可以向话题发布消息。

话题、发布者和订阅者的概念如图所示:

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

  • 等待收到新消息
  • 使用回调在后台处理新消息

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

3.1 订阅和等待消息

使用 rosinit 命令在 MATLAB? 中启动 ROS 主程序。

rosinit
Launching ROS Core...
.....Done in 5.4209 seconds.
Initializing ROS master on http://172.21.16.85:56764.
Initializing global node /matlab_global_node_69902 with NodeURI http://ah-avijayar:62300/ and MasterURI http://localhost:56764.

使用提供的辅助函数 exampleHelperROSCreateSampleNetwork,创建一个包含多个发布者和订阅者的 ROS 示例网络。

exampleHelperROSCreateSampleNetwork

使用 rostopic 列表查看有哪些话题。

rostopic list
/pose  
/rosout
/scan  
/tf    

使用 rostopic info 查看是否有节点正在向 /scan 话题发布信息。下面的命令显示 node_3 正在发布该主题。

rostopic info /scan
Type: sensor_msgs/LaserScan
 
Publishers:
* /node_3 (http://ah-avijayar:62315/)
 
Subscribers:
* /node_1 (http://ah-avijayar:62305/)
* /node_2 (http://ah-avijayar:62310/)

使用 rossubscriber 订阅 /scan 话题。如果 ROS 网络中已经存在该话题(如此处),rossubscriber 会自动检测其消息类型,因此无需指定。使用 struct 格式的消息可以提高效率。

laser = rossubscriber("/scan","DataFormat","struct");
pause(2)

使用 receive 等待新消息(第二个参数是以秒为单位的超时时间)。(第二个参数是以秒为单位的超时时间。)输出 scandata 包含接收到的消息数据。

scandata = receive(laser,10)
scandata = struct with fields:
       MessageType: 'sensor_msgs/LaserScan'
            Header: [1×1 struct]
          AngleMin: -0.5467
          AngleMax: 0.5467
    AngleIncrement: 0.0017
     TimeIncrement: 0
          ScanTime: 0.0330
          RangeMin: 0.4500
          RangeMax: 10
            Ranges: [640×1 single]
       Intensities: []

某些消息类型会关联可视化器。对于 LaserScan 消息,rosPlot 会绘制扫描数据。MaximumRange 名 - 值对指定了最大绘图范围。

figure
rosPlot(scandata,"MaximumRange",7)

3.2 使用回调函数订阅

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

使用回调函数 exampleHelperROSPoseCallback 订阅 /pose 话题。

robotpose = rossubscriber("/pose",@exampleHelperROSPoseCallback,"DataFormat","struct")
robotpose = 
  Subscriber with properties:

        TopicName: '/pose'
    LatestMessage: []
      MessageType: 'geometry_msgs/Twist'
       BufferSize: 1
    NewMessageFcn: @exampleHelperROSPoseCallback
       DataFormat: 'struct'

在主工作区和回调函数之间共享数据的一种方法是使用全局变量。定义两个全局变量 pos 和 orient。

global pos
global orient

当 /pose 话题收到新消息数据时,全局变量 pos 和 orient 将在 exampleHelperROSPoseCallback 函数中分配。

等待几秒钟以确保订阅者可以接收消息。最新的位置和方向数据将始终存储在 pos 和 orient 变量中。

pause(2) 
pos
pos = 1×3

   -0.0292   -0.0199   -0.0029
orient
orient = 1×3

   -0.0270    0.0344   -0.0305

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

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

clear robotpose

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

3.3 发布消息

创建一个向 /chatter 话题发送 ROS 字符串消息的发布器(请参阅 "使用基本 ROS 消息")。

chatterpub = rospublisher("/chatter","std_msgs/String","DataFormat","struct")
chatterpub = 
  Publisher with properties:

         TopicName: '/chatter'
    NumSubscribers: 0
        IsLatching: 1
       MessageType: 'std_msgs/String'
        DataFormat: 'struct'
pause(2) % Wait to ensure publisher is registered

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

chattermsg = rosmessage(chatterpub);
chattermsg.Data = 'hello world'
chattermsg = struct with fields:
    MessageType: 'std_msgs/String'
           Data: 'hello world'

使用 rostopic list 验证 /chatter 话题在 ROS 网络中是否可用。

rostopic list
/chatter
/pose   
/rosout 
/scan   
/tf     

为 /chatter 话题定义一个订阅者。exampleHelperROSChatterCallback 在收到新消息时被调用,并显示消息中的字符串内容。

chattersub = rossubscriber("/chatter",@exampleHelperROSChatterCallback,"DataFormat","struct")
chattersub = 
  Subscriber with properties:

        TopicName: '/chatter'
    LatestMessage: []
      MessageType: 'std_msgs/String'
       BufferSize: 1
    NewMessageFcn: @exampleHelperROSChatterCallback
       DataFormat: 'struct'

向 /chatter 话题发布消息。订阅者回调将显示该字符串。

send(chatterpub,chattermsg)
pause(2)
ans = 
'hello world'

一旦您发布了字符串消息,exampleHelperROSChatterCallback 函数就会被调用。

3.4 关闭 ROS 网络

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

exampleHelperROSShutDownSampleNetwork
clear global pos orient

关闭 ROS 主节点并删除全局节点。

rosshutdown
Shutting down global node /matlab_global_node_69902 with NodeURI http://ah-avijayar:62300/ and MasterURI http://localhost:56764.
Shutting down ROS master on http://172.21.16.85:56764.
文章来源:https://blog.csdn.net/weixin_46300916/article/details/135719583
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。