Work with Specialized ROS Messages
Some commonly used ROS messages store data in a format that requires some transformation before it can be used for further processing. MATLAB® can help you by formatting these specialized ROS messages for easy use. In this example, you can explore how message types for laser scans, uncompressed and compressed images, and point clouds are handled.
Prerequisites: Work with Basic ROS Messages
Load Sample Messages
Load some sample messages. These messages are populated with data gathered from various robotics sensors.
Laser Scan Messages
Laser scanners are commonly used sensors in robotics. You can see the standard ROS format for a laser scan message by creating an empty message of the appropriate type.
rosmessage to create the message.
emptyscan = rosmessage("sensor_msgs/LaserScan","DataFormat","struct")
emptyscan = struct with fields: MessageType: 'sensor_msgs/LaserScan' Header: [1x1 struct] AngleMin: 0 AngleMax: 0 AngleIncrement: 0 TimeIncrement: 0 ScanTime: 0 RangeMin: 0 RangeMax: 0 Ranges: [0x1 single] Intensities: [0x1 single]
Since you created an empty message,
emptyscan does not contain any meaningful data. For convenience, the
exampleHelperROSLoadMessages function loaded a laser scan message that is fully populated and is stored in the
scan variable. The primary data in the message is in the
Ranges property. The data in
Ranges is a vector of obstacle distances recorded at small angle increments.
scan = struct with fields: 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] Intensities: [0x1 single]
You can get the measured points in Cartesian coordinates using the
xy = rosReadCartesian(scan);
xy with a list of
[x,y] coordinates that were calculated based on all valid range readings. Visualize the scan message using the
MATLAB also provides support for image messages, which always have the message type
Create an empty image message using
rosmessage to see the standard ROS format for an image message.
emptyimg = rosmessage("sensor_msgs/Image","DataFormat","struct")
emptyimg = struct with fields: MessageType: 'sensor_msgs/Image' Header: [1x1 struct] Height: 0 Width: 0 Encoding: '' IsBigendian: 0 Step: 0 Data: [0x1 uint8]
For convenience, the
exampleHelperROSLoadMessages function loaded an image message that is fully populated and is stored in the
Inspect the image message variable
img in your workspace. The size of the image is stored in the
Height properties. ROS sends the actual image data using a vector in the
img = struct with fields: MessageType: 'sensor_msgs/Image' Header: [1x1 struct] Height: 480 Width: 640 Encoding: 'rgb8' IsBigendian: 0 Step: 1920 Data: [921600x1 uint8]
Data property stores raw image data that cannot be used directly for processing and visualization in MATLAB. You can use the
rosReadImage function to retrieve the image in a format that is compatible with MATLAB.
imageFormatted = rosReadImage(img);
MATLAB® supports all ROS image encoding formats, and
rosReadImage handles the complexity of converting the image data. In addition to color images, MATLAB also supports monochromatic and depth images.
Many ROS systems send their image data in a compressed format. MATLAB provides support for these compressed image messages.
Create an empty compressed image message using
rosmessage. Compressed images in ROS have the message type
sensor_msgs/CompressedImage and have a standard structure.
emptyimgcomp = rosmessage("sensor_msgs/CompressedImage","DataFormat","struct")
emptyimgcomp = struct with fields: MessageType: 'sensor_msgs/CompressedImage' Header: [1x1 struct] Format: '' Data: [0x1 uint8]
For convenience, the
exampleHelperROSLoadMessages function loaded a compressed image message that is already populated.
imgcomp variable that was captured by a camera. The
Format property captures all the information that MATLAB needs to decompress the image data stored in
imgcomp = struct with fields: MessageType: 'sensor_msgs/CompressedImage' Header: [1x1 struct] Format: 'bgr8; jpeg compressed bgr8' Data: [30376x1 uint8]
Similar to the image message, you can use
rosReadImage to obtain the image in standard RGB format. Even though the original encoding for this compressed image is
rosReadImage the conversion.
compressedFormatted = rosReadImage(imgcomp);
Visualize the image using the
Most image formats are supported for the compressed image message type. The
32FC1 encodings are not supported for compressed depth images. Monochromatic and color image encodings are supported.
Point clouds can be captured by a variety of sensors used in robotics, including LIDARs, Kinect®, and stereo cameras. The most common message type in ROS for transmitting point clouds is
sensor_msgs/PointCloud2 and MATLAB provides some specialized functions for you to work with this data.
You can see the standard ROS format for a point cloud message by creating an empty point cloud message.
emptyptcloud = rosmessage("sensor_msgs/PointCloud2","DataFormat","struct")
emptyptcloud = struct with fields: MessageType: 'sensor_msgs/PointCloud2' Header: [1x1 struct] Height: 0 Width: 0 Fields: [0x1 struct] IsBigendian: 0 PointStep: 0 RowStep: 0 Data: [0x1 uint8] IsDense: 0
View the populated point cloud message that is stored in the
ptcloud variable in your workspace:
ptcloud = struct with fields: MessageType: 'sensor_msgs/PointCloud2' Header: [1x1 struct] Height: 480 Width: 640 Fields: [4x1 struct] IsBigendian: 0 PointStep: 32 RowStep: 20480 Data: [9830400x1 uint8] IsDense: 0
The point cloud information is encoded in the
Data property of the message. You can extract the x
,z coordinates as an N-by-3 matrix by calling the
xyz = rosReadXYZ(ptcloud)
xyz = 307200x3 single matrix NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ⋮
NaN in the point cloud data indicates that some of the x
,z values are not valid. This is an artifact of the Kinect® sensor, and you can safely remove all
xyzvalid = xyz(~isnan(xyz(:,1)),:)
xyzvalid = 193359x3 single matrix 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 ⋮
Some point cloud sensors also assign RGB color values to each point in a point cloud. If these color values exist, you can retrieve them with a call to
rgb = rosReadRGB(ptcloud)
rgb = 307200×3 0.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 ⋮
You can visualize the point cloud with the
rosPlot automatically extracts the x
,z coordinates and the RGB color values (if they exist) and show them in a 3-D scatter plot. The
rosPlot function ignores all
,z coordinates, even if RGB values exist for that point.