最近,在探索使用MATLAB来辅助ROS开发,当我们想要实现某项功能或者完成某项任务的时候,不知道有哪些已有的工具可以使用也是开发过程中的阻碍之一,本篇文章介绍一下我对相关的simulink模块的使用探索

   本文以MATLAB2020B的Simulink模块为例进行介绍


   目录:

   1、Subscribe模块与Bus selector模块
   2、MATLAB Function模块
   3、Blank Message模块、Bus Assignment模块与Publish模块
   4、Current Time模块
   5、Get Parameter模块与Set Parameter模块
   6、Read Image模块与Video Viewer模块
   7、Read Point Could模块


   1、Subscribe模块与Bus selector模块

Subscribe模块可以创建一个订阅者,接收来自ROS网络的消息。它的输出Msg是一个ROS消息(总线信号)。Msg一般需要接一个Bus selector模块来选择提取总线中我们想要处理的信号。

   该模块可以创建一个订阅者,接收来自ROS网络的消息。它的输出Msg是一个ROS消息(总线信号)。Msg一般需要接一个Bus selector模块来选择提取总线中我们想要处理的信号。

   如下图所示,我订阅了ROS发布的话题/imu_data,并使用Bus selector模块选择了从总线中提取我们需要的惯性传感器IMU输出的四元数


   经过转换公式与角度变化,将其转换成欧拉角,就可以使用MATLAB实时观测小车的姿态信息了,如下面的动图所示:

在这里插入图片描述

   Subscribe模块的输出IsNew是一个布尔值,表示在上一个时间步骤中是否收到了消息。当IsNew为真时,Msg持有新收到的消息。当IsNew为假时,Msg持有最后收到的消息。如果我们对该输出此并不关心,可以连一个terminator模块,terminator的作用是终止未连接的输出端口。使用Terminator模块去盖住不与其他模块连接的模块的输出。如果我们需要对其进行观测,则可以连一个Scope模块,如下图所示:

在这里插入图片描述


   2、MATLAB Function模块

   simulink的使用,通过模块化的编程方式,看似是简单了,但是当面对比较复杂的数学公式的时候,使用simulink搭建速度就变慢了,这个时候就可以使用MATLAB Function模块了,它允许我们在simulink中嵌入MATLAB代码,比如上面读取四元数转化为欧拉角,并进行进制转换的例子中,转化公式就可以通过MATLAB Function来实现,编写快速,也很方便
在这里插入图片描述


   3、Blank Message模块、Bus Assignment模块与Publish模块


   Blank Message模块可以用指定的消息或服务类型创建一个空白消息。这里的空白消息的消息类型,根据我们的需要进行设定,它的输出Msg是一个空白的ROS消息(总线信号)。设置Class参数可以在ROS消息、服务请求和服务响应消息之间进行选择。一般接到使用总线分配块Bus Assignment的Bus接口,来使用Bus Assignment模块修改总线信号中的特定字段。Bus Assignment模块允许总线中的元素被分配新的值。左边的列表框显示输入总线中的元素。使用选择按钮来选择要分配的元素。右边的列表框显示选择的内容。使用向上、向下或移除按钮重新排列选择。

   比如我选择指定了名为ackermann_msgs/AckermannDriveStamped消息,并通过Bus Assignment模块对我们想要指定的值SteeringAngle和Speed进行赋值


   到这里,我们需要发布的消息就配置完成了,接下来就要通过Publish模块将其发送出去了

   Publish模块用于向ROS网络发送消息。它的输入需要接一个一个ROS消息(总线信号)。该信号一般由Bus Assignment模块提供

   在这个例子里,我们将配置好的消息以话题的形式发布出去,在ROS中已经写好了一个订阅者,它会订阅名为/ackermann_cmd_mux/output的话题,然后控制小车按照接收到的数据运动,因此我们需要将已经配置好的运动信息以话题/ackermann_cmd_mux/output的形式发布出去,我们将SteeringAngle设为-0.4,Speed设为0.7就可以让小车画圆,如下图所示

