Main MRPT website > C++ reference for MRPT 1.5.6
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 on Linux and Windows.
24  * (Using this class requires WinPCap as a run-time dependency in Windows).
25  * It can receive data from real devices via an Ethernet connection or parse a WireShark PCAP file for offline processing.
26  * The choice of online vs. offline operation is taken upon calling \a initialize(): if a PCAP input file has been defined,
27  * offline operation takes place and network is not listened for incomming packets.
28  *
29  * Parsing dual return scans requires a VLP-16 with firmware version 3.0.23 or newer. While converting the scan into a
30  * point cloud in mrpt::obs::CObservationVelodyneScan you can select whether to keep the strongest, the last or both laser returns.
31  *
32  * XML calibration files are not mandatory for VLP-16 and HDL-32, but they are for HDL-64.
33  *
34  * <h2>Grabbing live data (as a user)</h2> <hr>
35  * - Use the application [velodyne-view](http://www.mrpt.org/list-of-mrpt-apps/application-velodyne-view/) to visualize the LIDAR output in real-time (optionally saving to a PCAP file) or to playback a PCAP file.
36  * - Use [rawlog-grabber](http://www.mrpt.org/list-of-mrpt-apps/application-rawlog-grabber/) to record a dataset in MRPT's format together with any other set of sensors. See example config file: [MRPT\share\mrpt\config_files\rawlog-grabber\velodyne.ini](https://github.com/MRPT/mrpt/blob/master/share/mrpt/config_files/rawlog-grabber/velodyne.ini)
37  *
38  * <h2>Grabbing live data (programmatically)</h2> <hr>
39  * - See CGenericSensor for a general overview of the sequence of methods to be called: loadConfig(), initialize(), doProcess().
40  * - Or use this class inside the application [rawlog-grabber](http://www.mrpt.org/list-of-mrpt-apps/application-rawlog-grabber/). See example config files: [MRPT\share\mrpt\config_files\rawlog-grabber\velodyne.ini](https://github.com/MRPT/mrpt/blob/master/share/mrpt/config_files/rawlog-grabber/velodyne.ini)
41  *
42  * See the source code of the example application `[MRPT]/apps/velodyne-view` ([velodyne-view web page](http://www.mrpt.org/list-of-mrpt-apps/application-velodyne-view/)) for more details.
43  *
44  * <h2>Playing back a PCAP file:</h2><hr>
45  * It is common to save Velodyne datasets as Wireshark's PCAP files.
46  * These files can be played back with tools like [bittwist](http://bittwist.sourceforge.net/), which emit all UDP packets in the PCAP log.
47  * Then, use this class to receive the packets as if they come from the real sensor.
48  *
49  * Alternatively, if MRPT is linked against libpcap, this class can directly parse a PCAP file to simulate reading from a device offline.
50  * See method setPCAPInputFile() and config file parameter ``
51  *
52  * To compile with PCAP support: In Debian/Ubuntu, install libpcap-dev. In Windows, install WinPCap developer packages + the regular WinPCap driver.
53  *
54  * <h2>Configuration and usage:</h2> <hr>
55  * Data is returned as observations of type:
56  * - mrpt::obs::CObservationVelodyneScan for one or more "data packets" (refer to Velodyne usage manual)
57  * - mrpt::obs::CObservationGPS for GPS (GPRMC) packets, if available via the synchronization interface of the device.
58  * See those classes for documentation on their fields.
59  *
60  * Configuration includes setting the device IP (optional) and sensor model (mandatory only if a calibration file is not provided).
61  * These parameters can be set programmatically (see methods of this class), or via a configuration file with CGenericSensor::loadConfig() (see example config file section below).
62  *
63  * <h2>About timestamps:</h2><hr>
64  * Each gathered observation of type mrpt::obs::CObservationVelodyneScan is populated with two timestamps, one for the local PC timestamp and,
65  * if available, another one for the GPS-stamped timestamp. Refer to the observation docs for details.
66  *
67  * <h2>Format of parameters for loading from a .ini file</h2><hr>
68  * \code
69  * PARAMETERS IN THE ".INI"-LIKE CONFIGURATION STRINGS:
70  * -------------------------------------------------------
71  * [supplied_section_name]
72  * # ---- Sensor description ----
73  * #calibration_file = PUT_HERE_FULL_PATH_TO_CALIB_FILE.xml // Optional but recommended: put here your vendor-provided calibration file
74  * model = VLP16 // Can be any of: `VLP16`, `HDL32`, `HDL64` (It is used to load default calibration file. Parameter not required if `calibration_file` is provided.
75  * #pos_packets_min_period = 0.5 // (Default=0.5 seconds) Minimum period to leave between reporting position packets. Used to decimate the large number of packets of this type.
76  * # How long to wait, after loss of GPS signal, to report timestamps as "not based on satellite time". 30 secs, with typical velodyne clock drifts, means a ~1.7 ms typical drift.
77  * #pos_packets_timing_timeout = 30 // (Default=30 seconds)
78  * # ---- Online operation ----
79  *
80  * # IP address of the device. UDP packets from other IPs will be ignored. Leave commented or blank
81  * # if only one scanner is present (no IP filtering)
82  * #device_ip = XXX.XXX.XXX.XXX
83  *
84  * #rpm = 600 // Sensor RPM (Default: unchanged). Requires setting `device_ip`
85  * #return_type = STRONGEST // Any of: 'STRONGEST', 'LAST', 'DUAL' (Default: unchanged). Requires setting `device_ip`
86  *
87  * # ---- Offline operation ----
88  * # If uncommented, this class will read from the PCAP instead of connecting and listeling
89  * # for online network packets.
90  * # pcap_input = PUT_FULL_PATH_TO_PCAP_LOG_FILE.pcap
91  * # pcap_read_once = false // Do not loop
92  * # pcap_read_fast = false // fast forward skipping non-velodyne packets
93  * # pcap_read_full_scan_delay_ms = 100 // Used to simulate a reasonable number of full scans / second
94  * # pcap_repeat_delay = 0.0 // seconds
95  *
96  * # ---- Save to PCAP file ----
97  * # If uncommented, a PCAP file named `[pcap_output_prefix]_[DATE_TIME].pcap` will be
98  * # written simultaneously to the normal operation of this class.
99  * # pcap_output = velodyne_log
100  *
101  * # 3D position of the sensor on the vehicle:
102  * pose_x = 0 // 3D position (meters)
103  * pose_y = 0
104  * pose_z = 0
105  * pose_yaw = 0 // 3D orientation (degrees)
106  * pose_pitch = 0
107  * pose_roll = 0
108  *
109  * \endcode
110  *
111  *
112  * <h2>Copyright notice</h2><hr>
113  * Portions of this class are based on code from velodyne ROS node in https://github.com/ros-drivers/velodyne
114  * Copyright (C) 2007 Austin Robot Technology, Patrick Beeson
115  * Copyright (C) 2009, 2010 Austin Robot Technology, Jack O'Quin
116  * License: Modified BSD Software License Agreement
117  *
118  * \note New in MRPT 1.4.0
119  * \ingroup mrpt_hwdrivers_grp
120  */
122  {
124  public:
125  static short int VELODYNE_DATA_UDP_PORT; //!< Default: 2368. Change it if required.
126  static short int VELODYNE_POSITION_UDP_PORT; //!< Default: 8308. Change it if required.
127 
128  /** LIDAR model types */
129  enum model_t {
130  VLP16 = 1,
131  HDL32 = 2,
132  HDL64 = 3
133  };
134 
135  /** LIDAR return type */
137  UNCHANGED = 0,
140  DUAL
141  };
142 
143  /** Hard-wired properties of LIDARs depending on the model */
145  double maxRange;
146  };
147  typedef std::map<model_t,TModelProperties> model_properties_list_t;
148  /** Access to default sets of parameters for Velodyne LIDARs */
150  static const model_properties_list_t & get(); //!< Singleton access
151  static std::string getListKnownModels(); //!< Return human-readable string: "`VLP16`,`XXX`,..."
152  };
153 
154  protected:
156  model_t m_model; //!< Default: "VLP16"
157  double m_pos_packets_min_period; //!< Default: 0.5 seconds
158  double m_pos_packets_timing_timeout; //!< Default: 30 seconds
159  std::string m_device_ip; //!< Default: "" (no IP-based filtering)
160  bool m_pcap_verbose; //!< Default: true Output PCAP Info msgs
161  std::string m_pcap_input_file; //!< Default: "" (do not operate from an offline file)
162  std::string m_pcap_output_file; //!< Default: "" (do not dump to an offline file)
164  mrpt::obs:: VelodyneCalibration m_velodyne_calib; //!< Device calibration file (supplied by vendor in an XML file)
166 
167  // offline operation:
168  void * m_pcap; //!< opaque ptr: "pcap_t*"
169  void * m_pcap_out; //!< opaque ptr: "pcap_t*"
170  void * m_pcap_dumper; //!< opaque ptr: "pcap_dumper_t *"
171  void * m_pcap_bpf_program; //!< opaque ptr: bpf_program*
173  unsigned int m_pcap_read_count; //!< number of pkts read from the file so far (for debugging)
174  bool m_pcap_read_once; //!< Default: false
175  bool m_pcap_read_fast; //!< (Default: false) If false, will use m_pcap_read_full_scan_delay_ms
176  double m_pcap_read_full_scan_delay_ms; //!< (Default:100 ms) delay after each full scan read from a PCAP log
177  double m_pcap_repeat_delay; //!< Default: 0 (in seconds)
178 
179 
180  /** See the class documentation at the top for expected parameters */
181  void loadConfig_sensorSpecific(
182  const mrpt::utils::CConfigFileBase &configSource,
183  const std::string &section );
184 
185  public:
186  CVelodyneScanner( );
187  virtual ~CVelodyneScanner();
188 
189  /** @name Change configuration parameters; to be called BEFORE initialize(); see above for the list of parameters and their meaning
190  * @{ */
191  /** See supported model names in the general discussion docs for mrpt::hwdrivers::CVelodyneScanner */
192  void setModelName(const model_t model) { m_model = model; }
193  model_t getModelName() const { return m_model; }
194 
195  /** Set the minimum period between the generation of mrpt::obs::CObservationGPS observations from Velodyne Position RMC GPS packets */
196  void setPosPacketsMinPeriod(double period_seconds) { m_pos_packets_min_period = period_seconds; }
197  double getPosPacketsMinPeriod() const { return m_pos_packets_min_period; }
198 
199  /** Set how long to wait, after loss of GPS signal, to report timestamps as "not based on satellite time". 30 secs, with typical velodyne clock drifts, means a ~1.7 ms typical drift. */
200  void setPosPacketsTimingTimeout(double timeout) { m_pos_packets_timing_timeout = timeout; }
201  double getPosPacketsTimingTimeout() const { return m_pos_packets_timing_timeout; }
202 
203  /** UDP packets from other IPs will be ignored. Default: empty string, means do not filter by IP */
204  void setDeviceIP(const std::string & ip) { m_device_ip = ip; }
205  const std::string &getDeviceIP() const { return m_device_ip; }
206 
207  /** Enables/disables PCAP info messages to console (default: true) */
208  void setPCAPVerbosity(const bool verbose) { m_pcap_verbose = verbose; }
209 
210  /** Enables reading from a PCAP file instead of live UDP packet listening */
211  void setPCAPInputFile(const std::string &pcap_file) { m_pcap_input_file = pcap_file; }
212  const std::string & getPCAPInputFile() const { return m_pcap_input_file; }
213 
214  /** Enables dumping to a PCAP file in parallel to returning regular MRPT objects. Default="": no pcap log. */
215  void setPCAPOutputFile(const std::string &out_pcap_file) { m_pcap_output_file = out_pcap_file; }
216  const std::string & getPCAPOutputFile() const { return m_pcap_output_file; }
217 
218  void setPCAPInputFileReadOnce(bool read_once) { m_pcap_read_once=read_once; }
219  bool getPCAPInputFileReadOnce() const { return m_pcap_read_once; }
220 
221  const mrpt::obs:: VelodyneCalibration & getCalibration() const { return m_velodyne_calib; }
222  void setCalibration(const mrpt::obs::VelodyneCalibration & calib) { m_velodyne_calib=calib; }
223  bool loadCalibrationFile(const std::string & velodyne_xml_calib_file_path ); //!< Returns false on error. \sa mrpt::obs::VelodyneCalibration::loadFromXMLFile()
224 
225  /** Changes among STRONGEST, LAST, DUAL return types (via HTTP post interface).
226  * Can be called at any instant, before or after initialize().
227  * Requires setting a device IP address.
228  * \return false on error */
229  bool setLidarReturnType(return_type_t ret_type);
230 
231  /** Changes Lidar RPM (valid range: 300-600) (via HTTP post interface).
232  * Can be called at any instant, before or after initialize().
233  * Requires setting a device IP address.
234  * \return false on error*/
235  bool setLidarRPM(int rpm);
236 
237  /** Switches the LASER on/off (saves energy when not measuring) (via HTTP post interface).
238  * Can be called at any instant, before or after initialize().
239  * Requires setting a device IP address.
240  * \return false on error*/
241  bool setLidarOnOff(bool on);
242 
243  /** @} */
244 
245  /** Polls the UDP port for incoming data packets. The user *must* call this method in a timely fashion to grab data as it it generated by the device.
246  * The minimum call rate should be the expected number of data packets/second (!=scans/second). Checkout Velodyne user manual if in doubt.
247  *
248  * \param[out] outScan Upon return, an empty smart pointer will be found here if no new data was available. Otherwise, a valid scan.
249  * \param[out] outGPS Upon return, an empty smart pointer will be found here if no new GPS data was available. Otherwise, a valid GPS reading.
250  * \return true if no error ocurred (even if there was no new observation). false if any communication error occurred.
251  */
252  bool getNextObservation(
253  mrpt::obs::CObservationVelodyneScanPtr & outScan,
254  mrpt::obs::CObservationGPSPtr & outGPS
255  );
256 
257  // See docs in parent class
258  void doProcess();
259 
260  /** Tries to initialize the sensor driver, after setting all the parameters with a call to loadConfig.
261  * Velodyne specifics: this method sets up the UDP listening sockets, so all relevant params MUST BE SET BEFORE calling this.
262  * \exception This method must throw an exception with a descriptive message if some critical error is found.
263  */
264  virtual void initialize();
265 
266  /** Close the UDP sockets set-up in \a initialize(). This is called automatically upon destruction */
267  void close();
268 
269  /** Users normally would prefer calling \a getNextObservation() instead.
270  * This method polls the UDP data port and returns one Velodyne DATA packet (1206 bytes) and/or one POSITION packet. Refer to Velodyne users manual.
271  * Approximate timestamps (based on this computer clock) are returned for each kind of packets, or INVALID_TIMESTAMP if timeout ocurred waiting for a packet.
272  * \return true on all ok. false only for pcap reading EOF
273  */
274  bool receivePackets(
275  mrpt::system::TTimeStamp &data_pkt_timestamp,
277  mrpt::system::TTimeStamp &pos_pkt_timestamp,
279  );
280 
281  private:
282  /** Handles for the UDP sockets, or INVALID_SOCKET (-1) */
283  typedef
284 #ifdef MRPT_OS_WINDOWS
285 # if MRPT_WORD_SIZE==64
286  uint64_t
287 # else
288  uint32_t
289 # endif
290 #else
291  int
292 #endif
294 
296 
297  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);
298 
299  bool internal_read_PCAP_packet(
300  mrpt::system::TTimeStamp & data_pkt_time, uint8_t *out_data_buffer,
301  mrpt::system::TTimeStamp & pos_pkt_time, uint8_t *out_pos_buffer
302  );
303 
304  mrpt::obs::CObservationVelodyneScanPtr m_rx_scan; //!< In progress RX scan
305 
310 
311  bool internal_send_http_post(const std::string &post_data);
312 
313  }; // end of class
314  } // end of namespace
315 
316  namespace utils // Specializations MUST occur at the same namespace:
317  {
318  template <>
319  struct TEnumTypeFiller<hwdrivers::CVelodyneScanner::model_t>
320  {
322  static void fill(bimap<enum_t,std::string> &m_map)
323  {
327  }
328  };
329 
330  template <>
331  struct TEnumTypeFiller<hwdrivers::CVelodyneScanner::return_type_t>
332  {
334  static void fill(bimap<enum_t, std::string> &m_map)
335  {
340  }
341  };
342  } // End of namespace
343 } // end of namespace
344 
345 
346 #endif
A generic interface for a wide-variety of sensors designed to be used in the application RawLogGrabbe...
uint64_t TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1...
Definition: datetime.h:30
std::map< model_t, TModelProperties > model_properties_list_t
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. Change it if required.
void setPosPacketsMinPeriod(double period_seconds)
Set the minimum period between the generation of mrpt::obs::CObservationGPS observations from Velodyn...
void setPCAPInputFile(const std::string &pcap_file)
Enables reading from a PCAP file instead of live UDP packet listening.
int platform_socket_t
Handles for the UDP sockets, or INVALID_SOCKET (-1)
void setPCAPVerbosity(const bool verbose)
Enables/disables PCAP info messages to console (default: true)
bool m_pcap_read_once
Default: false.
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.
Only specializations of this class are defined for each enum type of interest.
Definition: TEnumType.h:23
const std::string & getPCAPInputFile() const
const std::string & getDeviceIP() const
bool m_pcap_read_fast
(Default: false) If false, will use m_pcap_read_full_scan_delay_ms
const std::string & getPCAPOutputFile() const
mrpt::system::TTimeStamp m_last_pos_packet_timestamp
This class allows loading and storing values and vectors of different types from a configuration text...
unsigned char uint8_t
Definition: rptypes.h:43
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"...
void setPCAPOutputFile(const std::string &out_pcap_file)
Enables dumping to a PCAP file in parallel to returning regular MRPT objects.
mrpt::obs::VelodyneCalibration m_velodyne_calib
Device calibration file (supplied by vendor in an XML file)
double m_pos_packets_min_period
Default: 0.5 seconds.
_u8 model
Definition: rplidar_cmd.h:21
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.
A bidirectional version of std::map, declared as bimap<KEY,VALUE> and which actually contains two std::...
Definition: bimap.h:28
bool m_pcap_verbose
Default: true Output PCAP Info msgs.
void setCalibration(const mrpt::obs::VelodyneCalibration &calib)
std::string m_pcap_input_file
Default: "" (do not operate from an offline file)
#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*"
unsigned __int64 uint64_t
Definition: rptypes.h:52
double m_pos_packets_timing_timeout
Default: 30 seconds.
GLsizei const GLcharARB ** string
Definition: glew.h:3293
static void fill(bimap< enum_t, std::string > &m_map)
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:72
One unit of data from the scanner (the payload of one UDP DATA packet)
static short int VELODYNE_DATA_UDP_PORT
Default: 2368. Change it if required.
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 insert(const KEY &k, const VALUE &v)
Insert a new pair KEY<->VALUE in the bi-map.
Definition: bimap.h:69
const mrpt::obs::VelodyneCalibration & getCalibration() const
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)
mrpt::obs::CObservationVelodyneScanPtr m_rx_scan
In progress RX scan.
unsigned __int32 uint32_t
Definition: rptypes.h:49
mrpt::system::TTimeStamp m_last_gps_rmc_age
void setDeviceIP(const std::string &ip)
UDP packets from other IPs will be ignored.
model_t m_model
Default: "VLP16".
mrpt::obs::gnss::Message_NMEA_RMC m_last_gps_rmc



Page generated by Doxygen 1.8.6 for MRPT 1.5.6 Git: 4c65e84 Tue Apr 24 08:18:17 2018 +0200 at mar abr 24 08:26:17 CEST 2018