19 #define _USE_MATH_DEFINES
43 #define DEG2RAD M_PI/180.0
100 rosPC_data.
fields.resize(3);
101 rosPC_data.
fields[0].name =
"x";
102 rosPC_data.
fields[0].offset = 0;
103 rosPC_data.
fields[0].datatype = 7;
104 rosPC_data.
fields[0].count = 1;
106 rosPC_data.
fields[1].name =
"y";
107 rosPC_data.
fields[1].offset = 4;
108 rosPC_data.
fields[1].datatype = 7;
109 rosPC_data.
fields[1].count = 1;
111 rosPC_data.
fields[2].name =
"z";
112 rosPC_data.
fields[2].offset = 8;
113 rosPC_data.
fields[2].datatype = 7;
114 rosPC_data.
fields[2].count = 1;
116 #if defined(YARP_BIG_ENDIAN)
118 #elif defined(YARP_LITTLE_ENDIAN)
121 #error "Cannot detect endianness"
138 unsigned char* rpointer = rosPC_data.
data.data();
143 for (; elem<pc.
size()*3*4; elem++)
148 if (elem%12==0) { ypointer+=4; yelem+=4;}
161 m_info =
"LaserFromPointCloud device";
167 m_min_distance = 0.1;
168 m_max_distance = 5.0;
169 m_floor_height = 0.1;
170 m_pointcloud_max_distance = 10.0;
171 m_ceiling_height = 2;
172 m_publish_ros_pc =
false;
176 m_laser_data.resize(m_sensorsNum, 0.0);
183 m_transform_mtrx(4,4); m_transform_mtrx.eye();
186 m_ground_frame_id =
"/ground_frame";
187 m_camera_frame_id =
"/depth_camera_frame";
189 if (config.
check(
"publish_ROS_pointcloud"))
191 m_publish_ros_pc=
true;
195 bool bpcr = config.
check(
"POINTCLOUD_QUALITY");
199 if (pointcloud_quality_config.
check(
"x_step")) { m_pc_stepx = pointcloud_quality_config.
find(
"x_step").
asFloat64(); }
200 if (pointcloud_quality_config.
check(
"y_step")) { m_pc_stepy = pointcloud_quality_config.
find(
"y_step").
asFloat64(); }
204 bool bpc = config.
check(
"Z_CLIPPING_PLANES");
208 if (pointcloud_clip_config.
check(
"floor_height")) {m_floor_height = pointcloud_clip_config.
find(
"floor_height").
asFloat64();}
209 if (pointcloud_clip_config.
check(
"ceiling_height")) {m_ceiling_height=pointcloud_clip_config.
find(
"ceiling_height").
asFloat64();}
210 if (pointcloud_clip_config.
check(
"max_distance")) { m_pointcloud_max_distance = pointcloud_clip_config.
find(
"max_distance").
asFloat64(); }
211 if (pointcloud_clip_config.
check(
"ground_frame_id")) {m_ground_frame_id = pointcloud_clip_config.
find(
"ground_frame_id").
asString();}
212 if (pointcloud_clip_config.
check(
"camera_frame_id")) {m_camera_frame_id = pointcloud_clip_config.
find(
"camera_frame_id").
asString();}
214 yCInfo(
LASER_FROM_POINTCLOUD) <<
"Z clipping planes (floor,ceiling) have been set to ("<< m_floor_height <<
","<< m_ceiling_height <<
")";
216 if (this->parseConfiguration(config) ==
false)
224 if(!config.
check(
"TRANSFORM_CLIENT"))
230 tcprop.
put(
"device",
"transformClient");
232 m_tc_driver.open(tcprop);
233 if (!m_tc_driver.isValid())
238 m_tc_driver.view(m_iTc);
249 if(!config.
check(
"RGBD_SENSOR_CLIENT"))
255 prop.
put(
"device",
"RGBDSensorClient");
258 m_rgbd_driver.open(prop);
259 if (!m_rgbd_driver.isValid())
264 m_rgbd_driver.view(m_iRGBD);
273 m_depth_width = m_iRGBD->getRgbWidth();
274 m_depth_height = m_iRGBD->getRgbHeight();
275 bool propintr = m_iRGBD->getDepthIntrinsicParam(m_propIntrinsics);
278 m_intrinsics.fromProperty(m_propIntrinsics);
280 PeriodicThread::start();
284 if (m_publish_ros_pc)
294 PeriodicThread::stop();
296 if(m_rgbd_driver.isValid())
297 m_rgbd_driver.close();
299 if(m_tc_driver.isValid())
308 std::lock_guard<std::mutex> guard(m_mutex);
309 m_min_distance = min;
310 m_max_distance = max;
317 std::lock_guard<std::mutex> guard(m_mutex);
324 std::lock_guard<std::mutex> guard(m_mutex);
331 std::lock_guard<std::mutex> guard(m_mutex);
349 for (
size_t i=0; i<pc.
size(); i++)
351 auto v1 = pc(i).toVector4();
368 bool depth_ok = m_iRGBD->getDepthImage(m_depth_image);
369 if (depth_ok ==
false)
375 if (m_depth_image.getRawImage()==
nullptr)
381 if (m_depth_image.width() != m_depth_width ||
382 m_depth_image.height() != m_depth_height)
384 yCDebug(
LASER_FROM_POINTCLOUD)<<
"invalid image size: (" << m_depth_image.width() <<
" " << m_depth_image.height() <<
") vs (" << m_depth_width <<
" " << m_depth_height <<
")" ;
388 const double myinf =std::numeric_limits<double>::infinity();
389 const double mynan =std::nan(
"");
411 bool frame_exists = m_iTc->getTransform(m_camera_frame_id,m_ground_frame_id, m_transform_mtrx);
412 if (frame_exists==
false)
424 left[0] = (0 - m_intrinsics.principalPointX)/m_intrinsics.focalLengthX*1000;
425 left[1] = (0 - m_intrinsics.principalPointY)/m_intrinsics.focalLengthY*1000;
430 right[0] = (m_depth_image.width() - m_intrinsics.principalPointX)/m_intrinsics.focalLengthX*1000;
431 right[1] = (0 - m_intrinsics.principalPointY)/m_intrinsics.focalLengthY*1000;
439 left = m_transform_mtrx * left;
440 right = m_transform_mtrx * right;
444 data_left.
get_polar(left_dist, left_theta);
448 data_right.
get_polar(right_dist, right_theta);
450 bool left_elem_neg = 0;
451 bool right_elem_neg = 0;
453 left_theta=left_theta*180/
M_PI;
454 right_theta=right_theta*180/
M_PI;
461 else if (left_theta>360) left_theta-=360;
462 size_t left_elem= left_theta/m_resolution;
469 else if (right_theta>360) right_theta-=360;
470 size_t right_elem= right_theta/m_resolution;
473 std::lock_guard<std::mutex> guard(m_mutex);
478 for (
auto it= m_laser_data.begin(); it!=m_laser_data.end(); it++)
483 if ((!left_elem_neg) && (right_elem_neg))
485 for (
size_t i=0; i<left_elem; i++)
487 m_laser_data[i] = myinf;
489 for (
size_t i=right_elem; i<m_sensorsNum; i++)
491 m_laser_data[i] = myinf;
496 for (
size_t i=right_elem; i<left_elem; i++)
498 m_laser_data[i] = myinf;
504 for (
size_t i=0; i<pc.
size(); i++)
515 if (vec[2]>m_floor_height && vec[2]<m_ceiling_height &&
516 vec[0]<m_pointcloud_max_distance)
532 theta=theta*180/
M_PI;
533 if (theta<0) theta+=360;
534 else if (theta>360) theta-=360;
535 size_t elem= theta/m_resolution;
536 if (elem>=m_laser_data.size())
546 if (distance<m_laser_data[elem])
548 m_laser_data[elem]=distance;
558 applyLimitsOnLaserData();
void run() override
Loop function.
bool setScanRate(double rate) override
set the scan rate (scans per seconds)
bool setDistanceRange(double min, double max) override
set the device detection range.
bool close() override
Close the DeviceDriver.
bool setHorizontalResolution(double step) override
get the angular step between two measurments (if available)
void threadRelease() override
Release method.
bool setScanLimits(double min, double max) override
set the scan angular range.
bool open(yarp::os::Searchable &config) override
Open the DeviceDriver.
bool threadInit() override
Initialization method.
void set_cartesian(const double x, const double y)
void get_polar(double &rho, double &theta)
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 port specialized for publishing data of a constant type on a topic.
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.
virtual yarp::conf::float64_t asFloat64() const
Get 64-bit floating point value.
virtual std::string asString() const
Get string value.
yarp::rosmsg::std_msgs::Header header
std::vector< std::uint8_t > data
std::vector< yarp::rosmsg::sensor_msgs::PointField > fields
virtual size_t width() const
virtual size_t height() const
const char * getRawData() const override
Get the pointer to the data.
size_t size() const override
void ros_compute_and_send_pc(const yarp::sig::PointCloud< yarp::sig::DataXYZ > &pc, string frame_id)
const yarp::os::LogComponent & LASER_FROM_POINTCLOUD()
yarp::os::Publisher< yarp::rosmsg::sensor_msgs::PointCloud2 > * pointCloud_outTopic
void rotate_pc(yarp::sig::PointCloud< yarp::sig::DataXYZ > &pc, const yarp::sig::Matrix &m)
#define yCInfo(component,...)
#define yCError(component,...)
#define yCWarning(component,...)
#define yCDebug(component,...)
#define YARP_LOG_COMPONENT(name,...)
yarp::rosmsg::sensor_msgs::PointCloud2 PointCloud2
yarp::sig::Matrix rpy2dcm(const yarp::sig::Vector &rpy)
Converts roll-pitch-yaw angles in the corresponding dcm (direction cosine matrix) rotation matrix (de...
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.
yarp::sig::PointCloud< yarp::sig::DataXYZ > depthToPC(const yarp::sig::ImageOf< yarp::sig::PixelFloat > &depth, const yarp::sig::IntrinsicParams &intrinsic)
depthToPC, compute the PointCloud given depth image and the intrinsic parameters of the camera.
The main, catch-all namespace for YARP.