Skip to content

Commit

Permalink
make Velodyne/Ouster input a config option
Browse files Browse the repository at this point in the history
  • Loading branch information
valgur committed Nov 22, 2020
1 parent 45d8482 commit c7ce1fb
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 47 deletions.
11 changes: 2 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,16 +166,9 @@ rosbag play your-bag.bag -r 3
- Hardware:
- Use an external IMU. LIO-SAM does not work with the internal 6-axis IMU of Ouster lidar. You need to attach a 9-axis IMU to the lidar and perform data-gathering.
- Configure the driver. Change "timestamp_mode" in your Ouster launch file to "TIME_FROM_PTP_1588" so you can have ROS format timestamp for the point clouds.
- Software:
- Change "timeField" in "params.yaml" to "t". "t" is the point timestamp in a scan for Ouster lidar.
- Config:
- Change "sensor" in "params.yaml" to "ouster".
- Change "N_SCAN" and "Horizon_SCAN" in "params.yaml" according to your lidar, i.e., N_SCAN=128, Horizon_SCAN=1024.
- Comment the point definition for Velodyne on top of "imageProjection.cpp".
- Uncomment the point definition for Ouster on top of "imageProjection.cpp".
- Comment line "timeScanEnd = timeScanCur + laserCloudIn->points.back().time" in "imageProjection.cpp".
- Uncomment line "timeScanEnd = timeScanCur + (float)laserCloudIn->points.back().t / 1000000000.0" in "imageProjection.cpp".
- Comment line "deskewPoint(&thisPoint, laserCloudIn->points[i].time)" in "imageProjection.cpp".
- Uncomment line "deskewPoint(&thisPoint, (float)laserCloudIn->points[i].t / 1000000000.0" in "imageProjection.cpp".
- Run "catkin_make" to re-compile the package.
- Gen 1 and Gen 2 Ouster:
It seems that the point coordinate definition might be different in different generations. Please refer to [Issue #94](https://github.com/TixiaoShan/LIO-SAM/issues/94) for debugging.

Expand Down
6 changes: 3 additions & 3 deletions config/params.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ lio_sam:
savePCDDirectory: "/Downloads/LOAM/" # in your home folder, starts and ends with "/". Warning: the code deletes "LOAM" folder then recreates it. See "mapOptimization" for implementation

# Sensor Settings
sensor: velodyne # lidar sensor type, either 'velodyne' or 'ouster'
N_SCAN: 16 # number of lidar channel (i.e., 16, 32, 64, 128)
Horizon_SCAN: 1800 # lidar horizontal resolution (Velodyne:1800, Ouster:512,1024,2048)
timeField: "time" # point timestamp field, Velodyne - "time", Ouster - "t"
downsampleRate: 1 # default: 1. Downsample your data if too many points. i.e., 16 = 64 / 4, 16 = 16 / 1
downsampleRate: 1 # default: 1. Downsample your data if too many points. i.e., 16 = 64 / 4, 16 = 16 / 1
lidarMinRange: 1.0 # default: 1.0, minimum lidar range to be used
lidarMaxRange: 1000.0 # default: 1000.0, maximum lidar range to be used

Expand Down Expand Up @@ -158,4 +158,4 @@ ekf_gps:
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.01, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.01, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.015]
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.015]
26 changes: 22 additions & 4 deletions include/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ using namespace std;

typedef pcl::PointXYZI PointType;

enum class SensorType { VELODYNE, OUSTER };

class ParamServer
{
public:
Expand Down Expand Up @@ -87,10 +89,10 @@ class ParamServer
bool savePCD;
string savePCDDirectory;

// Velodyne Sensor Configuration: Velodyne
// Lidar Sensor Configuration
SensorType sensor;
int N_SCAN;
int Horizon_SCAN;
string timeField;
int downsampleRate;
float lidarMinRange;
float lidarMaxRange;
Expand Down Expand Up @@ -170,9 +172,25 @@ class ParamServer
nh.param<bool>("lio_sam/savePCD", savePCD, false);
nh.param<std::string>("lio_sam/savePCDDirectory", savePCDDirectory, "/Downloads/LOAM/");

std::string sensorStr;
nh.param<std::string>("lio_sam/sensor", sensorStr, "");
if (sensorStr == "velodyne")
{
sensor = SensorType::VELODYNE;
}
else if (sensorStr == "ouster")
{
sensor = SensorType::OUSTER;
}
else
{
ROS_ERROR_STREAM(
"Invalid sensor type (must be either 'velodyne' or 'ouster'): " << sensorStr);
ros::shutdown();
}

nh.param<int>("lio_sam/N_SCAN", N_SCAN, 16);
nh.param<int>("lio_sam/Horizon_SCAN", Horizon_SCAN, 1800);
nh.param<std::string>("lio_sam/timeField", timeField, "time");
nh.param<int>("lio_sam/downsampleRate", downsampleRate, 1);
nh.param<float>("lio_sam/lidarMinRange", lidarMinRange, 1.0);
nh.param<float>("lio_sam/lidarMaxRange", lidarMaxRange, 1000.0);
Expand Down Expand Up @@ -321,4 +339,4 @@ float pointDistance(PointType p1, PointType p2)
return sqrt((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y) + (p1.z-p2.z)*(p1.z-p2.z));
}

#endif
#endif
86 changes: 55 additions & 31 deletions src/imageProjection.cpp
Original file line number Diff line number Diff line change
@@ -1,38 +1,37 @@
#include "utility.h"
#include "lio_sam/cloud_info.h"

