# Read and analyze rosbag data in Matlab

I was experimenting with the Sawyer robot and using rosbag to record the robot status data, which need to be visualized and analyzed later. Usually the built-in rqt_plot in ROS can be used to have a overview of the data. However, rqt_plot is relatively simple and not handy when the data size is large. So it is better to import data into Matlab for analysis.

Matlab can directly read rosbag data. For topics common used in ROS, such as /joint_states and /cmd_vel, it is very convenient to use Matlab to read. However, topics that use a custom message type, you will need to recompile the ROS package that stores the msg file. This step can be completed using rosgenmsg command in Matlab, with the help of Matlab’s java interface, Matlab will be able to recognize the custom message.

My Matlab version is R2021a when I was writing this blog. Note that in the R2020b version, Matlab’s support for ROS has been greatly changed. rosgenmsg is directly included in the toolbox (no additional support package is required). You may found some online tutorials use the roboticsAddons command to install rosgenmsg plugin, maybe the Matlab version they used is before R2020b. You may read this official document directly in the future: ROS Custom Message Support, just follow the documentation step by step, purpose of this blog is mainly to record some tricky problems that need attention when the first time you are dealing with it.

## Update Cmake version

Make sure your Cmake version is 3.15.5 or later, this requirement can be found in official Matlab document ROS System Requirements.

If the version is older than 3.15.5, it needs to be updated. The most common way is directly with sudo apt-get install cmake in the Linux terminal, but after installation, you may found the version is still older than the required version, such as Ubuntu 16.04 I was using, I can only get 3.5.1. The reason why I can not install the latest version with sudo apt-get install cmake is that the repositories of the operating system itself have not been updated. 16.04 is the long-term support (LTS) version of Ubuntu, and it must be stable within 5 years. Generally, only critical or security updates are performed, and the latest versions of packages are not updated frequently, usually every 6 months.

Recommended installation method:

• Uninstall the default version provided by Ubuntu: Or
• Go to CMake official website download interface, check the Cmake version number, and determine the version to be installed (modify the version and build variables to the required version number, following example: 3.19.1):
• Create a temp folder to store the cmake source package, and download the cmake source package:
• Unzip the source package:
• Enter the unzipped cmake directory:
• Install cmake：

Note:

• Because I have a multi-core CPU, the make -j\$(nproc) command is used here for parallel compilation, just using make is also ok, the nproc information can be found here
• make install command requires root privilege
• Finally, open a new terminal and check the Cmake version:

Note:

• cmake --version is only valid in a new terminal, because for the method used above, Cmake will be installed in /usr/local/bin/ by default, and if you use the sudo apt-get install cmake mentioned at the beginning, the default installation path will be /usr/bin/, the reason can be seen This answer on StackExchange：/usr/local/bin is for normal user programs not managed by the distribution package manager, e.g. locally compiled packages. You should not install them into /usr/bin because future distribution upgrades may modify or delete them without warning.

Result after running cmake --version:

## Confirm Cmake path

After updating the Cmake version, in order to ensure Cmake is available in Matlab, you need to check Cmake is on the environment variables of Matlab:

• First, check the Cmake path in the Linux terminal. As mentioned above, Cmake will be installed by default in /usr/local/bin/, which can be check in the terminal: Result：
• Then open Mtalab and run the command: The result should be consistent with the path found in the Linux terminal earlier:
• Finally, check the Cmake version in Matlab: The running result should be consistent with the version number found in the Linux terminal earlier:

## Compile the custom message

Here I use the ROS package intera_core_msgs provided by Sawyer as an example. The custom message file is in msg folder. I first create a folder custom_msgs, and create a folder sawyer_custom_msg_matlab inside it to contain the package, other packages also can be placed in this folder in the future. I copied the intera_core_msgs package directly from Github, which has already generated and configured CmakeLists.txt and package.xml file, if you wish to create a ROS package yourself, don’t forget to modify these two files. The following matlab_msg_gen_ros1 folder is generated by compiling with Matlab, which will be demonstrated below.

Note

• Only msg is used here, I did not copy srv when coping the intera_core_msgs package, I can add it when it is needed.
• ROS actions are not supported currently, it will be ignored during custom message generation.

Next, you can use the rosgenmsg command to compile in Matlab:

• Declare the path of the ROS package where the custom message is located: Result:
• Call rosgenmsg: Result：
• Then follow the instructions above to add environment variables, clear the workspace, and run the following commands one by one:

Note
When executing savepath, if you are prompted that the Matlab path file cannot be modified, there are two solutions:

• Method 1: Modify permissions in the current Matlab command window:
Check pathdef path: Result： Modify it so that all users have read and write permissions:
• Method 2: Reopen Matlab with sudo matlab in the Linux terminal

Finally, use to see if the custom message types are successfully generated：

We can see that all custom messages in the msg folder under the intera_core_msgs package have been successfully generated:

## Rosbag data processing

Next, I will take the custom message intera_core_msgs/EndpointState as an example, and use Matlab to process the robot data recorded by rosbag.

• Read bag file: After running, click the bag variable in the Workspace to get the information shown in the following figure:

• Select Topic
Click AvailableTopics in the above picture to review what topics are recorded. I only recorded one topic /robot/limb/right/endpoint_state here, as shown in the following figure:

After reviewing the topic, use the select function to select the topic name to be processed:

In the figure as shown above, you may also notice that the intera_core_msgs/EndpointState in the MessageType column is the message we customized before.

• Use the readMessages function to read the data selected by the select function

After running, click the stateMsgs variable in the Workspace to get the information shown in the following figure:

You can see that stateMsgs is a 1408x1 array, which contains 1408 message data records, click on the first one:

The figure above shows the data structure that defines intera_core_msgs/EndpointState. We can first look at the content in the Linux terminal:

Result：

We can see that intera_core_msgs/EndpointState uses two ROS built-in messages std_msgs and geometry_msgs, intera_core_msgs/EndpointState mainly contains the following information of the robot TCP:

pose:

• positon: x y z coordinates
• orinentation: represented by quaternions

twist (a screw, 6-dimensional vector):

• linear: linear velocity along an axis, a 3-dimensional vector
• angular: angular velocity about an axis, a 3-dimensional vector

wrench (a screw, 6-dimensional vector):

• force: a 3-dimensional vector
• torque: a 3-dimensional vector

Note: Quaternion and Screw theory will be discussed separately later if I have time.

Take the position in pose as an example: click 1x1 Pose in the stateMsgs shown in the above figure, get the information shown in the figure below:

You can see that Pose contains positon and orinentation information, click on positon:

The positon contains the x y z coordinates of the robot TCP, which are consistent with the results viewed in the terminal. Click on the information of X:

Note：
The name of each tab in the figure represents the method of accessing the current data. For example, stateMsg{1,1}.Pose.Position.X represents the method of accessing X.

Next, to visualize the data, we can create a three-dimensional array, and put all the position data into the array:

Draw a trajectory graph:

Complete Matlab code: