19 #define _USE_MATH_DEFINES
41 #define DEG2RAD M_PI/180.0
45 #define RAD2DEG 180/M_PI
89 m_contains_data=
false;
99 size_t ros_size = b.
ranges.size();
100 if (ros_size != m_lastScan.scans.size())
102 m_lastScan.scans.resize (ros_size);
104 for (
size_t i = 0; i < ros_size; i++)
106 m_lastScan.scans[i] = b.
ranges[i];
108 getEnvelope(m_lastStamp);
109 m_contains_data=
true;
110 m_port_mutex.unlock();
117 while (m_contains_data==
false)
120 if (counter++ > 100) {
yDebug() <<
"Waiting for incoming data..."; counter=0;}
126 m_port_mutex.unlock();
134 m_info =
"LaserFromRosTopic device";
140 if (this->parseConfiguration(config) ==
false)
148 if (general_config.
check(
"input_topics_name"))
153 for (
size_t i = 0; i < portlist->
size(); i++)
154 m_port_names.push_back(portlist->
get(i).
asString());
158 m_port_names.push_back(
"/laserFromExternalPort:i");
161 for (
size_t i = 0; i < m_port_names.size(); i++)
164 m_input_ports.push_back(proc);
166 m_last_stamp.resize(m_port_names.size());
167 m_last_scan_data.resize(m_port_names.size());
170 if (general_config.
check(
"base_type"))
172 string bt = general_config.
find(
"base_type").
asString();
181 m_empty_laser_data = m_laser_data;
184 for (
size_t i = 0; i < m_empty_laser_data.size(); i++) m_empty_laser_data[i] = std::numeric_limits<double>::infinity();
188 for (
size_t i = 0; i < m_empty_laser_data.size(); i++) m_empty_laser_data[i] = std::nanf(
"");
192 for (
size_t i = 0; i < m_empty_laser_data.size(); i++) m_empty_laser_data[i] = 0;
200 if (general_config.
check(
"override"))
202 if (m_input_ports.size() != 1)
209 m_option_override_limits =
true;
214 if (config.
check(
"TRANSFORMS") && config.
check(
"TRANSFORM_CLIENT"))
220 if (src_frames_list->
size() != m_input_ports.size())
225 for (
size_t i = 0; i < src_frames_list->
size(); i++)
227 m_src_frame_id.push_back(src_frames_list->
get(i).
asString());
235 m_dst_frame_id = transforms_config.
find(
"dst_frame").
asString();
236 if (m_dst_frame_id==
"")
244 if (client_cfg_string==
"")
252 tcprop.
put(
"device",
"transformClient");
254 m_tc_driver.open(tcprop);
255 if (!m_tc_driver.isValid())
260 m_tc_driver.view(m_iTc);
270 for (
size_t i = 0; i < m_input_ports.size(); i++)
273 if (m_input_ports[i].topic(m_port_names[i]) ==
false)
278 m_input_ports[i].useCallback();
280 PeriodicThread::start();
282 yInfo(
"LaserFromRosTopic: Sensor ready");
288 PeriodicThread::stop();
290 for (
auto it=m_input_ports.begin(); it!= m_input_ports.end(); it++)
303 std::lock_guard<std::mutex> guard(m_mutex);
304 m_min_distance = min;
305 m_max_distance = max;
311 std::lock_guard<std::mutex> guard(m_mutex);
320 std::lock_guard<std::mutex> guard(m_mutex);
327 std::lock_guard<std::mutex> guard(m_mutex);
348 double t_off_rad = temp[2];
349 double x_off = m[0][3];
350 double y_off = m[1][3];
352 #ifdef DO_NOTHING_DEBUG
355 double t_off_deg = 0;
356 double t_off_rad = 0;
361 for (
size_t i = 0; i < scan_data.
scans.
size(); i++)
363 double distance = scan_data.
scans[i];
364 if (distance == std::numeric_limits<double>::infinity())
368 if (std::isnan(distance))
375 double angle_input_deg = (i * resolution) + scan_data.
angle_min;
376 double angle_input_rad = (angle_input_deg) *
DEG2RAD;
379 double Ay = (sin(angle_input_rad + t_off_rad) * distance);
380 double Ax = (cos(angle_input_rad + t_off_rad) * distance);
383 double By = Ay + y_off;
384 double Bx = Ax + x_off;
386 double angle_output_rad = atan2(By, Bx);
387 double angle_output_deg = angle_output_rad *
RAD2DEG;
391 if (angle_output_deg > m_max_angle) {
continue; }
392 if (angle_output_deg < m_min_angle) {
continue; }
395 int new_i = lrint ((angle_output_deg - m_min_angle) / m_resolution);
396 if (new_i ==
static_cast<int>(m_laser_data.size())) {new_i=0;}
399 yAssert (new_i <
static_cast<int>(m_laser_data.size()));
402 double newdistance = std::sqrt((Bx * Bx) + (By * By));
405 if (std::isnan(m_laser_data[new_i]))
407 m_laser_data[new_i] = newdistance;
409 else if (newdistance < m_laser_data[new_i])
411 m_laser_data[new_i] = newdistance;
422 std::lock_guard<std::mutex> guard(m_mutex);
423 m_laser_data = m_empty_laser_data;
425 size_t nports= m_input_ports.size();
428 m_input_ports[0].getLast(m_last_scan_data[0], m_last_stamp[0]);
429 size_t received_scans = m_last_scan_data[0].scans.size();
431 if (m_option_override_limits)
434 m_sensorsNum = received_scans;
435 m_max_angle = m_last_scan_data[0].angle_max;
436 m_min_angle = m_last_scan_data[0].angle_min;
437 m_max_distance = m_last_scan_data[0].range_max;
438 m_min_distance = m_last_scan_data[0].range_min;
439 m_resolution = received_scans / (m_max_angle - m_min_angle);
440 if (m_laser_data.size() != m_sensorsNum) m_laser_data.resize(m_sensorsNum);
445 for (
size_t elem = 0; elem < m_sensorsNum; elem++)
447 m_laser_data[elem] = m_last_scan_data[0].scans[elem];
453 bool frame_exists = m_iTc->getTransform(m_src_frame_id[0], m_dst_frame_id, m);
454 if (frame_exists ==
false)
458 calculate(m_last_scan_data[0], m);
463 for (
size_t i = 0; i < nports; i++)
466 bool frame_exists = m_iTc->getTransform(m_src_frame_id[i], m_dst_frame_id, m);
467 if (frame_exists ==
false)
471 m_input_ports[i].getLast(m_last_scan_data[i], m_last_stamp[i]);
472 calculate(m_last_scan_data[i], m);
476 applyLimitsOnLaserData();
double constrainAngle(double x)
const yarp::os::LogComponent & LASER_FROM_ROS_TOPIC()
bool close() override
Close the DeviceDriver.
bool setDistanceRange(double min, double max) override
set the device detection range.
bool open(yarp::os::Searchable &config) override
Open the DeviceDriver.
void calculate(yarp::dev::LaserScan2D scan, yarp::sig::Matrix m)
bool setHorizontalResolution(double step) override
get the angular step between two measurments (if available)
void run() override
Loop function.
bool setScanLimits(double min, double max) override
set the scan angular range.
bool threadInit() override
Initialization method.
void threadRelease() override
Release method.
bool setScanRate(double rate) override
set the scan rate (scans per seconds)
yarp::sig::Vector scans
the scan data, measured in [m].
double angle_min
first angle of the scan [deg]
double angle_max
last angle of the scan [deg]
A simple collection of objects that can be described and transmitted in a portable way.
size_type size() const
Gets the number of elements in the bottle.
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
std::string toString() const override
Gives a human-readable textual representation of the bottle.
A class for storing options and configuration information.
void fromString(const std::string &txt, bool wipe=true)
Interprets a string as a list of properties.
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
A base class for nested structures that can be searched.
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
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.
An abstraction for a time stamp and/or sequence number.
virtual Bottle * asList() const
Get list value.
virtual std::string asString() const
Get string value.
yarp::conf::float32_t range_min
yarp::conf::float32_t angle_min
std::vector< yarp::conf::float32_t > ranges
yarp::conf::float32_t range_max
yarp::conf::float32_t angle_max
const Matrix & eye()
Build an identity matrix, don't resize.
#define yCInfo(component,...)
#define yCError(component,...)
#define yCWarning(component,...)
#define yCDebug(component,...)
#define YARP_LOG_COMPONENT(name,...)
An interface for the device drivers.
yarp::sig::Vector dcm2rpy(const yarp::sig::Matrix &R)
Converts a dcm (direction cosine matrix) rotation matrix to roll-pitch-yaw angles (defined in Math....
double now()
Return the current time in seconds, relative to an arbitrary starting point.
void delay(double seconds)
Wait for a certain number of seconds.
An interface to the operating system, including Port based communication.