本文使用Linux matlab 2016b
无意中知道Matlab能直接读取rosbag,https://github.com/ethz-adrl/towr/blob/master/towr/matlab/plot_rosbag.m
后来在做实验的过程中,有需要分析rosbag的需要,这里就产生了这篇文章。之前的做法都是rostopic echo导入txt中分析,现在能直接分析了,应该更直接、爽快了,自己很久之前也做过这样子的尝试。有兴趣的见https://blog.csdn.net/yaked/article/details/45534381
其他方式:bag2csv,bag2matlab,rosbag_pandas.
https://github.com/unl-nimbus-lab/bag2csv
https://nimbus.unl.edu/2016/06/exporting-ros-bag-files-to-matlab-v2-0/
https://nimbus.unl.edu/2014/11/using-rosbag_pandas-to-analyze-rosbag-files/
这里,我就直接放出结论: 对于ROS自带的topic信息,还是比较比较方便的。但是,如果是自定义的rosmsg信息,则需要重新编译ros msg文件,借助matlab的java接口,让matlab知道或“认识”你的消息格式。
针对ROS 已有到msg信息, 如odom, Jointstate和cmd_vel等, 这篇博文比较有参考价值.
https://blog.csdn.net/weixin_40712763/article/details/78909608
他这里的topic是/leica/position, 利用指令
rostopic type /leica/position
得知topic type是geometry_msgs/PointStamped
使用指令rosmsg show geometry_msgs/PointStamped
msg其实就是定义了一种数据结构, 因而可以使用data{1,1}.Point.X进行数据提取.千万注意的是这里都是大写.
不过不建议大家像他那样按照消息类型获取数据,因为一个bag里如果有多个同类型的数据,势必导致混乱。还是按下文的topic来读取稳当一些。
有时候接触到的msg类型,不都是ros自带的.这里Matlab官方把这部分内容作为了插件, https://www.mathworks.com/help/robotics/custom-message-support.html?s_tid=CRUX_lftnav 安装需要参照这里到步骤.
在matlab命令窗口输入: roboticsAddons, 进入机器人插件商店.
Matlab ROS custom messages addons
这个插件通过对rosmsg的文件进行解析,然后该插件生成对应的java文件(以.jar文件结尾),作为桥梁,连接ROS 和matlab.
这里速度稍慢, 若如长久时间下载不下来,参看这里https://www.mathworks.com/support/bugreports/1741173
下载完毕以后, 跟着官方教程走一遍就可以慢慢理解背后的原理了.
cd(fullfile(fileparts(which('rosgenmsg')), 'examples', 'packages'))
我这里到路经是
/home/yake/Documents/MATLAB/SupportPackages/R2016b/toolbox/robotics/supportpackages/roscustommsg/examples/packages
接着编译自定义的rosmsg,唯一要注意,路径问题. 对于自定义的iiwa_msgs文件夹,需要建立个文件夹包含它, iiwa_msgs文件夹包含msg文件夹,与package.xml同级. 比如我这里的iiwa_custom_msg_matlab. 后面的那个matlab_gen就是利用插件生成的.
CMakeLists.txt内容如下,记得添加引用到的标准msg, 如 这里的std_msgs, geometry_msgs
cmake_minimum_required(VERSION 3.5)
project(iiwa_msgs)
find_package(catkin REQUIRED COMPONENTS
message_generation
cmake_modules
geometry_msgs
std_msgs
)
add_message_files(DIRECTORY msg)
generate_messages(DEPENDENCIES std_msgs geometry_msgs)
catkin_package(CATKIN_DEPENDS message_runtime std_msgs geometry_msgs)
package.xml内容如下
iiwa_msgs
1.0
message_generation
std_msgs
geometry_msgs
利用以下两句就可以编译生成需要的java中间文件了.
iiwa_Folder = '/home/yake/matlab_ws/iiwa_matlab/iiwa_custom_msg_matlab';
rosgenmsg(iiwa_Folder);
最后按照提示说明加入环境变量就可以了
addpath('/home/yake/matlab_ws/iiwa_matlab/iiwa_custom_msg_matlab/matlab_gen/msggen')
savepath
这里给出一个matlab读取rosbag的程序,算是抛砖引玉吧.
特别注意这一行: stateMsgs = readMessages(state_select);有了这句,点击变量窗口,可以查看到数据内部,对于后续的数据提取和代码调试很有帮助.
clear all;
close all;
clc;
bag = rosbag('/home/yake/matlab_ws/iiwa_matlab/iiwa_bag/2019-07-27-16-31-36_circle_OK.bag');
state_select = select(bag, 'Time',[bag.StartTime bag.EndTime], 'Topic', '/iiwa/state/JointPosition');% {'iiwa_msgs/JointPosition'}
stateMsgs = readMessages(state_select);
% rosmsg show iiwa_msgs/JointPosition
% std_msgs/Header header
% uint32 seq
% time stamp
% string frame_id
% iiwa_msgs/JointQuantity position
% float32 a1
% float32 a2
% float32 a3
% float32 a4
% float32 a5
% float32 a6
% float32 a7
ts_state = timeseries(state_select, 'Position.A1','Position.A2','Position.A3','Position.A4','Position.A5','Position.A6','Position.A7');% uppercase
t = ts_state.Time;
j1 = ts_state.Data(:,1);
% plot state in relative time.
t_relative = ts_state.Time - ts_state.Time(1,1);
plot((t_relative), j1, ' : ','LineWidth',2,'DisplayName','StateJ1');
hold on;
for i=2:7
plot(t_relative, ts_state.Data(:, i), ' : ','LineWidth',2, 'DisplayName', int2str(i));
end
xlabel('time(s)'); ylabel('Joint angle(rad)');
legend('show');
本文使用的rosbag下载:https://download.csdn.net/download/yaked/11449817
======================================
对于本自定义msg依赖系统到msg, 而matlab中引入的系统msg不全的情况. 如下图左边是matlab中geometry_msgs的情况,右边是系统的同类型msg的情况.可以看到Accel等相关msg, matlab并没有相应的转接接口.目前两种办法,1. 更换到更新版本的matlab 2.下载需要依赖的msg和自定义的同时编译.
下载官方geometry_msgs重新在matlab下编译
一个个编译,先编译完geometry_msgs再把自定义的xpp_msgs放在同个目录下