主要内容

使用专门的ROS的消息

这个例子展示了如何处理消息类型的激光扫描、压缩和压缩图像,点云,相机信息,occcupancy网格,和octomap消息。

这是一些常用的ROS消息存储数据的格式,需要一些转换之前,可以用于进一步的处理。MATLAB®可以帮助你通过格式化这些专业ROS消息,方便使用。

先决条件:处理基本的ROS消息

加载示例消息

加载一些示例消息。这些信息是真实和合成数据填充不同机器人传感器。

负载(“specialROSMessageData.mat”)

图像信息

MATLAB支持图像信息,总是有金宝app消息类型sensor_msgs /形象

创建一个空的图像信息使用rosmessage看到的标准ROS格式图像的信息。

emptyimg = rosmessage (“sensor_msgs /形象”DataFormat =“结构”)
emptyimg =结构体字段:MessageType: sensor_msgs /图片的标题:[1×1 struct]高度:0宽度:0编码:“IsBigendian: 0步骤:0数据:[0×1 uint8]

为了方便起见,一个完全填充的图像信息,存储在img变量是加载自specialROSMessageData.mat

检查图像信息变量img在你的工作空间。中存储的图像的大小宽度高度属性。ROS发送实际的图像数据使用一个向量数据财产。

img
img =结构体字段:MessageType: sensor_msgs /图片的标题:[1×1 struct]高度:480宽度:640编码:“rgb8”IsBigendian: 0步骤:数据:1920 (921600×1 uint8)

数据属性存储原始图像数据,不能直接使用MATLAB处理和可视化。您可以使用rosReadImage函数来检索图像的格式与MATLAB兼容。

imageFormatted = rosReadImage (img);

原始图像有rgb8编码。默认情况下,rosReadImage返回图像在标准的480 - 640 - 3uint8格式。查看这张图片使用imshow函数。

imshow (imageFormatted)

MATLAB®支金宝app持所有ROS图像编码格式,和rosReadImage处理图像数据转换的复杂性。除了彩色图像,MATLAB还支持单色和深度图像。金宝app

此外,MATLAB提供的rosWriteImage函数MATLAB图像转换为ROS消息使用函数。运用基本的对象检测样本图像的颜色阈值。可视化修改后的图像。

