hku-mars / FAST_LIO

A computationally efficient and robust LiDAR-inertial odometry (LIO) package
GNU General Public License v2.0
2.78k stars 936 forks source link

'time' field in velodyne data and `timestamp_first_packet` #91

Closed cosama closed 3 years ago

cosama commented 3 years ago

First, FAST_LIO is one of the best SLAM algorithm I have seen so far and performs extremely stable on our system despite it being operated in a very challenging environment. Thank you so much for releasing the code.

However, we do use some older velodyne driver and the 'time' field is not defined. Furthermore, we record individual packages not complete 360deg scans, so I need to do some preprocessing of the data to bring it into the proper format and I am not 100% sure how to do that.

Working through this I noticed two things. This is somewhat a followup to #55.

1) I think the velodyne driver indeed publishes the 'time' field in seconds: The time offset is calculated here in seconds and then the time is calculated here without any changes to the units, which is called from here in the main unpack function. This is called here, before being published. At least to me, this all happens in seconds. This furthermore agrees with the description from LIO_SAM's README, and it's own data, which to me look to have the 'time' field in seconds. In LIO_SAM that field is then used here, also assuming seconds. I don't know anything about the other datasets that you looked into, I actually couldn't find any definition of their point cloud data anywhere. I am not sure if you did any preprocessing of your data before, but it could well be that FAST_LIO performs even better on these datasets if properly taking this into account. In my tests it performs well independent of if this is done correctly or not (which shows how great this SLAM algorithm actually is).

2) I am quite uncertain for some of these data set how the Header.timestamps is calculated. There is one reference for the dataset here, Section 7.3: 'The reported UTIME in the header is the timestamp of the last laser fired within the packet'. I couldn't find any other reference about this in the other datasets. This however would be counter the assumption LIO_SAM makes in it's code referenced above, where they clearly takes the Header.timestamp as the start. I feel FAST_LIO performs slightly better if I do the same, but I don't see that being reflected in the code. I feel you assumed that the header timestamp is defined as the end of the scan. Is that correct?

Thanks.

XW-HKU commented 3 years ago

First of all, thanks for your interest in our work.

  1. The point cloud 2 data structure has many different types. Here we support the below types for Velodyne lidar:

[ PointField('x'. FLOAT32), PointField('y', FLOAT32), PointField('z', FLOAT32), PointField('intensity', FLOAT32), PointField('time', FLOAT32), PointField('ring', UINT16) ]

The PointField 'time' stands for the offset time w.r.t the first point's time in a scan. The unit should be us for FAST-LIO, as I said in #55. Of course, you can modify the preprocess.cpp line 320 (https://github.com/hku-mars/FAST_LIO/blob/d0a877db69f569964697e1135e1fcb42aae9b3f2/src/preprocess.cpp#L320): The left added_pt.curvature's unit is ms and will be used in other modules of FAST-LIO. So if your data's time field (pl_orig.points[i].time) is in another unit, you can just change the number 1000.0 to support your data. For example: if your time field is in second. what you should do is just change the 1000.0 to 0.001.

  1. I think the header.timestamp in the point cloud ROS topic is the first lidar point's time for all the Velodyne, Ouster, and Livox LiDARs.
cosama commented 3 years ago

Thanks for your quick reply. This pretty much agrees with what I have been observing. I will close this.