使用专门的ROS消息
一些常用的ROS消息以一种需要进行转换的格式存储数据,然后才能用于进一步处理。MATLAB®可以帮助您格式化这些专门的ROS消息,方便使用。在本例中,您将探索如何处理激光扫描、未压缩和压缩图像、点云、相机信息、占用网格和八元地图消息的消息类型。
先决条件:处理基本ROS消息
加载示例消息
加载一些示例消息。这些信息由来自各种机器人传感器的真实和合成数据填充。
负载(“specialROSMessageData.mat”)
图像信息
MATLAB提供了对图像消息的支持,它总是具有消息类型sensor_msgs /形象
.
使用创建空图像消息rosmessage
参阅图像消息的标准ROS格式。
Emptyimg = rosmessage(“sensor_msgs /形象”DataFormat =“结构”)
emptyimg =带有字段的结构:MessageType: 'sensor_msgs/Image' Header: [1x1 struct] Height: 0 Width: 0 Encoding: " IsBigendian: 0 Step: 0 Data: [0x1 uint8]
为方便起见,完全填充并存储在img
变量从specialROSMessageData.mat
.
检查图像消息变量img
在你的工作空间。图像的大小存储在宽度
而且高度
属性。中的向量发送实际的图像数据数据
财产。
img
img =带有字段的结构:MessageType: 'sensor_msgs/Image'头:[1x1 struct]高度:480宽度:640编码:'rgb8' IsBigendian: 0步骤:1920数据:[921600x1 uint8]
的数据
属性存储的原始图像数据不能直接用于MATLAB中的处理和可视化。您可以使用rosReadImage
函数以与MATLAB兼容的格式检索图像。
imageformatting = rosReadImage(img);
原始图像是rgb8编码。默认情况下,rosReadImage
返回标准480 × 640 × 3的图像uint8
格式。的方法查看此图像imshow
函数。
imshow (imageFormatted)
MATLAB®支持所有ROS图像编码格式,和rosReadImage
处理转换图像数据的复杂性。除了彩色图像,MATLAB还支持单色和深度图像。
此外,MATLAB提供了rosWriteImage
函数使用该函数将MATLAB图像转换为ROS消息。利用彩色阈值对样本图像进行基本目标检测。可视化修改后的图像。
greenPercentage = 100*double(image格式化(:,:,2))./sum(image格式化,3);thresholdImg = 255*uint8(greenPercentage > 35);imshow (thresholdImg)
方法将修改后的映像写入ROS消息rosWriteImage
函数。因为修改后的图像只有一个通道,并且是类型的uint8
,使用mono8
编码。
imageMsg = rosWriteImage(emptyimg, thresholdigg,Encoding=“mono8”);
压缩消息
许多ROS系统以压缩格式发送图像数据。MATLAB提供了对这些压缩图像消息的支持。
使用创建一个空的压缩图像消息rosmessage
.ROS中的压缩映像具有消息类型sensor_msgs / CompressedImage
有一个标准的结构。
Emptyimgcomp = rosmessage(“sensor_msgs / CompressedImage”DataFormat =“结构”)
emptyimgcomp =带有字段的结构:MessageType: 'sensor_msgs/ compres沉积物'报头:[1x1 struct]格式:" Data: [0x1 uint8]
为方便起见,从已填充的压缩图像消息加载specialROSMessageData.mat
.
检查imgcomp
被摄像头捕捉到的变量。的格式
属性捕获MATLAB解压存储在其中的图像数据所需的所有信息数据
.
imgcomp
imgcomp =带有字段的结构:MessageType: 'sensor_msgs/ compres沉积物'头文件:[1x1 struct]格式:'bgr8;jpeg压缩bgr8'数据:[30376x1 uint8]
类似于图片消息,您可以使用rosReadImage
以获取标准RGB格式的图像。尽管这个压缩图像的原始编码是bgr8
,rosReadImage
进行转换。
compressed格式化= rosReadImage(imgcomp);
可视化图像使用imshow
函数。
imshow (compressedFormatted)
对于压缩图像消息类型,支持大多数图像格式。的16 uc1
而且32 fc1
压缩深度图像不支持编码。支持单色和彩色图像编码。
点云
点云可以被机器人中使用的各种传感器捕获,包括激光雷达、Kinect®和立体摄像机。ROS中用于传输点云的最常见的消息类型是sensor_msgs / PointCloud2
MATLAB为你提供了一些专门的函数来处理这些数据。
您可以通过创建一个空的点云消息来查看点云消息的标准ROS格式。
Emptyptcloud = rosmessage(“sensor_msgs / PointCloud2”DataFormat =“结构”)
emptyptcloud =带有字段的结构:MessageType: 'sensor_msgs/PointCloud2' Header: [1x1 struct] Height: 0 Width: 0 Fields: [0x1 struct] IsBigendian: 0 PointStep: 0 RowStep: 0 Data: [0x1 uint8] isdensity: 0
控件中存储的填充点云消息ptcloud
变量在您的工作空间:
ptcloud
ptcloud =带有字段的结构:MessageType: 'sensor_msgs/PointCloud2' Header: [1x1 struct]高度:480宽度:640字段:[4x1 struct] IsBigendian: 0 PointStep: 32 RowStep: 20480 Data: [9830400x1 uint8] is高密度:0
点云信息编码在数据
属性。您可以提取x,
y,
z坐标作为N-by-3矩阵调用rosReadXYZ
函数。
rosReadXYZ(ptcloud)
xyz =307200x3单矩阵南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南
南
在点云数据中表明了一些x,
y,
z值无效。这是一个Kinect®传感器的神器,你可以安全地删除所有南
值。
xyzValid = xyz(~isnan(:,1)),:)
xyzValid =193359x3单矩阵0.1378 -0.6705 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颜色值(如果它们存在),并在3d散点图中显示它们。的rosPlot
函数忽略所有南
x,
y,
z坐标,即使该点存在RGB值。
rosPlot (ptcloud)
方法检查点云消息中的所有存储字段rosReadAllFieldNames
函数。加载的点云消息包含四个字段x
,y
,z
,rgb
.
fieldNames = rosReadAllFieldNames(ptcloud)
字段名=1 x4单元格{'x'} {'y'} {'z'} {'rgb'}
方法可以访问任何字段的相应数据rosReadField
函数。您必须手动解包返回的数据,这取决于数据的格式化方式。例如,可以通过对数据的类型转换来提取RGB图像uint8
重塑结果。的结果rosReadAllFieldNames
用于输入验证的函数。
如果任何(包含字段名,“rgb”) rawData = typeecast (rosReadField(ptcloud,“rgb”),“uint8”);tmp =重塑(permute(重塑(rawData,4,[]),[3,2,1]),ptcloud.Width,ptcloud.Height,4);pcImg = permute(tmp(:,:,[3,2,1]),[2 1 3]);imshow (pcImg)结束
Octomap消息
ROS使用Octomap消息实现3D占用网格。八幅图信息通常用于机器人应用,如3D导航.您可以通过创建适当类型的空消息来查看octomap消息的标准ROS格式。
使用rosmessage
来创建消息。
Emptyoctomap = rosmessage(“octomap_msgs / Octomap”DataFormat =“结构”)
emptyoctomap =带有字段的结构:MessageType: 'octomap_msgs/Octomap' Header: [1x1 struct] Binary: 0 Id: " Resolution: 0 Data: [0x1 int8]
为方便起见,octomap
对象中完全填充并存储在octomap
载入的变量specialROSMessageData.mat。
检查变量octomap
在你的工作空间。的数据
字段包含序列化格式的octomap结构。
octomap
octomap =带有字段的结构:MessageType: 'octomap_msgs/Octomap'头文件:[1x1 struct]二进制文件:1 Id: 'OcTree'分辨率:0.0250 Data: [3926x1 int8]
创建一个occupancyMap3D
(导航工具箱)对象从ROS消息中获取rosReadOccupancyMap3D
函数。控件显示3D占用地图显示
函数。
occuancymap3dobj = rosreadoccuancymap3d (octomap);显示(occupancyMap3DObj)
四元数信息
四元数在机器人技术中常用来表示方向。使用rosmessage
创建一个四元数消息并观察字段。
Emptyquatmsg = rosmessage(“geometry_msgs /四元数”DataFormat =“结构”)
emptyquatmsg =带有字段的结构:message: 'geometry_msgs/Quaternion' X: 0 Y: 0 Z: 0 W: 0
为了方便起见,从加载表示绕z轴90度旋转的四元数消息specialROSMessageData.mat
.检查变量quatMsg
在你的工作空间。
quatmsg
quatmsg =带有字段的结构:X: 0 Y: 0 Z: 0.7071 W: 0.7071
创建一个四元数
对象从ROS消息中获取rosReadQuaternion
函数。的四元数
对象包含x、y、z和w组件,并提供其他功能,例如旋转一个点。
quat = 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(quat,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' Header: [1x1 struct]高度:0宽度:0失真模型:" D: [0x1 double] K: [9x1 double] R: [9x1 double] P: [12x1 double] BinningX: 0 BinningY: 0 Roi: [1x1 struct]
值得注意的是,消息存储矩阵K
而且P
向量。ROS要求以行主格式存储这些矩阵。MATLAB以列为主存储矩阵,因此提取K
而且P
矩阵需要重塑和换位。
的estimateCameraParameters
(计算机视觉工具箱)函数可以用来创建cameraParameters
(计算机视觉工具箱)而且stereoParameters
(计算机视觉工具箱)对象。你可以创建sensor_msgs / CameraInfo
的消息来自这些对象rosWriteCameraInfo
函数。使用前必须将对象转换为结构。加载摄像机标定结构。
负载(“calibrationStructs.mat”)
为方便起见,变量参数个数
加载自calibrationStructs.mat
是一个人口充足的cameraParameters
结构体。写cameraParameters
struct到新的ROS消息rosWriteCameraInfo
函数。
msg = rosWriteCameraInfo(emptycamerainfomsg,params);
下表显示了cameraparparameters对象和ROS消息之间的对应关系。
exampleHelperShowCameraParametersTable
ans =5×2表ROS消息相机参数 ___________ ______________________ 内在矩阵“K”“IntrinsicMatrix径向畸变“D”(1:2)切向失真D(3:5)"TangentialDistortion" Height" Height" ImageSize(1)"宽度"Width" "ImageSize(2)"
验证ROS消息的内禀矩阵与的内禀矩阵匹配参数个数
.
K =重塑(msg.K,3,3)'
K =3×3714.1885 0 563.6481 0 710.3785 355.7254 00 1.0000
intrinsicMatrix = params。IntrinsicMatrix”
intrinsicMatrix =3×3714.1885 0 563.6481 0 710.3785 355.7254 00 1.0000
为方便起见,变量stereoParams
加载自calibrationStructs.mat
是一个人口充足的stereoParameters
结构体。写stereoParameters
struct转换为两个新的ROS消息rosWriteCameraInfo
函数。
[ms1, ms2] = rosWriteCameraInfo(msg, steroparams);
下表显示了立体参数对象和ROS消息之间的对应关系。
exampleHelperShowStereoParametersTable
ans =2×2表ROS消息stereoParameters ____________ ___________________________ 翻译的照相机2 P(: 1:2)”“TranslationOfCamera2(1:2)”摄像头2旋转inv(R1)*R2" "摄像头2旋转"
验证相机2旋转矩阵的ROS消息和stereoParams
匹配。
R1 =重塑(msg1.R,3,3)';R2 =重塑(msg2.R,3,3)';R = r1 \ r2
R =3×31.000 -0.0002 -0.0050 0.0002 1.000 -0.0037 0.0050 0.0037 1.000
rotationOfCamera2 = stereo oparams。RotationOfCamera2
rotationOfCamera2 =3×31.000 -0.0002 -0.0050 0.0002 1.000 -0.0037 0.0050 0.0037 1.000
验证摄像头2的ROS信息和平移向量stereoParams
匹配。
P =重塑(msg2.P,4,3)';P(1:2)”
ans =1×2-119.8720 - -0.4005
translate of camera2 (1:2)
translationOfCamera2 =1×2-119.8720 - -0.4005
激光扫描信息
激光扫描仪是机器人技术中常用的传感器。ROS提供sensor_msgs /提升
发布激光扫描消息的消息类型。使用rosmessage
创建一个激光扫描消息并观察字段。
Emptyscan = rosmessage(“sensor_msgs /提升”,“DataFormat”,“结构”)
emptyscan =带有字段的结构:MessageType: 'sensor_msgs/LaserScan' Header: [1x1 struct] AngleMin: 0 AngleMax: 0 AngleIncrement: 0 TimeIncrement: 0 ScanTime: 0 RangeMin: 0 RangeMax: 0 Ranges: [0x1 single]强度:[0x1 single]
既然你创建了一条空消息,emptyscan
不包含任何有意义的数据。为方便起见,完全填充的激光扫描消息存储在扫描
变量已从specialROSMessageData.mat
.
检查扫描
变量。消息中的主要数据位于范围
财产。的数据范围
是一个以小角度增量记录的障碍物距离向量。
扫描
扫描=带有字段的结构:MessageType: 'sensor_msgs/LaserScan' Header: [1x1 struct] AngleMin: -0.5467 AngleMax: 0.5467 AngleIncrement: 0.0017 TimeIncrement: 0 ScanTime: 0.0330 RangeMin: 0.4500 RangeMax: 10 Ranges: [640x1 single]强度:[0x1 single]
可以从ROS消息中获取扫描角度rosReadScanAngles
函数。在极坐标中可视化扫描数据polarPlot
函数。
角度= rosReadScanAngles(扫描);图极坐标(角度,scan.Ranges,LineWidth=2)“激光扫描”)
可以在笛卡尔坐标中得到测量点rosReadCartesian
函数。
xy = rosReadCartesian(扫描);
这个填充xy
列出了(x, y)
坐标是根据所有有效的距离读数计算出来的。方法可视化扫描消息rosPlot
功能:
rosPlot(扫描,“MaximumRange”5)
创建一个lidarScan
对象从ROS消息中获取rosReadLidarScan
函数。的lidarScan
对象包含范围、角度和笛卡尔点,并提供附加功能,如转换扫描点。使用transformScan
函数旋转扫描点并使其可视化情节
.
lidarScanObj = rosReadLidarScan(扫描)
lidarScanObj = lidarScan with properties:范围:[640x1 double]角度:[640x1 double]直角坐标:[640x2 double]计数:640
rotateScan = transformScan(lidarScanObj,[0,0,pi/2]);情节(rotateScan)
占用网格消息
占用网格消息通常用于机器人的2D导航应用.ROS提供nav_msgs / OccupancyGrid
发布激光扫描消息的消息类型。使用rosmessage
创建占用网格消息并观察字段。
emptyMap = rosmessage(“nav_msgs / OccupancyGrid”DataFormat =“结构”)
emptyMap =带有字段的结构:MessageType: 'nav_msgs/OccupancyGrid'头:[1x1 struct]信息:[1x1 struct]数据:[0x1 int8]
请注意,emptyMap
不包含任何有意义的数据。为方便起见,一个完全填充的占用网格消息存储在mapMsg
载入的变量specialROSMessageData.mat。
检查mapMsg
变量。占用网格值编码在数据
字段。
mapMsg
mapMsg =带有字段的结构:MessageType: 'nav_msgs/OccupancyGrid'头:[1x1 struct]信息:[1x1 struct]数据:[251001x1 int8]
使用rosReadOccupancyGrid
函数将ROS消息转换为occupancyMap
(导航工具箱)对象。使用显示
函数显示占用网格。
;;;;;;;显示(occupancyMapObj);
您可以使用occupancyMap
(导航工具箱)对象函数来操作占用网格。使用膨胀
扩大占领区域的功能。方法将occuancymap对象写入新的ROS消息rosWriteOccupancyGrid
函数。使用显示
函数显示新的占用网格。
inflation (occuancymapinflatedmsg,5) = roswriteoccuancymapinflatedmsg (mapMsg, occuancymapobj);显示(occupancyMapObj);
或者,您也可以创建binaryOccupancyMap
(导航工具箱)对象从ROS占用网格消息中获取rosReadBinaryOccupancyGrid
函数。的离散占用值0
或1
在每个单元格中,而占用率图保存的概率占用率值范围为0
而且1
在每个单元格。使用显示
函数显示二进制占用网格。
binaryMapObj = rosreadbinaryoccuancygrid (mapMsg);显示(binaryMapObj);
类似地,您可以使用binaryOccupancyMap
(导航工具箱)对象函数来操作二进制占用网格。使用膨胀
函数来改变二进制占用网格并创建一个新的ROS消息rosWriteBinaryOccupancyGrid
函数。使用显示
函数显示新的二元占用网格。
膨胀(binaryMapObj,5) binaryMapInflatedMsg = roswritebinaryoccuancygrid (mapMsg,binaryMapObj);显示(binaryMapObj);