激光SLAM简单入门(1)-matlab读取bag文件并保存为mat文件
最近在一篇公众号发现了一篇激光SLAM的入门文章,作者提供了源码,下载下来跑了一下,效果还不错。之前一直在用激光雷达建图,但一直没能对激光雷达SLAM基础理论有深入的研究,因此萌生了以该代码为基础,系统整理激光雷达SLAM步骤的想法。原文见:
本系列主要内容是理解激光SLAM的过程,在原文的基础上进行了改进和升级,并增加了的细节内容,同时也加入了部分自己的理解。
作者在文章中提供了所有的代码,把所有的代码复制到同一文件夹下,运行main.m文件即可,我也将代码整理到我的github,下载地址为:
第一部分记录matlab读取bag文件并将需要的数据保存成mat文件的过程。写这部分的原因是网络上关于matlab读取bag文件的内容较少,在提取数据的过程中浪费了较多时间。主要步骤包括下载bag文件,在ros环境下解压缩,解压缩后bag文件的数据提取和保存(matlab)。
1 下载bag文件
谷歌的Cartographer算法中提供的数据集,文件下载地址:
我下载了 b2-2014-12-12-14-41-29.bag ,文件大小为46MB。
ps:下载后直接在matlab下用rosbag函数读取,会提示如下错误:
原因:matlab只能读取未压缩的文件,直接下载的bag文件是压缩后的文件,因此首先需要解压缩。
2 在ros环境中解压缩bag文件
在ros环境(ubuntu16.04+ros kinetic)下对原始的bag文件进行解压缩,得到解压后的bag文件。
rosbag decompress b2-2014-12-12-14-41-29.bag
解压后文件大小为230M:
3 在matlab下对bag文件中的数据进行提取和保存
matlab提供了ros相关的函数来提取数据,但是一次对所有的数据进行处理,会发生内存不足的问题。比如我用如下的代码读取bag文件:
bag = rosbag('b2-2014-12-12-14-41-29.bag');%读取所有数据
%读取水平雷达topic 数据
laser = select(bag, 'Time', ...
[bag.StartTime bag.EndTime], 'Topic', '/horizontal_laser_2d');
x = readMessages(laser);
matlab报错(内存不足):
Error in robotics.ros.BagSelection/readMessages (line 194)
msgs = obj.deserializeMessages(obj.MessageList, rows);
Error in LoadMeasurements (line 47)
msgs = readMessages(bag);
因此,采用循环的方式逐一读取数据,代码如下:
clear;clc;
bag = rosbag('b2-2014-12-12-14-41-29.bag');%读取所有数据
%读取水平雷达topic 数据
laser = select(bag, 'Time', ...
[bag.StartTime bag.EndTime], 'Topic', '/horizontal_laser_2d');
%% 从文件中查找数据的大小
N = laser.NumMessages;%雷达数据条数
x = readMessages(laser,1);
[M,~] = size(x{1,1}.Ranges);
times = zeros(N,1);%时间参数
ranges = zeros(N,M);%距离参数
%% 循环读取数据 :整体读取时会出现内存不足的情况
for i=1:N
temp = readMessages(laser,i);
times(i) = temp{1,1}.Header.Stamp.Sec;%时间
ranges_temp = temp{1,1}.Ranges;%雷达测量(1079维数据)
for j = 1:M %不知道如何整体读取,所以加了循环
laser_echo = ranges_temp(j,1).Echoes;
[xx,yy] = size(laser_echo);
if xx*yy<1 %当laser_echo为空时,跳出当前循环
continue
ranges(i,j) = laser_echo(1);%雷达测量的距离数据
%显示进度