-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathCalib_3LRF_PreProc.m
More file actions
283 lines (252 loc) · 6.97 KB
/
Copy pathCalib_3LRF_PreProc.m
File metadata and controls
283 lines (252 loc) · 6.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
%% Preprocess data
% 1.load data
% 2.frames alignment (including IMU data)
% 3.generate 2D LRFs point clouds
% 4.save the LRFs data, IMU data and ini Poses to '.mat' file
close all;clc;clear;
NUMBER_LRFs=3;
bMyData=0;
% bMyData=1;
bHaveIMUData=1;
% RawFilePath = 'E:\SLAM\Data\LaserData\20180203\';
% fileName0='UTM30LX_0_20180203_151541';
% RawFilePath = 'D:\LaserData\20180629\data\';
% fileName0='4.bag_0';
% imuDataPath='D:\LaserData\20180629\data\';
% imuDataFileName='4.bag_imu';
% RawFilePath = 'E:\SLAM\Data\20180802\';
% RawFilePath = 'E:\SLAM\Matlab\Calib_3LRFs-V1.0\Data\20180802\';
RawFilePath = 'E:\SLAM\Matlab\Calib_3LRFs-V1.0\Data\20180928\';
fileName0='1_0';
imuDataFileName='1_imu';
imuDataPath=RawFilePath;
% guess - the pose angle and translation of three LRFs
ang_LRFsIni=[
0,0,0;
90,0,-155;
90, 0, 155;
];
% From LRF0 to LRFi
T_LRFsIni=[
0,0,0;
-0.1,0.15,-1.5;
0.1, 0.15,-1.2;
];
% ang_LRFsIni=[
% 0,0,0;
% -80, 0.0, -30;
% 90, 1.0,-135;
% ];
% % From LRF0 to LRFi
% T_LRFsIni=[
% 0,0,0;
% 0.1, 0.05,-0.4;
% -0.1,0.05,-0.6;
% ];
% % calibed - the pose angle and translation of three LRFs
% ang_LRFsIni=[
% 0,0,0;
% -80.5, 0.45, -30;
% 88,1.45,-136.8;
% ];
% % From LRF0 to LRFi
% T_LRFsIni=[
% 0,0,0;
% 0.087, 0.069,-0.394;
% -0.134,0.025,-0.622;
% ];
if bMyData
PTS_PER_FRAME=1081;
else
PTS_PER_FRAME=1080;
end
timePerFrame_LRF=25; % 25ms per frame
timePerFrame_IMU=100;
%% 解算3LRF扫描得到的点云
%文件路径
fileName1=fileName0; fileName2=fileName1;
if bMyData
fileName1(9)='1';
fileName2(9)='2';
% else
% fileName1(7)='1';
% fileName2(7)='2';
else
fileName1(3)='1';
fileName2(3)='2';
end
RawFileFullPath0=[RawFilePath fileName0 '.txt'];
RawFileFullPath1=[RawFilePath fileName1 '.txt'];
RawFileFullPath2=[RawFilePath fileName2 '.txt'];
TimestampFileFullPath0=[RawFilePath fileName0 '.timestamp'];
TimestampFileFullPath1=[RawFilePath fileName1 '.timestamp'];
TimestampFileFullPath2=[RawFilePath fileName2 '.timestamp'];
if bHaveIMUData==1
% load IMU data
imuData=load([imuDataPath imuDataFileName '.txt']);
% get start time and end time
startTime=imuData(1,:);
endTime=imuData(size(imuData,1),:);
% remv the first row and last row (start time and end time)
timestamps_IMU=imuData(:,1); % save the timestamp
nImuFrames=size(imuData,1);
imuData=[imuData(:,5),imuData(:,2),imuData(:,3),imuData(:,4)]; % remv the timestamp
% imuData=[imuData(:,2),imuData(:,3),imuData(:,4),imuData(:,5)]; % remv the timestamp
end
% load raw data
tic
rawData0=load(RawFileFullPath0);
rawData1=load(RawFileFullPath1);
rawData2=load(RawFileFullPath2);
timestamps0=load(TimestampFileFullPath0);
timestamps1=load(TimestampFileFullPath1);
timestamps2=load(TimestampFileFullPath2);
toc
%% frame alignment according to timestamp
maxTimestampDiff=25/2; % 25ms/2
iSearchRadius_LRF=40;
iSearchRadius_IMU=1000;
cntValidFrame=0;
alpha=timePerFrame_IMU/timePerFrame_LRF;
lastIMUFrame=1;
for iFrame0=1:size(rawData0,1)
t0=timestamps0(iFrame0);
% search the neighbor frame of LRF1
iSuccess=0;
for iOffset=0:iSearchRadius_LRF
if iSuccess==1
break;
end
for iDirection=-1:2:1
if iSuccess==1
break;
end
iFrame1=iDirection*iOffset+iFrame0;
if iFrame1<1 || iFrame1>size(rawData1,1)
continue;
end
t1=timestamps1(iFrame1);
if abs(t1-t0)<maxTimestampDiff
iSuccess=1;
end
end
end
if iSuccess==0
continue;
end
% search the neighbor frame of LRF1
iSuccess=0;
for iOffset=0:iSearchRadius_LRF
if iSuccess==1
break;
end
for iDirection=-1:2:1
if iSuccess==1
break;
end
iFrame2=iDirection*iOffset+iFrame0;
if iFrame2<1 || iFrame2>size(rawData2,1)
continue;
end
t2=timestamps2(iFrame2);
if abs(t2-t0)<maxTimestampDiff
iSuccess=1;
break;
end
end
end
if iSuccess==0
continue;
end
if bHaveIMUData==1
% search the neighbor frame of IMU
iSuccess=0;
for iOffset=0:iSearchRadius_IMU
if iSuccess==1
break;
end
for iDirection=-1:2:1
if iSuccess==1
break;
end
iFrame_IMU=iDirection*iOffset+lastIMUFrame+alpha;
if iFrame_IMU<1 || iFrame_IMU>size(imuData,1)
continue;
end
t3=timestamps_IMU(iFrame_IMU);
if abs(t3-t0)<maxTimestampDiff
iSuccess=1;
lastIMUFrame=iFrame_IMU;
break;
end
end
end
if iSuccess==0
continue;
end
end
% recording
cntValidFrame=cntValidFrame+1;
rawData0_(cntValidFrame,:)=rawData0(iFrame0,:);
rawData1_(cntValidFrame,:)=rawData1(iFrame1,:);
rawData2_(cntValidFrame,:)=rawData2(iFrame2,:);
if bHaveIMUData==1
imuData_(cntValidFrame,:)=imuData(iFrame_IMU,:);
end
end
if size(rawData0,1)-cntValidFrame>50
disp('Warning, please check.');
return;
end
if bHaveIMUData==1
IMU=imuData_;
end
% fusion 3 Datas to one matrix
rawData(1,:,:)=rawData0_;
rawData(2,:,:)=rawData1_;
rawData(3,:,:)=rawData2_;
rawData(isnan(rawData)==1)=0;
rawData(rawData==inf)=0;
%% Device frame
% the orientation equals to the orientation of LRF0
R_D=eye(3,3);
T_D=[0,-0.130,-1.000];
% IMU frame
ang_Z_D2IMU=-pi/2;
ang_X_D2IMU=-pi;
R_D2IMU=EulerAngle2RotateMat(ang_X_D2IMU,0,ang_Z_D2IMU,'zxy');
T_IMU=[0.100 0.020 -1.050];
ang_LRFsIni_radian=ang_LRFsIni.*pi/180;
R_LRFsIni=zeros(3,3,3);
for i=1:3
R_LRFsIni(i,:,:)=EulerAngle2RotateMat(ang_LRFsIni_radian(i,1),ang_LRFsIni_radian(i,2),ang_LRFsIni_radian(i,3),'xyz');
end
%% generate 2D point clouds
PC_Raw=zeros(NUMBER_LRFs,cntValidFrame,PTS_PER_FRAME,3);
% PC_IniPos=zeros(NUMBER_LRFs,cntValidFrame,PTS_PER_FRAME,3);
for iLRFs=1:NUMBER_LRFs
for row=1:cntValidFrame
PC_Raw(iLRFs,row,:,1:2)=OneFrameRawData2Pts_2D_UTM30LX(rawData(iLRFs,row,:));
% PC_IniPos(iLRFs,row,:,:)=...
% (squeeze(R_LRFsIni(iLRFs,:,:))*squeeze(PC_Raw(1,row,:,:))')'+repmat(squeeze(T_LRFsIni(iLRFs,:)),size(PC_Raw,3),1);
end
end
toc
%% save data to file
if bMyData
PC_Raw=PC_Raw.*0.001; % change the unit to milimeter
end
tic
% LRF datas
fileName_PC=fileName0;
fileFullPath_Data=[RawFilePath 'Data_' fileName_PC '.mat'];
fileFullPath_IniPosPC=[RawFilePath 'IniPosPC_' fileName_PC '.mat'];
if bHaveIMUData==1
save(fileFullPath_Data,'PC_Raw','IMU');
else
save(fileFullPath_Data,'PC_Raw');
end
% angles and Ts
fileFullPath_LRFsIniPos=[RawFilePath 'LRFsIniPos.mat'];
save(fileFullPath_LRFsIniPos,'ang_LRFsIni','T_LRFsIni');
toc