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  {
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) */
403  using platform_socket_t =
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 
A generic interface for a wide-variety of sensors designed to be used in the application RawLogGrabbe...
Velodyne calibration data, for usage in mrpt::obs::CObservationVelodyneScan.
A C++ interface to Velodyne laser scanners (HDL-64, HDL-32, VLP-16), working on Linux and Windows...
static short int VELODYNE_POSITION_UDP_PORT
Default: 8308.
void setPosPacketsMinPeriod(double period_seconds)
Set the minimum period between the generation of mrpt::obs::CObservationGPS observations from Velodyn...
std::map< model_t, TModelProperties > model_properties_list_t
void setPCAPInputFile(const std::string &pcap_file)
Enables reading from a PCAP file instead of live UDP packet listening.
void setPCAPVerbosity(const bool verbose)
Enables/disables PCAP info messages to console (default: true)
const std::string & getDeviceIP() const
bool getNextObservation(mrpt::obs::CObservationVelodyneScan::Ptr &outScan, mrpt::obs::CObservationGPS::Ptr &outGPS)
Polls the UDP port for incoming 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_return_frames
Default: true Output whole frames and not data packets.
static std::string getListKnownModels()
Return human-readable string: "`VLP16`,`XXX`,...".
void close()
Close the UDP sockets set-up in initialize().
bool m_pcap_read_once
Default: false.
Contains classes for various device interfaces.
void * m_pcap_bpf_program
opaque ptr: bpf_program*
void setModelName(const model_t model)
See supported model names in the general discussion docs for mrpt::hwdrivers::CVelodyneScanner.
bool m_pcap_read_fast
(Default: false) If false, will use m_pcap_read_full_scan_delay_ms
mrpt::system::TTimeStamp m_last_pos_packet_timestamp
unsigned char uint8_t
Definition: rptypes.h:41
double m_pcap_repeat_delay
Default: 0 (in seconds)
void setPosPacketsTimingTimeout(double timeout)
Set how long to wait, after loss of GPS signal, to report timestamps as "not based on satellite time"...
mrpt::obs::VelodyneCalibration m_velodyne_calib
Device calibration file (supplied by vendor in an XML file)
void setPCAPOutputFile(const std::string &out_pcap_file)
Enables dumping to a PCAP file in parallel to returning regular MRPT objects.
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
const std::string & getPCAPOutputFile() const
const std::string & getPCAPInputFile() const
This class allows loading and storing values and vectors of different types from a configuration text...
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
double m_pos_packets_min_period
Default: 0.5 seconds.
bool setLidarOnOff(bool on)
Switches the LASER on/off (saves energy when not measuring) (via HTTP post interface).
_u8 model
Definition: rplidar_cmd.h:19
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.
unsigned int m_pcap_read_count
number of pkts read from the file so far (for debugging)
std::string m_pcap_output_file
Default: "" (do not dump to an offline file)
Hard-wired properties of LIDARs depending on the model.
bool m_pcap_verbose
Default: true Output PCAP Info msgs.
void setCalibration(const mrpt::obs::VelodyneCalibration &calib)
#define MRPT_ENUM_TYPE_END()
Definition: TEnumType.h:78
bool setLidarReturnType(return_type_t ret_type)
Changes among STRONGEST, LAST, DUAL return types (via HTTP post interface).
GLsizei const GLchar ** string
Definition: glext.h:4101
std::string m_pcap_input_file
Default: "" (do not operate from an offline file)
MRPT_FILL_ENUM_MEMBER(CVelodyneScanner, VLP16)
void setFramePublishing(bool on)
Switches whole frame (points in a single revolution) on/off publication to data packet publication...
#define DEFINE_GENERIC_SENSOR(class_name)
This declaration must be inserted in all CGenericSensor classes definition, within the class declarat...
void * m_pcap_out
opaque ptr: "pcap_t*"
bool internal_send_http_post(const std::string &post_data)
unsigned __int64 uint64_t
Definition: rptypes.h:50
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
double m_pos_packets_timing_timeout
Default: 30 seconds.
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:86
One unit of data from the scanner (the payload of one UDP DATA packet)
static short int VELODYNE_DATA_UDP_PORT
Default: 2368.
double m_pcap_read_full_scan_delay_ms
(Default:100 ms) delay after each full scan read from a PCAP log
void * m_pcap
opaque ptr: "pcap_t*"
void setPCAPInputFileReadOnce(bool read_once)
void doProcess()
This method will be invoked at a minimum rate of "process_rate" (Hz)
uint32_t platform_socket_t
Handles for the UDP sockets, or INVALID_SOCKET (-1)
Access to default sets of parameters for Velodyne LIDARs.
void * m_pcap_dumper
opaque ptr: "pcap_dumper_t *"
std::string m_device_ip
Default: "" (no IP-based filtering)
#define MRPT_ENUM_TYPE_BEGIN(_ENUM_TYPE_WITH_NS)
Definition: TEnumType.h:62
bool loadCalibrationFile(const std::string &velodyne_xml_calib_file_path)
Returns false on error.
unsigned __int32 uint32_t
Definition: rptypes.h:47
void loadConfig_sensorSpecific(const mrpt::config::CConfigFileBase &configSource, const std::string &section)
See the class documentation at the top for expected parameters.
mrpt::system::TTimeStamp m_last_gps_rmc_age
mrpt::obs::CObservationVelodyneScan::Ptr m_rx_scan
In progress RX scan.
void setDeviceIP(const std::string &ip)
UDP packets from other IPs will be ignored.
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)
model_t m_model
Default: "VLP16".
mrpt::obs::gnss::Message_NMEA_RMC m_last_gps_rmc
bool setLidarRPM(int rpm)
Changes Lidar RPM (valid range: 300-600) (via HTTP post interface).



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020