24 #include <sensor_msgs/PointCloud2.h>
25 #include <sensor_msgs/PointField.h>
27 bool equals(
const sensor_msgs::PointCloud2& lhs,
const sensor_msgs::PointCloud2& rhs)
30 bool are_header_equals = (lhs.header.seq == rhs.header.seq) &&
31 (lhs.header.stamp.sec == rhs.header.stamp.sec) &&
32 (lhs.header.stamp.nsec == rhs.header.stamp.nsec) &&
33 (lhs.header.frame_id == rhs.header.frame_id);
34 if (!are_header_equals)
40 bool are_parameters_equals = (lhs.height == rhs.height) &&
41 (lhs.width == rhs.width) &&
42 (lhs.is_bigendian == rhs.is_bigendian) &&
43 (lhs.point_step == rhs.point_step) &&
44 (lhs.row_step == rhs.row_step) &&
45 (lhs.is_dense == rhs.is_dense);
46 if (!are_parameters_equals)
52 bool are_all_fields_equals =
true;
53 if (lhs.fields.size() == rhs.fields.size()){
54 for (uint i=0; i < lhs.fields.size(); i++)
56 if (!((lhs.fields[i].name == rhs.fields[i].name) &&
57 (lhs.fields[i].offset == rhs.fields[i].offset) &&
58 (lhs.fields[i].datatype == rhs.fields[i].datatype) &&
59 (lhs.fields[i].count == rhs.fields[i].count)))
61 are_all_fields_equals =
false;
68 are_all_fields_equals =
false;
70 if (!are_all_fields_equals)
76 bool is_data_equal = (lhs.data.size() == rhs.data.size()) &&
77 (memcmp(lhs.data.data(),rhs.data.data(),lhs.data.size())) == 0;
86 std::string
decode_chunk(
const sensor_msgs::PointCloud2& sensor_msg, uint index)
88 std::stringstream output_buffer;
90 size_t point_size = sensor_msg.row_step/sensor_msg.width;
92 const uint8_t* chunk_start_ptr =
reinterpret_cast<const uint8_t*
>(sensor_msg.data.data()) + (index*point_size);
94 output_buffer <<
"chunk#" << index <<
" : ";
96 for (uint i = 0; i < sensor_msg.fields.size(); i++)
98 uint offset = sensor_msg.fields[i].offset;
99 for (uint current_count = 0; current_count < sensor_msg.fields[i].count ; current_count++)
102 switch(sensor_msg.fields[i].datatype)
104 case sensor_msgs::PointField::INT8 :
107 memcpy(&val8, chunk_start_ptr+offset+(current_count*read_size), read_size);
108 output_buffer << sensor_msg.fields[i].name <<
" : " << val8 <<
"; ";
110 case sensor_msgs::PointField::UINT8 :
113 memcpy(&valu8, chunk_start_ptr+offset+(current_count*read_size), read_size);
114 output_buffer << sensor_msg.fields[i].name <<
" : " << valu8 <<
"; ";
116 case sensor_msgs::PointField::INT16 :
119 memcpy(&val16, chunk_start_ptr+offset+(current_count*read_size), read_size);
120 output_buffer << sensor_msg.fields[i].name <<
" : " << val16 <<
"; ";
122 case sensor_msgs::PointField::UINT16 :
125 memcpy(&valu16, chunk_start_ptr+offset+(current_count*read_size), read_size);
126 output_buffer << sensor_msg.fields[i].name <<
" : " << valu16 <<
"; ";
128 case sensor_msgs::PointField::INT32 :
131 memcpy(&val32, chunk_start_ptr+offset+(current_count*read_size), read_size);
132 output_buffer << sensor_msg.fields[i].name <<
" : " << val32 <<
"; ";
134 case sensor_msgs::PointField::UINT32 :
137 memcpy(&valu32, chunk_start_ptr+offset+(current_count*read_size), read_size);
138 output_buffer << sensor_msg.fields[i].name <<
" : " << valu32 <<
"; ";
140 case sensor_msgs::PointField::FLOAT32 :
143 memcpy(&valf32, chunk_start_ptr+offset+(current_count*read_size), read_size);
144 output_buffer << sensor_msg.fields[i].name <<
" : " << valf32 <<
"; ";
146 case sensor_msgs::PointField::FLOAT64 :
149 memcpy(&valf64, chunk_start_ptr+offset+(current_count*read_size), read_size);
150 output_buffer << sensor_msg.fields[i].name <<
" : " << valf64 <<
"; ";
155 return output_buffer.str();
160 const std::vector<uint8_t>& tested,
161 uint chunk_size, uint* out_index =
nullptr)
163 uint min_size = std::min(expected.size(),tested.size());
164 for (uint i = 0; i < min_size; i++)
166 if (expected[i]!=tested[i])
169 uint chunk_id = i / chunk_size;
170 uint chunk_start_index = chunk_id * chunk_size;
171 std::stringstream output_buffer;
172 output_buffer <<
"first mismatch at index " << i <<
" (chunk #" << chunk_id <<
") : ";
173 for (uint j = chunk_start_index; j < std::min(chunk_start_index+chunk_size, min_size); j++)
175 output_buffer << std::hex << static_cast<int>(expected[j]);
177 output_buffer <<
" | ";
178 for (uint j = chunk_start_index; j < std::min(chunk_start_index+chunk_size, min_size); j++)
180 output_buffer << std::hex << static_cast<int>(tested[j]);
182 if (out_index !=
nullptr)
184 *out_index = chunk_id;
186 return output_buffer.str();
189 if (out_index !=
nullptr)
197 const sensor_msgs::PointCloud2& tested,
198 bool locate_first_data_disparity =
false)
200 std::stringstream output_buffer;
203 if (expected.header.seq != tested.header.seq)
205 output_buffer <<
"header.seq are differents : expected : " << expected.header.seq
206 <<
"; got : " << tested.header.seq << std::endl;
208 if (expected.header.stamp.sec != tested.header.stamp.sec)
210 output_buffer <<
"header.stamp.sec are differents : expected : " << expected.header.stamp.sec
211 <<
"; got : " << tested.header.stamp.sec << std::endl;
213 if (expected.header.stamp.nsec != tested.header.stamp.nsec)
215 output_buffer <<
"header.stamp.nsec are differents : expected : " << expected.header.stamp.nsec
216 <<
"; got : " << tested.header.stamp.nsec << std::endl;
218 if (expected.header.frame_id != tested.header.frame_id)
220 output_buffer <<
"header.frame_id are differents : expected : " << expected.header.frame_id
221 <<
"; got : " << tested.header.frame_id << std::endl;
225 if (expected.height != tested.height)
227 output_buffer <<
"height are differents : expected : " << expected.height
228 <<
"; got : " << tested.height << std::endl;
230 if (expected.width != tested.width)
232 output_buffer <<
"width are differents : expected : " << expected.width <<
233 "; got : " << tested.width << std::endl;
235 if (expected.is_bigendian != tested.is_bigendian)
237 output_buffer <<
"is_bigendian are differents : expected : " << expected.is_bigendian
238 <<
"; got : " << tested.is_bigendian << std::endl;
240 if (expected.point_step != tested.point_step)
242 output_buffer <<
"point_step are differents : expected : " << expected.point_step
243 <<
"; got : " << tested.point_step << std::endl;
245 if (expected.row_step != tested.row_step)
247 output_buffer <<
"row_step are differents : expected : " << expected.row_step
248 <<
"; got : " << tested.row_step << std::endl;
250 if (expected.is_dense != tested.is_dense)
252 output_buffer <<
"is_dense are differents : expected : " << expected.is_dense
253 <<
"; got : " << tested.is_dense << std::endl;
257 if (expected.fields.size() != tested.fields.size())
259 output_buffer <<
"field sizes are differents : expected : " << expected.fields.size()
260 <<
"; got : " << tested.fields.size() << std::endl;
263 uint min_field_size = std::min(expected.fields.size(),tested.fields.size());
264 for (uint i=0; i < min_field_size; i++)
266 if (expected.fields[i].name != tested.fields[i].name)
268 output_buffer <<
"fields[" << i <<
"].name are differents : expected : "
269 << expected.fields[i].name <<
"; got : " << tested.fields[i].name << std::endl;
271 if (expected.fields[i].offset != tested.fields[i].offset)
273 output_buffer <<
"fields[" << i <<
"].offset are differents : expected : "
274 << expected.fields[i].offset <<
"; got : " << tested.fields[i].offset << std::endl;
276 if (expected.fields[i].datatype != tested.fields[i].datatype)
278 output_buffer <<
"fields[" << i <<
"].datatype are differents : expected : "
279 << expected.fields[i].datatype <<
"; got : " << tested.fields[i].datatype << std::endl;
281 if (expected.fields[i].count != tested.fields[i].count)
283 output_buffer <<
"fields[" << i <<
"].count are differents : expected : "
284 << expected.fields[i].count <<
"; got : " << tested.fields[i].count << std::endl;
289 if(expected.data.size() != tested.data.size())
291 output_buffer <<
"data sizes are differents : expected : " << expected.data.size()
292 <<
"; got : " << tested.data.size() << std::endl;
294 if (memcmp(expected.data.data(),tested.data.data(),expected.data.size()) != 0)
296 output_buffer <<
"data are differents";
297 if (locate_first_data_disparity)
299 uint point_size = expected.row_step/expected.width;
300 uint mismatch_index = 0;
301 output_buffer <<
" : " <<
get_first_mismatch(expected.data, tested.data, point_size, &mismatch_index);
302 output_buffer << std::endl <<
"expected : " <<
decode_chunk(expected, mismatch_index);
303 output_buffer << std::endl <<
" got : " <<
decode_chunk(tested, mismatch_index);
305 output_buffer << std::endl;
308 return output_buffer.str();
314 const sensor_msgs::PointCloud2& expected_no_ground,
315 const sensor_msgs::PointCloud2& tested_ground,
316 const sensor_msgs::PointCloud2& tested_no_ground,
317 uint* out_false_ground_count,
318 uint* out_false_no_ground_count)
320 uint point_size = expected_no_ground.row_step/expected_no_ground.width;
321 if (((expected_ground.data.size()%point_size) != 0) ||
322 ((expected_no_ground.data.size()%point_size) != 0) ||
323 ((tested_ground.data.size()%point_size) != 0) ||
324 ((tested_no_ground.data.size()%point_size) != 0))
329 uint expected_ground_point_count = expected_ground.data.size()/point_size;
330 uint expected_no_ground_point_count = expected_no_ground.data.size()/point_size;
331 uint tested_ground_point_count = tested_ground.data.size()/point_size;
332 uint tested_no_ground_point_count = tested_no_ground.data.size()/point_size;
334 uint tested_no_ground_index = 0;
335 uint expected_no_ground_index = 0;
337 *out_false_ground_count = 0;
338 *out_false_no_ground_count = 0;
340 bool all_mismatches_are_legit =
true;
342 while ((tested_no_ground_index < tested_no_ground_point_count) &&
343 (expected_no_ground_index < expected_no_ground_point_count))
348 is_equal = memcmp(tested_no_ground.data.data() + tested_no_ground_index*point_size,
349 expected_no_ground.data.data() + (expected_no_ground_index)*point_size,
351 tested_no_ground_index++;
352 expected_no_ground_index++;
353 }
while (is_equal && (tested_no_ground_index < tested_no_ground_point_count) &&
354 (expected_no_ground_index < expected_no_ground_point_count));
359 bool is_false_no_ground =
false;
360 for (uint i=0; i<expected_ground_point_count; i++)
362 if (0 == memcmp(tested_no_ground.data.data() + (tested_no_ground_index-1)*point_size,
363 expected_ground.data.data() + i*point_size,point_size))
365 is_false_no_ground =
true;
370 bool is_false_ground =
false;
371 for (uint i=0; i<tested_ground_point_count; i++)
373 if (0 == memcmp(expected_no_ground.data.data() + (expected_no_ground_index-1)*point_size,
374 tested_ground.data.data() + i*point_size,point_size))
376 is_false_ground =
true;
382 if (is_false_no_ground)
387 *out_false_ground_count += 1;
388 *out_false_no_ground_count += 1;
393 expected_no_ground_index--;
394 *out_false_no_ground_count += 1;
402 tested_no_ground_index--;
403 *out_false_ground_count += 1;
408 all_mismatches_are_legit =
false;
413 return all_mismatches_are_legit;