YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
RgbdToPointCloudSensor_nws_ros2.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2023 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
7
9#include <yarp/os/LogStream.h>
10
12
13#include <rclcpp/time.hpp>
14#include <sensor_msgs/image_encodings.hpp>
15#include <string>
16#include <vector>
17#include <Ros2Utils.h>
18
19using namespace std::chrono_literals;
20using namespace std;
21using namespace yarp::sig;
22using namespace yarp::dev;
23using namespace yarp::os;
24using namespace RGBDToPointCloudRos2Impl;
26
31
32
33// DeviceDriver
35{
36 yCDebug(RGBDTOPOINTCLOUDSENSOR_NWS_ROS2) << "Parameters are: " << config.toString();
37
38 if(!fromConfig(config)) {
39 yCError(RGBDTOPOINTCLOUDSENSOR_NWS_ROS2) << "Failed to open, check previous log for error messages.";
40 return false;
41 }
42
43 if(!initialize_ROS2(config)) {
44 yCError(RGBDTOPOINTCLOUDSENSOR_NWS_ROS2) << "Error initializing ROS topic";
45 return false;
46 }
47
48 return true;
49}
50
51
52bool RgbdToPointCloudSensor_nws_ros2::fromConfig(yarp::os::Searchable &config)
53{
54 parseParams(config);
56
57 return true;
58}
59
60
61bool RgbdToPointCloudSensor_nws_ros2::initialize_ROS2(yarp::os::Searchable &params)
62{
63
65 m_rosPublisher_pointCloud2 = m_node->create_publisher<sensor_msgs::msg::PointCloud2>(m_topic_name, 10);
66 return true;
67}
68
69
77
78
79// PeriodicThread
81{
82 if (m_sensor_p!=nullptr) {
83 static int i = 0;
84 switch (m_sensor_p->getSensorStatus()) {
86 if (!writeData()) {
87 yCError(RGBDTOPOINTCLOUDSENSOR_NWS_ROS2, "Image not captured.. check hardware configuration");
88 }
89 i = 0;
90 break;
92 if(i < 1000) {
93 if((i % 30) == 0) {
94 yCInfo(RGBDTOPOINTCLOUDSENSOR_NWS_ROS2) << "Device not ready, waiting...";
95 }
96 } else {
97 yCWarning(RGBDTOPOINTCLOUDSENSOR_NWS_ROS2) << "Device is taking too long to start..";
98 }
99 i++;
100 break;
101 default:
102 yCError(RGBDTOPOINTCLOUDSENSOR_NWS_ROS2, "Sensor returned error");
103 }
104 } else {
105 yCError(RGBDTOPOINTCLOUDSENSOR_NWS_ROS2, "Sensor interface is not valid");
106 }
107}
108
109
110bool RgbdToPointCloudSensor_nws_ros2::attach(yarp::dev::PolyDriver* poly)
111{
112 if(poly)
113 {
114 poly->view(m_sensor_p);
115 poly->view(m_fgCtrl);
116 }
117
118 if(m_sensor_p == nullptr)
119 {
120 yCError(RGBDTOPOINTCLOUDSENSOR_NWS_ROS2) << "Attached device has no valid IRGBDSensor interface.";
121 return false;
122 }
123
124 if(m_fgCtrl == nullptr)
125 {
126 yCWarning(RGBDTOPOINTCLOUDSENSOR_NWS_ROS2) << "Attached device has no valid IFrameGrabberControls interface.";
127 }
128
129 return PeriodicThread::start();
130}
131
132
134{
137
138 m_sensor_p = nullptr;
139 if (m_fgCtrl)
140 {
141 m_fgCtrl = nullptr;
142 }
143 return true;
144}
145
146bool RgbdToPointCloudSensor_nws_ros2::writeData()
147{
148 yarp::sig::FlexImage colorImage;
150 yarp::os::Stamp colorStamp;
151 yarp::os::Stamp depthStamp;
152
153 if (!m_sensor_p->getImages(colorImage, depthImage, &colorStamp, &depthStamp)) {
154 return false;
155 }
156
157 static Stamp oldColorStamp = Stamp(0, 0);
158 static Stamp oldDepthStamp = Stamp(0, 0);
160 bool rgb_data_ok = true;
161 bool depth_data_ok = true;
162 bool intrinsic_ok = false;
163
164 if ((colorStamp.getTime() - oldColorStamp.getTime()) <= 0) {
165 rgb_data_ok = false;
166 } else {
167 oldColorStamp = colorStamp;
168 }
169
170 if ((depthStamp.getTime() - oldDepthStamp.getTime()) <= 0) {
171 depth_data_ok = false;
172 } else {
173 oldDepthStamp = depthStamp;
174 }
176
177
178 // TBD: We should check here somehow if the timestamp was correctly updated and, if not, update it ourselves.
179 if (rgb_data_ok) {
180 if (depth_data_ok) {
181 if (intrinsic_ok) {
184 colorImagePixelRGB.setExternal(colorImage.getRawImage(), colorImage.width(), colorImage.height());
185 // create point cloud in yarp format
187 yarp::sig::PixelRgb>(depthImage,
191 sensor_msgs::msg::PointCloud2 pc2Ros;
192
193 // filling ros header
194 pc2Ros.header.frame_id = m_frame_id;
195
196 //pc2Ros.header.stamp.sec = depthStamp.;
197 pc2Ros.header.stamp.sec = int(depthStamp.getTime());
198 pc2Ros.header.stamp.nanosec = int(1000000000UL * (depthStamp.getTime() - int(depthStamp.getTime())));
199
200 // filling ros point field
201 pc2Ros.fields.push_back(sensor_msgs::msg::PointField());
202 pc2Ros.fields.push_back(sensor_msgs::msg::PointField());
203 pc2Ros.fields.push_back(sensor_msgs::msg::PointField());
204 pc2Ros.fields.push_back(sensor_msgs::msg::PointField());
205 pc2Ros.fields[0].name = "x";
206 pc2Ros.fields[0].offset = 0;
207 pc2Ros.fields[0].datatype = 7;
208 pc2Ros.fields[0].count = 1;
209 pc2Ros.fields[1].name = "y";
210 pc2Ros.fields[1].offset = 4;
211 pc2Ros.fields[1].datatype = 7;
212 pc2Ros.fields[1].count = 1;
213 pc2Ros.fields[2].name = "z";
214 pc2Ros.fields[2].offset = 8;
215 pc2Ros.fields[2].datatype = 7;
216 pc2Ros.fields[2].count = 1;
217 pc2Ros.fields[3].name = "rgb";
218 pc2Ros.fields[3].offset = 16;
219 pc2Ros.fields[3].datatype = 7;
220 pc2Ros.fields[3].count = 1;
221
222 std::vector<unsigned char> vec(yarpCloud.getRawData(), yarpCloud.getRawData() + yarpCloud.dataSizeBytes());
223 pc2Ros.data = vec;
224 pc2Ros.width = yarpCloud.width() * yarpCloud.height();
225 pc2Ros.height = 1;
226 pc2Ros.is_dense = yarpCloud.isDense();
227
228 pc2Ros.point_step = sizeof(yarp::sig::DataXYZRGBA);
229 pc2Ros.row_step = static_cast<std::uint32_t>(sizeof(yarp::sig::DataXYZRGBA) * pc2Ros.width);
230 m_rosPublisher_pointCloud2->publish(pc2Ros);
231 }
232 }
233 }
234
235 nodeSeq++;
236
237 return true;
238}
yarp::sig::ImageOf< yarp::sig::PixelFloat > depthImage
const yarp::os::LogComponent & RGBDTOPOINTCLOUDSENSOR_NWS_ROS2()
static rclcpp::Node::SharedPtr createNode(std::string name)
Definition Ros2Utils.cpp:9
bool parseParams(const yarp::os::Searchable &config) override
Parse the DeviceDriver parameters.
bool close() override
Close the DeviceDriver.
bool detach() override
Detach the object (you must have first called attach).
bool open(yarp::os::Searchable &config) override
Open the DeviceDriver.
bool view(T *&x)
Get an interface to the device driver.
bool getRgbIntrinsicParam(yarp::os::Property &intrinsic) override=0
Get the intrinsic parameters of the rgb camera.
virtual bool getImages(yarp::sig::FlexImage &colorFrame, yarp::sig::ImageOf< yarp::sig::PixelFloat > &depthFrame, yarp::os::Stamp *colorStamp=nullptr, yarp::os::Stamp *depthStamp=nullptr)=0
Get the both the color and depth frame in a single call.
virtual RGBDSensor_status getSensorStatus()=0
Get the surrent status of the sensor, using enum type.
A container for a device driver.
Definition PolyDriver.h:23
bool detachAll() final
Detach the object (you must have first called attach).
A mini-server for performing network communication in the background.
@ TraceType
Definition Log.h:92
An abstraction for a periodic thread.
bool setPeriod(double period)
Set the (new) period of the thread.
bool isRunning() const
Returns true when the thread is started, false otherwise.
bool start()
Call this to start the thread.
void stop()
Call this to stop the thread, this call blocks until the thread is terminated (and releaseThread() ca...
A class for storing options and configuration information.
Definition Property.h:33
A base class for nested structures that can be searched.
Definition Searchable.h:31
virtual std::string toString() const =0
Return a standard text representation of the content of the object.
An abstraction for a time stamp and/or sequence number.
Definition Stamp.h:21
double getTime() const
Get the time stamp.
Definition Stamp.cpp:34
Image class with user control of representation details.
Definition Image.h:363
Typed image class.
Definition Image.h:605
size_t width() const
Gets width of image in pixels.
Definition Image.h:171
unsigned char * getRawImage() const
Access to the internal image buffer.
Definition Image.cpp:479
size_t height() const
Gets height of image in pixels.
Definition Image.h:177
The PointCloud class.
Definition PointCloud.h:21
#define yCInfo(component,...)
#define yCError(component,...)
#define yCTrace(component,...)
#define yCWarning(component,...)
#define yCDebug(component,...)
#define YARP_LOG_COMPONENT(name,...)
STL namespace.
For streams capable of holding different kinds of content, check what they actually have.
Definition jointData.cpp:13
An interface to the operating system, including Port based communication.
yarp::sig::PointCloud< T1 > depthRgbToPC(const yarp::sig::ImageOf< yarp::sig::PixelFloat > &depth, const yarp::sig::ImageOf< T2 > &color, const yarp::sig::IntrinsicParams &intrinsic, const yarp::sig::utils::OrganizationType organizationType=yarp::sig::utils::OrganizationType::Organized, size_t step_x=1, size_t step_y=1, const std::string &output_order="+X+Y+Z")
depthRgbToPC, compute the colored PointCloud given depth image, color image and the intrinsic paramet...
The main, catch-all namespace for YARP.
Definition dirs.h:16
The IntrinsicParams struct to handle the intrinsic parameter of cameras(RGB and RGBD either).