MRPT  1.9.9
CVelodyneScanner.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #ifndef CVelodyneScanner_H
11 #define CVelodyneScanner_H
12 
18 
19 namespace mrpt::hwdrivers
20 {
21 /** A C++ interface to Velodyne laser scanners (HDL-64, HDL-32, VLP-16), working
22  * on Linux and Windows.
23  * (Using this class requires WinPCap as a run-time dependency in Windows).
24  * It can receive data from real devices via an Ethernet connection or parse a
25  * WireShark PCAP file for offline processing.
26  * The choice of online vs. offline operation is taken upon calling \a
27  * initialize(): if a PCAP input file has been defined,
28  * offline operation takes place and network is not listened for incomming
29  * packets.
30  *
31  * Parsing dual return scans requires a VLP-16 with firmware version 3.0.23 or
32  * newer. While converting the scan into a
33  * point cloud in mrpt::obs::CObservationVelodyneScan you can select whether to
34  * keep the strongest, the last or both laser returns.
35  *
36  * XML calibration files are not mandatory for VLP-16 and HDL-32, but they are
37  * for HDL-64.
38  *
39  * <h2>Grabbing live data (as a user)</h2> <hr>
40  * - Use the application
41  * [velodyne-view](http://www.mrpt.org/list-of-mrpt-apps/application-velodyne-view/)
42  * to visualize the LIDAR output in real-time (optionally saving to a PCAP file)
43  * or to playback a PCAP file.
44  * - Use
45  * [rawlog-grabber](http://www.mrpt.org/list-of-mrpt-apps/application-rawlog-grabber/)
46  * to record a dataset in MRPT's format together with any other set of sensors.
47  * See example config file:
48  * [MRPT\share\mrpt\config_files\rawlog-grabber\velodyne.ini](https://github.com/MRPT/mrpt/blob/master/share/mrpt/config_files/rawlog-grabber/velodyne.ini)
49  *
50  * <h2>Grabbing live data (programmatically)</h2> <hr>
51  * - See CGenericSensor for a general overview of the sequence of methods to
52  * be called: loadConfig(), initialize(), doProcess().
53  * - Or use this class inside the application
54  * [rawlog-grabber](http://www.mrpt.org/list-of-mrpt-apps/application-rawlog-grabber/).
55  * See example config files:
56  * [MRPT\share\mrpt\config_files\rawlog-grabber\velodyne.ini](https://github.com/MRPT/mrpt/blob/master/share/mrpt/config_files/rawlog-grabber/velodyne.ini)
57  *
58  * See the source code of the example application `[MRPT]/apps/velodyne-view`
59  * ([velodyne-view web
60  * page](http://www.mrpt.org/list-of-mrpt-apps/application-velodyne-view/)) for
61  * more details.
62  *
63  * <h2>Playing back a PCAP file:</h2><hr>
64  * It is common to save Velodyne datasets as Wireshark's PCAP files.
65  * These files can be played back with tools like
66  * [bittwist](http://bittwist.sourceforge.net/), which emit all UDP packets in
67  * the PCAP log.
68  * Then, use this class to receive the packets as if they come from the real
69  * sensor.
70  *
71  * Alternatively, if MRPT is linked against libpcap, this class can directly
72  * parse a PCAP file to simulate reading from a device offline.
73  * See method setPCAPInputFile() and config file parameter ``
74  *
75  * To compile with PCAP support: In Debian/Ubuntu, install libpcap-dev. In
76  * Windows, install WinPCap developer packages + the regular WinPCap driver.
77  *
78  * <h2>Configuration and usage:</h2> <hr>
79  * Data is returned as observations of type:
80  * - mrpt::obs::CObservationVelodyneScan for one or more "data packets" (refer
81  * to Velodyne usage manual)
82  * - mrpt::obs::CObservationGPS for GPS (GPRMC) packets, if available via the
83  * synchronization interface of the device.
84  * See those classes for documentation on their fields.
85  *
86  * Configuration includes setting the device IP (optional) and sensor model
87  * (mandatory only if a calibration file is not provided).
88  * These parameters can be set programmatically (see methods of this class), or
89  * via a configuration file with CGenericSensor::loadConfig() (see example
90  * config file section below).
91  *
92  * <h2>About timestamps:</h2><hr>
93  * Each gathered observation of type mrpt::obs::CObservationVelodyneScan is
94  * populated with two timestamps, one for the local PC timestamp and,
95  * if available, another one for the GPS-stamped timestamp. Refer to the
96  * observation docs for details.
97  *
98  * <h2>Format of parameters for loading from a .ini file</h2><hr>
99  * \code
100  * PARAMETERS IN THE ".INI"-LIKE CONFIGURATION STRINGS:
101  * -------------------------------------------------------
102  * [supplied_section_name]
103  * # ---- Sensor description ----
104  * #calibration_file = PUT_HERE_FULL_PATH_TO_CALIB_FILE.xml //
105  * Optional but recommended: put here your vendor-provided calibration file
106  * model = VLP16 // Can be any of: `VLP16`, `HDL32`,
107  * `HDL64` (It is used to load default calibration file. Parameter not required
108  * if `calibration_file` is provided.
109  * #pos_packets_min_period = 0.5 // (Default=0.5 seconds) Minimum
110  * period to leave between reporting position packets. Used to decimate the
111  * large number of packets of this type.
112  * # How long to wait, after loss of GPS signal, to report timestamps as "not
113  * based on satellite time". 30 secs, with typical velodyne clock drifts, means
114  * a ~1.7 ms typical drift.
115  * #pos_packets_timing_timeout = 30 // (Default=30 seconds)
116  * # ---- Online operation ----
117  *
118  * # IP address of the device. UDP packets from other IPs will be ignored.
119  * Leave commented or blank
120  * # if only one scanner is present (no IP filtering)
121  * #device_ip = XXX.XXX.XXX.XXX
122  *
123  * #rpm = 600 // Sensor RPM (Default: unchanged). Requires
124  * setting `device_ip`
125  * #return_type = STRONGEST // Any of: 'STRONGEST', 'LAST', 'DUAL'
126  * (Default: unchanged). Requires setting `device_ip`
127  *
128  * # ---- Offline operation ----
129  * # If uncommented, this class will read from the PCAP instead of connecting
130  * and listeling
131  * # for online network packets.
132  * # pcap_input = PUT_FULL_PATH_TO_PCAP_LOG_FILE.pcap
133  * # pcap_read_once = false // Do not loop
134  * # pcap_read_fast = false // fast forward skipping non-velodyne packets
135  * # pcap_read_full_scan_delay_ms = 100 // Used to simulate a reasonable
136  * number of full scans / second
137  * # pcap_repeat_delay = 0.0 // seconds
138  *
139  * # ---- Save to PCAP file ----
140  * # If uncommented, a PCAP file named
141  * `[pcap_output_prefix]_[DATE_TIME].pcap` will be
142  * # written simultaneously to the normal operation of this class.
143  * # pcap_output = velodyne_log
144  *
145  * # 3D position of the sensor on the vehicle:
146  * pose_x = 0 // 3D position (meters)
147  * pose_y = 0
148  * pose_z = 0
149  * pose_yaw = 0 // 3D orientation (degrees)
150  * pose_pitch = 0
151  * pose_roll = 0
152  *
153  * \endcode
154  *
155  *
156  * <h2>Copyright notice</h2><hr>
157  * Portions of this class are based on code from velodyne ROS node in
158  * https://github.com/ros-drivers/velodyne
159  * Copyright (C) 2007 Austin Robot Technology, Patrick Beeson
160  * Copyright (C) 2009, 2010 Austin Robot Technology, Jack O'Quin
161  * License: Modified BSD Software License Agreement
162  *
163  * \note New in MRPT 1.4.0
164  * \ingroup mrpt_hwdrivers_grp
165  */
167 {
169  public:
170  /** Default: 2368. Change it if required. */
171  static short int VELODYNE_DATA_UDP_PORT;
172  /** Default: 8308. Change it if required. */
173  static short int VELODYNE_POSITION_UDP_PORT;
174 
175  /** LIDAR model types */
176  enum model_t
177  {
178  VLP16 = 1,
179  HDL32 = 2,
180  HDL64 = 3
181  };
182 
183  /** LIDAR return type */
185  {
189  DUAL
190  };
191 
192  /** Hard-wired properties of LIDARs depending on the model */
194  {
195  double maxRange;
196  };
197  using model_properties_list_t = std::map<model_t, TModelProperties>;
198  /** Access to default sets of parameters for Velodyne LIDARs */
200  {
201  /** Singleton access */
202  static const model_properties_list_t& get();
203  /** Return human-readable string: "`VLP16`,`XXX`,..." */
205  };
206 
207  protected:
209  /** Default: "VLP16" */
211  /** Default: 0.5 seconds */
213  /** Default: 30 seconds */
215  /** Default: "" (no IP-based filtering) */
217  /** Default: true Output whole frames and not data packets */
219  /** Default: true Output PCAP Info msgs */
221  /** Default: "" (do not operate from an offline file) */
223  /** Default: "" (do not dump to an offline file) */
226  /** Device calibration file (supplied by vendor in an XML file) */
229 
230  // offline operation:
231  /** opaque ptr: "pcap_t*" */
232  void* m_pcap;
233  /** opaque ptr: "pcap_t*" */
234  void* m_pcap_out;
235  /** opaque ptr: "pcap_dumper_t *" */
237  /** opaque ptr: bpf_program* */
240  /** number of pkts read from the file so far (for debugging) */
241  unsigned int m_pcap_read_count;
242  /** Default: false */
244  /** (Default: false) If false, will use m_pcap_read_full_scan_delay_ms */
246  /** (Default:100 ms) delay after each full scan read from a PCAP log */
248  /** Default: 0 (in seconds) */
250 
251  /** See the class documentation at the top for expected parameters */
253  const mrpt::config::CConfigFileBase& configSource,
254  const std::string& section);
255 
256  public:
258  virtual ~CVelodyneScanner();
259 
260  /** @name Change configuration parameters; to be called BEFORE initialize();
261  * see above for the list of parameters and their meaning
262  * @{ */
263  /** See supported model names in the general discussion docs for
264  * mrpt::hwdrivers::CVelodyneScanner */
266  model_t getModelName() const { return m_model; }
267  /** Set the minimum period between the generation of
268  * mrpt::obs::CObservationGPS observations from Velodyne Position RMC GPS
269  * packets */
270  void setPosPacketsMinPeriod(double period_seconds)
271  {
272  m_pos_packets_min_period = period_seconds;
273  }
275  /** Set how long to wait, after loss of GPS signal, to report timestamps as
276  * "not based on satellite time". 30 secs, with typical velodyne clock
277  * drifts, means a ~1.7 ms typical drift. */
278  void setPosPacketsTimingTimeout(double timeout)
279  {
281  }
283  {
285  }
286 
287  /** UDP packets from other IPs will be ignored. Default: empty string, means
288  * do not filter by IP */
289  void setDeviceIP(const std::string& ip) { m_device_ip = ip; }
290  const std::string& getDeviceIP() const { return m_device_ip; }
291  /** Enables/disables PCAP info messages to console (default: true) */
292  void setPCAPVerbosity(const bool verbose) { m_pcap_verbose = verbose; }
293  /** Enables reading from a PCAP file instead of live UDP packet listening */
294  void setPCAPInputFile(const std::string& pcap_file)
295  {
296  m_pcap_input_file = pcap_file;
297  }
298  const std::string& getPCAPInputFile() const { return m_pcap_input_file; }
299  /** Enables dumping to a PCAP file in parallel to returning regular MRPT
300  * objects. Default="": no pcap log. */
301  void setPCAPOutputFile(const std::string& out_pcap_file)
302  {
303  m_pcap_output_file = out_pcap_file;
304  }
306  void setPCAPInputFileReadOnce(bool read_once)
307  {
308  m_pcap_read_once = read_once;
309  }
312  {
313  return m_velodyne_calib;
314  }
316  {
317  m_velodyne_calib = calib;
318  }
319  /** Returns false on error. \sa
320  * mrpt::obs::VelodyneCalibration::loadFromXMLFile() */
321  bool loadCalibrationFile(const std::string& velodyne_xml_calib_file_path);
322 
323  /** Changes among STRONGEST, LAST, DUAL return types (via HTTP post
324  * interface).
325  * Can be called at any instant, before or after initialize().
326  * Requires setting a device IP address.
327  * \return false on error */
328  bool setLidarReturnType(return_type_t ret_type);
329 
330  /** Changes Lidar RPM (valid range: 300-600) (via HTTP post interface).
331  * Can be called at any instant, before or after initialize().
332  * Requires setting a device IP address.
333  * \return false on error*/
334  bool setLidarRPM(int rpm);
335 
336  /** Switches the LASER on/off (saves energy when not measuring) (via HTTP
337  * post interface).
338  * Can be called at any instant, before or after initialize().
339  * Requires setting a device IP address.
340  * \return false on error*/
341  bool setLidarOnOff(bool on);
342 
343  /** Switches whole frame (points in a single revolution) on/off publication
344  * to data packet publication. When on, getNextObservation() will return
345  * true whenever a frame is avaliable, when off, getNextObservation() will
346  * return true whenever a data packet is avaliable. The default is on. When
347  * listening to data packets on a PCAP, pcap_read_fast is enforced.
348  */
349  void setFramePublishing(bool on);
350 
351  /** @} */
352 
353  /** Polls the UDP port for incoming data packets. The user *must* call this
354  * method in a timely fashion to grab data as it it generated by the device.
355  * The minimum call rate should be the expected number of data
356  * packets/second (!=scans/second). Checkout Velodyne user manual if in
357  * doubt.
358  *
359  * \param[out] outScan Upon return, an empty smart pointer will be found
360  * here if no new data was available. Otherwise, a valid scan.
361  * \param[out] outGPS Upon return, an empty smart pointer will be found
362  * here if no new GPS data was available. Otherwise, a valid GPS reading.
363  * \return true if no error ocurred (even if there was no new observation).
364  * false if any communication error occurred.
365  */
366  bool getNextObservation(
369 
370  // See docs in parent class
371  void doProcess();
372 
373  /** Tries to initialize the sensor driver, after setting all the parameters
374  * with a call to loadConfig.
375  * Velodyne specifics: this method sets up the UDP listening sockets, so
376  * all relevant params MUST BE SET BEFORE calling this.
377  * \exception This method must throw an exception with a descriptive
378  * message if some critical error is found.
379  */
380  virtual void initialize();
381 
382  /** Close the UDP sockets set-up in \a initialize(). This is called
383  * automatically upon destruction */
384  void close();
385 
386  /** Users normally would prefer calling \a getNextObservation() instead.
387  * This method polls the UDP data port and returns one Velodyne DATA packet
388  * (1206 bytes) and/or one POSITION packet. Refer to Velodyne users manual.
389  * Approximate timestamps (based on this computer clock) are returned for
390  * each kind of packets, or INVALID_TIMESTAMP if timeout ocurred waiting for
391  * a packet.
392  * \return true on all ok. false only for pcap reading EOF
393  */
394  bool receivePackets(
395  mrpt::system::TTimeStamp& data_pkt_timestamp,
397  mrpt::system::TTimeStamp& pos_pkt_timestamp,
399  out_pos_pkt);
400 
401  private:
402  /** Handles for the UDP sockets, or INVALID_SOCKET (-1) */
404 #ifdef _WIN32
405 #if MRPT_WORD_SIZE == 64
406  uint64_t
407 #else
408  uint32_t
409 #endif
410 #else
411  int
412 #endif
413  ;
414 
416 
418  platform_socket_t hSocket, uint8_t* out_buffer,
419  const size_t expected_packet_size,
420  const std::string& filter_only_from_IP);
421 
423  mrpt::system::TTimeStamp& data_pkt_time, uint8_t* out_data_buffer,
424  mrpt::system::TTimeStamp& pos_pkt_time, uint8_t* out_pos_buffer);
425 
426  /** In progress RX scan */
428 
433 
434  bool internal_send_http_post(const std::string& post_data);
435 
436 }; // end of class
437 }
439 using namespace mrpt::hwdrivers;
444 
445 MRPT_ENUM_TYPE_BEGIN(mrpt::hwdrivers::CVelodyneScanner::return_type_t)
446 using namespace mrpt::hwdrivers;
452 
453 #endif
454 
455 
#define DEFINE_GENERIC_SENSOR(class_name)
This declaration must be inserted in all CGenericSensor classes definition, within the class declarat...
MRPT_FILL_ENUM_MEMBER(CVelodyneScanner, VLP16)
#define MRPT_ENUM_TYPE_END()
Definition: TEnumType.h:78
#define MRPT_ENUM_TYPE_BEGIN(_ENUM_TYPE_WITH_NS)
Definition: TEnumType.h:62
This class allows loading and storing values and vectors of different types from a configuration text...
A generic interface for a wide-variety of sensors designed to be used in the application RawLogGrabbe...
A C++ interface to Velodyne laser scanners (HDL-64, HDL-32, VLP-16), working on Linux and Windows.
static mrpt::system::TTimeStamp internal_receive_UDP_packet(platform_socket_t hSocket, uint8_t *out_buffer, const size_t expected_packet_size, const std::string &filter_only_from_IP)
mrpt::obs::VelodyneCalibration m_velodyne_calib
Device calibration file (supplied by vendor in an XML file)
static short int VELODYNE_DATA_UDP_PORT
Default: 2368.
void setDeviceIP(const std::string &ip)
UDP packets from other IPs will be ignored.
bool setLidarOnOff(bool on)
Switches the LASER on/off (saves energy when not measuring) (via HTTP post interface).
void * m_pcap_dumper
opaque ptr: "pcap_dumper_t *"
void setPCAPVerbosity(const bool verbose)
Enables/disables PCAP info messages to console (default: true)
void setPCAPInputFile(const std::string &pcap_file)
Enables reading from a PCAP file instead of live UDP packet listening.
uint32_t platform_socket_t
Handles for the UDP sockets, or INVALID_SOCKET (-1)
bool receivePackets(mrpt::system::TTimeStamp &data_pkt_timestamp, mrpt::obs::CObservationVelodyneScan::TVelodyneRawPacket &out_data_pkt, mrpt::system::TTimeStamp &pos_pkt_timestamp, mrpt::obs::CObservationVelodyneScan::TVelodynePositionPacket &out_pos_pkt)
Users normally would prefer calling getNextObservation() instead.
void setPosPacketsTimingTimeout(double timeout)
Set how long to wait, after loss of GPS signal, to report timestamps as "not based on satellite time"...
virtual void initialize()
Tries to initialize the sensor driver, after setting all the parameters with a call to loadConfig.
const mrpt::obs::VelodyneCalibration & getCalibration() const
bool getNextObservation(mrpt::obs::CObservationVelodyneScan::Ptr &outScan, mrpt::obs::CObservationGPS::Ptr &outGPS)
Polls the UDP port for incoming data packets.
std::string m_pcap_output_file
Default: "" (do not dump to an offline file)
std::string m_device_ip
Default: "" (no IP-based filtering)
unsigned int m_pcap_read_count
number of pkts read from the file so far (for debugging)
void doProcess()
This method will be invoked at a minimum rate of "process_rate" (Hz)
std::map< model_t, TModelProperties > model_properties_list_t
void * m_pcap_out
opaque ptr: "pcap_t*"
void * m_pcap
opaque ptr: "pcap_t*"
void setPCAPOutputFile(const std::string &out_pcap_file)
Enables dumping to a PCAP file in parallel to returning regular MRPT objects.
bool setLidarReturnType(return_type_t ret_type)
Changes among STRONGEST, LAST, DUAL return types (via HTTP post interface).
void loadConfig_sensorSpecific(const mrpt::config::CConfigFileBase &configSource, const std::string &section)
See the class documentation at the top for expected parameters.
bool m_pcap_verbose
Default: true Output PCAP Info msgs.
double m_pcap_read_full_scan_delay_ms
(Default:100 ms) delay after each full scan read from a PCAP log
mrpt::obs::CObservationVelodyneScan::Ptr m_rx_scan
In progress RX scan.
const std::string & getPCAPOutputFile() const
void setFramePublishing(bool on)
Switches whole frame (points in a single revolution) on/off publication to data packet publication.
mrpt::system::TTimeStamp m_last_gps_rmc_age
const std::string & getDeviceIP() const
bool setLidarRPM(int rpm)
Changes Lidar RPM (valid range: 300-600) (via HTTP post interface).
const std::string & getPCAPInputFile() const
double m_pcap_repeat_delay
Default: 0 (in seconds)
double m_pos_packets_min_period
Default: 0.5 seconds.
double m_pos_packets_timing_timeout
Default: 30 seconds.
void close()
Close the UDP sockets set-up in initialize().
static short int VELODYNE_POSITION_UDP_PORT
Default: 8308.
mrpt::system::TTimeStamp m_last_pos_packet_timestamp
bool internal_send_http_post(const std::string &post_data)
bool m_return_frames
Default: true Output whole frames and not data packets
bool internal_read_PCAP_packet(mrpt::system::TTimeStamp &data_pkt_time, uint8_t *out_data_buffer, mrpt::system::TTimeStamp &pos_pkt_time, uint8_t *out_pos_buffer)
bool m_pcap_read_fast
(Default: false) If false, will use m_pcap_read_full_scan_delay_ms
void setModelName(const model_t model)
See supported model names in the general discussion docs for mrpt::hwdrivers::CVelodyneScanner.
void setPosPacketsMinPeriod(double period_seconds)
Set the minimum period between the generation of mrpt::obs::CObservationGPS observations from Velodyn...
std::string m_pcap_input_file
Default: "" (do not operate from an offline file)
bool loadCalibrationFile(const std::string &velodyne_xml_calib_file_path)
Returns false on error.
mrpt::obs::gnss::Message_NMEA_RMC m_last_gps_rmc
void setPCAPInputFileReadOnce(bool read_once)
void * m_pcap_bpf_program
opaque ptr: bpf_program*
model_t m_model
Default: "VLP16".
void setCalibration(const mrpt::obs::VelodyneCalibration &calib)
std::shared_ptr< CObservationGPS > Ptr
std::shared_ptr< CObservationVelodyneScan > Ptr
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:87
GLsizei const GLchar ** string
Definition: glext.h:4101
mrpt::Clock::time_point TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1,...
Definition: datetime.h:40
Contains classes for various device interfaces.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
_u8 model
Definition: rplidar_cmd.h:0
unsigned __int32 uint32_t
Definition: rptypes.h:47
unsigned char uint8_t
Definition: rptypes.h:41
unsigned __int64 uint64_t
Definition: rptypes.h:50
Access to default sets of parameters for Velodyne LIDARs.
static const model_properties_list_t & get()
Singleton access.
static std::string getListKnownModels()
Return human-readable string: "`VLP16`,`XXX`,...".
Hard-wired properties of LIDARs depending on the model.
One unit of data from the scanner (the payload of one UDP DATA packet)
Velodyne calibration data, for usage in mrpt::obs::CObservationVelodyneScan.



Page generated by Doxygen 1.9.1 for MRPT 1.9.9 Git: 814d80880 Fri Aug 24 01:51:28 2018 +0200 at mar 26 may 2026 12:30:59 CEST