YARP
Yet Another Robot Platform
Lidar2DDeviceBase.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * All rights reserved.
4  *
5  * This software may be modified and distributed under the terms of the
6  * BSD-3-Clause license. See the accompanying LICENSE file for details.
7  */
8 
9 #define _USE_MATH_DEFINES
10 
12 #include <yarp/os/LogStream.h>
13 #include <mutex>
14 #include <limits>
15 #include <cmath>
16 
17 using namespace yarp::os;
18 using namespace yarp::dev;
19 using namespace std;
20 
21 #ifndef DEG2RAD
22 #define DEG2RAD M_PI/180.0
23 #endif
24 
25 YARP_LOG_COMPONENT(LASER_BASE, "yarp.devices.Lidar2DDeviceBase")
26 
27 bool Lidar2DDeviceBase::getScanLimits(double& min, double& max)
28 {
29  std::lock_guard<std::mutex> guard(m_mutex);
30  min = m_min_angle;
31  max = m_max_angle;
32  return true;
33 }
34 
35 bool Lidar2DDeviceBase::getDistanceRange(double& min, double& max)
36 {
37  std::lock_guard<std::mutex> guard(m_mutex);
38  min = m_min_distance;
39  max = m_max_distance;
40  return true;
41 }
42 
43 bool Lidar2DDeviceBase::getHorizontalResolution(double& step)
44 {
45  std::lock_guard<std::mutex> guard(m_mutex);
46  step = m_resolution;
47  return true;
48 }
49 
50 bool Lidar2DDeviceBase::getDeviceStatus(Device_status& status)
51 {
52  std::lock_guard<std::mutex> guard(m_mutex);
53  status = m_device_status;
54  return true;
55 }
56 
57 bool Lidar2DDeviceBase::getRawData(yarp::sig::Vector& out)
58 {
59  std::lock_guard<std::mutex> guard(m_mutex);
60  out = m_laser_data;
61  return true;
62 }
63 
64 bool Lidar2DDeviceBase::getScanRate(double& rate)
65 {
66  std::lock_guard<std::mutex> guard(m_mutex);
67  rate = m_scan_rate;
68  return true;
69 }
70 
71 bool Lidar2DDeviceBase::getDeviceInfo(std::string& device_info)
72 {
73  std::lock_guard<std::mutex> guard(m_mutex);
74  device_info = m_info;
75  return true;
76 }
77 
78 bool Lidar2DDeviceBase::getLaserMeasurement(std::vector<LaserMeasurementData>& data)
79 {
80  std::lock_guard<std::mutex> guard(m_mutex);
81 #ifdef LASER_DEBUG
82  //yDebug("data: %s\n", laser_data.toString().c_str());
83 #endif
84  size_t size = m_laser_data.size();
85  data.resize(size);
86  if (m_max_angle < m_min_angle) { yCError(LASER_BASE) << "getLaserMeasurement failed"; return false; }
87  double laser_angle_of_view = m_max_angle - m_min_angle;
88  for (size_t i = 0; i < size; i++)
89  {
90  double angle = (i / double(size) * laser_angle_of_view + m_min_angle) * DEG2RAD;
91  data[i].set_polar(m_laser_data[i], angle);
92  }
93  return true;
94 }
95 
96 Lidar2DDeviceBase::Lidar2DDeviceBase() :
97  m_device_status(yarp::dev::IRangefinder2D::Device_status::DEVICE_GENERAL_ERROR),
98  m_scan_rate(0.0),
99  m_sensorsNum(0),
100  m_min_angle(0.0),
101  m_max_angle(0.0),
102  m_min_distance(0.1),
103  m_max_distance(30.0),
104  m_resolution(0.0),
105  m_clip_max_enable(false),
106  m_clip_min_enable(false),
107  m_do_not_clip_and_allow_infinity_enable(true)
108 {}
109 
111 {
112  //sensor options (should be mandatory? TBD)
113  {
114  bool br = config.check("SENSOR");
115  if (br != false)
116  {
117  yarp::os::Searchable& general_config = config.findGroup("SENSOR");
118  if (general_config.check("max_angle")) { m_max_angle = general_config.find("max_angle").asFloat64(); }
119  if (general_config.check("min_angle")) { m_min_angle = general_config.find("min_angle").asFloat64(); }
120  if (general_config.check("resolution")) { m_resolution = general_config.find("resolution").asFloat64(); }
121  m_clip_max_enable = general_config.check("max_distance");
122  m_clip_min_enable = general_config.check("min_distance");
123  if (m_clip_max_enable) { m_max_distance = general_config.find("max_distance").asFloat64(); }
124  if (m_clip_min_enable) { m_min_distance = general_config.find("min_distance").asFloat64(); }
125  m_do_not_clip_and_allow_infinity_enable = (general_config.find("allow_infinity").asInt32() == 1);
126  }
127  else
128  {
129  //yCError(LASER_BASE) << "Missing SENSOR section";
130  //return false;
131  }
132  }
133 
134  //skip options (optional)
135  {
136  bool bs = config.check("SKIP");
137  if (bs == true)
138  {
139  yarp::os::Searchable& skip_config = config.findGroup("SKIP");
140  Bottle mins = skip_config.findGroup("min");
141  Bottle maxs = skip_config.findGroup("max");
142  size_t s_mins = mins.size();
143  size_t s_maxs = mins.size();
144  if (s_mins == s_maxs && s_maxs > 1)
145  {
146  for (size_t s = 1; s < s_maxs; s++)
147  {
148  Range_t range;
149  range.max = maxs.get(s).asFloat64();
150  range.min = mins.get(s).asFloat64();
151  if (range.max >= 0 && range.max <= 360 &&
152  range.min >= 0 && range.min <= 360 &&
153  range.max > range.min)
154  {
155  m_range_skip_vector.push_back(range);
156  }
157  else
158  {
159  yCError(LASER_BASE) << "Invalid range in SKIP section:"<< range.min << range.max;
160  return false;
161  }
162  }
163  }
164  //yCDebug(LASER_BASE) << "Skip section set successfully";
165  }
166  else
167  {
168  //yCDebug(LASER_BASE) << "No Skip section required";
169  }
170  }
171 
172  //checks and allocation
173  if (m_max_distance - m_min_distance <= 0)
174  {
175  yCError(LASER_BASE) << "invalid parameters: max_distance/min_distance";
176  return false;
177  }
178  double fov = (m_max_angle - m_min_angle);
179  if (fov <= 0)
180  {
181  yCError(LASER_BASE) << "invalid parameters: max_angle should be > min_angle";
182  return false;
183  }
184  if (fov > 360)
185  {
186  yCError(LASER_BASE) << "invalid parameters: max_angle - min_angle <= 360";
187  return false;
188  }
189  if (m_resolution <= 0)
190  {
191  yCError(LASER_BASE) << "invalid parameters resolution";
192  return false;
193  }
194  m_sensorsNum = (int)(fov / m_resolution);
196 
197  yCInfo(LASER_BASE) << "Using the following parameters:";
198  yCInfo(LASER_BASE) << "max_dist:" << m_max_distance << " min_dist:" << m_min_distance;
199  yCInfo(LASER_BASE) << "max_angle:" << m_max_angle << " min_angle:" << m_min_angle;
200  yCInfo(LASER_BASE) << "resolution:" << m_resolution;
201  yCInfo(LASER_BASE) << "sensors:" << m_sensorsNum;
202  yCInfo(LASER_BASE) << "allow_infinity:" << (m_do_not_clip_and_allow_infinity_enable ==true);
203  if (m_range_skip_vector.size() >0)
204  {
205  for (size_t i=0; i< m_range_skip_vector.size(); i++)
206  yCInfo(LASER_BASE) << "skip area:" << m_range_skip_vector[i].min << "->" << m_range_skip_vector[i].max;
207  }
208  return true;
209 }
210 
211 //this function checks if the angle is inside the allowed limits
212 //if not, distance value is set to NaN
213 bool Lidar2DDeviceBase::checkSkipAngle(const double& angle, double& distance)
214 {
215  for (auto& it_skip : m_range_skip_vector)
216  {
217  if (angle > it_skip.min&& angle < it_skip.max)
218  {
219  distance = std::nan("");
220  return true;
221  }
222  }
223  return false;
224 }
225 
227 {
228  for (size_t i = 0; i < m_sensorsNum; i++)
229  {
230  double& distance = m_laser_data[i];
231  double angle = i * m_resolution;
232 
233  if (std::isnan(distance)) continue;
234  if (checkSkipAngle(angle, distance)) continue;
235 
236  if (m_clip_min_enable)
237  {
238  if (distance < m_min_distance)
239  {
240  distance = std::numeric_limits<double>::infinity();
241  //the following means: if we want to clip infinity...
243  {
244  distance = m_min_distance;
245  }
246  }
247  }
248  if (m_clip_max_enable)
249  {
250  if (distance > m_max_distance)
251  {
252  distance = std::numeric_limits<double>::infinity();
253  //the following means: if we want to clip infinity...
255  {
256  distance = m_max_distance;
257  }
258  }
259  }
260  }
261 }
LogStream.h
yarp::os::Bottle
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:73
yarp::dev::Lidar2DDeviceBase::m_laser_data
yarp::sig::Vector m_laser_data
Definition: Lidar2DDeviceBase.h:37
yarp::sig::VectorOf::resize
void resize(size_t size) override
Resize the vector.
Definition: Vector.h:254
yarp::os::Searchable
A base class for nested structures that can be searched.
Definition: Searchable.h:69
yarp::os::Bottle::size
size_type size() const
Gets the number of elements in the bottle.
Definition: Bottle.cpp:254
yarp::os::Searchable::findGroup
virtual Bottle & findGroup(const std::string &key) const =0
Gets a list corresponding to a given keyword.
Lidar2DDeviceBase.h
yarp::dev::Lidar2DDeviceBase::applyLimitsOnLaserData
void applyLimitsOnLaserData()
Definition: Lidar2DDeviceBase.cpp:226
YARP_LOG_COMPONENT
#define YARP_LOG_COMPONENT(name,...)
Definition: LogComponent.h:80
yarp::dev::Lidar2DDeviceBase::m_resolution
double m_resolution
Definition: Lidar2DDeviceBase.h:50
yarp::dev::IRangefinder2D
A generic interface for planar laser range finders.
Definition: IRangefinder2D.h:38
yarp::dev::IRangefinder2D::Device_status
Device_status
Definition: IRangefinder2D.h:41
yarp::dev::Lidar2DDeviceBase::m_min_angle
double m_min_angle
Definition: Lidar2DDeviceBase.h:46
yarp::dev
An interface for the device drivers.
Definition: audioBufferSizeData.cpp:17
yarp::dev::Lidar2DDeviceBase::parseConfiguration
bool parseConfiguration(yarp::os::Searchable &config)
Definition: Lidar2DDeviceBase.cpp:110
yarp::dev::Lidar2DDeviceBase
The DLidarDeviceTemplate class.
Definition: Lidar2DDeviceBase.h:33
yarp::dev::Range_t::min
double min
Definition: Lidar2DDeviceBase.h:24
yarp::dev::Lidar2DDeviceBase::m_do_not_clip_and_allow_infinity_enable
bool m_do_not_clip_and_allow_infinity_enable
Definition: Lidar2DDeviceBase.h:53
yarp::sig::VectorOf< double >
yarp::dev::Lidar2DDeviceBase::m_sensorsNum
size_t m_sensorsNum
Definition: Lidar2DDeviceBase.h:45
yarp::os::Bottle::get
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Definition: Bottle.cpp:249
yarp::dev::Lidar2DDeviceBase::m_clip_max_enable
bool m_clip_max_enable
Definition: Lidar2DDeviceBase.h:51
yarp::dev::Lidar2DDeviceBase::m_max_distance
double m_max_distance
Definition: Lidar2DDeviceBase.h:49
yarp::dev::Range_t
Definition: Lidar2DDeviceBase.h:23
LASER_BASE
const yarp::os::LogComponent & LASER_BASE()
Definition: Lidar2DDeviceBase.cpp:25
yarp::os::Searchable::check
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
yarp::dev::Lidar2DDeviceBase::m_clip_min_enable
bool m_clip_min_enable
Definition: Lidar2DDeviceBase.h:52
yarp::os::Searchable::find
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
DEG2RAD
#define DEG2RAD
Definition: Lidar2DDeviceBase.cpp:22
yCError
#define yCError(component,...)
Definition: LogComponent.h:157
yarp::dev::Range_t::max
double max
Definition: Lidar2DDeviceBase.h:25
yarp::os::Value::asInt32
virtual std::int32_t asInt32() const
Get 32-bit integer value.
Definition: Value.cpp:207
yCInfo
#define yCInfo(component,...)
Definition: LogComponent.h:135
yarp::os
An interface to the operating system, including Port based communication.
Definition: AbstractCarrier.h:17
yarp
The main, catch-all namespace for YARP.
Definition: environment.h:18
yarp::dev::Lidar2DDeviceBase::m_min_distance
double m_min_distance
Definition: Lidar2DDeviceBase.h:48
yarp::dev::Lidar2DDeviceBase::m_range_skip_vector
std::vector< Range_t > m_range_skip_vector
Definition: Lidar2DDeviceBase.h:54
yarp::os::Value::asFloat64
virtual yarp::conf::float64_t asFloat64() const
Get 64-bit floating point value.
Definition: Value.cpp:225
yarp::dev::Lidar2DDeviceBase::m_max_angle
double m_max_angle
Definition: Lidar2DDeviceBase.h:47