greenPercentage = 100 *双(imageFormatted(:,: 2)。/笔(imageFormatted 3);thresholdImg = 255 * uint8 (greenPercentage > 35);imshow (thresholdImg)

写修改图像ROS的消息rosWriteImage函数。由于修改后的图像只有1频道和类型uint8,可以使用mono8编码。

imageMsg = rosWriteImage (emptyimg thresholdImg,编码=“mono8”);

压缩消息

许多活性氧系统把图像数据压缩格式。MATLAB支持这些压缩消息。金宝app

创建一个空压缩消息使用rosmessage。压缩图像ROS消息类型sensor_msgs / CompressedImage和有一个标准的结构。

emptyimgcomp = rosmessage (“sensor_msgs / CompressedImage”DataFormat =“结构”)
emptyimgcomp =结构体字段:MessageType:‘sensor_msgs / CompressedImage’头:1×1结构形式:”数据:[0×1 uint8]

为了方便起见,一个压缩的图像信息,已经被加载specialROSMessageData.mat

检查imgcomp变量被相机捕获。的格式属性捕获的所有信息需要解压缩图像数据存储在MATLAB数据

imgcomp
imgcomp =结构体字段:MessageType:“sensor_msgs / CompressedImage”标题:[1×1 struct]格式:“bgr8;jpeg压缩bgr8”数据:[30376×1 uint8]

类似的图像信息,您可以使用rosReadImage获取标准RGB格式的图像。尽管最初的编码压缩的图像bgr8,rosReadImage的转换。

compressedFormatted = rosReadImage (imgcomp);

使用可视化图像imshow函数。

imshow (compressedFormatted)

大多数图像格式支持压缩消息类型。金宝app的16 uc132 fc1编码不支持压缩深度图像。金宝app支持单色和彩色图像编码。金宝app

点云

点云可以被各种各样的传感器用于机器人技术,包括激光雷达,Kinect®,立体相机。最常见的消息类型ROS传送点云sensor_msgs / PointCloud2和MATLAB为您提供一些专门的函数来处理这些数据。

你可以看到点云的标准ROS格式消息通过创建一个空的点云消息。

emptyptcloud = rosmessage (“sensor_msgs / PointCloud2”DataFormat =“结构”)
emptyptcloud =结构体字段:MessageType:“sensor_msgs / PointCloud2”标题:[1×1 struct]高度:0宽度:0字段:[0×1 struct] IsBigendian: 0 PointStep: 0 RowStep: 0数据:[0×1 uint8] IsDense: 0

查看存储在密集的点云的消息ptcloud工作空间中的变量:

ptcloud
ptcloud =结构体字段:MessageType:“sensor_msgs / PointCloud2”标题:[1×1 struct]高度:480宽度:640字段:[4×1 struct] IsBigendian: 0 PointStep: 32 RowStep: 20480数据:[9830400×1 uint8] IsDense: 0

点云信息编码的数据消息的属性。你可以提取x,y,z作为一个坐标N3矩阵通过调用rosReadXYZ函数。

xyz = rosReadXYZ (ptcloud)
xyz =307200×3个矩阵南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南⋮

在点云数据表明一些x,y,z值是无效的。这是一个工件的Kinect®传感器,你可以安全地删除所有值。

xyzValid = xyz (~ isnan (xyz (: 1)):)
xyzValid =193359×3个矩阵0.1378 -0.6705 1.6260 0.1409 -0.6705 1.6260 0.1433 -0.6672 1.6180 0.1464 -0.6672 1.6180 0.1502 -0.6705 1.6260 0.1526 -0.6672 1.6180 0.1556 -0.6672 1.6180 0.1587 -0.6672 1.6180 0.1618 -0.6672 1.6180 0.1649 -0.6672 1.6180⋮

一些点云传感器也将RGB颜色值分配给每个点的点云。如果这些颜色值存在,您可以检索调用rosReadRGB

rgb = rosReadRGB (ptcloud)
rgb =307200×30.8392 0.7059 0.5255 0.8392 0.7059 0.5255 0.8392 0.7137 0.5333 0.8392 0.7216 0.5451 0.8431 0.7137 0.5529 0.8431 0.7098 0.5569 0.8471 0.7137 0.5569 0.8549 0.7098 0.5569 0.8588 0.7137 0.5529 0.8627 0.7137 0.5490⋮

你可以想象的点云rosPlot函数。rosPlot自动提取x,y,z坐标和RGB颜色值(如果存在的话),向他们展示三维散点图。的rosPlot函数忽略所有x,y,z坐标,即使RGB值存在。

rosPlot (ptcloud)

检查所有点云存储字段信息使用rosReadAllFieldNames函数。加载点云的消息包含四个字段x,y,z,rgb

= rosReadAllFieldNames字段名(ptcloud)
字段名=1×4细胞{x} {y} {' z '} {rgb的}

您可以访问任何领域使用的相应数据rosReadField函数。您必须手动将返回的数据,这取决于它是如何格式化。例如,RGB图像可以根据类型中提取数据uint8并重塑结果。使用的结果rosReadAllFieldNames函数的输入验证。

如果任何(包含字段名,“rgb”)rawData =定型(rosReadField (ptcloud“rgb”),“uint8”);tmp =重塑(排列(重塑(rawData 4 []), (3,2,1)), ptcloud.Width, ptcloud.Height, 4);pcImg =排列(tmp (:,:, (3,2,1)), [2 1 3]);imshow (pcImg)结束

Octomap消息

ROS使用Octomap消息来实现3 d占用网格。Octomap消息是常用的在机器人应用程序中,如3 d导航你可以看到的标准ROS格式octomap适当类型的消息通过创建一个空的消息。

使用rosmessage创建消息。

emptyoctomap = rosmessage (“octomap_msgs / Octomap”DataFormat =“结构”)
emptyoctomap =结构体字段:MessageType:“octomap_msgs / Octomap”标题:[1×1 struct]二进制:0 Id:”决议:0数据:[0×1 int8]

为了方便起见,一个octomap信息是完全填充和存储在octomap变量加载自specialROSMessageData.mat。

检查变量octomap在你的工作空间。的数据字段包含octomap结构序列化格式。

octomap
octomap =结构体字段:MessageType:“octomap_msgs / Octomap”标题:[1×1 struct]二进制:1 Id:八叉树的解析:0.0250数据:[3926×1 int8]

创建一个occupancyMap3D(导航工具箱)对象从ROS消息使用rosReadOccupancyMap3D函数。显示3 d入住率地图使用显示函数。

occupancyMap3DObj = rosReadOccupancyMap3D (octomap);显示(occupancyMap3DObj)

四元数信息

四元数在机器人常用的表达定位。使用rosmessage创建一个四元数的信息和观察字段。

emptyquatmsg = rosmessage (“geometry_msgs /四元数”DataFormat =“结构”)
emptyquatmsg =结构体字段:MessageType:“geometry_msgs /四元数”X: 0 Y: 0 Z: 0 W: 0

为了方便起见,一个四元数的信息代表一个90度旋转对z轴加载specialROSMessageData.mat。检查变量quatMsg在你的工作空间。

quatmsg
quatmsg =结构体字段:MessageType:“geometry_msgs /四元数”X: 0 Y: 0 Z: 0.7071 W: 0.7071

创建一个四元数对象从ROS消息使用rosReadQuaternion函数。的四元数对象包含x, y, z和w组件提供了额外的功能,如旋转的一个点。

皮疹= rosReadQuaternion (quatmsg);

定义一个点在三维空间中,使用旋转rotatepoint函数。可视化两个点

cartesianPoint = [1, 0, 1];cartesianPoint plot3 (cartesianPoint (1) (2), cartesianPoint (3),“波”)举行plot3 ([0; cartesianPoint (1)]、[0; cartesianPoint (2)]、[0; cartesianPoint (3)),“k”)rotationResult = rotatepoint(皮疹、cartesianPoint);rotationResult plot3 (rotationResult (1) (2), rotationResult (3),“罗”)plot3 ([0; rotationResult (1)]、[0; rotationResult (2)]、[0; rotationResult (3)),“k”)包含(“x”)ylabel (“y”)zlabel (“z”网格)

相机信息消息

机器人视觉摄像机标定是一种常用的程序应用。ROS提供sensor_msgs / CameraInfo消息类型来发布校准信息。使用rosmessage创建一个相机和观察字段信息消息。

emptycamerainfomsg = rosmessage (“sensor_msgs / CameraInfo”DataFormat =“结构”)
emptycamerainfomsg =结构体字段:MessageType:“sensor_msgs / CameraInfo”标题:[1×1 struct]高度:0宽度:0 DistortionModel:“D:[0×1双)K:[9×1双]R:[9×1双]P:[12×1双]BinningX: 0 BinningY: 0 Roi: [1×1 struct]

值得注意的是,消息存储矩阵KP向量。ROS需要存储在这些矩阵行格式。MATLAB矩阵存储在列为主,因此提取KP矩阵需要重塑和置换。

estimateCameraParameters(计算机视觉工具箱)可以用来创建函数cameraParameters(计算机视觉工具箱)stereoParameters(计算机视觉工具箱)对象。您可以创建sensor_msgs / CameraInfo从这些对象使用的消息rosWriteCameraInfo函数。在使用前必须被转化为结构的对象。加载相机校正结构。

负载(“calibrationStructs.mat”)

为了方便起见,变量参数个数加载自calibrationStructs.mat是一个完全填充的cameraParameters结构体。写cameraParameters结构新ROS消息使用rosWriteCameraInfo函数。

味精= rosWriteCameraInfo (emptycamerainfomsg params);

下面的表显示了ROS cameraParameters对象之间的通信和消息。

exampleHelperShowCameraParametersTable
ans =5×2表ROS消息相机参数___________ ______________________内在矩阵“K”“IntrinsicMatrix径向畸变“D”(1:2)"RadialDistortion" Tangential distortion "D(3:5)" "TangentialDistortion" Height "Height" "ImageSize(1)" Width "Width" "ImageSize(2)"

验证的内在矩阵ROS消息匹配的内在矩阵参数个数

K =重塑(msg.K 3 3) '
K =3×31.0000 714.1885 563.6481 710.3785 - 355.7254 0 0
intrinsicMatrix = params.IntrinsicMatrix '
intrinsicMatrix =3×31.0000 714.1885 563.6481 710.3785 - 355.7254 0 0

为了方便起见,变量stereoParams加载自calibrationStructs.mat是一个完全填充的stereoParameters结构体。写stereoParameters结构使用两个新的ROS消息rosWriteCameraInfo函数。

[msg1, msg2] = rosWriteCameraInfo(味精、stereoParams);

下面的表显示了ROS stereoParameters对象之间的通信和消息。

exampleHelperShowStereoParametersTable
ans =2×2表ROS消息stereoParameters _______ ___________________________翻译照相机2 P (: 1:2)”"TranslationOfCamera2(1:2)" Rotation of camera 2 "inv(R1)*R2" "RotationOfCamera2"

验证相机2 ROS消息的旋转矩阵stereoParams匹配。

R1 =重塑(msg1.R 3 3) ';R2 =重塑(msg2.R 3 3) ';R = R1、R2
R =3×31.0000 -0.0002 -0.0050 0.0002 1.0000 -0.0037 0.0050 0.0037 1.0000
rotationOfCamera2 = stereoParams.RotationOfCamera2
rotationOfCamera2 =3×31.0000 -0.0002 -0.0050 0.0002 1.0000 -0.0037 0.0050 0.0037 1.0000

验证相机2翻译ROS消息的矢量和stereoParams匹配。

P =重塑(msg2.P 4 3) ';P (1:2)”
ans =1×2-119.8720 - -0.4005
translationOfCamera2 = stereoParams.TranslationOfCamera2 (1:2)
translationOfCamera2 =1×2-119.8720 - -0.4005

激光扫描信息

激光扫描仪在机器人常用的传感器。ROS提供sensor_msgs /提升消息类型来发布激光扫描信息。使用rosmessage创建一个激光扫描信息和观察字段。

emptyscan = rosmessage (“sensor_msgs /提升”,“DataFormat”,“结构”)
emptyscan =结构体字段:MessageType:“sensor_msgs /提升”标题:[1×1 struct] AngleMin: 0 AngleMax: 0 AngleIncrement: 0 TimeIncrement: 0 ScanTime: 0 RangeMin: 0 RangeMax: 0范围:[0×1单]强度:(0×1个)

既然你创建了一个空的消息,emptyscan不包含任何有意义的数据。为了方便起见,激光扫描的消息完全填充和存储在扫描变量是加载自specialROSMessageData.mat

检查扫描变量。主数据的消息范围财产。中的数据范围是一个向量的障碍距离记录在小角增量。

扫描
扫描=结构体字段:MessageType:“sensor_msgs /提升”标题:[1×1 struct] AngleMin: -0.5467 AngleMax: 0.5467 AngleIncrement: 0.0017 TimeIncrement: 0 ScanTime: 0.0330 RangeMin: 0.4500 RangeMax: 10范围:[640×1单]强度:(0×1个)

你可以扫描角度的ROS消息使用rosReadScanAngles函数。在极坐标下使用可视化扫描数据polarPlot函数。

角= rosReadScanAngles(扫描);图polarplot(角度、scan.Ranges,线宽= 2)标题(“激光扫描”)

你可以测量的点在笛卡尔坐标使用rosReadCartesian函数。

xy = rosReadCartesian(扫描);

这个填充xy的列表(x, y)坐标计算基于所有有效的阅读范围。使用可视化扫描信息rosPlot功能:

rosPlot(扫描,“MaximumRange”5)

创建一个lidarScan对象从ROS消息使用rosReadLidarScan函数。的lidarScan对象包含范围、角度、和笛卡尔点,提供了额外的功能,如改变扫描点。使用transformScan函数使用旋转扫描点和可视化情节

lidarScanObj = rosReadLidarScan(扫描)
lidarScanObj = lidarScan属性:范围:(640×1双)角度:(640×1双)笛卡尔:(640×2双)数:640
rotateScan = transformScan (lidarScanObj[0, 0,π/ 2]);情节(rotateScan)

占用网格信息

占用网格消息2 d导航应用程序常用的机器人ROS提供nav_msgs / OccupancyGrid消息类型来发布激光扫描信息。使用rosmessage创建一个占用网格信息和观察字段。

emptyMap = rosmessage (“nav_msgs / OccupancyGrid”DataFormat =“结构”)
emptyMap =结构体字段:MessageType:“nav_msgs / OccupancyGrid”标题:[1×1 struct]信息:[1×1 struct]数据:[0×1 int8]

请注意,emptyMap不包含任何有意义的数据。为了方便起见,一个占用网格的消息完全填充和存储在mapMsg变量加载自specialROSMessageData.mat。

检查mapMsg变量。占用网格值进行编码的数据字段。

mapMsg
mapMsg =结构体字段:MessageType:“nav_msgs / OccupancyGrid”标题:[1×1 struct]信息:[1×1 struct]数据:[251001×1 int8]

使用rosReadOccupancyGridROS消息转换为一个函数occupancyMap(导航工具箱)对象。使用显示函数显示占用网格。

occupancyMapObj = rosReadOccupancyGrid (mapMsg);显示(occupancyMapObj);

您可以使用occupancyMap(导航工具箱)对象函数来操纵占用网格。使用膨胀函数被占领的地区扩张。occupancyMap对象写入一个新的ROS消息使用rosWriteOccupancyGrid函数。使用显示函数来显示新的占用网格。

充气(occupancyMapObj 5) occupancyMapInflatedMsg = rosWriteOccupancyGrid (mapMsg occupancyMapObj);显示(occupancyMapObj);

或者,您可以创建一个binaryOccupancyMap(导航工具箱)对象从ROS占用网格信息使用rosReadBinaryOccupancyGrid函数。一个二进制入住率地图离散入住率的值01在每个细胞而入住率地图概率区间占用值01在每一个细胞。使用显示函数显示二进制占用网格。

binaryMapObj = rosReadBinaryOccupancyGrid (mapMsg);显示(binaryMapObj);

类似地,您可以使用binaryOccupancyMap(导航工具箱)对象操作二进制占用网格功能。使用膨胀函数来改变二进制占用网格和创建一个新的ROS消息使用rosWriteBinaryOccupancyGrid函数。使用显示函数来显示新的二进制占用网格。

充气(binaryMapObj 5) binaryMapInflatedMsg = rosWriteBinaryOccupancyGrid (mapMsg binaryMapObj);显示(binaryMapObj);