39 if(cloud.data.empty())
44 int fieldStates[10] = {0};
45#if PCL_VERSION_COMPARE(>=, 1, 10, 0)
46 std::uint32_t fieldOffsets[10] = {0};
48 pcl::uint32_t fieldOffsets[10] = {0};
50 for(
unsigned int i=0; i<cloud.fields.size(); ++i)
52 if(cloud.fields[i].name.compare(
"x") == 0)
55 fieldOffsets[0] = cloud.fields[i].offset;
57 else if(cloud.fields[i].name.compare(
"y") == 0)
60 fieldOffsets[1] = cloud.fields[i].offset;
62 else if(cloud.fields[i].name.compare(
"z") == 0 && !is2D)
65 fieldOffsets[2] = cloud.fields[i].offset;
67 else if(cloud.fields[i].name.compare(
"normal_x") == 0)
70 fieldOffsets[3] = cloud.fields[i].offset;
72 else if(cloud.fields[i].name.compare(
"normal_y") == 0)
75 fieldOffsets[4] = cloud.fields[i].offset;
77 else if(cloud.fields[i].name.compare(
"normal_z") == 0)
80 fieldOffsets[5] = cloud.fields[i].offset;
82 else if(cloud.fields[i].name.compare(
"rgb") == 0 || cloud.fields[i].name.compare(
"rgba") == 0)
85 fieldOffsets[6] = cloud.fields[i].offset;
87 else if(cloud.fields[i].name.compare(
"intensity") == 0)
89 if(cloud.fields[i].datatype != pcl::PCLPointField::FLOAT32)
91 static bool warningShown =
false;
94 UWARN(
"The input scan cloud has an \"intensity\" field "
95 "but the datatype (%d) is not supported. Intensity will be ignored. "
96 "This message is only shown once.", cloud.fields[i].datatype);
103 fieldOffsets[7] = cloud.fields[i].offset;
105 else if(cloud.fields[i].name.compare(
"time") == 0)
107 if(cloud.fields[i].datatype != pcl::PCLPointField::FLOAT32)
109 static bool warningShown =
false;
112 UWARN(
"The input scan cloud has an \"time\" field "
113 "but the datatype (%d) is not supported. Time will be ignored. "
114 "This message is only shown once.", cloud.fields[i].datatype);
121 fieldOffsets[8] = cloud.fields[i].offset;
123 else if(cloud.fields[i].name.compare(
"ring") == 0)
125 if(cloud.fields[i].datatype != pcl::PCLPointField::UINT16)
127 static bool warningShown =
false;
130 UWARN(
"The input scan cloud has an \"ring\" field "
131 "but the datatype (%d) is not supported. Ring will be ignored. "
132 "This message is only shown once.", cloud.fields[i].datatype);
139 fieldOffsets[9] = cloud.fields[i].offset;
143 UDEBUG(
"Ignoring \"%s\" field", cloud.fields[i].name.c_str());
146 if(fieldStates[0]==0 || fieldStates[1]==0)
149 UERROR(
"Cloud has not corresponding fields to laser scan!");
153 bool hasNormals = fieldStates[3] || fieldStates[4] || fieldStates[5];
154 bool hasIntensity = fieldStates[7];
155 bool hasRGB = !hasIntensity&&fieldStates[6];
156 bool hasTime = hasIntensity&&fieldStates[8];
157 bool hasRing = hasIntensity&&fieldStates[9];
158 bool is3D = fieldStates[0] && fieldStates[1] && fieldStates[2];
161 int outputNormalOffset = 0;
164 if(hasNormals && hasIntensity)
167 outputNormalOffset = 4;
169 else if(hasNormals && !hasIntensity && !hasRGB)
172 outputNormalOffset = 3;
174 else if(hasNormals && hasRGB)
177 outputNormalOffset = 4;
179 else if(!hasNormals && hasIntensity)
181 if(hasTime && hasRing)
194 else if(!hasNormals && hasRGB)
205 if(hasNormals && hasIntensity)
208 outputNormalOffset = 3;
210 else if(hasNormals && !hasIntensity)
213 outputNormalOffset = 2;
215 else if(!hasNormals && hasIntensity)
225 UASSERT(cloud.data.size()/cloud.point_step == (uint32_t)cloud.height*cloud.width);
226 cv::Mat laserScan = cv::Mat(1, (
int)cloud.data.size()/cloud.point_step, CV_32FC(LaserScan::channels(format)));
232 transformRot = transform.
rotation();
235 UASSERT(cloud.height == 1 || cloud.row_step != 0);
236 for (uint32_t row = 0; row < (uint32_t)cloud.height; ++row)
238 const uint8_t* row_data = &cloud.data[row * cloud.row_step];
239 for (uint32_t col = 0; col < (uint32_t)cloud.width; ++col)
241 const uint8_t* msg_data = row_data + col * cloud.point_step;
243 float * ptr = laserScan.ptr<
float>(0, oi);
246 if(laserScan.channels() == 2)
248 ptr[0] = *(
float*)(msg_data + fieldOffsets[0]);
249 ptr[1] = *(
float*)(msg_data + fieldOffsets[1]);
252 else if(laserScan.channels() == 3)
254 ptr[0] = *(
float*)(msg_data + fieldOffsets[0]);
255 ptr[1] = *(
float*)(msg_data + fieldOffsets[1]);
258 ptr[2] = *(
float*)(msg_data + fieldOffsets[7]);
262 ptr[2] = *(
float*)(msg_data + fieldOffsets[2]);
266 else if(laserScan.channels() == 4)
268 ptr[0] = *(
float*)(msg_data + fieldOffsets[0]);
269 ptr[1] = *(
float*)(msg_data + fieldOffsets[1]);
270 ptr[2] = *(
float*)(msg_data + fieldOffsets[2]);
273 ptr[3] = *(
float*)(msg_data + fieldOffsets[7]);
277#if PCL_VERSION_COMPARE(>=, 1, 10, 0)
278 std::uint8_t b=*(msg_data + fieldOffsets[6]);
279 std::uint8_t g=*(msg_data + fieldOffsets[6]+1);
280 std::uint8_t r=*(msg_data + fieldOffsets[6]+2);
282 pcl::uint8_t b=*(msg_data + fieldOffsets[6]);
283 pcl::uint8_t g=*(msg_data + fieldOffsets[6]+1);
284 pcl::uint8_t r=*(msg_data + fieldOffsets[6]+2);
286 int * ptrInt = (
int*)ptr;
287 ptrInt[3] = int(b) | (int(g) << 8) | (
int(r) << 16);
291 else if(laserScan.channels() == 5)
293 ptr[0] = *(
float*)(msg_data + fieldOffsets[0]);
294 ptr[1] = *(
float*)(msg_data + fieldOffsets[1]);
297 ptr[2] = *(
float*)(msg_data + fieldOffsets[2]);
298 ptr[3] = *(
float*)(msg_data + fieldOffsets[7]);
299 ptr[4] = *(
float*)(msg_data + fieldOffsets[8]);
303 ptr[2] = *(
float*)(msg_data + fieldOffsets[3]);
304 ptr[3] = *(
float*)(msg_data + fieldOffsets[4]);
305 ptr[4] = *(
float*)(msg_data + fieldOffsets[5]);
309 else if(laserScan.channels() == 6)
311 ptr[0] = *(
float*)(msg_data + fieldOffsets[0]);
312 ptr[1] = *(
float*)(msg_data + fieldOffsets[1]);
315 ptr[2] = *(
float*)(msg_data + fieldOffsets[2]);
316 ptr[3] = *(
float*)(msg_data + fieldOffsets[7]);
317 ptr[4] = float(*(
unsigned short*)(msg_data + fieldOffsets[9]));
318 ptr[5] = *(
float*)(msg_data + fieldOffsets[8]);
324 ptr[2] = *(
float*)(msg_data + fieldOffsets[7]);
328 ptr[2] = *(
float*)(msg_data + fieldOffsets[2]);
330 ptr[3] = *(
float*)(msg_data + fieldOffsets[3]);
331 ptr[4] = *(
float*)(msg_data + fieldOffsets[4]);
332 ptr[5] = *(
float*)(msg_data + fieldOffsets[5]);
336 else if(laserScan.channels() == 7)
338 ptr[0] = *(
float*)(msg_data + fieldOffsets[0]);
339 ptr[1] = *(
float*)(msg_data + fieldOffsets[1]);
340 ptr[2] = *(
float*)(msg_data + fieldOffsets[2]);
343 ptr[3] = *(
float*)(msg_data + fieldOffsets[7]);
347#if PCL_VERSION_COMPARE(>=, 1, 10, 0)
348 std::uint8_t b=*(msg_data + fieldOffsets[6]);
349 std::uint8_t g=*(msg_data + fieldOffsets[6]+1);
350 std::uint8_t r=*(msg_data + fieldOffsets[6]+2);
352 pcl::uint8_t b=*(msg_data + fieldOffsets[6]);
353 pcl::uint8_t g=*(msg_data + fieldOffsets[6]+1);
354 pcl::uint8_t r=*(msg_data + fieldOffsets[6]+2);
356 int * ptrInt = (
int*)ptr;
357 ptrInt[3] = int(b) | (int(g) << 8) | (
int(r) << 16);
359 ptr[4] = *(
float*)(msg_data + fieldOffsets[3]);
360 ptr[5] = *(
float*)(msg_data + fieldOffsets[4]);
361 ptr[6] = *(
float*)(msg_data + fieldOffsets[5]);
366 UFATAL(
"Cannot handle as many channels (%d)!", laserScan.channels());
369 if(!filterNaNs || valid)
371 if(valid && transformValid)
382 pt =
util3d::transformPoint(cv::Point3f(ptr[outputNormalOffset], ptr[outputNormalOffset+1], ptr[outputNormalOffset+2]), transformRot);
383 ptr[outputNormalOffset] = pt.x;
384 ptr[outputNormalOffset+1] = pt.y;
385 ptr[outputNormalOffset+2] = pt.z;
397 return LaserScan(laserScan(cv::Range::all(), cv::Range(0,oi)), 0, 0, format);