Capture Laser Data retrieve from Velodyne LiDAR

VelodyneCapture

I create VelodyneCapture class for retrieve data from Velodyne LiDAR.
It is implement in one header file, You can use easily.

VelodyneCapture is published in following.

What is Data?

VelodyneCapture can retrieve the data that by capture 360-degree rotation as one frame.
The each lasers has following information.

  • azimuth
  • vertical
  • distance
  • intensity
  • id
  • time

What is Dependent Libraries?

VelodyneCapture can be direct capture from Velodyne sensors in real-time.
Also, VelodyneCapture can be offline capture from PCAP files.
It depends on the following library depending on each capture method.*1

*1 Please define HAVE_BOOST, HAVE_PCAP in pre-processor.

  • Direct Capture from Sensor
  • Boost.Asio

  • Offline Capture from PCAP
  • libpcap ( or WinPCAP )

Basic usage for VelodyneCapture

I introduce the basic usage of VelodyneCapture.

Include Header

Please include VelodyneCapture.h to use VelodyneCapture.

#include "VelodyneCapture.h"

Generate Instance

Then, You need create instance of capture class.
VelodyneCapture has capture class for each Velodyne sensors.

  • velodyne::VLP16Capture
  • Capture Class for VLP-16

  • velodyne::HDL32ECapture
  • Capture Class for HDL-32E

// Capture Class for VLP-16
velodyne::VLP16Capture capture;

// Capture Class for HDL-32E
velodyne::HDL32ECapture capture;

Open Capture

If you want to direct capture in real time from Velodyne sensors, You give IP address and port number.
If you want to offline capture from PCAP files, You give PCAP file path.
You can check with isOpen() whether capture was successfully started.

// Open Direct Capture retrieve from Sensor
const boost::asio::ip::address address = boost::asio::ip::address::from_string( "192.168.1.21" );
const unsigned short port = 2368;
capture.open( address, port );
if( !capture.isOpen() ){
    std::cerr << "Can't open VelodyneCapture." << std::endl;
    return -1;
}

// Open Offline Capture retrieve from PCAP
const std::string filename = "../file.pcap";
capture.open( filename );
if( !capture.isOpen() ){
    std::cerr << "Can't open VelodyneCapture." << std::endl;
    return -1;
}

Retrieve One Rotation Data

You can retrieve one frame data that captured 360-degree rotation.
That data is stored in array of velodyne::Laser structures
You can use >> operator or retrieve().

That data has not been sorted by azimuth and laser id.
If you want to retrieve sorted data, You can use std::sort() as needed.

while( capture.isRun() ){
    // Capture One Rotation Laser Data
    std::vector<velodyne::Laser> lasers;
    capture >> lasers;
    if( lasers.empty() ){
        continue;
    }

    /*
    // Sort Laser Data ( 0 degree -> 359 degree, 0 id -> n id )
    std::sort( lasers.begin(), lasers.end() );
    */

    // Access to Laser Data
    for( const velodyne::Laser& laser : lasers ){
        // Laser Azimuth ( degree )
        const double azimuth = laser.azimuth;

        // Laser Vertical ( degree )
        const double vertical = laser.vertical;

        // Laser Distance ( centimeter )
        const unsigned short distance = laser.distance;

        // Laser Intensity
        const unsigned char intensity = laser.intensity;

        // Laser ID ( VLP-16 : 0 - 15, HDL-32E : 0 - 31 )
        const unsigned char id = laser.id;

        // Laser TimeStamp ( microseconds )
        const long long unixtime = laser.time;
    }
}

Draw Velodyne LiDAR Data using OpenCV Viz module

I will introduce sample program that draw data retrieved from Velodyne sensors using OpenCV Viz module.
This sample program is published in following.

Convert to 3-dimention Coordinates

You need convert to 3-dimension coordinate from data that retrieved using VelodyneCapture.
You can calculate 3-dimension position from distance, vertical angle, horizontal angle as follows.
The horizontal and vertical angles are converted to radian from degree in advance because trigonometric functions specification.

// Convert to 3-dimension Coordinates
std::vector<cv::Vec3f> buffer( lasers.size() );
for( const velodyne::Laser& laser : lasers ){
    const double distance = static_cast<double>( laser.distance );
    const double azimuth  = laser.azimuth  * CV_PI / 180.0;
    const double vertical = laser.vertical * CV_PI / 180.0;

    float x = static_cast<float>( ( distance * std::cos( vertical ) ) * std::sin( azimuth ) );
    float y = static_cast<float>( ( distance * std::cos( vertical ) ) * std::cos( azimuth ) );
    float z = static_cast<float>( ( distance * std::sin( vertical ) ) );

    if( x == 0.0f && y == 0.0f && z == 0.0f ){
        x = std::numeric_limits<float>::quiet_NaN();
        y = std::numeric_limits<float>::quiet_NaN();
        z = std::numeric_limits<float>::quiet_NaN();
    }

    buffer.push_back( cv::Vec3f( x, y, z ) );
}

Execution Result

It will be display Point Cloud that retrieved from Velodyne LiDAR when running this sample program.
This sample data (HDL32-V2_Monterey Highway.pcap) has been retrieved from sensor that mount on car top.


2 thoughts on “Capture Laser Data retrieve from Velodyne LiDAR”

  1. Hi,

    I am trying to use your class, but in my example I get an error:

    LINK : fatal error LNK1104: can’t open file ‘opencv_contrib249d.lib’

    I have installed the last version of OpenCV, but I don’t know if I am missing something.

    Thanks in advance

    1. Hi Jorge Mirantes,

      I could build sample program with OpenCV 3.1 (It was linked VTK 7.1 to generate Viz module).
      Sorry, I don’t know whether it work with OpenCV 2.4.x, because I have never tried it.

      The contribution modules is not necessary to build this sample program.
      This sample program requires Core module (opencv_core) and Viz module (opencv_viz) of OpenCV.
      You need to build Viz module from source code, because it is not included in pre-built package.

      Note: VelodyneCapture class itself doesn’t require OpenCV.

Leave a Reply

Your email address will not be published. Required fields are marked *