hku-mars / FAST_LIO

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

velodyne not fit into this project. #302

Closed shaoxh closed 8 months ago

shaoxh commented 9 months ago

I used the provided Velodyne data, but found it not suitable. After a whole day work on it, finally figure the problem out.

This code requires that a point cloud in ROS topic MUST has fields named x-y-z-intensity-time, like here: `void Preprocess::velodyne_handler(const sensor_msgs::PointCloud2::ConstPtr &msg) { pl_surf.clear(); pl_corn.clear(); pl_full.clear();

pcl::PointCloud<velodyne_ros::Point> pl_orig;
pcl::fromROSMsg(*msg, pl_orig);
int plsize = pl_orig.points.size();
if (plsize == 0) return;
pl_surf.reserve(plsize);

for (int i = 0; i < plsize; i++) { PointType added_pt; // cout<<"!!!!!!"<<i<<" "<<plsize<<endl;

    added_pt.normal_x = 0;
    added_pt.normal_y = 0;
    added_pt.normal_z = 0;
    added_pt.x = pl_orig.points[i].x;
    added_pt.y = pl_orig.points[i].y;
    added_pt.z = pl_orig.points[i].z;
    added_pt.intensity = pl_orig.points[i].intensity;
    added_pt.curvature = pl_orig.points[i].time * time_unit_scale;  // curvature unit: ms // cout<<added_pt.curvature<<endl;

`

However, the so-provided velodyne data in ReadMe.md is made by the python file. This python file does NOT process intensity but refer to a RING field, like here:

` for i in range(num_hits): x = struct.unpack('<H', f_vel.read(2))[0] y = struct.unpack('<H', f_vel.read(2))[0] z = struct.unpack('<H', f_vel.read(2))[0] i = struct.unpack('B', f_vel.read(1))[0] l = struct.unpack('B', f_vel.read(1))[0]

        if l <= l_last:
            N += 1

        if N>12:
            N = 12

        l_last = l

        # layer_point_num[l] += 1
        # offset_time_ind[l][layer_point_num[l]] = offset_time_base + dt * N
        # if layer_point_num[l] >= 12:
        #     print(l, yaw_ind[l], offset_time_ind[l])
        x, y, z = convert_vel(x, y, z)
        offset_time = int(offset_time_base + dt * N)
        if offset_time + last_time >= utime:
            offset_time = utime - last_time
        off_t = float(offset_time)
        data.append([x, y, z, offset_time, l])`

and here: `if utime - last_time > 1e5:

print(last_time / 1e6)

        # print(utime)
        header = Header()
        header.frame_id = 'velodyne'
        header.stamp = rospy.Time.from_sec(last_time/1e6)
        fields = [PointField('x', 0, PointField.FLOAT32, 1),
                PointField('y', 4, PointField.FLOAT32, 1),
                PointField('z', 8, PointField.FLOAT32, 1),
                // PointField('intensity', 12, PointField.FLOAT32, 1),
                PointField('time', 16, PointField.FLOAT32, 1),
                PointField('ring', 20, PointField.UINT16, 1)]`

This explains it! No Intensity on the provided ros bag file, and the FASTLIO keep throwing errors like these: Failed to find match for field 'intensity'. Failed to find match for field 'intensity'. Failed to find match for field 'intensity'.

Do not know the reason they offer this wired codes and wrong test data. https://drive.google.com/drive/folders/1blQJuAB4S80NwZmpM6oALyHWvBljPSOE Write here in case someone else confront with the same issue. Good luck!

shaoxh commented 9 months ago

Remember to remap topic name points_raw and imu_raw to /velodyne_points and /imu/data respectively when playing the ROS_Bag.

stale[bot] commented 8 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.