// Velodyne
struct PointXYZIRT
struct VelodynePointXYZIRT
{
PCL_ADD_POINT4D
PCL_ADD_INTENSITY;
uint16_t ring;
float time;
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
} EIGEN_ALIGN16;

POINT_CLOUD_REGISTER_POINT_STRUCT (PointXYZIRT,
POINT_CLOUD_REGISTER_POINT_STRUCT (VelodynePointXYZIRT,
(float, x, x) (float, y, y) (float, z, z) (float, intensity, intensity)
(uint16_t, ring, ring) (float, time, time)
)

// Ouster
// struct PointXYZIRT {
// PCL_ADD_POINT4D;
// float intensity;
// uint32_t t;
// uint16_t reflectivity;
// uint8_t ring;
// uint16_t noise;
// uint32_t range;
// EIGEN_MAKE_ALIGNED_OPERATOR_NEW
// }EIGEN_ALIGN16;

// POINT_CLOUD_REGISTER_POINT_STRUCT(PointXYZIRT,
// (float, x, x) (float, y, y) (float, z, z) (float, intensity, intensity)
// (uint32_t, t, t) (uint16_t, reflectivity, reflectivity)
// (uint8_t, ring, ring) (uint16_t, noise, noise) (uint32_t, range, range)
// )
struct OusterPointXYZIRT {
PCL_ADD_POINT4D;
float intensity;
uint32_t t;
uint16_t reflectivity;
uint8_t ring;
uint16_t noise;
uint32_t range;
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
} EIGEN_ALIGN16;
POINT_CLOUD_REGISTER_POINT_STRUCT(OusterPointXYZIRT,
(float, x, x) (float, y, y) (float, z, z) (float, intensity, intensity)
(uint32_t, t, t) (uint16_t, reflectivity, reflectivity)
(uint8_t, ring, ring) (uint16_t, noise, noise) (uint32_t, range, range)
)

// Use the Velodyne point format as a common representation
using PointXYZIRT = VelodynePointXYZIRT;

const int queueLength = 2000;

Expand All @@ -57,7 +56,7 @@ class ImageProjection : public ParamServer

std::deque<sensor_msgs::PointCloud2> cloudQueue;
sensor_msgs::PointCloud2 currentCloudMsg;

double *imuTime = new double[queueLength];
double *imuRotX = new double[queueLength];
double *imuRotY = new double[queueLength];
Expand Down Expand Up @@ -199,13 +198,39 @@ class ImageProjection : public ParamServer
// convert cloud
currentCloudMsg = cloudQueue.front();
cloudQueue.pop_front();
pcl::fromROSMsg(currentCloudMsg, *laserCloudIn);
if (sensor == SensorType::VELODYNE)
{
pcl::moveFromROSMsg(currentCloudMsg, *laserCloudIn);
}
else if (sensor == SensorType::OUSTER)
{
// Convert to Velodyne format
pcl::PointCloud<OusterPointXYZIRT> tmpOusterCloud;
pcl::moveFromROSMsg(currentCloudMsg, tmpOusterCloud);
laserCloudIn->points.resize(tmpOusterCloud.size());
laserCloudIn->is_dense = tmpOusterCloud.is_dense;
for (size_t i = 0; i < tmpOusterCloud.size(); i++)
{
auto &src = tmpOusterCloud.points[i];
auto &dst = laserCloudIn->points[i];
dst.x = src.x;
dst.y = src.y;
dst.z = src.z;
dst.intensity = src.intensity;
dst.ring = src.ring;
dst.time = src.t * 1e-9f;
}
}
else
{
ROS_ERROR_STREAM("Unknown sensor type: " << int(sensor));
ros::shutdown();
}

// get timestamp
cloudHeader = currentCloudMsg.header;
timeScanCur = cloudHeader.stamp.toSec();
timeScanEnd = timeScanCur + laserCloudIn->points.back().time; // Velodyne
// timeScanEnd = timeScanCur + (float)laserCloudIn->points.back().t / 1000000000.0; // Ouster
timeScanEnd = timeScanCur + laserCloudIn->points.back().time;

// check dense flag
if (laserCloudIn->is_dense == false)
Expand All @@ -232,15 +257,15 @@ class ImageProjection : public ParamServer
ROS_ERROR("Point cloud ring channel not available, please configure your point cloud data!");
ros::shutdown();
}
}
}

// check point time
if (deskewFlag == 0)
{
deskewFlag = -1;
for (int i = 0; i < (int)currentCloudMsg.fields.size(); ++i)
for (auto &field : currentCloudMsg.fields)
{
if (currentCloudMsg.fields[i].name == timeField)
if (field.name == "time" || field.name == "t")
{
deskewFlag = 1;
break;
Expand Down Expand Up @@ -524,8 +549,7 @@ class ImageProjection : public ParamServer
if (rangeMat.at<float>(rowIdn, columnIdn) != FLT_MAX)
continue;

thisPoint = deskewPoint(&thisPoint, laserCloudIn->points[i].time); // Velodyne
// thisPoint = deskewPoint(&thisPoint, (float)laserCloudIn->points[i].t / 1000000000.0); // Ouster
thisPoint = deskewPoint(&thisPoint, laserCloudIn->points[i].time);

rangeMat.at<float>(rowIdn, columnIdn) = range;

Expand Down Expand Up @@ -580,4 +604,4 @@ int main(int argc, char** argv)
spinner.spin();

return 0;
}
}

0 comments on commit c7ce1fb

Please sign in to comment.