YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
Lidar2DDeviceBase.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
6#define _USE_MATH_DEFINES
7
9#include <yarp/os/LogStream.h>
10#include <mutex>
11#include <limits>
12#include <cmath>
13
14using namespace yarp::os;
15using namespace yarp::dev;
16using namespace yarp::sig;
17
18#ifndef DEG2RAD
19#define DEG2RAD M_PI/180.0
20#endif
21
22YARP_LOG_COMPONENT(LASER_BASE, "yarp.devices.Lidar2DDeviceBase")
23
24ReturnValue Lidar2DDeviceBase::getScanLimits(double& min, double& max)
25{
26 std::lock_guard<std::mutex> guard(m_mutex);
27 min = m_min_angle;
28 max = m_max_angle;
29 return ReturnValue_ok;
30}
31
33{
34 std::lock_guard<std::mutex> guard(m_mutex);
35 min = m_min_distance;
36 max = m_max_distance;
37 return ReturnValue_ok;
38}
39
41{
42 std::lock_guard<std::mutex> guard(m_mutex);
43 step = m_resolution;
44 return ReturnValue_ok;
45}
46
48{
49 std::lock_guard<std::mutex> guard(m_mutex);
50 status = m_device_status;
51 return ReturnValue_ok;
52}
53
55{
56 std::lock_guard<std::mutex> guard(m_mutex);
57 out = m_laser_data;
58 if (timestamp != nullptr)
59 {
60 *timestamp = m_timestamp.getTime();
61 }
62 return ReturnValue_ok;
63}
64
66{
67 std::lock_guard<std::mutex> guard(m_mutex);
68 rate = m_scan_rate;
69 return ReturnValue_ok;
70}
71
73{
74 std::lock_guard<std::mutex> guard(m_mutex);
75 device_info = m_info;
76 return ReturnValue_ok;
77}
78
79ReturnValue Lidar2DDeviceBase::getLaserMeasurement(std::vector<LaserMeasurementData>& data, double* timestamp)
80{
81 std::lock_guard<std::mutex> guard(m_mutex);
82#ifdef LASER_DEBUG
83 //yDebug("data: %s\n", laser_data.toString().c_str());
84#endif
85 size_t size = m_laser_data.size();
86 data.resize(size);
88 {
89 yCError(LASER_BASE) << "getLaserMeasurement failed";
91 }
93 for (size_t i = 0; i < size; i++)
94 {
95 double angle = (i / double(size) * laser_angle_of_view + m_min_angle) * DEG2RAD;
96 data[i].set_polar(m_laser_data[i], angle);
97 }
98 if (timestamp!=nullptr)
99 {
100 *timestamp = m_timestamp.getTime();
101 }
102 return ReturnValue_ok;
103}
104
106 m_device_status(yarp::dev::IRangefinder2D::Device_status::DEVICE_GENERAL_ERROR),
107 m_scan_rate(0.0),
108 m_sensorsNum(0),
109 m_min_angle(0.0),
110 m_max_angle(0.0),
111 m_min_distance(0.1),
112 m_max_distance(30.0),
113 m_resolution(0.0),
114 m_clip_max_enable(false),
115 m_clip_min_enable(false),
116 m_do_not_clip_and_allow_infinity_enable(true)
117{}
118
120{
121 std::string config_str = config.toString();
122
123 //sensor options (should be mandatory? TBD)
124 {
125 bool br = config.check("SENSOR");
126 if (br != false)
127 {
129 if (general_config.check("max_angle")) { m_max_angle = general_config.find("max_angle").asFloat64(); }
130 if (general_config.check("min_angle")) { m_min_angle = general_config.find("min_angle").asFloat64(); }
131 if (general_config.check("resolution")) { m_resolution = general_config.find("resolution").asFloat64(); }
132 m_clip_max_enable = general_config.check("max_distance");
133 m_clip_min_enable = general_config.check("min_distance");
134 if (m_clip_max_enable) { m_max_distance = general_config.find("max_distance").asFloat64(); }
135 if (m_clip_min_enable) { m_min_distance = general_config.find("min_distance").asFloat64(); }
136 m_do_not_clip_and_allow_infinity_enable = (general_config.find("allow_infinity").asInt32() == 1);
137 }
138 else
139 {
140 //yCError(LASER_BASE) << "Missing SENSOR section";
141 //return false;
142 }
143 }
144
145 //skip options (optional)
146 {
147 bool bs = config.check("SKIP");
148 if (bs == true)
149 {
151 Bottle mins = skip_config.findGroup("min");
152 Bottle maxs = skip_config.findGroup("max");
153 size_t s_mins = mins.size();
154 size_t s_maxs = mins.size();
155 if (s_mins == s_maxs && s_maxs > 1)
156 {
157 for (size_t s = 1; s < s_maxs; s++)
158 {
160 range.max = maxs.get(s).asFloat64();
161 range.min = mins.get(s).asFloat64();
162 if (range.max >= 0 && range.max <= 360 &&
163 range.min >= 0 && range.min <= 360 &&
164 range.max > range.min)
165 {
166 m_range_skip_vector.push_back(range);
167 }
168 else
169 {
170 yCError(LASER_BASE) << "Invalid range in SKIP section:"<< range.min << range.max;
171 return false;
172 }
173 }
174 }
175 //yCDebug(LASER_BASE) << "Skip section set successfully";
176 }
177 else
178 {
179 //yCDebug(LASER_BASE) << "No Skip section required";
180 }
181 }
182
183 //checks and allocation
185 {
186 yCError(LASER_BASE) << "invalid parameters: max_distance/min_distance";
187 return false;
188 }
189 double fov = (m_max_angle - m_min_angle);
190 if (fov <= 0)
191 {
192 yCError(LASER_BASE) << "invalid parameters: max_angle should be > min_angle";
193 return false;
194 }
195 if (fov > 360)
196 {
197 yCError(LASER_BASE) << "invalid parameters: max_angle - min_angle <= 360";
198 return false;
199 }
200 if (m_resolution <= 0)
201 {
202 yCError(LASER_BASE) << "invalid parameters resolution";
203 return false;
204 }
205 m_sensorsNum = (int)(fov / m_resolution);
207
208 yCInfo(LASER_BASE) << "Using the following parameters:";
209 yCInfo(LASER_BASE) << "max_dist:" << m_max_distance << " min_dist:" << m_min_distance;
210 yCInfo(LASER_BASE) << "max_angle:" << m_max_angle << " min_angle:" << m_min_angle;
211 yCInfo(LASER_BASE) << "resolution:" << m_resolution;
212 yCInfo(LASER_BASE) << "sensors:" << m_sensorsNum;
213 yCInfo(LASER_BASE) << "allow_infinity:" << (m_do_not_clip_and_allow_infinity_enable ==true);
214 if (m_range_skip_vector.size() >0)
215 {
216 for (size_t i = 0; i < m_range_skip_vector.size(); i++) {
217 yCInfo(LASER_BASE) << "skip area:" << m_range_skip_vector[i].min << "->" << m_range_skip_vector[i].max;
218 }
219 }
220 return true;
221}
222
223//this function checks if the angle is inside the allowed limits
224//if not, distance value is set to NaN
225bool Lidar2DDeviceBase::checkSkipAngle(const double& angle, double& distance)
226{
227 for (auto& it_skip : m_range_skip_vector)
228 {
229 if (angle > it_skip.min&& angle < it_skip.max)
230 {
231 distance = std::nan("");
232 return true;
233 }
234 }
235 return false;
236}
237
239{
240 for (size_t i = 0; i < m_sensorsNum; i++)
241 {
242 double& distance = m_laser_data[i];
243 double angle = i * m_resolution;
244
245 if (std::isnan(distance)) {
246 continue;
247 }
248 if (checkSkipAngle(angle, distance)) {
249 continue;
250 }
251
253 {
255 {
256 distance = std::numeric_limits<double>::infinity();
257 //the following means: if we want to clip infinity...
259 {
261 }
262 }
263 }
265 {
267 {
268 distance = std::numeric_limits<double>::infinity();
269 //the following means: if we want to clip infinity...
271 {
273 }
274 }
275 }
276 }
277 return true;
278}
279
281{
282 bool b = true;
283 b &= acquireDataFromHW();
284 if (!b) {
285 return false;
286 }
288 if (!b) {
289 return false;
290 }
291 b &= updateTimestamp();
292 return b;
293}
294
296{
298 return true;
299}
const yarp::os::LogComponent & LASER_BASE()
#define DEG2RAD
#define ReturnValue_ok
Definition ReturnValue.h:77
A generic interface for planar laser range finders.
The Lidar2DDeviceBase class.
yarp::dev::ReturnValue getLaserMeasurement(std::vector< yarp::sig::LaserMeasurementData > &data, double *timestamp=nullptr) override
Get the device measurements.
yarp::dev::ReturnValue getHorizontalResolution(double &step) override
get the angular step between two measurements.
yarp::dev::ReturnValue getDeviceStatus(Device_status &status) override
get the device status
virtual bool updateLidarData()
This utility method calls in sequence: grabDataFromHW(), updateTimestamp and applyLimitsOnLaserData()...
virtual bool acquireDataFromHW()=0
This method should be implemented by the user, and contain the logic to grab data from the hardware.
virtual bool applyLimitsOnLaserData()
Apply the limits on the internally stored lidar measurements.
yarp::dev::ReturnValue getScanRate(double &rate) override
get the scan rate (scans per seconds)
std::vector< Range_t > m_range_skip_vector
yarp::dev::ReturnValue getDeviceInfo(std::string &device_info) override
get the device hardware characteristics
yarp::dev::IRangefinder2D::Device_status m_device_status
virtual bool updateTimestamp()
By default, it automatically updates the internal timestamp with the yarp time.
bool parseConfiguration(yarp::os::Searchable &config)
yarp::dev::ReturnValue getDistanceRange(double &min, double &max) override
get the device detection range
yarp::dev::ReturnValue getRawData(yarp::sig::Vector &data, double *timestamp=nullptr) override
Get the device measurements.
@ return_value_error_method_failed
Method is deprecated.
A simple collection of objects that can be described and transmitted in a portable way.
Definition Bottle.h:64
A mini-server for performing network communication in the background.
A base class for nested structures that can be searched.
Definition Searchable.h:31
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
virtual std::string toString() const =0
Return a standard text representation of the content of the object.
virtual Bottle & findGroup(const std::string &key) const =0
Gets a list corresponding to a given keyword.
void update()
Set the timestamp to the current time, and increment the sequence number (wrapping to 0 if the sequen...
Definition Stamp.cpp:124
double getTime() const
Get the time stamp.
Definition Stamp.cpp:34
void resize(size_t size) override
Resize the vector.
Definition Vector.h:221
size_t size() const
Definition Vector.h:341
#define yCInfo(component,...)
#define yCError(component,...)
#define YARP_LOG_COMPONENT(name,...)
For streams capable of holding different kinds of content, check what they actually have.
An interface to the operating system, including Port based communication.
The main, catch-all namespace for YARP.
Definition dirs.h:16