在这里插入图片描述


   4、Current Time模块


   Current Time模块是一个简单,但是非常重要的模块,它可以检索当前的ROS时间或系统时间。可以选择输出格式为一个总线或一个double类型数据。这里我们介绍输出为double时的应用,这段时间,我在研究MALTAB与ROS的联合仿真的时候,遇到的其中一个问题就是时间维度不同。
   我当前的研究是控制器由simulink搭建,控制对象为ROS中运行在gazebo的小车,比如现在我在simulink中的控制器去发布一个目标轨迹并同时发布小车的运动指令去跟踪这个轨迹,让ROS中的小车订阅该运动指令完成轨迹跟踪,那么问题来了在给定这个轨迹的时候,我们期望它是随时间变化的实时的轨迹,而不是由一堆写好的坐标点构成的,就需要用到时间的给定,在了解到Current Time模块之前,我是用ramp模块作为时间给定的,可想而知控制器用的MALTAB的时间维度,而控制对象用的ROS的时间维度,控制起来效果并不能令人满意,改为Current Time模块作为控制器的时间给定后,两者的时间维度都统一到了ROS的时间维度,控制效果良好

   我们可以将该模块的输出连一个display模块看一下,时间是否跟ROS中时间相同,如下所示,当它输出910的时候,对应于gazebo底部的ros时间(Sim Time)是00:00:15:10:000,也就是15分钟10秒,换成秒正好就是910秒与该模块的输出相同

在这里插入图片描述


   5、Get Parameter模块与Set Parameter模块

   Get Parameter模块可以用于从ROS参数服务器获取数值,并通过Value输出,ErrorCode端口输出ROS参数的检索状态,是一个整数值。

   Set Parameter模块可以用于在ROS参数服务器上设置数值。Value端口包含ROS参数的值。这个值将被发送到ROS参数服务器上进行更新。

   下面通过一个例子来简单看一下他们的使用方法,我们使用Get Parameter模块可以用于从ROS参数服务器取/racecarljoint_state_controller的发布速率,默认值为50,然后通过MATLAB Function编写一个简单的函数 当读取到的值为50时,函数输出60,当读取到的值为60时,函数输出50,并把输出值给Set Parameter模块在ROS参数服务器上对该数值进行修改,然后我们将 Set Parameter模块读取到的值用display模块显示出来,按照我们的设想,它应该是50跟60的相互切换
   搭建的程序如下:


   我们来看一下运行效果(动态):

在这里插入图片描述

   可以看到确实是在进行50跟60的切换,但要注意肯定不是50到60再到50这种模式,还是时间不同步以及时间维度不同的问题,它是保持若干个50后,才切换到60,再保持若干60,再切换到50,且个数并不是一个固定的数


   6、Read Image模块与Video Viewer模块


   Read Image模块用于从ROS图像信息中提取图像信号。Msg端口接受一个代表图像的ROS消息(总线信号)。一般可由Subscribe模块给定,图像端口image为灰度图像输出一个[MxN]数组,为彩色图像输出一个[MxNx3]数组可以与Video Viewer模块相连显示出订阅的图像信息。ErrorCode端口以整数值输出图像转换状态。

   下面通过一个例子来简单看一下他们的使用方法,我们使用Subscribe模块可以用于从ROS中订阅话题/camera/image_raw(在ROS中的传感器已成功运行),然后将其输出Msg与Read Image模块的Msg端相连,Read Image模块的输出Image与Video Viewer模块的Image端相连,如下图所示:


   我们来看一下运行效果:

在这里插入图片描述


   7、Read Point Could模块


   Read Point Could模块用于从ROS点云信息中提取点云数据。Msg端口接受一个代表点云的ROS消息(总线信号)。如果保留点云结构没有被选中(默认),XYZ端口将点的笛卡尔坐标输出为[Px3]数组,其中P是传入点云中的点的数量。否则,XYZ端口会以[MxNx3]数组的形式输出点的笛卡尔坐标,其中M和N分别是输入的点云的高度和宽度,经过简单的运算后配合scatter3函数即可输出其点云图像,除此之外还可以通过set函数设定3D点云图像的视野。ErrorCode端口将图像转换状态输出为一个整数值。勾选上RGB输出后可输出深度RGB,同样可以连接Video Viewer模块来查看

   下面通过一个例子来简单看一下他们的使用方法,我们使用Subscribe模块可以用于从ROS中订阅话题/cameraldepth/points(在ROS中的传感器已成功运行),然后将其输出Msg与Read Point Could模块的Msg端相连,Read Point Could模块的输出RGB与Video Viewer模块的Image端相连,Read Point Could模块的输出XYZ经过pointCloudCOM模块的处理后成功将X,Y,Z三个坐标轴上的数据分离开来,再使用scatter3函数就能画出其点云图像了,如下图所示:

function [xPoints,yPoints,zPoints] = pointCloudCOM(xyzPoints)

% Turn matrix into vectors.
xPoints = reshape(xyzPoints(:,:,1),numel(xyzPoints(:,:,1)),1);
yPoints = reshape(xyzPoints(:,:,2),numel(xyzPoints(:,:,2)),1);
zPoints = reshape(xyzPoints(:,:,3),numel(xyzPoints(:,:,3)),1);


end


   我们来看一下运行效果:

在这里插入图片描述