@@ -43,7 +43,9 @@ class DLLNode
43
43
m_globalFrameId = " map" ;
44
44
if (!lnh.getParam (" use_imu" , m_use_imu))
45
45
m_use_imu = false ;
46
- m_roll = m_pitch = m_yaw = 0.0 ;
46
+ if (!lnh.getParam (" use_yaw_increments" , m_useYawIncrements))
47
+ m_useYawIncrements = false ;
48
+ m_roll_imu = m_pitch_imu = m_yaw_imu = 0.0 ;
47
49
48
50
// Read DLL parameters
49
51
if (!lnh.getParam (" update_rate" , m_updateRate))
@@ -205,25 +207,28 @@ class DLLNode
205
207
// ! IMU callback
206
208
void imuCallback (const sensor_msgs::Imu::ConstPtr& msg)
207
209
{
208
- double r = m_roll ;
209
- double p = m_pitch ;
210
- double y = m_yaw ;
210
+ double r = m_roll_imu ;
211
+ double p = m_pitch_imu ;
212
+ double y = m_yaw_imu ;
211
213
auto o = msg->orientation ;
212
214
tf::Quaternion q;
213
215
tf::quaternionMsgToTF (o, q);
214
216
tf::Matrix3x3 M (q);
215
- M.getRPY (m_roll, m_pitch, m_yaw );
216
- if (isnan (m_roll ) || isnan (m_pitch ) || isnan (m_yaw ))
217
+ M.getRPY (m_roll_imu, m_pitch_imu, m_yaw_imu );
218
+ if (isnan (m_roll_imu ) || isnan (m_pitch_imu ) || isnan (m_yaw_imu ))
217
219
{
218
- m_roll = r;
219
- m_pitch = p;
220
- m_yaw = y;
220
+ m_roll_imu = r;
221
+ m_pitch_imu = p;
222
+ m_yaw_imu = y;
221
223
}
222
224
}
223
225
224
226
// ! 3D point-cloud callback
225
227
void pointcloudCallback (const sensor_msgs::PointCloud2ConstPtr& cloud)
226
- {
228
+ {
229
+ static double lastYaw_imu = -1000.0 ;
230
+ double deltaYaw_imu = 0 ;
231
+
227
232
// If the filter is not initialized then exit
228
233
if (!m_init)
229
234
return ;
@@ -265,7 +270,7 @@ class DLLNode
265
270
sensor_msgs::PointCloud2 baseCloud;
266
271
pcl_ros::transformPointCloud (m_baseFrameId, m_pclTf, *cloud, baseCloud);
267
272
268
- // Uniform lidar downsampling based on front view projection
273
+ // PointCloud2 to PointXYZ conevrsion, with range limits [0,1000]
269
274
std::vector<pcl::PointXYZ> downCloud;
270
275
PointCloud2_to_PointXYZ (baseCloud, downCloud);
271
276
@@ -276,20 +281,35 @@ class DLLNode
276
281
tz = mapTf.getOrigin ().getZ ();
277
282
278
283
// Get estimated orientation into the map
279
- double r, p ;
284
+ double roll, pitch, yaw ;
280
285
if (m_use_imu)
281
- mapTf.getBasis ().getRPY (r, p, m_yaw); // Get roll and pitch from IMU
286
+ {
287
+ // Get roll and pitch from IMU, yaw from TF
288
+ double r, p;
289
+ mapTf.getBasis ().getRPY (r, p, yaw);
290
+ roll = m_roll_imu;
291
+ pitch = m_pitch_imu;
292
+
293
+ // Get yaw increment from IMU, if so required
294
+ if (m_useYawIncrements)
295
+ {
296
+ if (lastYaw_imu < -100.0 )
297
+ lastYaw_imu = m_yaw_imu;
298
+ deltaYaw_imu = m_yaw_imu-lastYaw_imu;
299
+ lastYaw_imu = m_yaw_imu;
300
+ }
301
+ }
282
302
else
283
- mapTf.getBasis ().getRPY (m_roll, m_pitch, m_yaw );
303
+ mapTf.getBasis ().getRPY (roll, pitch, yaw );
284
304
285
305
// Tilt-compensate point-cloud according to roll and pitch
286
306
std::vector<pcl::PointXYZ> points;
287
307
float cr, sr, cp, sp, cy, sy, rx, ry;
288
308
float r00, r01, r02, r10, r11, r12, r20, r21, r22;
289
- sr = sin (m_roll );
290
- cr = cos (m_roll );
291
- sp = sin (m_pitch );
292
- cp = cos (m_pitch );
309
+ sr = sin (roll );
310
+ cr = cos (roll );
311
+ sp = sin (pitch );
312
+ cp = cos (pitch );
293
313
r00 = cp; r01 = sp*sr; r02 = cr*sp;
294
314
r10 = 0 ; r11 = cr; r12 = -sr;
295
315
r20 = -sp; r21 = cp*sr; r22 = cp*cr;
@@ -303,16 +323,21 @@ class DLLNode
303
323
}
304
324
305
325
// Launch DLL solver
326
+ double a;
327
+ if (m_use_imu && m_useYawIncrements)
328
+ a = yaw+deltaYaw_imu;
306
329
if (m_alignMethod == 1 ) // DLL solver
307
- m_solver.solve (points, tx, ty, tz, m_yaw );
330
+ m_solver.solve (points, tx, ty, tz, a );
308
331
else if (m_alignMethod == 2 ) // NDT solver
309
- m_grid3d.alignNDT (points, tx, ty, tz, m_yaw );
332
+ m_grid3d.alignNDT (points, tx, ty, tz, a );
310
333
else if (m_alignMethod == 3 ) // ICP solver
311
- m_grid3d.alignICP (points, tx, ty, tz, m_yaw);
334
+ m_grid3d.alignICP (points, tx, ty, tz, a);
335
+ if (m_use_imu && m_useYawIncrements)
336
+ yaw = a;
312
337
313
338
// Update global TF
314
339
tf::Quaternion q;
315
- q.setRPY (m_roll, m_pitch, m_yaw );
340
+ q.setRPY (roll, pitch, yaw );
316
341
m_lastGlobalTf = tf::Transform (q, tf::Vector3 (tx, ty, tz))*odomTf.inverse ();
317
342
318
343
// Update time and transform information
@@ -336,19 +361,25 @@ class DLLNode
336
361
}
337
362
338
363
// Get estimated orientation from IMU if available
339
- double r, p ;
364
+ double roll, pitch, yaw ;
340
365
if (m_use_imu)
341
- m_lastOdomTf.getBasis ().getRPY (r, p, m_yaw); // Get roll and pitch from IMU
366
+ {
367
+ // Get roll and pitch from IMU, yaw from TF
368
+ double r, p;
369
+ m_lastOdomTf.getBasis ().getRPY (r, p, yaw);
370
+ roll = m_roll_imu;
371
+ pitch = m_pitch_imu;
372
+ }
342
373
else
343
- m_lastOdomTf.getBasis ().getRPY (m_roll, m_pitch, m_yaw );
374
+ m_lastOdomTf.getBasis ().getRPY (roll, pitch, yaw );
344
375
345
376
// Get position information from pose
346
377
tf::Vector3 t = initPose.getOrigin ();
347
- m_yaw = getYawFromTf (initPose);
378
+ yaw = getYawFromTf (initPose);
348
379
349
380
// Update global TF
350
381
tf::Quaternion q;
351
- q.setRPY (m_roll, m_pitch, m_yaw );
382
+ q.setRPY (roll, pitch, yaw );
352
383
m_lastGlobalTf = tf::Transform (q, tf::Vector3 (t.x (), t.y (), t.z ()+m_initZOffset))*m_lastOdomTf.inverse ();
353
384
354
385
// Prepare next iterations
@@ -387,14 +418,14 @@ class DLLNode
387
418
bool m_init;
388
419
389
420
// ! Use IMU flag
390
- bool m_use_imu;
421
+ bool m_use_imu, m_useYawIncrements ;
391
422
392
423
// ! Indicates that the local transfrom for the pint-cloud is cached
393
424
bool m_tfCache;
394
425
tf::StampedTransform m_pclTf;
395
426
396
427
// ! Particles roll and pich (given by IMU)
397
- double m_roll, m_pitch, m_yaw ;
428
+ double m_roll_imu, m_pitch_imu, m_yaw_imu ;
398
429
399
430
// ! Filter initialization
400
431
double m_initX, m_initY, m_initZ, m_initA, m_initZOffset;
0 commit comments