Main MRPT website > C++ reference for 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-2017, 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 
17 #include <mrpt/utils/TEnumType.h>
18 
19 namespace mrpt
20 {
21 namespace hwdrivers
22 {
23 /** A C++ interface to Velodyne laser scanners (HDL-64, HDL-32, VLP-16), working
24  * on Linux and Windows.
25  * (Using this class requires WinPCap as a run-time dependency in Windows).
26  * It can receive data from real devices via an Ethernet connection or parse a
27  * WireShark PCAP file for offline processing.
28  * The choice of online vs. offline operation is taken upon calling \a
29  * initialize(): if a PCAP input file has been defined,
30  * offline operation takes place and network is not listened for incomming
31  * packets.
32  *
33  * Parsing dual return scans requires a VLP-16 with firmware version 3.0.23 or
34  * newer. While converting the scan into a
35  * point cloud in mrpt::obs::CObservationVelodyneScan you can select whether to
36  * keep the strongest, the last or both laser returns.
37  *
38  * XML calibration files are not mandatory for VLP-16 and HDL-32, but they are
39  * for HDL-64.
40  *
41  * <h2>Grabbing live data (as a user)</h2> <hr>
42  * - Use the application
43  * [velodyne-view](http://www.mrpt.org/list-of-mrpt-apps/application-velodyne-view/)
44  * to visualize the LIDAR output in real-time (optionally saving to a PCAP file)
45  * or to playback a PCAP file.
46  * - Use
47  * [rawlog-grabber](http://www.mrpt.org/list-of-mrpt-apps/application-rawlog-grabber/)
48  * to record a dataset in MRPT's format together with any other set of sensors.
49  * See example config file:
50  * [MRPT\share\mrpt\config_files\rawlog-grabber\velodyne.ini](https://github.com/MRPT/mrpt/blob/master/share/mrpt/config_files/rawlog-grabber/velodyne.ini)
51  *
52  * <h2>Grabbing live data (programmatically)</h2> <hr>
53  * - See CGenericSensor for a general overview of the sequence of methods to
54  * be called: loadConfig(), initialize(), doProcess().
55  * - Or use this class inside the application
56  * [rawlog-grabber](http://www.mrpt.org/list-of-mrpt-apps/application-rawlog-grabber/).
57  * See example config files:
58  * [MRPT\share\mrpt\config_files\rawlog-grabber\velodyne.ini](https://github.com/MRPT/mrpt/blob/master/share/mrpt/config_files/rawlog-grabber/velodyne.ini)
59  *
60  * See the source code of the example application `[MRPT]/apps/velodyne-view`
61  * ([velodyne-view web
62  * page](http://www.mrpt.org/list-of-mrpt-apps/application-velodyne-view/)) for
63  * more details.
64  *
65  * <h2>Playing back a PCAP file:</h2><hr>
66  * It is common to save Velodyne datasets as Wireshark's PCAP files.
67  * These files can be played back with tools like
68  * [bittwist](http://bittwist.sourceforge.net/), which emit all UDP packets in
69  * the PCAP log.
70  * Then, use this class to receive the packets as if they come from the real
71  * sensor.
72  *
73  * Alternatively, if MRPT is linked against libpcap, this class can directly
74  * parse a PCAP file to simulate reading from a device offline.
75  * See method setPCAPInputFile() and config file parameter ``
76  *
77  * To compile with PCAP support: In Debian/Ubuntu, install libpcap-dev. In
78  * Windows, install WinPCap developer packages + the regular WinPCap driver.
79  *
80  * <h2>Configuration and usage:</h2> <hr>
81  * Data is returned as observations of type:
82  * - mrpt::obs::CObservationVelodyneScan for one or more "data packets" (refer
83  * to Velodyne usage manual)
84  * - mrpt::obs::CObservationGPS for GPS (GPRMC) packets, if available via the
85  * synchronization interface of the device.
86  * See those classes for documentation on their fields.
87  *
88  * Configuration includes setting the device IP (optional) and sensor model
89  * (mandatory only if a calibration file is not provided).
90  * These parameters can be set programmatically (see methods of this class), or
91  * via a configuration file with CGenericSensor::loadConfig() (see example
92  * config file section below).
93  *
94  * <h2>About timestamps:</h2><hr>
95  * Each gathered observation of type mrpt::obs::CObservationVelodyneScan is
96  * populated with two timestamps, one for the local PC timestamp and,
97  * if available, another one for the GPS-stamped timestamp. Refer to the
98  * observation docs for details.
99  *
100  * <h2>Format of parameters for loading from a .ini file</h2><hr>
101  * \code
102  * PARAMETERS IN THE ".INI"-LIKE CONFIGURATION STRINGS:
103  * -------------------------------------------------------
104  * [supplied_section_name]
105  * # ---- Sensor description ----
106  * #calibration_file = PUT_HERE_FULL_PATH_TO_CALIB_FILE.xml //
107  * Optional but recommended: put here your vendor-provided calibration file
108  * model = VLP16 // Can be any of: `VLP16`, `HDL32`,
109  * `HDL64` (It is used to load default calibration file. Parameter not required
110  * if `calibration_file` is provided.
111  * #pos_packets_min_period = 0.5 // (Default=0.5 seconds) Minimum
112  * period to leave between reporting position packets. Used to decimate the
113  * large number of packets of this type.
114  * # How long to wait, after loss of GPS signal, to report timestamps as "not
115  * based on satellite time". 30 secs, with typical velodyne clock drifts, means
116  * a ~1.7 ms typical drift.
117  * #pos_packets_timing_timeout = 30 // (Default=30 seconds)
118  * # ---- Online operation ----
119  *
120  * # IP address of the device. UDP packets from other IPs will be ignored.
121  * Leave commented or blank
122  * # if only one scanner is present (no IP filtering)
123  * #device_ip = XXX.XXX.XXX.XXX
124  *
125  * #rpm = 600 // Sensor RPM (Default: unchanged). Requires
126  * setting `device_ip`
127  * #return_type = STRONGEST // Any of: 'STRONGEST', 'LAST', 'DUAL'
128  * (Default: unchanged). Requires setting `device_ip`
129  *
130  * # ---- Offline operation ----
131  * # If uncommented, this class will read from the PCAP instead of connecting
132  * and listeling
133  * # for online network packets.
134  * # pcap_input = PUT_FULL_PATH_TO_PCAP_LOG_FILE.pcap
135  * # pcap_read_once = false // Do not loop
136  * # pcap_read_fast = false // fast forward skipping non-velodyne packets
137  * # pcap_read_full_scan_delay_ms = 100 // Used to simulate a reasonable
138  * number of full scans / second
139  * # pcap_repeat_delay = 0.0 // seconds
140  *
141  * # ---- Save to PCAP file ----
142  * # If uncommented, a PCAP file named
143  * `[pcap_output_prefix]_[DATE_TIME].pcap` will be
144  * # written simultaneously to the normal operation of this class.
145  * # pcap_output = velodyne_log
146  *
147  * # 3D position of the sensor on the vehicle:
148  * pose_x = 0 // 3D position (meters)
149  * pose_y = 0
150  * pose_z = 0
151  * pose_yaw = 0 // 3D orientation (degrees)
152  * pose_pitch = 0
153  * pose_roll = 0
154  *
155  * \endcode
156  *
157  *
158  * <h2>Copyright notice</h2><hr>
159  * Portions of this class are based on code from velodyne ROS node in
160  * https://github.com/ros-drivers/velodyne
161  * Copyright (C) 2007 Austin Robot Technology, Patrick Beeson
162  * Copyright (C) 2009, 2010 Austin Robot Technology, Jack O'Quin
163  * License: Modified BSD Software License Agreement
164  *
165  * \note New in MRPT 1.4.0
166  * \ingroup mrpt_hwdrivers_grp
167  */
169 {
171  public:
172  /** Default: 2368. Change it if required. */
173  static short int VELODYNE_DATA_UDP_PORT;
174  /** Default: 8308. Change it if required. */
175  static short int VELODYNE_POSITION_UDP_PORT;
176 
177  /** LIDAR model types */
178  enum model_t
179  {
180  VLP16 = 1,
181  HDL32 = 2,
182  HDL64 = 3
183  };
184 
185  /** LIDAR return type */
187  {
191  DUAL
192  };
193 
194  /** Hard-wired properties of LIDARs depending on the model */
196  {
197  double maxRange;
198  };
199  typedef std::map<model_t, TModelProperties> model_properties_list_t;
200  /** Access to default sets of parameters for Velodyne LIDARs */
202  {
203  /** Singleton access */
204  static const model_properties_list_t& get();
205  /** Return human-readable string: "`VLP16`,`XXX`,..." */
207  };
208 
209  protected:
211  /** Default: "VLP16" */
213  /** Default: 0.5 seconds */
215  /** Default: 30 seconds */
217  /** Default: "" (no IP-based filtering) */
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::utils::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  /** @} */
344 
345  /** Polls the UDP port for incoming data packets. The user *must* call this
346  * method in a timely fashion to grab data as it it generated by the device.
347  * The minimum call rate should be the expected number of data
348  * packets/second (!=scans/second). Checkout Velodyne user manual if in
349  * doubt.
350  *
351  * \param[out] outScan Upon return, an empty smart pointer will be found
352  * here if no new data was available. Otherwise, a valid scan.
353  * \param[out] outGPS Upon return, an empty smart pointer will be found
354  * here if no new GPS data was available. Otherwise, a valid GPS reading.
355  * \return true if no error ocurred (even if there was no new observation).
356  * false if any communication error occurred.
357  */
358  bool getNextObservation(
361 
362  // See docs in parent class
363  void doProcess();
364 
365  /** Tries to initialize the sensor driver, after setting all the parameters
366  * with a call to loadConfig.
367  * Velodyne specifics: this method sets up the UDP listening sockets, so
368  * all relevant params MUST BE SET BEFORE calling this.
369  * \exception This method must throw an exception with a descriptive
370  * message if some critical error is found.
371  */
372  virtual void initialize();
373 
374  /** Close the UDP sockets set-up in \a initialize(). This is called
375  * automatically upon destruction */
376  void close();
377 
378  /** Users normally would prefer calling \a getNextObservation() instead.
379  * This method polls the UDP data port and returns one Velodyne DATA packet
380  * (1206 bytes) and/or one POSITION packet. Refer to Velodyne users manual.
381  * Approximate timestamps (based on this computer clock) are returned for
382  * each kind of packets, or INVALID_TIMESTAMP if timeout ocurred waiting for
383  * a packet.
384  * \return true on all ok. false only for pcap reading EOF
385  */
386  bool receivePackets(
387  mrpt::system::TTimeStamp& data_pkt_timestamp,
389  mrpt::system::TTimeStamp& pos_pkt_timestamp,
391  out_pos_pkt);
392 
393  private:
394  /** Handles for the UDP sockets, or INVALID_SOCKET (-1) */
395  typedef
396 #ifdef MRPT_OS_WINDOWS
397 #if MRPT_WORD_SIZE == 64
398  uint64_t
399 #else
400  uint32_t
401 #endif
402 #else
403  int
404 #endif
406 
408 
410  platform_socket_t hSocket, uint8_t* out_buffer,
411  const size_t expected_packet_size,
412  const std::string& filter_only_from_IP);
413 
415  mrpt::system::TTimeStamp& data_pkt_time, uint8_t* out_data_buffer,
416  mrpt::system::TTimeStamp& pos_pkt_time, uint8_t* out_pos_buffer);
417 
418  /** In progress RX scan */
420 
425 
426  bool internal_send_http_post(const std::string& post_data);
427 
428 }; // end of class
429 } // end of namespace
430 
431 namespace utils // Specializations MUST occur at the same namespace:
432 {
433 template <>
434 struct TEnumTypeFiller<hwdrivers::CVelodyneScanner::model_t>
435 {
437  static void fill(bimap<enum_t, std::string>& m_map)
438  {
442  }
443 };
444 
445 template <>
446 struct TEnumTypeFiller<hwdrivers::CVelodyneScanner::return_type_t>
447 {
449  static void fill(bimap<enum_t, std::string>& m_map)
450  {
455  }
456 };
457 } // End of namespace
458 } // end of namespace
459 
460 #endif
#define DEFINE_GENERIC_SENSOR(class_name)
This declaration must be inserted in all CGenericSensor classes definition, within the class declarat...
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.
std::map< model_t, TModelProperties > model_properties_list_t
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)
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).
int platform_socket_t
Handles for the UDP sockets, or INVALID_SOCKET (-1)
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
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 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 loadConfig_sensorSpecific(const mrpt::utils::CConfigFileBase &configSource, const std::string &section)
See the class documentation at the top for expected parameters.
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:89
This class allows loading and storing values and vectors of different types from a configuration text...
A bidirectional version of std::map, declared as bimap<KEY,VALUE> and which actually contains two std...
Definition: bimap.h:35
void insert(const KEY &k, const VALUE &v)
Insert a new pair KEY<->VALUE in the bi-map.
Definition: bimap.h:75
GLsizei const GLchar ** string
Definition: glext.h:4101
uint64_t TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1,...
Definition: datetime.h:32
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.
static void fill(bimap< enum_t, std::string > &m_map)
Only specializations of this class are defined for each enum type of interest.
Definition: TEnumType.h:25



Page generated by Doxygen 1.9.1 for MRPT 1.9.9 Git: 63ea9d1f1 Thu Nov 23 00:06:53 2017 +0100 at mar 26 may 2026 12:19:29 CEST