48 #include <sensor_msgs/PointCloud2.h> 50 #include <pcl/point_cloud.h> 51 #include <pcl/point_types.h> 92 void dump2csv(
const sensor_msgs::PointCloud2ConstPtr &cloud,
int x_offset,
int y_offset,
int z_offset)
95 char szFileName[255] = {0};
96 sprintf(szFileName,
"/tmp/cloud_dump_%04d.csv", cnt);
98 fout = fopen(szFileName,
"w");
102 fprintf(fout,
"%-8s;%-8s;%-8s;%-8s;%-8s;%-8s\n",
"X(col)",
"Y(Col)",
"X",
"Y",
"Z",
"Range");
103 for (i = 0; i < cloud->height; i++)
105 for (j = 0; j < cloud->width; j++)
107 float xRange,yRange,zRange;
109 memcpy(&xRange, &(cloud->data[x_offset]),
sizeof(
float));
110 memcpy(&yRange, &(cloud->data[y_offset]),
sizeof(
float));
111 memcpy(&zRange, &(cloud->data[z_offset]),
sizeof(
float));
112 range = sqrt(xRange*xRange + yRange*yRange + zRange*zRange);
113 fprintf(fout,
"%5d;%5d;", i, j);
114 fprintf(fout,
"%8.3f;%8.3f;%8.3f;%8.3f", xRange, yRange, zRange, range);
117 x_offset += cloud->point_step;
118 y_offset += cloud->point_step;
119 z_offset += cloud->point_step;
141 sensor_msgs::Image
msg;
142 sensor_msgs::Image msgVGA;
148 int conversionTask = 3;
149 float range_eps = 0.1;
152 int heightUsed = cloud->height;
161 for (
size_t d = 0;
d < cloud->fields.size(); ++
d)
163 if (cloud->fields[
d].name ==
"intensity")
165 rgb_index =
static_cast<int>(
d);
168 if (cloud->fields[
d].name ==
"x")
170 x_index =
static_cast<int>(
d);
173 if (cloud->fields[
d].name ==
"y")
175 y_index =
static_cast<int>(
d);
178 if (cloud->fields[
d].name ==
"z")
180 z_index =
static_cast<int>(
d);
193 throw std::runtime_error(
"No intensity entry!!");
199 int heightStretch = 5;
201 int imgChannelCnt = 0;
203 const int maxAllowedEncodings = 2;
204 bool encodeFlagArray[maxAllowedEncodings] = {0};
205 bool useHDFormat =
false;
206 if (conversionTask & 1)
208 encodeFlagArray[0] =
true;
211 if (conversionTask & 2)
213 encodeFlagArray[1] =
true;
217 if (cloud->width == 0 && heightUsed == 0)
219 throw std::runtime_error(
"Needs to be a dense like cloud!!");
223 msg.height = heightStretch * heightUsed * imgChannelCnt;
224 msg.width = cloud->width;
227 if (1080 > msg.height)
231 if (1920 > msg.width)
237 int rgb_offset = cloud->fields[rgb_index].offset;
238 int x_offset = cloud->fields[x_index].offset;
239 int y_offset = cloud->fields[y_index].offset;
240 int z_offset = cloud->fields[z_index].offset;
244 int point_step = cloud->point_step;
253 dump2csv(cloud, x_offset, y_offset, z_offset);
256 msg.encoding =
"bgr8";
257 msg.step =
static_cast<uint32_t
>(msg.width *
sizeof(uint8_t) * 3);
258 msg.data.resize(msg.step * msg.height);
261 int maxY = imgChannelCnt * heightStretch * heightUsed;
263 for (
size_t y = 0;
y < heightUsed;
y++)
265 for (
size_t x = 0;
x < cloud->width;
x++)
267 for (
int chIdx = 0; chIdx < imgChannelCnt; chIdx++)
271 for (
int j = 0; j < maxAllowedEncodings; j++)
273 if (encodeFlagArray[j])
275 if (chIdx == encodingCnt)
284 for (
int rowInner = 0; rowInner < heightStretch; rowInner++)
286 int rowTmp = (
y * heightStretch + rowInner);
287 rowTmp += encodingCnt * heightStretch * heightUsed;
289 int rowInnerIdx = maxY - (rowTmp) - 1;
291 xTmp = cloud->width - 1 -
x;
292 uint8_t *pixel = &(msg.data[rowInnerIdx * msg.step + xTmp * 3]);
293 uint8_t *pixelVGA = NULL;
300 memcpy(&xRange, &(cloud->data[x_offset]),
sizeof(
float));
301 memcpy(&yRange, &(cloud->data[y_offset]),
sizeof(
float));
302 memcpy(&zRange, &(cloud->data[z_offset]),
sizeof(
float));
303 range = sqrt(xRange * xRange + yRange * yRange + zRange * zRange);
304 memcpy(&intensity, &(cloud->data[rgb_offset]),
sizeof(
float));
305 if (intensity > 255.0)
313 unsigned char r, g, b;
314 unsigned char grey = 0;
317 grey = (
unsigned char) intensity;
325 bool setBlack =
false;
326 if (range < range_eps)
330 if (range < minRealRange)
332 range = minRealRange;
335 if (range > maxRealRange)
337 range = maxRealRange;
343 grey = (
unsigned char) range;
369 rgb_offset += point_step;
370 x_offset += point_step;
371 y_offset += point_step;
372 z_offset += point_step;
384 printf(
"sick_pcl_converter <input_pointcloud2-topic> <output_image-topic>");
390 bool dumpCsvFlag =
false;
400 std::string inputTopic = argv[1];
401 std::string outputTopic = argv[2];
402 ros::init(argc, argv,
"sick_pcl_converter");
409 nh.
getParam(
"dump_csv", dumpCsvFlag);
415 ROS_INFO(
"Dump to csv file for debugging enabled.\n Files will be dumped at /tmp ");
420 if (heatMap.length() > 0)
422 std::string heatMapFileName = path +
"/config/" + heatMap;
423 pal.
load(heatMapFileName);
426 ROS_INFO(
"Subscribing to %s and publishing images to %s\n", inputTopic.c_str(), outputTopic.c_str());
434 pub = nh.
advertise<sensor_msgs::Image>(outputTopic, 1);
ParamSettings paramSettings
void dump2csv(const sensor_msgs::PointCloud2ConstPtr &cloud, int x_offset, int y_offset, int z_offset)
void setDump2csv(bool dump2csv)
void publish(const boost::shared_ptr< M > &message) const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
TFSIMD_FORCE_INLINE const tfScalar & y() const
int load(std::string palettName)
ROSCPP_DECL void spin(Spinner &spinner)
unsigned char getRbgValue(unsigned char greyIdx, unsigned int channelIdx)
void cloud2image_cb(const sensor_msgs::PointCloud2ConstPtr &cloud)
Copy the RGB fields of a PCLPointCloud2 msg into pcl::PCLImage format.
TFSIMD_FORCE_INLINE const tfScalar & x() const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ROSLIB_DECL std::string getPath(const std::string &package_name)
bool getParam(const std::string &key, std::string &s) const
bool ignoreIntensityMissing
int main(int argc, char **argv)