ROS与Matlab语言入门教程-开始在Simulink中使用ROS
Simulink支持机器人操作系统(ROS),使得用户可用Simulink创建模型在ROS网络中使用。ROS是一个通信布局,允许机器人系统的不同部分以消息的形式交换信息。一个组件通过发布消息到一个话题,例如“/odometry”,其它组件通过订阅该话题接收。
Simulink支持ROS包括Simulink库用于发送和接收指定话题的消息,当用户仿真模型时,Simulink连接到ROS网络,该网络可以运行在Simulink上的机器人,也可以是远程的系统。一旦建立连接,Simulink一直与ROS网络交换消息直到仿真结束。如果安装了嵌入式代码,用户还可以从Simulink模型为单独的ROS组件或者节点生成C++代码。
本例中,用户将学习:
设置ROS网络;
创建和运行Simulink模型以发送和接收ROS消息;
在ROS消息中使用消息。
预备知识
如果用户对Simulink或者ROS陌生,建议复习如下内容:
Create a Simple Model;
1.2 开始使用ROS.
模型
用户将会使用Simulink发布机器人的(x,y)位置坐标,还会订阅相同的定位话题并显示接收到的(x,y)坐标。你将在本例程创建的模型如下图所示。
初始化ROS
每一个ROS网络都有一个ROS主控节点,用于协调ROS网络中的所有部分,在本例程,用户将会使用MATLAB在本地系统创建ROS主控节点。Simulink将会自动检测并使用本地主控节点,在MATLAB命令行,执行如下代码:
rosinit
任务1-创建发布器
本任务中,用户将配置一个块以发送“geometry_msgs/Point”消息到“/location”话题。(“/”是标准的ROS语法)。
从MATLAB的工具栏,选择“HOME > New > Simulink Model”以打开一个新的Simulink模型。
从模型窗口选择“View > Library Browser”以打开Simulink库浏览器,点击“Robotics System Toolbox”选项卡(用户还可以在MATLAB的命令行窗口输入“robotlib”)。
拖放一个“Publish”块到模型中并双击以配置话题和消息的类型。
在“Topic source”域选择“Specify your own”,在“Topic”域输入“/location”。
在“Message Type”域的右侧,点击“Select...”,将弹出一个窗口,选择“geometry_msgs/Point”并点击“OK”以关闭弹出的窗口。
任务2-创建ROS消息
本任务中,用户将会创建一个空白的ROS消息,输入(x,y)位置数据给机器人路径,更新ROS消息到ROS网络。
ROS消息在Simulink中被表述为“bus signal”,总线信号是Simulink信号的捆绑,可以包含其它总线信号(参阅Simulink的“busdemo”例程获得综述)。ROS“Blank Message”块输出一个与ROS消息有关的Simulink总线消息。
点击Simulink库浏览器的“Robotics System Toolbox”选项卡,或者在MATLAB命令行输入“robotlib”。
拖放一个“Blank Message”块到模型中并双击打开。点击“Message type”域旁边的“Select…”并从弹出的查询窗口中选择“geometry_msgs/Point”,最后点击“OK”。
从库浏览器的选择“Simulink > Signal Routing”选项卡,拖放一个“Bus Assignment”块。连接“Blank Message”块的输出端口到“Bus Assignment”块的输入端口,连接“Bus Assignment”块的输出端口到“ROS Publish”块的输入端口,如下图所示。
双击“Bus Assignment”块,用户将会在左侧的列表中看到X,Y,Z(组成“geometry_msgs/Point”消息的信号)。从右侧列表选择“??? signal1”并点击“Remove”,从左侧列表选择X和Y并点击“Select>>”,最后点击“OK”。
注意:如果用户在左侧的列表中看不到X,Y和Z,关闭“Bus Assignment”块掩膜,点击“Simulation > Update Diagram”确保总线信息正确传播。如果用户看到“Selected signal 'signal1' in the Bus Assignment block cannot be found”,说明总线的信息没有被传播。关闭诊断观察器,重复上述步骤。
用户现在可以传播带有机器人位置的总线信号。
从库浏览器的“Simulink > Sources”选项卡,拖放两个“Sine Wave”块到模型中。连接每个“Sine Wave”块的输出端口到“Bus Assignment”块指定的输入端口X和Y。
双击连接到输入端口X的“Sine Wave”块,设置“Phase”参数的值为“-pi/2”并点击“OK”。
用户的发布器看起来如下图所示。
此时,模型被设置好以发布消息到ROS网络,用户可以根据如下步骤验证:
在工具栏,设置仿真停止时间为“inf”。
点击“Play”按钮开始仿真,Simulink为模型创建了一个专用的ROS节点,创建了一个与“Publish”块一致的发布器。
在仿真运行期间,在MATLAB命令窗口输入“rosnode list”,该指令会列出ROS网络中所有可用的节点,应该包含了名称类似“/untitled_81473”的节点。(模型的名称,后缀是随机数以让该名称唯一)。
在仿真运行期间,在MATLAB命令窗口输入“rostopic list”,该指令将列出ROS网络中所有可用的话题,且应该包括“/location”话题。
观察到基本的MATLAB工作弓箭有一个或多个名称以“SLBus”为开头的变量。这些是Simulink创建的临时总线对象且不可修改。然而,安全起见应该从工作空间中清除这些变量,因为当有需要时还会重新创建。
点击“Stop”按钮停止仿真,Simulink删除ROS节点和ROS发布器。通常来说,模型的ROS节点以及相关的发布器和订阅器会在仿真结束的时候自动删除,不需要附加的清除步骤。
任务3-创建订阅器
本任务中,用户将使用Simulink订阅发送到“/location”话题的消息,并从消息中提取(x,y)位置并绘制在XY-面板中。
从库浏览器的“Robotics System Toolbox”选项卡,拖放一个“Subscribe”块到模型中并双击。
为“Topic source”域选择“Specify your own”,并在“Topic”域输入“/location”。
点击“Message type”域右边的“Select...”,从弹出的窗口选择“geometry_msgs/Point”并点击“OK”。“Subscribe”块输出一个Simulink总线信号,因此用户需要从该信号提取出X和Y。
从库浏览器的“Simulink > Signal Routing”选项卡,拖放一个“Bus Selector”块到模型中。
连接“Subscribe”的输出“Msg”到“Bus Selector”块的输入端口。
点击“Simulation > Update Diagram”确定总线信息已经被传播。用户可能得到一个错误“Selected signal 'signal1' in the Bus Selector block 'untitled/Bus Selector' cannot be found in the input bus signal”,该错误是预料中的,且将在下面的步骤中解决。
双击“Bus Selector”,选择右侧列表中的“??? signal1”和“??? Signal2”并点击“Remove”,从左侧列表中选择X和Y信号点击“Select>>”并点击“OK”。
“Subscribe”块在每个时间步进都会输出最新的从话题接收的消息,“IsNew”输出指示在时间步进期间消息是否已经被接收,在当前任务中,不需要“IsNew”输出,因此做如下的操作:
点击库浏览器中的“Simulink > Sinks”选项卡,拖放一个“Terminator”块到模型中。
剩下的步骤配置显示提取的X和Y信号。
从库浏览器中选择“Simulink > Sinks”选项卡,拖放一个“XY Graph”到模型中,连接“Bus Selector”块的输出端口到“XY Graph”块的输入端口。
从库浏览器中选择“Simulink > Sinks”选项卡,拖放一个“Display”到模型中,连接每一个“Bus Selector”块的输出端口到“Display”块。
用户的整体模型看起来如下图所示。
保存模型。
任务4-配置和运行模型
本任务中,用户将配置并运行自己的模型。
点击“Simulation > Model Configuration Parameters”,在“Solver”面板,设置“Type”为“Fixed-step”,“ Fixed-step size”的值为0.01。
设置仿真停止时间为10.0。
点击“Play”按钮开始仿真,一个XY绘图将会出现。
当第一次运行Simulink中的模型,XY绘图可能比上图看起来更抖晃,这是由载入ROS库引入的延迟造成的。只要重新运行几次仿真,绘图将看起来更平滑。
注意,仿真并不是以实际或者真是的时间工作,模型中的块在一个循环中估计,仅仅仿真进程时间,并没有跟踪实际时钟时间(详细信息请参阅Simulation Loop Phase)
任务5-修改模型仅对消息反应
在上面的模型中,“Subscribe”块在每个时间步进输出一个消息(总线信号),如果根本没有接收到消息,会输出空白消息(例如,消息的值为0)。因此,(X,Y)坐标初始化绘制在(0,0)。
在本任务中,用户将会修改模型以使用一个使能的子系统,因此仅当接收到新消息是绘制位置(更多信息,参阅Create an Enabled Subsystem)。简便期间,已经包含了一个预定义的模型(pre-configured model)。
在模型中,点击并拖以选中“Bus Selector”和“XY Graph”块,右键点击选择“Create Subsystem from Selection”。
从库浏览器的“Simulink > Ports & Subsystems”选项卡,拖放一个“Enabled”块到新建的子系统中。(同时选中新建子系统和使能块,出现小提示图标,选择“created enabled subsystem”)
连接“IsNew”块的输出到“Subscribe”块的子系统的使能输入,如下图所示。删除“Terminator”块,注意“IsNew”输出仅当在前一个时间步进中接收到新消息才为真。
保存模型。
点击“Play”按钮开始仿真,用户将会看到XY绘图如下图所示。
使能子系统中的块仅当新的ROS消息被“Subscribe”块接收的时候才执行,因此,初始(0,0)不会在XY绘图中显示。
获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号