ros_msgpack_publisher.h
Go to the documentation of this file.
1 #include "sick_scan/sick_scan_base.h" /* Base definitions included in all header files, added by add_sick_scan_base_header.py. Do not edit this line. */
2 /*
3  * @brief RosMsgpackPublisher publishes PointCloud2 messages with msgpack data
4  * received from multiScan136.
5  *
6  * Copyright (C) 2020 Ing.-Buero Dr. Michael Lehning, Hildesheim
7  * Copyright (C) 2020 SICK AG, Waldkirch
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  * All rights reserved.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions are met:
25  *
26  * * Redistributions of source code must retain the above copyright
27  * notice, this list of conditions and the following disclaimer.
28  * * Redistributions in binary form must reproduce the above copyright
29  * notice, this list of conditions and the following disclaimer in the
30  * documentation and/or other materials provided with the distribution.
31  * * Neither the name of SICK AG nor the names of its
32  * contributors may be used to endorse or promote products derived from
33  * this software without specific prior written permission
34  * * Neither the name of Ing.-Buero Dr. Michael Lehning nor the names of its
35  * contributors may be used to endorse or promote products derived from
36  * this software without specific prior written permission
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
39  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
42  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
43  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
44  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
45  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
46  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
47  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
48  * POSSIBILITY OF SUCH DAMAGE.
49  *
50  * Authors:
51  * Michael Lehning <michael.lehning@lehning.de>
52  *
53  * Copyright 2020 SICK AG
54  * Copyright 2020 Ing.-Buero Dr. Michael Lehning
55  *
56  */
57 #ifndef __SICK_SCANSEGMENT_XD_ROS_MSGPACK_PUBLISHER_H
58 #define __SICK_SCANSEGMENT_XD_ROS_MSGPACK_PUBLISHER_H
59 
63 
64 namespace sick_scansegment_xd
65 {
66  /*
67  * class PointXYZRAEI32f is just a container for a single multiScan136 point in cartesian coordinates (x, y, z), polar coordinates (range, azimuth, elevation), and intensity i
68  */
70  {
71  public:
72  PointXYZRAEI32f() : x(0), y(0), z(0), range(0), azimuth(0), elevation(0), i(0), layer(0), echo(0), lidar_timestamp_microsec(0), reflectorbit(0), infringed(0) {}
73  PointXYZRAEI32f(float _x, float _y, float _z, float _range, float _azimuth, float _elevation, float _i, int _layer, int _echo, uint64_t _lidar_timestamp_microsec, uint8_t _reflector_bit)
74  : x(_x), y(_y), z(_z), range(_range), azimuth(_azimuth), elevation(_elevation), i(_i), layer(_layer), echo(_echo), lidar_timestamp_microsec(_lidar_timestamp_microsec), reflectorbit(_reflector_bit), infringed(0) {}
75  float x; // cartesian x coordinate in meter
76  float y; // cartesian y coordinate in meter
77  float z; // cartesian z coordinate in meter
78  float range; // polar coordinate range in meter
79  float azimuth; // polar coordinate azimuth in radians
80  float elevation; // polar coordinate elevation in radians
81  float i; // intensity
82  int layer; // group index (layer), 0 <= layer < 16 for multiScan136
83  int echo; // echo index, 0 <= echo < 3 for multiScan136
84  uint64_t lidar_timestamp_microsec; // lidar timestamp in microseconds
85  uint8_t reflectorbit; // optional reflector bit, 0 or 1, default: 0
86  uint8_t infringed; // optional infringed bit, 0 or 1, default: 0
87  };
88 
91  {
92  public:
93  PointCloudFieldProperty(const std::string& _name, uint8_t _datatype, size_t _datasize, size_t _fieldoffset) : name(_name), datatype(_datatype), datasize(_datasize), fieldoffset(_fieldoffset) {}
94  std::string name = ""; // id like "x", "y", "z", "i", "range", "azimuth", "elevation", "layer", "echo", "reflector"
95  uint8_t datatype = 0; // datatype like PointField::FLOAT32 or PointField::INT8
96  size_t datasize = 0; // number of bytes, e.g. sizeof(float) or sizeof(int8_t)
97  size_t fieldoffset = 0; // offset in bytes in structure PointXYZRAEI32f
98  };
99 
100 
103  {
104  public:
106  CustomPointCloudConfiguration(const std::string& cfg_name, const std::string& cfg_str);
107  const std::string& cfgName(void) const { return m_cfg_name; } // name of configuration, e.g. custom_pointcloud_cartesian_segmented
108  bool publish(void) const { return m_publish; } // if true, pointcloud will be published (otherwise not)
109  const std::string& topic(void) const { return m_topic; } // ros topic to publish the pointcloud
110  const std::string& frameid(void) const { return m_frameid ; } // ros frame_id of the pointcloud
111  bool fullframe(void) const { return m_update_method == 0; } // returns true for fullframe pointcloud, or false for segmented pointcloud
112  int coordinateNotation(void) const { return m_coordinate_notation; } // 0 = cartesian, 1 = polar, 2 = both cartesian and polar, 3 = customized fields
113  PointCloud2MsgPublisher& publisher(void) { return m_publisher; } // ros publisher of customized pointcloud
114  inline bool fieldEnabled(const std::string& fieldname) // returns true, if a field given its name (like "x", "y", "z", "i", etc.) is enabled (i.e. activated in the launchfile), otherwise false
115  {
116  return m_field_enabled[fieldname];
117  }
118  inline bool pointEnabled(sick_scansegment_xd::PointXYZRAEI32f& lidar_point) // returns true, if a point is enabled (i.e. properties echo, layer, reflectorbit etc. are activated in the launchfile), otherwise false
119  {
120  bool range_modified = false;
121  bool point_enabled = m_echo_enabled[lidar_point.echo]
122  && m_layer_enabled[lidar_point.layer]
123  && m_reflector_enabled[lidar_point.reflectorbit]
124  && m_infringed_enabled[lidar_point.infringed]
125  && m_range_filter.apply(lidar_point.range, range_modified); // note: range can be set depending on filter settings
126  if (range_modified)
127  {
128  m_range_filter.applyXYZ(lidar_point.x, lidar_point.y, lidar_point.z, lidar_point.azimuth, lidar_point.elevation);
129  }
130  return point_enabled;
131  }
132  void print(void) const;
133  protected:
134  static std::string printValuesEnabled(const std::map<std::string,bool>& mapped_values, const std::string& delim = ",");
135  static std::string printValuesEnabled(const std::map<int8_t,bool>& mapped_values, const std::string& delim = ",");
136  std::string m_cfg_name = ""; // name of configuration, e.g. custom_pointcloud_cartesian_segmented
137  bool m_publish = false; // if true, pointcloud will be published (otherwise not)
138  std::string m_topic = ""; // ros topic to publish the pointcloud
139  std::string m_frameid = ""; // ros frame_id of the pointcloud
140  int m_coordinate_notation = 0; // 0 = cartesian, 1 = polar, 2 = both cartesian and polar, 3 = customized fields
141  int m_update_method = 0; // 0 = fullframe pointcloud, 1 = segmented pointcloud
143  std::map<std::string, bool> m_field_enabled; // names of enabled field names (i.e. field enabled if m_field_enabled[field_name]==true), where field_name is "x", "y", "z", "i", "range", "azimuth", "elevation", "layer", "echo" or "reflector"
144  std::map<int8_t, bool> m_echo_enabled; // enabled echos (i.e. point inserted in pointcloud, if m_echo_enabled[echo_idx]==true)
145  std::map<int8_t, bool> m_layer_enabled; // enabled layers (i.e. point inserted in pointcloud, if m_layer_enabled[layer_idx]==true)
146  std::map<int8_t, bool> m_reflector_enabled; // enabled reflectors (i.e. point inserted in pointcloud, if m_reflector_enabled[reflector_bit]==true)
147  std::map<int8_t, bool> m_infringed_enabled; // enabled infringments (i.e. point inserted in pointcloud, if m_infringed_enabled[infringed_bit]==true)
148  PointCloud2MsgPublisher m_publisher; // ros publisher of customized pointcloud
149  };
150 
151  /*
152  * @brief class RosMsgpackPublisher implements interface MsgPackExportListenerIF
153  * and publishes PointCloud2 messages with msgpack data from multiScan136.
154  */
155  #if defined __ROS_VERSION && __ROS_VERSION > 1
156  class RosMsgpackPublisher : public rclcpp::Node, public sick_scansegment_xd::MsgPackExportListenerIF
157  #else
159  #endif
160  {
161  public:
162 
163  /*
164  * @brief RosMsgpackPublisher constructor
165  * @param[in] node_name name of the ros node
166  * @param[in] config sick_scansegment_xd configuration, RosMsgpackPublisher uses
167  * config.publish_frame_id: frame id of ros Laserscan messages, default: "world"
168  * @param[in] qos quality of service profile for the ros publisher, default: 1
169  */
170  RosMsgpackPublisher(const std::string& node_name = "sick_scansegment_xd", const sick_scansegment_xd::Config& config = sick_scansegment_xd::Config());
171 
172  /*
173  * @brief RosMsgpackPublisher destructor
174  */
175  virtual ~RosMsgpackPublisher();
176 
177  /* @brief Determine and initialize all_segments_min/max_deg by LFPangleRangeFilter
178  ** host_set_LFPangleRangeFilter = "<enabled> <azimuth_start> <azimuth_stop> <elevation_start> <elevation_stop> <beam_increment>" with azimuth and elevation given in degree
179  ** Returns true, if angleRangeFilterSettings are enabled, otherwise false.
180  */
181  virtual bool initLFPangleRangeFilterSettings(const std::string& host_LFPangleRangeFilter);
182 
183  /* @brief Determine and initialize all_segments_elevation_min/max_deg by host_LFPlayerFilter"
184  ** host_LFPlayerFilter = "<enabled> <layer0enabled> <layer1enabled> ... <layer15enabled>", default: "0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"
185  ** Returns true, if layerFilterSettings are enabled, otherwise false.
186  */
187  virtual bool initLFPlayerFilterSettings(const std::string& host_LFPlayerFilter);
188 
189  /*
190  * Callback function of MsgPackExportListenerIF. HandleMsgPackData() will be called in MsgPackExporter
191  * for each registered listener after msgpack data have been received and converted.
192  * This function converts and publishes msgpack data to PointCloud2 messages.
193  */
194  virtual void HandleMsgPackData(const sick_scansegment_xd::ScanSegmentParserOutput& msgpack_data);
195 
196  /*
197  * Returns this instance explicitely as an implementation of interface MsgPackExportListenerIF.
198  */
200 
201  /*
202  * Activates resp. deactivates publishing
203  */
204  virtual void SetActive(bool active)
205  {
206  m_active = active;
207  }
208 
209  /*
210  * Returns expected min and max azimuth and elevation angle of a fullframe scan
211  */
212  virtual void GetFullframeAngleRanges(float& fullframe_azimuth_min_deg, float& fullframe_azimuth_max_deg, float& fullframe_elevation_min_deg, float& fullframe_elevation_max_deg) const
213  {
214  fullframe_azimuth_min_deg = m_all_segments_azimuth_min_deg;
215  fullframe_azimuth_max_deg = m_all_segments_azimuth_max_deg;
216  fullframe_elevation_min_deg = m_all_segments_elevation_min_deg;
217  fullframe_elevation_max_deg = m_all_segments_elevation_max_deg;
218  }
219 
220  protected:
221 
222  typedef std::map<int,std::map<int,ros_sensor_msgs::LaserScan>> LaserScanMsgMap; // LaserScanMsgMap[echo][layer] := LaserScan message given echo (Multiscan136: max 3 echos) and layer index (Multiscan136: 16 layer)
223 
224  /*
225  * Container to collect all points of 12 segments (12 segments * 30 deg = 360 deg)
226  */
228  {
229  public:
231  {
232  segment_list.reserve(12);
233  telegram_list.reserve(12);
234  segment_coverage.clear();
235  }
236  void appendLidarPoints(const std::vector<std::vector<sick_scansegment_xd::PointXYZRAEI32f>>& points, int32_t segment_idx, int32_t telegram_cnt)
237  {
238  for (int echoIdx = 0; echoIdx < points.size() && echoIdx < lidar_points.size(); echoIdx++)
239  {
240  size_t num_points = points[echoIdx].size();
241  if (num_points > 0)
242  {
243  lidar_points[echoIdx].insert(lidar_points[echoIdx].end(), points[echoIdx].begin(), points[echoIdx].end());
244  assert(lidar_points.size() > echoIdx && lidar_points[echoIdx].size() > 0);
245  if (lidar_timestamp_start_microsec == 0) // first time initialization of lidar start timestamp
246  lidar_timestamp_start_microsec = lidar_points[0].front().lidar_timestamp_microsec;
247  if (lidar_timestamp_stop_microsec == 0) // first time initialization of lidar stop timestamp
248  lidar_timestamp_stop_microsec = lidar_points[0].front().lidar_timestamp_microsec;
249  lidar_timestamp_start_microsec = std::min<uint64_t>(lidar_points[echoIdx].front().lidar_timestamp_microsec, lidar_timestamp_start_microsec); // update lidar start timestamp
250  lidar_timestamp_stop_microsec = std::max<uint64_t>(lidar_points[echoIdx].back().lidar_timestamp_microsec, lidar_timestamp_stop_microsec); // update lidar stop timestamp
251  for (int n = 0; n < num_points; n++)
252  {
253  const sick_scansegment_xd::PointXYZRAEI32f& point = points[echoIdx][n];
254  float elevation_deg = point.elevation * 180.0f / (float)M_PI;
255  float azimuth_fdeg = point.azimuth * 180.0f / (float)M_PI;
256  // Note: The azimuth values of a segment crossing +/-180 degrees are still monotonous, i.e. azimuth values received from the lidar are within -PI to +3*PI.
257  // See compact format specification: "the maximum allowed value range of [-pi, 3*pi] is fully utilized."
258  // To check that the scan points of a fullframe pointclouds covers the complete azimuth range from -180 to +180 degree, we collect the azimuth histogram with 180 deg wrap around.
259  if (azimuth_fdeg > 180.0f)
260  azimuth_fdeg -= 360.0f; // i.e. -180 <= azimuth_deg <= +180
261  int elevation_mdeg = (int)(1000.0f * elevation_deg);
262  int azimuth_ideg = (int)(azimuth_fdeg);
263  segment_coverage[elevation_mdeg][azimuth_ideg] += 1;
264  if (azimuth_fdeg - azimuth_ideg > 0.5f)
265  segment_coverage[elevation_mdeg][azimuth_ideg + 1] += 1;
266  if (azimuth_fdeg - azimuth_ideg < -0.5f)
267  segment_coverage[elevation_mdeg][azimuth_ideg - 1] += 1;
268  }
269  }
270  }
271  segment_list.push_back(segment_idx);
272  telegram_list.push_back(telegram_cnt);
273  // for (std::map<int, std::map<int, int>>::iterator segment_coverage_elevation_iter = segment_coverage.begin(); segment_coverage_elevation_iter != segment_coverage.end(); segment_coverage_elevation_iter++)
274  // {
275  // const int& elevation_deg = segment_coverage_elevation_iter->first;
276  // std::map<int, int>& azimuth_histogram = segment_coverage_elevation_iter->second;
277  // for (std::map<int, int>::iterator segment_coverage_azimuth_iter = azimuth_histogram.begin(); segment_coverage_azimuth_iter != azimuth_histogram.end(); segment_coverage_azimuth_iter++)
278  // {
279  // const int& azimuth_deg = segment_coverage_azimuth_iter->first;
280  // int cnt = segment_coverage_azimuth_iter->second;
281  // std::cout << "seg[" << elevation_deg << "][" << azimuth_deg << "]=" << cnt << " ";
282  // }
283  // std::cout << std::endl;
284  // }
285  }
286 
287  // Returns the last segment index appended by appendLidarPoints
288  int32_t lastSegmentIdx()
289  {
290  return segment_list.empty() ? -1 : segment_list.back();
291  }
292  // Returns true, if all scans in all elevation angles cover azimuth from all_segments_azimuth_min_deg to all_segments_azimuth_max_deg
293  // and all elevation angles cover all_segments_elevation_min_deg to all_segments_elevation_max_deg.
294  // Otherwise allSegmentsCovered returns false.
295  bool allSegmentsCovered(float all_segments_azimuth_min_deg, float all_segments_azimuth_max_deg, float all_segments_elevation_min_deg, float all_segments_elevation_max_deg)
296  {
297  float elevation_deg_min = 999, elevation_deg_max = -999;
298  for (std::map<int, std::map<int, int>>::iterator segment_coverage_elevation_iter = segment_coverage.begin(); segment_coverage_elevation_iter != segment_coverage.end(); segment_coverage_elevation_iter++)
299  {
300  int azimuth_deg_first = 999, azimuth_deg_last = -999;
301  float elevation_deg = 0.001f * (segment_coverage_elevation_iter->first);
302  elevation_deg_min = std::min<float>(elevation_deg, elevation_deg_min);
303  elevation_deg_max = std::max<float>(elevation_deg, elevation_deg_max);
304  std::map<int, int>& azimuth_histogram = segment_coverage_elevation_iter->second;
305  for (std::map<int, int>::iterator segment_coverage_azimuth_iter = azimuth_histogram.begin(); segment_coverage_azimuth_iter != azimuth_histogram.end(); segment_coverage_azimuth_iter++)
306  {
307  const int& azimuth_deg = segment_coverage_azimuth_iter->first;
308  const int& azimuth_cnt = segment_coverage_azimuth_iter->second;
309  if (azimuth_cnt > 0 && azimuth_deg >= (int)all_segments_azimuth_min_deg && azimuth_deg <= (int)all_segments_azimuth_max_deg)
310  {
311  azimuth_deg_first = std::min<int>(azimuth_deg_first, azimuth_deg);
312  azimuth_deg_last = std::max<int>(azimuth_deg_last, azimuth_deg);
313  }
314  }
315  bool azimuth_success = (azimuth_deg_last - azimuth_deg_first + 1 >= all_segments_azimuth_max_deg - all_segments_azimuth_min_deg);
316  // Check azimuth_histogram[azimuth_deg] > 0 for all azimuth_deg in range (azimuth_deg_first, azimuth_deg_last)
317  for(int azimuth_deg = azimuth_deg_first; azimuth_success && azimuth_deg <= azimuth_deg_last; azimuth_deg++)
318  {
319  if (azimuth_histogram[azimuth_deg] <= 0)
320  azimuth_success = false;
321  }
322  // ROS_INFO_STREAM(" SegmentPointsCollector::allSegmentsCovered(): lastSegmentIdx=" << lastSegmentIdx() << ", total_point_count=" << total_point_count
323  // << ", cur_elevation=" << elevation_deg << ", azimuth=(" << azimuth_deg_first << "," << azimuth_deg_last << ")"
324  // << ", azimuth_range=(" << all_segments_azimuth_min_deg << "," << all_segments_azimuth_max_deg << "), azimuth_success=" << azimuth_success);
325  if (!azimuth_success)
326  return false;
327  }
328  bool elevation_success = (elevation_deg_max - elevation_deg_min + 1 >= all_segments_elevation_max_deg - all_segments_elevation_min_deg);
329  // ROS_INFO_STREAM(" SegmentPointsCollector::allSegmentsCovered(): lastSegmentIdx=" << lastSegmentIdx() << ", total_point_count=" << total_point_count
330  // << ", elevation_deg_min=" << elevation_deg_min << ", elevation_deg_max=" << elevation_deg_max
331  // << ", all_segments_elevation_min_deg=" << all_segments_elevation_min_deg << ", all_segments_elevation_max_deg=" << all_segments_elevation_max_deg
332  // << ", elevation_success=" << elevation_success);
333  if (!elevation_success)
334  return false;
335  return true; // all scans in all elevation angles cover azimuth from all_segments_azimuth_min_deg to all_segments_azimuth_max_deg
336  }
337 
338  // Returns the number of echos
339  int numEchos(void) const { return (int)lidar_points.size(); }
340 
341  uint32_t timestamp_sec; // seconds part of timestamp of the first segment (system time)
342  uint32_t timestamp_nsec; // nanoseconds part of timestamp of the first segment (system time)
343  // int32_t segment_count; // number of segments collected
344  int32_t telegram_cnt; // telegram counter (must be continuously incremented)
345  float min_azimuth; // min azimuth of all points in radians
346  float max_azimuth; // max azimuth of all points in radians
347  size_t total_point_count; // total number of points in all segments
348  uint64_t lidar_timestamp_start_microsec; // lidar start timestamp in microseconds
349  uint64_t lidar_timestamp_stop_microsec; // lidar stop timestamp in microseconds
350  std::vector<std::vector<sick_scansegment_xd::PointXYZRAEI32f>> lidar_points; // list of PointXYZRAEI32f: lidar_points[echoIdx] are the points of all segments of an echo (idx echoIdx)
351  std::vector<int32_t> segment_list; // list of all collected segment indices
352  std::vector<int32_t> telegram_list; // list of all collected telegram counters
353  std::map<int, std::map<int, int>> segment_coverage; // (elevation,azimuth) histogram: segment_coverage[elevation][azimuth] > 0: elevation in mdeg and azimuth in deg covered (otherwise no hits)
354  };
355 
356  /*
357  * Converts the lidarpoints to a customized PointCloud2Msg containing configured fields (e.g. x, y, z, i, range, azimuth, elevation, layer, echo, reflector).
358  * @param[in] timestamp_sec seconds part of timestamp (system time)
359  * @param[in] timestamp_nsec nanoseconds part of timestamp (system time)
360  * @param[in] lidar_timestamp_start_microsec lidar start timestamp in microseconds (lidar ticks)
361  * @param[in] lidar_points list of PointXYZRAEI32f: lidar_points[echoIdx] are the points of one echo
362  * @param[in] pointcloud_cfg configuration of customized pointcloud
363  * @param[out] pointcloud_msg customized pointcloud message
364  */
365  void convertPointsToCustomizedFieldsCloud(uint32_t timestamp_sec, uint32_t timestamp_nsec, uint64_t lidar_timestamp_start_microsec,
366  const std::vector<std::vector<sick_scansegment_xd::PointXYZRAEI32f>>& lidar_points, CustomPointCloudConfiguration& pointcloud_cfg, PointCloud2Msg& pointcloud_msg);
367 
368  void convertPointsToLaserscanMsg(uint32_t timestamp_sec, uint32_t timestamp_nsec, const std::vector<std::vector<sick_scansegment_xd::PointXYZRAEI32f>>& lidar_points, size_t total_point_count, LaserScanMsgMap& laser_scan_msg_map, const std::string& frame_id, bool is_fullframe);
369 
371  void publishPointCloud2Msg(rosNodePtr node, PointCloud2MsgPublisher& publisher, PointCloud2Msg& pointcloud_msg, int32_t num_echos, int32_t segment_idx, int coordinate_notation, const std::string& topic);
372 
374  void publishLaserScanMsg(rosNodePtr node, LaserscanMsgPublisher& laserscan_publisher, LaserScanMsgMap& laser_scan_msg_map, int32_t num_echos, int32_t segment_idx);
375 
377  // void publish(rosNodePtr node, PointCloud2MsgPublisher& publisher, PointCloud2Msg& pointcloud_msg, PointCloud2Msg& pointcloud_msg_polar,
378  // LaserscanMsgPublisher& laserscan_publisher, LaserScanMsgMap& laser_scan_msg_map, int32_t num_echos, int32_t segment_idx);
379 
381  std::string printElevationAzimuthTable(const std::vector<std::vector<sick_scansegment_xd::PointXYZRAEI32f>>& lidar_points);
382 
384  std::string printCoverageTable(const std::map<int, std::map<int, int>>& elevation_azimuth_histograms);
385 
386  bool m_active; // activate publishing
387  rosNodePtr m_node; // ros node handle
388  std::string m_frame_id; // frame id of ros Laserscan messages, default: "world"
389  float m_all_segments_azimuth_min_deg = -180; // angle range covering all segments: all segments pointcloud on topic publish_topic_all_segments is published,
390  float m_all_segments_azimuth_max_deg = +180; // if received segments cover azimuth angle range from m_all_segments_azimuth_min_deg to m_all_segments_azimuth_max_deg. -180...+180 for multiScan136 (360 deg fullscan)
391  float m_all_segments_elevation_min_deg = 0; // angle range covering all segments: all segments pointcloud on topic publish_topic_all_segments is published,
392  float m_all_segments_elevation_max_deg = 0; // if received segments cover elevation angle range from m_all_segments_elevation_min_deg to m_all_segments_elevation_max_deg.
393  int m_host_FREchoFilter; // configuration from launchfile: Optionally set FREchoFilter with 0 for FIRST_ECHO (EchoCount=1), 1 for ALL_ECHOS (EchoCount=3), or 2 for LAST_ECHO (EchoCount=1)
394  bool m_host_set_FREchoFilter; // configuration from launchfile: If true, FREchoFilter is set at startup (default: false)
395  SegmentPointsCollector m_points_collector; // collects all points of 12 segments (12 segments * 30 deg = 360 deg)
396  LaserscanMsgPublisher m_publisher_laserscan_360; // ros publisher to publish LaserScan messages of all segments (360 degree)
397  LaserscanMsgPublisher m_publisher_laserscan_segment; // ros publisher to publish LaserScan messages of the current segment
398  ImuMsgPublisher m_publisher_imu; // ros publisher to publish Imu messages
399  bool m_publisher_imu_initialized = false; // imu messages enabled, ros publisher for Imu messages initialized
400  double m_scan_time = 0; // scan_time = 1 / scan_frequency = time for a full 360-degree rotation of the sensor
401  std::vector<int> m_laserscan_layer_filter; // Configuration of laserscan messages (ROS only), activate/deactivate laserscan messages for each layer
402  std::vector<CustomPointCloudConfiguration> m_custom_pointclouds_cfg; // Configuration of customized pointclouds
403 
404  }; // class RosMsgpackPublisher
405 
406 } // namespace sick_scansegment_xd
407 #endif // __SICK_SCANSEGMENT_XD_ROS_MSGPACK_PUBLISHER_H
sick_scansegment_xd::CustomPointCloudConfiguration::printValuesEnabled
static std::string printValuesEnabled(const std::map< std::string, bool > &mapped_values, const std::string &delim=",")
Definition: ros_msgpack_publisher.cpp:169
sick_scansegment_xd::CustomPointCloudConfiguration::topic
const std::string & topic(void) const
Definition: ros_msgpack_publisher.h:109
sick_scansegment_xd::PointCloudFieldProperty::PointCloudFieldProperty
PointCloudFieldProperty(const std::string &_name, uint8_t _datatype, size_t _datasize, size_t _fieldoffset)
Definition: ros_msgpack_publisher.h:93
sick_scansegment_xd::RosMsgpackPublisher::SegmentPointsCollector::telegram_cnt
int32_t telegram_cnt
Definition: ros_msgpack_publisher.h:344
sick_scansegment_xd::RosMsgpackPublisher::ExportListener
virtual sick_scansegment_xd::MsgPackExportListenerIF * ExportListener(void)
Definition: ros_msgpack_publisher.cpp:1123
sick_scansegment_xd::RosMsgpackPublisher::SegmentPointsCollector::segment_list
std::vector< int32_t > segment_list
Definition: ros_msgpack_publisher.h:351
sick_scansegment_xd::RosMsgpackPublisher::~RosMsgpackPublisher
virtual ~RosMsgpackPublisher()
Definition: ros_msgpack_publisher.cpp:420
sick_scansegment_xd::CustomPointCloudConfiguration::publisher
PointCloud2MsgPublisher & publisher(void)
Definition: ros_msgpack_publisher.h:113
sick_scansegment_xd::PointXYZRAEI32f::range
float range
Definition: ros_msgpack_publisher.h:78
sick_scansegment_xd::RosMsgpackPublisher::m_publisher_laserscan_360
LaserscanMsgPublisher m_publisher_laserscan_360
Definition: ros_msgpack_publisher.h:396
sick_scansegment_xd::CustomPointCloudConfiguration::m_publisher
PointCloud2MsgPublisher m_publisher
Definition: ros_msgpack_publisher.h:148
sick_scansegment_xd::CustomPointCloudConfiguration::frameid
const std::string & frameid(void) const
Definition: ros_msgpack_publisher.h:110
PointCloud2Msg
ros_sensor_msgs::PointCloud2 PointCloud2Msg
Definition: include/sick_scansegment_xd/common.h:121
sick_scansegment_xd::RosMsgpackPublisher::HandleMsgPackData
virtual void HandleMsgPackData(const sick_scansegment_xd::ScanSegmentParserOutput &msgpack_data)
Definition: ros_msgpack_publisher.cpp:906
sick_scansegment_xd::RosMsgpackPublisher::SegmentPointsCollector::appendLidarPoints
void appendLidarPoints(const std::vector< std::vector< sick_scansegment_xd::PointXYZRAEI32f >> &points, int32_t segment_idx, int32_t telegram_cnt)
Definition: ros_msgpack_publisher.h:236
sick_scansegment_xd::PointXYZRAEI32f::elevation
float elevation
Definition: ros_msgpack_publisher.h:80
sick_scansegment_xd::PointXYZRAEI32f::z
float z
Definition: ros_msgpack_publisher.h:77
sick_scansegment_xd::CustomPointCloudConfiguration::m_coordinate_notation
int m_coordinate_notation
Definition: ros_msgpack_publisher.h:140
sick_scansegment_xd::RosMsgpackPublisher::printCoverageTable
std::string printCoverageTable(const std::map< int, std::map< int, int >> &elevation_azimuth_histograms)
Definition: ros_msgpack_publisher.cpp:452
sick_scansegment_xd::CustomPointCloudConfiguration::m_layer_enabled
std::map< int8_t, bool > m_layer_enabled
Definition: ros_msgpack_publisher.h:145
sick_scansegment_xd
Definition: include/sick_scansegment_xd/common.h:138
sick_scansegment_xd::RosMsgpackPublisher::m_host_set_FREchoFilter
bool m_host_set_FREchoFilter
Definition: ros_msgpack_publisher.h:394
sick_scansegment_xd::CustomPointCloudConfiguration::m_update_method
int m_update_method
Definition: ros_msgpack_publisher.h:141
sick_scansegment_xd::PointCloudFieldProperty
Container for the field properties of a PointCloud2Msg with all fields (where each field contains x,...
Definition: ros_msgpack_publisher.h:90
sick_scansegment_xd::RosMsgpackPublisher::SetActive
virtual void SetActive(bool active)
Definition: ros_msgpack_publisher.h:204
sick_scansegment_xd::CustomPointCloudConfiguration::m_cfg_name
std::string m_cfg_name
Definition: ros_msgpack_publisher.h:136
sick_scansegment_xd::PointXYZRAEI32f::i
float i
Definition: ros_msgpack_publisher.h:81
sick_scansegment_xd::PointCloudFieldProperty::name
std::string name
Definition: ros_msgpack_publisher.h:94
sick_scansegment_xd::PointCloudFieldProperty::fieldoffset
size_t fieldoffset
Definition: ros_msgpack_publisher.h:97
sick_scansegment_xd::RosMsgpackPublisher::publishPointCloud2Msg
void publishPointCloud2Msg(rosNodePtr node, PointCloud2MsgPublisher &publisher, PointCloud2Msg &pointcloud_msg, int32_t num_echos, int32_t segment_idx, int coordinate_notation, const std::string &topic)
Definition: ros_msgpack_publisher.cpp:473
sick_scansegment_xd::RosMsgpackPublisher::SegmentPointsCollector::max_azimuth
float max_azimuth
Definition: ros_msgpack_publisher.h:346
sick_scansegment_xd::CustomPointCloudConfiguration::fieldEnabled
bool fieldEnabled(const std::string &fieldname)
Definition: ros_msgpack_publisher.h:114
sick_scansegment_xd::CustomPointCloudConfiguration::fullframe
bool fullframe(void) const
Definition: ros_msgpack_publisher.h:111
sick_scansegment_xd::CustomPointCloudConfiguration::m_range_filter
sick_scan_xd::SickRangeFilter m_range_filter
Definition: ros_msgpack_publisher.h:142
sick_scansegment_xd::RosMsgpackPublisher::m_all_segments_azimuth_max_deg
float m_all_segments_azimuth_max_deg
Definition: ros_msgpack_publisher.h:390
sick_scansegment_xd::RosMsgpackPublisher::SegmentPointsCollector::lidar_timestamp_start_microsec
uint64_t lidar_timestamp_start_microsec
Definition: ros_msgpack_publisher.h:348
sick_scansegment_xd::PointXYZRAEI32f::y
float y
Definition: ros_msgpack_publisher.h:76
sick_scansegment_xd::PointXYZRAEI32f
Definition: ros_msgpack_publisher.h:69
f
f
sick_ros_wrapper.h
sick_scansegment_xd::CustomPointCloudConfiguration::print
void print(void) const
Definition: ros_msgpack_publisher.cpp:154
sick_scansegment_xd::RosMsgpackPublisher::SegmentPointsCollector::lidar_timestamp_stop_microsec
uint64_t lidar_timestamp_stop_microsec
Definition: ros_msgpack_publisher.h:349
sick_scansegment_xd::CustomPointCloudConfiguration
Configuration of customized pointclouds.
Definition: ros_msgpack_publisher.h:102
sick_scansegment_xd::RosMsgpackPublisher::m_host_FREchoFilter
int m_host_FREchoFilter
Definition: ros_msgpack_publisher.h:393
sick_scansegment_xd::RosMsgpackPublisher::SegmentPointsCollector::lidar_points
std::vector< std::vector< sick_scansegment_xd::PointXYZRAEI32f > > lidar_points
Definition: ros_msgpack_publisher.h:350
sick_scansegment_xd::RosMsgpackPublisher::SegmentPointsCollector::total_point_count
size_t total_point_count
Definition: ros_msgpack_publisher.h:347
sick_scansegment_xd::RosMsgpackPublisher::printElevationAzimuthTable
std::string printElevationAzimuthTable(const std::vector< std::vector< sick_scansegment_xd::PointXYZRAEI32f >> &lidar_points)
Definition: ros_msgpack_publisher.cpp:425
sick_scansegment_xd::PointCloudFieldProperty::datatype
uint8_t datatype
Definition: ros_msgpack_publisher.h:95
sick_scansegment_xd::RosMsgpackPublisher::m_laserscan_layer_filter
std::vector< int > m_laserscan_layer_filter
Definition: ros_msgpack_publisher.h:401
sick_scansegment_xd::CustomPointCloudConfiguration::m_field_enabled
std::map< std::string, bool > m_field_enabled
Definition: ros_msgpack_publisher.h:143
sick_scansegment_xd::RosMsgpackPublisher::m_custom_pointclouds_cfg
std::vector< CustomPointCloudConfiguration > m_custom_pointclouds_cfg
Definition: ros_msgpack_publisher.h:402
sick_scansegment_xd::PointXYZRAEI32f::PointXYZRAEI32f
PointXYZRAEI32f()
Definition: ros_msgpack_publisher.h:72
sick_scansegment_xd::ScanSegmentParserOutput
Definition: scansegment_parser_output.h:118
sick_scansegment_xd::RosMsgpackPublisher::LaserScanMsgMap
std::map< int, std::map< int, ros_sensor_msgs::LaserScan > > LaserScanMsgMap
Definition: ros_msgpack_publisher.h:222
polar_to_cartesian_pointcloud_ros1.node
node
Definition: polar_to_cartesian_pointcloud_ros1.py:81
sick_scansegment_xd::CustomPointCloudConfiguration::m_echo_enabled
std::map< int8_t, bool > m_echo_enabled
Definition: ros_msgpack_publisher.h:144
rosPublisher< PointCloud2Msg >
sick_scansegment_xd::PointXYZRAEI32f::echo
int echo
Definition: ros_msgpack_publisher.h:83
sick_scansegment_xd::RosMsgpackPublisher::SegmentPointsCollector
Definition: ros_msgpack_publisher.h:227
sick_scansegment_xd::RosMsgpackPublisher::m_all_segments_elevation_min_deg
float m_all_segments_elevation_min_deg
Definition: ros_msgpack_publisher.h:391
sick_scansegment_xd::CustomPointCloudConfiguration::publish
bool publish(void) const
Definition: ros_msgpack_publisher.h:108
sick_scansegment_xd::CustomPointCloudConfiguration::CustomPointCloudConfiguration
CustomPointCloudConfiguration()
Definition: ros_msgpack_publisher.h:105
sick_scansegment_xd::RosMsgpackPublisher::m_scan_time
double m_scan_time
Definition: ros_msgpack_publisher.h:400
sick_scansegment_xd::RosMsgpackPublisher::initLFPlayerFilterSettings
virtual bool initLFPlayerFilterSettings(const std::string &host_LFPlayerFilter)
Definition: ros_msgpack_publisher.cpp:222
sick_scansegment_xd::RosMsgpackPublisher::m_node
rosNodePtr m_node
Definition: ros_msgpack_publisher.h:387
sick_scansegment_xd::RosMsgpackPublisher::convertPointsToLaserscanMsg
void convertPointsToLaserscanMsg(uint32_t timestamp_sec, uint32_t timestamp_nsec, const std::vector< std::vector< sick_scansegment_xd::PointXYZRAEI32f >> &lidar_points, size_t total_point_count, LaserScanMsgMap &laser_scan_msg_map, const std::string &frame_id, bool is_fullframe)
Definition: ros_msgpack_publisher.cpp:667
sick_scansegment_xd::RosMsgpackPublisher::initLFPangleRangeFilterSettings
virtual bool initLFPangleRangeFilterSettings(const std::string &host_LFPangleRangeFilter)
Definition: ros_msgpack_publisher.cpp:195
sick_scansegment_xd::PointXYZRAEI32f::lidar_timestamp_microsec
uint64_t lidar_timestamp_microsec
Definition: ros_msgpack_publisher.h:84
ros::NodeHandle
sick_scansegment_xd::Config
Definition: config.h:84
sick_scansegment_xd::PointXYZRAEI32f::layer
int layer
Definition: ros_msgpack_publisher.h:82
sick_scansegment_xd::RosMsgpackPublisher::GetFullframeAngleRanges
virtual void GetFullframeAngleRanges(float &fullframe_azimuth_min_deg, float &fullframe_azimuth_max_deg, float &fullframe_elevation_min_deg, float &fullframe_elevation_max_deg) const
Definition: ros_msgpack_publisher.h:212
sick_scansegment_xd::PointXYZRAEI32f::PointXYZRAEI32f
PointXYZRAEI32f(float _x, float _y, float _z, float _range, float _azimuth, float _elevation, float _i, int _layer, int _echo, uint64_t _lidar_timestamp_microsec, uint8_t _reflector_bit)
Definition: ros_msgpack_publisher.h:73
sick_scansegment_xd::CustomPointCloudConfiguration::pointEnabled
bool pointEnabled(sick_scansegment_xd::PointXYZRAEI32f &lidar_point)
Definition: ros_msgpack_publisher.h:118
sick_scansegment_xd::CustomPointCloudConfiguration::m_infringed_enabled
std::map< int8_t, bool > m_infringed_enabled
Definition: ros_msgpack_publisher.h:147
sick_scansegment_xd::RosMsgpackPublisher::m_active
bool m_active
Definition: ros_msgpack_publisher.h:386
sick_scansegment_xd::RosMsgpackPublisher::SegmentPointsCollector::timestamp_sec
uint32_t timestamp_sec
Definition: ros_msgpack_publisher.h:341
sick_scansegment_xd::PointXYZRAEI32f::reflectorbit
uint8_t reflectorbit
Definition: ros_msgpack_publisher.h:85
msgpack_exporter.h
sick_scansegment_xd::PointXYZRAEI32f::x
float x
Definition: ros_msgpack_publisher.h:75
sick_scansegment_xd::RosMsgpackPublisher::SegmentPointsCollector::min_azimuth
float min_azimuth
Definition: ros_msgpack_publisher.h:345
sick_scansegment_xd::RosMsgpackPublisher::m_publisher_laserscan_segment
LaserscanMsgPublisher m_publisher_laserscan_segment
Definition: ros_msgpack_publisher.h:397
sick_scansegment_xd::RosMsgpackPublisher
Definition: ros_msgpack_publisher.h:158
sick_scansegment_xd::RosMsgpackPublisher::m_publisher_imu
ImuMsgPublisher m_publisher_imu
Definition: ros_msgpack_publisher.h:398
sick_scansegment_xd::RosMsgpackPublisher::RosMsgpackPublisher
RosMsgpackPublisher(const std::string &node_name="sick_scansegment_xd", const sick_scansegment_xd::Config &config=sick_scansegment_xd::Config())
Definition: ros_msgpack_publisher.cpp:264
sick_scansegment_xd::RosMsgpackPublisher::convertPointsToCustomizedFieldsCloud
void convertPointsToCustomizedFieldsCloud(uint32_t timestamp_sec, uint32_t timestamp_nsec, uint64_t lidar_timestamp_start_microsec, const std::vector< std::vector< sick_scansegment_xd::PointXYZRAEI32f >> &lidar_points, CustomPointCloudConfiguration &pointcloud_cfg, PointCloud2Msg &pointcloud_msg)
Definition: ros_msgpack_publisher.cpp:558
sick_scan_xd::SickRangeFilter::apply
bool apply(float &range, bool &range_modified) const
Definition: sick_range_filter.h:107
sick_scansegment_xd::MsgPackExportListenerIF
Definition: msgpack_exporter.h:73
sick_scansegment_xd::RosMsgpackPublisher::m_frame_id
std::string m_frame_id
Definition: ros_msgpack_publisher.h:388
sick_scan_base.h
sick_scansegment_xd::PointXYZRAEI32f::infringed
uint8_t infringed
Definition: ros_msgpack_publisher.h:86
sick_scansegment_xd::PointCloudFieldProperty::datasize
size_t datasize
Definition: ros_msgpack_publisher.h:96
sick_scansegment_xd::RosMsgpackPublisher::publishLaserScanMsg
void publishLaserScanMsg(rosNodePtr node, LaserscanMsgPublisher &laserscan_publisher, LaserScanMsgMap &laser_scan_msg_map, int32_t num_echos, int32_t segment_idx)
Definition: ros_msgpack_publisher.cpp:498
config.h
sick_scansegment_xd::RosMsgpackPublisher::m_all_segments_elevation_max_deg
float m_all_segments_elevation_max_deg
Definition: ros_msgpack_publisher.h:392
sick_scansegment_xd::PointXYZRAEI32f::azimuth
float azimuth
Definition: ros_msgpack_publisher.h:79
sick_scansegment_xd::RosMsgpackPublisher::SegmentPointsCollector::lastSegmentIdx
int32_t lastSegmentIdx()
Definition: ros_msgpack_publisher.h:288
sick_scansegment_xd::CustomPointCloudConfiguration::m_reflector_enabled
std::map< int8_t, bool > m_reflector_enabled
Definition: ros_msgpack_publisher.h:146
sick_scansegment_xd::RosMsgpackPublisher::SegmentPointsCollector::numEchos
int numEchos(void) const
Definition: ros_msgpack_publisher.h:339
sick_scansegment_xd::CustomPointCloudConfiguration::m_topic
std::string m_topic
Definition: ros_msgpack_publisher.h:138
sick_scansegment_xd::RosMsgpackPublisher::SegmentPointsCollector::telegram_list
std::vector< int32_t > telegram_list
Definition: ros_msgpack_publisher.h:352
sick_scansegment_xd::RosMsgpackPublisher::SegmentPointsCollector::timestamp_nsec
uint32_t timestamp_nsec
Definition: ros_msgpack_publisher.h:342
sick_scansegment_xd::RosMsgpackPublisher::m_points_collector
SegmentPointsCollector m_points_collector
Definition: ros_msgpack_publisher.h:395
config
config
sick_scansegment_xd::RosMsgpackPublisher::m_all_segments_azimuth_min_deg
float m_all_segments_azimuth_min_deg
Definition: ros_msgpack_publisher.h:389
sick_scansegment_xd::RosMsgpackPublisher::SegmentPointsCollector::SegmentPointsCollector
SegmentPointsCollector(int telegram_idx=0)
Definition: ros_msgpack_publisher.h:230
sick_scansegment_xd::RosMsgpackPublisher::SegmentPointsCollector::allSegmentsCovered
bool allSegmentsCovered(float all_segments_azimuth_min_deg, float all_segments_azimuth_max_deg, float all_segments_elevation_min_deg, float all_segments_elevation_max_deg)
Definition: ros_msgpack_publisher.h:295
multiscan_perftest_player.num_echos
int num_echos
Definition: multiscan_perftest_player.py:22
sick_scansegment_xd::CustomPointCloudConfiguration::m_frameid
std::string m_frameid
Definition: ros_msgpack_publisher.h:139
sick_scansegment_xd::CustomPointCloudConfiguration::coordinateNotation
int coordinateNotation(void) const
Definition: ros_msgpack_publisher.h:112
sick_scansegment_xd::CustomPointCloudConfiguration::cfgName
const std::string & cfgName(void) const
Definition: ros_msgpack_publisher.h:107
sick_scansegment_xd::RosMsgpackPublisher::m_publisher_imu_initialized
bool m_publisher_imu_initialized
Definition: ros_msgpack_publisher.h:399
sick_scan_xd::SickRangeFilter::applyXYZ
bool applyXYZ(float &x, float &y, float &z, float azimuth, float elevation)
Definition: sick_range_filter.h:148
sick_scansegment_xd::CustomPointCloudConfiguration::m_publish
bool m_publish
Definition: ros_msgpack_publisher.h:137
sick_scansegment_xd::RosMsgpackPublisher::SegmentPointsCollector::segment_coverage
std::map< int, std::map< int, int > > segment_coverage
Definition: ros_msgpack_publisher.h:353
sick_scan_xd::SickRangeFilter
Definition: sick_range_filter.h:85


sick_scan_xd
Author(s): Michael Lehning , Jochen Sprickerhof , Martin Günther
autogenerated on Fri Oct 25 2024 02:47:10