Home » ROS与Matlab入门教程 » ROS与Matlab语言入门教程-使用发布器和订阅器交换数据

ROS与Matlab语言入门教程-使用发布器和订阅器交换数据

ROS节点最基本的交换数据的方式是发送和接收消息。消息通过主题传输,在ROS网络中,每一个主题都有唯一的名称。如果一个节点想要共享数据,那么它就要使用发布器将数据发送到主题。一个节点想要接收数据,需要使用接收器监听相应的主题。除了具有唯一的名称,每个主题都具有消息类型,决定主题所能传输的消息类型。

发布器/接收器具有如下特征:

  • 主题用于多对多通信,多个发布器可以发送消息到同样的主题,多个接收器也可以接收同样的主题的数据。

  • 发布器和接收器与主题是解耦的不挂钩的,它们可以用任何规则创建或者销毁。在主题没有接收器的情况下,消息仍然可以发送到主题上。

主题、发布器和接收器的概念如下图所示:

请输入图片描述

这个例子展示了在ROS网络中怎样发布和订阅主题,另外还展示了:

  • 等待直到接收新的消息。

  • 使用后台调用的形式处理新消息。

需要的预备知识:1.2开始使用ROS,1.3连接到ROS网络。

订阅和等待消息

在MATLAB®中启动ROS主控节点,创建一个带有若干发布器和接收器的采样ROS网络。代码运行示例:

rosinit
exampleHelperROSCreateSampleNetwork
Initializing ROS master onhttp://bat5136glnxa64.mathworks.com:11311/.
Initializing global node /matlab_global_node_8332 with         使

用“rostopic list”指令查看可用的主题,假设你想要订阅的主题是“/scan”。代码运行示例:NodeURIhttp://bat5136glnxa64:35671/

rostopic list
/pose
/rosout
/scan

使用“rostopic info”指令检查是否有节点发布数据到“/scan”主题,下面的指令显示“node_3”节点发布数据到“/scan”主题。

rostopic info /scan
Type: sensor_msgs/LaserScan
Publishers:

  • /node_3 (http://bat5136glnxa64:53950/)

Subscribers:

  • /node_1 (http://bat5136glnxa64:49726/)

  • /node_2 (http://bat5136glnxa64:59432/)

使用“rossubscriber”指令订阅“/scan”主题,如果该主题已经存在于ROS网络中(如本例),“rossubscriber”会自动的检测消息类型,你无须指定。代码运行示例:

laser = rossubscriber('/scan')
laser =
Subscriber with properties:
TopicName: '/scan'
MessageType: 'sensor_msgs/LaserScan'
LatestMessage: [0x1 LaserScan]
BufferSize: 1
NewMessageFcn: []

使用“receive”指令等待新消息(第二个参数是超时时间(s)),输出“scandata”包含了接收的数据。代码运行示例:

scandata = receive(laser,10)
scandata =
ROS LaserScan message with properties:
MessageType: 'sensor_msgs/LaserScan'
Header: [1x1 Header]
AngleMin: -0.5216
AngleMax: 0.5243
AngleIncrement: 0.0016
TimeIncrement: 0
ScanTime: 0.0330
RangeMin: 0.4500
RangeMax: 10
Ranges: [640x1 single]
Intensities: [0x1 single]

一些数据类型有与之相关的方便的可视化的方式,对于LaserScan数据,“plot”指令能够绘制曲线图,其中“MaximumRange”指定了曲线的最大值范围。运行示例:

plot(scandata,'MaximumRange',7)

请输入图片描述

使用回调函数订阅数据

你可以指定一个回调函数接收新的消息,而不必采用“receive”指令的方法。这种方法使得其它MATLAB代码能够在订阅器等待新消息的同时继续执行。如果想要使用多个订阅器,那么回调是必须的方法。

使用“exampleHelperROSPoseCallback”回调函数,订阅“/pose”主题。一种在主工作空间和回调函数中共享数据的方法是采用全局变量。定义两个全局变量“pos”和“orient”。代码运行示例:

robotpose = rossubscriber('/pose',@exampleHelperROSPoseCallback)
global pos
global orient
robotpose =
Subscriber with properties:
TopicName: '/pose'
MessageType: 'geometry_msgs/Twist'
LatestMessage: [0x1 Twist]
BufferSize: 1
NewMessageFcn: @exampleHelperROSPoseCallback

从“/pose”主题中接收到新消息时,全局变量“pos”和“orient”将在“exampleHelperROSPoseCallback”回调函数中赋值。

等待几秒钟,确认订阅器能够接收到消息,当前的位置和方向数据,将总是存放在 “pos”和“orient” 变量。代码运行示例:

pause(2)
pos

orient
pos =
-0.0725 -0.0805 -0.0628
orient =
0.0364 0.1791 0.0041

如果在命令行里输入几次的“pos”和“orient”,将会看到相应的数据不断的更新。

清除订阅器变量的方式停止位姿订阅器。代码运行示例:

clear robotpose

注意:除了使用全局变量,还有很多种方法从回调函数中提取信息,例如,可以传递一个句柄对象作为附加的参数到回调函数中。关于回调函数的定义详见Callback Definition文档。

发布消息

创建一个发布器,用于发送ROS字符串消息到“/chatter”主题(下回分解)。代码运行示例:

chatterpub = rospublisher('/chatter',rostype.std_msgs_String)
pause(2) % Wait to ensure publisher is setup
chatterpub =
Publisher with properties:
TopicName: '/chatter'
IsLatching: 1
NumSubscribers: 0
MessageType: 'std_msgs/String'

使用“rostopic list”命令,确认“/chatter”主题在ROS网络中是可用的。代码运行示例:

rostopic list
/chatter
/pose
/rosout
/scan

为“/chatter”主题定义一个订阅器,当接收到新的消息时,“exampleHelperROSChatterCallback”将会被调用,显示消息中的字符串内容。代码运行示例:

chattersub = rossubscriber('/chatter', @exampleHelperROSChatterCallback)
chattersub =
Subscriber with properties:
TopicName: '/chatter'
MessageType: 'std_msgs/String'
LatestMessage: [0x1 String]
BufferSize: 1
NewMessageFcn: @exampleHelperROSChatterCallback

创建并填充一个ROS消息,用于发送到“chatter”主题。

chattermsg = rosmessage(chatterpub);
chattermsg.Data = 'hello world'
chattermsg =
ROS String message with properties:
MessageType: 'std_msgs/String'
Data: 'hello world'
Use showdetails to show the contents of the message

发布一个消息到“/chatter”主题,观察到字符串被订阅器回调函数显示。

send(chatterpub,chattermsg)
pause(2)
Chatter Callback message data:
ans =
hello world

一旦你发布字符串数据,“exampleHelperROSChatterCallback”函数就会被调用。

关闭ROS网络

从ROS网络中移除采样节点、发布器和订阅器,同时清除全局变量“pos”和“orient”。代码运行示例:

exampleHelperROSShutDownSampleNetwork
clear global pos orient

关闭ROS主控节点并删除全局节点。代码运行示例:

rosshutdown
Shutting down global node /matlab_global_node_8332 with NodeURIhttp://bat5136glnxa64:35671/
Shutting down ROS master onhttp://bat5136glnxa64.mathworks.com:11311/.

纠错,疑问,交流: 请进入讨论区点击加入Q群

获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号


标签: ros与matlab语言入门教程