42 #include <sensor_msgs/LaserScan.h> 43 #include <sensor_msgs/PointCloud2.h> 44 #include <sensor_msgs/PointField.h> 45 #include <visualization_msgs/Marker.h> 46 #include <visualization_msgs/MarkerArray.h> 64 #include <find_moving_objects/MovingObject.h> 65 #include <find_moving_objects/MovingObjectArray.h> 169 os <<
"Bank Arguments:" << std::endl <<
170 " ema_alpha = " << ba.
ema_alpha << std::endl <<
173 " angle_min = " << ba.
angle_min << std::endl <<
174 " angle_max = " << ba.
angle_max << std::endl <<
182 " object_threshold_bank_tracking_max_delta_distance = " <<
186 " publish_ema = " << ba.
publish_ema << std::endl <<
199 " topic_ema = " << ba.
topic_ema << std::endl <<
205 " map_frame = " << ba.
map_frame << std::endl <<
206 " fixed_frame = " << ba.
fixed_frame << std::endl <<
207 " base_frame = " << ba.
base_frame << std::endl <<
220 os <<
"Private Bank Arguments:" << std::endl <<
224 " scan_time = " << ba.
scan_time << std::endl <<
225 " range_min = " << ba.
range_min << std::endl <<
226 " range_max = " << ba.
range_max << std::endl <<
250 bank_is_initialized =
false;
251 bank_is_filled =
false;
254 volatile uint32_t dummy = 0x01234567;
255 machine_is_little_endian = (*((uint8_t*)(&dummy))) == 0x67;
270 for (
int i=0; i<bank_argument.nr_scans_in_bank; ++i)
272 free(bank_ranges_ema[i]);
274 free(bank_ranges_ema);
285 "The EMA weighting decrease coefficient must be a value in [0,1].");
288 "There must be at least 2 messages in the bank. Otherwise, velocities cannot be calculated.");
291 "There must be at least 1 point per scan.");
294 "Angle interval cannot be larger than 2*PI (360 degrees).");
297 "Cannot be negative.");
300 "An object must consist of at least 1 point.");
303 "Cannot be negative.");
306 "Cannot be negative.");
309 "Cannot be negative.");
312 "Cannot be negative or larger than 1.0.");
326 "If publishing velocity arrows, then a name space for them must be given.");
329 "If publishing delta position lines, then a name space for them must be given.");
332 "If publishing width lines, then a name space for them must be given.");
335 "If publishing MovingObjectArray messages, then a topic for that must be given.");
338 "If publishing object points via LaserScan visualization messages, " 339 "then a topic for that must be given.");
342 "If publishing the closest point of each object via LaserScan visualization messages, " 343 "then a topic for that must be given.");
346 "If publishing the velocity of each object via MarkerArray visualization messages, " 347 "then a topic for that must be given.");
350 "If publishing the delta position of each object via MarkerArray visualization messages, " 351 "then a topic for that must be given.");
354 "If publishing the width of each object via MarkerArray visualization messages, " 355 "then a topic for that must be given.");
358 "Publish buffer size must be at least 1.");
361 "Please specify map frame.");
364 "Please specify fixed frame.");
367 "Please specify base frame.");
389 "Please specify a field name for x coordinates, or do not alter the default value.");
392 "Please specify a field name for y coordinates, or do not alter the default value.");
395 "Please specify a field name for z coordinates, or do not alter the default value.");
398 "Cannot be negative.");
401 "Invalid thresholds.");
410 if (bank_is_initialized)
415 bank_argument.
check();
418 bank_index_newest = -1;
422 node->advertise<sensor_msgs::LaserScan>(bank_argument.
topic_ema,
424 pub_objects_closest_point_markers =
427 pub_objects_velocity_arrows =
430 pub_objects_delta_position_lines =
433 pub_objects_width_lines =
437 node->advertise<MovingObjectArray>(bank_argument.
topic_objects,
441 this->bank_argument = bank_argument;
442 this->bank_argument.
sensor_is_360_degrees = fabsf(bank_argument.angle_max - bank_argument.angle_min - TWO_PI) <=
443 2.0 * bank_argument.angle_increment;
445 bank_stamp = (
double *) malloc(bank_argument.nr_scans_in_bank *
sizeof(
double));
446 bank_ranges_ema = (
float **) malloc(bank_argument.nr_scans_in_bank *
sizeof(
float*));
447 ROS_ASSERT_MSG(bank_ranges_ema != NULL,
"Could not allocate buffer space for messages.");
448 for (
unsigned int i=0; i<bank_argument.nr_scans_in_bank; ++i)
450 bank_ranges_ema[i] = (
float *) malloc(bank_argument.points_per_scan *
sizeof(
float));
451 ROS_ASSERT_MSG(bank_ranges_ema[i] != NULL,
"Could not allocate buffer space message %d.", i);
456 if (bank_argument.publish_ema)
458 msg_ema.header.frame_id = bank_argument.sensor_frame;
459 msg_ema.angle_min = bank_argument.angle_min;
460 msg_ema.angle_max = bank_argument.angle_max;
461 msg_ema.angle_increment = bank_argument.angle_increment;
462 msg_ema.time_increment = bank_argument.time_increment;
463 msg_ema.scan_time = bank_argument.scan_time;
464 msg_ema.range_min = bank_argument.range_min;
465 msg_ema.range_max = bank_argument.range_max;
466 msg_ema.ranges.resize(bank_argument.points_per_scan);
467 msg_ema.intensities.resize(bank_argument.points_per_scan);
468 bzero(&msg_ema.intensities[0], bank_argument.points_per_scan *
sizeof(
float));
471 if (bank_argument.publish_objects_velocity_arrows)
473 if (bank_argument.velocity_arrows_use_sensor_frame)
475 msg_objects_velocity_arrow.header.frame_id = bank_argument.sensor_frame;
477 else if (bank_argument.velocity_arrows_use_base_frame)
479 msg_objects_velocity_arrow.header.frame_id = bank_argument.base_frame;
481 else if (bank_argument.velocity_arrows_use_fixed_frame)
483 msg_objects_velocity_arrow.header.frame_id = bank_argument.fixed_frame;
487 msg_objects_velocity_arrow.header.frame_id = bank_argument.map_frame;
489 msg_objects_velocity_arrow.ns = bank_argument.velocity_arrow_ns;
490 msg_objects_velocity_arrow.type = visualization_msgs::Marker::ARROW;
491 msg_objects_velocity_arrow.action = visualization_msgs::Marker::ADD;
498 msg_objects_velocity_arrow.pose.orientation.w = 1.0;
499 msg_objects_velocity_arrow.scale.x = 0.05;
500 msg_objects_velocity_arrow.scale.y = 0.1;
505 msg_objects_velocity_arrow.color.a = 1.0;
507 msg_objects_velocity_arrow.frame_locked =
true;
508 msg_objects_velocity_arrow.points.resize(2);
513 if (bank_argument.publish_objects_delta_position_lines)
515 msg_objects_delta_position_line.header.frame_id = bank_argument.sensor_frame;
516 msg_objects_delta_position_line.ns = bank_argument.delta_position_line_ns;
517 msg_objects_delta_position_line.type = visualization_msgs::Marker::LINE_STRIP;
518 msg_objects_delta_position_line.action = visualization_msgs::Marker::ADD;
525 msg_objects_delta_position_line.pose.orientation.w = 1.0;
526 msg_objects_delta_position_line.scale.x = 0.04;
531 msg_objects_delta_position_line.color.b = 1.0;
532 msg_objects_delta_position_line.color.a = 1.0;
533 msg_objects_delta_position_line.lifetime =
ros::Duration(0.4);
534 msg_objects_delta_position_line.frame_locked =
true;
535 msg_objects_delta_position_line.points.resize(2);
540 if (bank_argument.publish_objects_width_lines)
542 msg_objects_width_line.header.frame_id = bank_argument.sensor_frame;
543 msg_objects_width_line.ns = bank_argument.width_line_ns;
544 msg_objects_width_line.type = visualization_msgs::Marker::LINE_STRIP;
545 msg_objects_width_line.action = visualization_msgs::Marker::ADD;
552 msg_objects_width_line.pose.orientation.w = 1.0;
553 msg_objects_width_line.scale.x = 0.02;
557 msg_objects_width_line.color.g = 1.0;
559 msg_objects_width_line.color.a = 1.0;
561 msg_objects_width_line.frame_locked =
true;
562 msg_objects_width_line.points.resize(2);
567 if (bank_argument.publish_objects_closest_point_markers)
569 msg_objects_closest_point_markers.header.frame_id = bank_argument.sensor_frame;
570 msg_objects_closest_point_markers.angle_min = bank_argument.angle_min;
571 msg_objects_closest_point_markers.angle_max = bank_argument.angle_max;
572 msg_objects_closest_point_markers.angle_increment = bank_argument.angle_increment;
573 msg_objects_closest_point_markers.time_increment = bank_argument.time_increment;
574 msg_objects_closest_point_markers.scan_time = bank_argument.scan_time;
575 msg_objects_closest_point_markers.range_min = bank_argument.range_min;
576 msg_objects_closest_point_markers.range_max = bank_argument.range_max;
577 msg_objects_closest_point_markers.intensities.resize(bank_argument.points_per_scan);
578 msg_objects_closest_point_markers.ranges.resize(bank_argument.points_per_scan);
579 for (
unsigned int i=0; i<bank_argument.points_per_scan; ++i)
581 msg_objects_closest_point_markers.ranges[i] = msg_objects_closest_point_markers.range_max + 10.0;
582 msg_objects_closest_point_markers.intensities[i] = 0.0;
587 bank_ranges_bytes =
sizeof(float) * bank_argument.points_per_scan;
592 bank_is_initialized =
true;
602 const unsigned int object_width_in_points,
603 const int current_level,
604 const unsigned int levels_searched,
605 const unsigned int index_mean,
606 const unsigned int consecutive_failures_to_find_object,
607 const unsigned int threshold_consecutive_failures_to_find_object,
609 int * index_mean_old,
611 float * range_sum_old,
612 float * range_at_min_index_old,
613 float * range_at_max_index_old)
616 if (levels_searched == bank_argument.nr_scans_in_bank)
622 int left = index_mean;
623 float prev_range = bank_ranges_ema[current_level][index_mean];
624 float range_sum = prev_range;
625 int right_upper_limit_out_of_bounds = bank_argument.points_per_scan;
626 unsigned int width_in_points = 1;
629 if (prev_range < range_min ||
630 range_max < prev_range)
633 *index_mean_old = -1;
636 *range_at_min_index_old = 0;
637 *range_at_max_index_old = 0;
642 bool stopped =
false;
643 for (
int i=index_mean-1; 0<=i; --i)
646 const float range = bank_ranges_ema[current_level][i];
647 if (range_min <= range &&
648 range <= range_max &&
649 fabsf(range - prev_range) <= bank_argument.object_threshold_edge_max_delta_range)
665 for (
int i=bank_argument.points_per_scan-1; index_mean<i; --i)
668 const float range = bank_ranges_ema[current_level][i];
669 if (range_min <= range &&
670 range <= range_max &&
671 fabsf(range - prev_range) <= bank_argument.object_threshold_edge_max_delta_range)
676 right_upper_limit_out_of_bounds--;
686 *range_at_min_index_old = prev_range;
690 int right = index_mean;
691 prev_range = bank_ranges_ema[current_level][index_mean];
692 for (
int i=index_mean+1; i<right_upper_limit_out_of_bounds; ++i)
695 const float range = bank_ranges_ema[current_level][i];
696 if (range_min <= range &&
697 range <= range_max &&
698 fabsf(range - prev_range) <= bank_argument.object_threshold_edge_max_delta_range)
712 if (!stopped && right_upper_limit_out_of_bounds == bank_argument.points_per_scan)
715 for (
int i=0; i<left; ++i)
718 const float range = bank_ranges_ema[current_level][i];
719 if (range_min <= range &&
720 range <= range_max &&
721 fabsf(range - prev_range) <= bank_argument.object_threshold_edge_max_delta_range)
735 *range_at_max_index_old = prev_range;
738 unsigned int misses = consecutive_failures_to_find_object;
739 if (width_in_points < bank_argument.object_threshold_min_nr_points ||
740 bank_argument.object_threshold_max_delta_width_in_points <
abs(width_in_points - object_width_in_points) ||
741 bank_argument.object_threshold_bank_tracking_max_delta_distance <
742 fabs(range_sum / width_in_points - *range_sum_old / object_width_in_points))
747 if (threshold_consecutive_failures_to_find_object < misses)
751 *index_mean_old = -1;
754 *range_at_min_index_old = 0;
755 *range_at_max_index_old = 0;
767 *index_min_old = left;
768 *index_mean_old = (left + (width_in_points-1) / 2) % bank_argument.points_per_scan;
769 *index_max_old = right;
770 *range_sum_old = range_sum;
773 getOldIndices(range_min,
776 (current_level - 1) < 0 ? bank_argument.nr_scans_in_bank - 1 : current_level - 1,
780 threshold_consecutive_failures_to_find_object,
785 range_at_min_index_old,
786 range_at_max_index_old);
926 ROS_WARN(
"Bank is not filled yet-cannot report objects!");
931 MovingObjectArray moa;
934 MovingObjectArray moa_old_positions;
937 unsigned int nr_objects_found = 0;
938 unsigned int nr_object_points = 0;
939 const float range_max = (bank_argument.range_max < bank_argument.object_threshold_max_distance ?
940 bank_argument.range_max : bank_argument.object_threshold_max_distance);
941 const float range_min = bank_argument.range_min;
949 unsigned int upper_limit_out_of_bounds_scan_point = bank_argument.points_per_scan;
950 while(i<upper_limit_out_of_bounds_scan_point)
953 const float range_i = bank_ranges_ema[bank_index_newest][i];
954 float object_range_sum = range_i;
957 if (range_i < bank_argument.range_min ||
958 bank_argument.range_max < range_i)
965 nr_object_points = 1;
966 float object_range_min = range_i;
967 float object_range_max = range_i;
968 unsigned int object_range_min_index = i;
969 unsigned int object_range_max_index = i;
973 float range_at_angle_begin = range_i;
974 float range_at_angle_end;
975 unsigned int index_at_angle_begin = i;
976 unsigned int index_at_angle_end;
977 float prev_range = range_i;
979 for (; j<bank_argument.points_per_scan; ++j)
981 const float range_j = bank_ranges_ema[bank_index_newest][j];
984 if (bank_argument.range_min <= range_j &&
985 range_j <= bank_argument.range_max &&
986 fabsf(prev_range - range_j) <= bank_argument.object_threshold_edge_max_delta_range)
990 object_range_sum += range_j;
993 if (range_j < object_range_min)
995 object_range_min = range_j;
996 object_range_min_index = j;
998 else if (object_range_max < range_j)
1000 object_range_max = range_j;
1001 object_range_max_index = j;
1003 prev_range = range_j;
1013 range_at_angle_end = prev_range;
1014 index_at_angle_end = j-1;
1017 if (i == 0 && bank_argument.sensor_is_360_degrees)
1020 prev_range = range_i;
1024 for (
unsigned int k=bank_argument.points_per_scan-1; j<k; k--)
1026 const float range_k = bank_ranges_ema[bank_index_newest][k];
1029 if (bank_argument.range_min <= range_k &&
1030 range_k <= bank_argument.range_max &&
1031 fabsf(prev_range - range_k) <= bank_argument.object_threshold_edge_max_delta_range)
1035 object_range_sum += range_k;
1038 upper_limit_out_of_bounds_scan_point--;
1041 if (range_k < object_range_min)
1043 object_range_min = range_k;
1044 object_range_min_index = k;
1046 else if (object_range_max < range_k)
1048 object_range_max = range_k;
1049 object_range_max_index = k;
1051 prev_range = range_k;
1061 range_at_angle_begin = prev_range;
1062 index_at_angle_begin = upper_limit_out_of_bounds_scan_point;
1066 const float distance = object_range_sum / nr_object_points;
1067 const float object_seen_width =
sqrt( range_at_angle_begin *
1068 range_at_angle_begin +
1069 range_at_angle_end *
1070 range_at_angle_end -
1071 2 * range_at_angle_begin *
1072 range_at_angle_end *
1073 cosf (bank_argument.angle_increment * nr_object_points)
1077 if (bank_argument.object_threshold_min_nr_points <= nr_object_points)
1084 const unsigned int index_min = index_at_angle_begin;
1085 const unsigned int index_max = index_at_angle_end;
1086 const unsigned int index_mean = (index_min + (nr_object_points-1) / 2) % bank_argument.points_per_scan;
1088 int index_min_old = -1;
1089 int index_mean_old = -1;
1090 int index_max_old = -1;
1091 float range_sum_old = object_range_sum;
1092 float range_at_min_index_old = 0;
1093 float range_at_max_index_old = 0;
1094 getOldIndices(range_min,
1097 (bank_index_newest - 1) < 0 ? bank_argument.nr_scans_in_bank - 1 : bank_index_newest - 1,
1106 &range_at_min_index_old,
1107 &range_at_max_index_old);
1110 if (0 <= index_mean_old)
1115 MovingObject mo_old_positions;
1118 mo.map_frame = bank_argument.map_frame;
1119 mo.fixed_frame = bank_argument.fixed_frame;
1120 mo.base_frame = bank_argument.base_frame;
1121 mo.header.frame_id = bank_argument.sensor_frame;
1122 mo.header.seq = nr_objects_found;
1123 mo.header.stamp = new_time;
1124 mo.seen_width = object_seen_width;
1125 mo.angle_begin = index_min * bank_argument.angle_increment + bank_argument.angle_min;
1126 mo.angle_end = index_max * bank_argument.angle_increment + bank_argument.angle_min;
1127 const double angle_mean = index_mean * bank_argument.angle_increment + bank_argument.angle_min;
1128 mo.distance_at_angle_begin = range_at_angle_begin;
1129 mo.distance_at_angle_end = range_at_angle_end;
1135 mo.distance = distance;
1138 if (bank_argument.sensor_frame_has_z_axis_forward)
1141 mo.position.x = (double) - distance * sinf(angle_mean);
1142 mo.position.y = 0.0;
1143 mo.position.z = (double) distance * cosf(angle_mean);
1148 mo.position.x = (double) distance * cosf(angle_mean);
1149 mo.position.y = (double) distance * sinf(angle_mean);
1150 mo.position.z = 0.0;
1154 mo.angle_for_closest_distance = object_range_min_index * bank_argument.angle_increment +
1155 bank_argument.angle_min;
1156 mo.closest_distance = object_range_min;
1159 if (bank_argument.sensor_frame_has_z_axis_forward)
1162 mo.closest_point.x = - object_range_min * sinf(mo.angle_for_closest_distance);
1163 mo.closest_point.y = 0.0;
1164 mo.closest_point.z = object_range_min * cosf(mo.angle_for_closest_distance);
1169 mo.closest_point.x = object_range_min * cosf(mo.angle_for_closest_distance);
1170 mo.closest_point.y = object_range_min * sinf(mo.angle_for_closest_distance);
1171 mo.closest_point.z = 0.0;
1175 const unsigned int nr_object_points_old = (index_min_old <= index_max_old) ?
1176 (index_max_old - index_min_old + 1) :
1177 bank_argument.points_per_scan - (index_min_old - index_max_old) + 1;
1178 const float distance_old = range_sum_old / nr_object_points_old;
1180 const double distance_angle_old = index_mean_old * bank_argument.angle_increment + bank_argument.angle_min;
1182 const double covered_angle_old = nr_object_points_old * bank_argument.angle_increment;
1184 const double object_seen_width_old =
sqrt( range_at_min_index_old *
1185 range_at_min_index_old +
1186 range_at_max_index_old *
1187 range_at_max_index_old -
1188 2 * range_at_min_index_old *
1189 range_at_max_index_old *
1190 cosf (covered_angle_old)
1197 if (bank_argument.sensor_frame_has_z_axis_forward)
1200 x_old = - distance_old * sinf(distance_angle_old);
1202 z_old = distance_old * cosf(distance_angle_old);
1206 x_old = distance_old * cosf(distance_angle_old);
1207 y_old = distance_old * sinf(distance_angle_old);
1211 mo_old_positions.position.x = x_old;
1212 mo_old_positions.position.y = y_old;
1213 mo_old_positions.position.z = z_old;
1473 geometry_msgs::PointStamped in;
1474 geometry_msgs::PointStamped out;
1477 in.header.frame_id = bank_argument.sensor_frame;
1478 in.header.stamp = old_time;
1479 in.point = mo_old_positions.position;
1484 bank_argument.map_frame,
1486 bank_argument.fixed_frame);
1487 mo_old_positions.position_in_map_frame = out.point;
1492 bank_argument.fixed_frame,
1494 bank_argument.fixed_frame);
1495 mo_old_positions.position_in_fixed_frame = out.point;
1499 bank_argument.base_frame,
1501 bank_argument.fixed_frame);
1502 mo_old_positions.position_in_base_frame = out.point;
1505 in.header.stamp = new_time;
1506 in.point = mo.position;
1510 bank_argument.map_frame,
1512 bank_argument.fixed_frame);
1513 mo.position_in_map_frame = out.point;
1517 bank_argument.fixed_frame,
1519 bank_argument.fixed_frame);
1520 mo.position_in_fixed_frame = out.point;
1524 bank_argument.base_frame,
1526 bank_argument.fixed_frame);
1527 mo.position_in_base_frame = out.point;
1530 in.point = mo.closest_point;
1534 bank_argument.map_frame,
1536 bank_argument.fixed_frame);
1537 mo.closest_point_in_map_frame = out.point;
1541 bank_argument.fixed_frame,
1543 bank_argument.fixed_frame);
1544 mo.closest_point_in_fixed_frame = out.point;
1548 bank_argument.base_frame,
1550 bank_argument.fixed_frame);
1551 mo.closest_point_in_base_frame = out.point;
1559 const double dx_map = mo.position_in_map_frame.x - mo_old_positions.position_in_map_frame.x;
1560 const double dy_map = mo.position_in_map_frame.y - mo_old_positions.position_in_map_frame.y;
1561 const double dz_map = mo.position_in_map_frame.z - mo_old_positions.position_in_map_frame.z;
1562 const double dx_fixed = mo.position_in_fixed_frame.x - mo_old_positions.position_in_fixed_frame.x;
1563 const double dy_fixed = mo.position_in_fixed_frame.y - mo_old_positions.position_in_fixed_frame.y;
1564 const double dz_fixed = mo.position_in_fixed_frame.z - mo_old_positions.position_in_fixed_frame.z;
1565 const double dx_base = mo.position_in_base_frame.x - mo_old_positions.position_in_base_frame.x;
1566 const double dy_base = mo.position_in_base_frame.y - mo_old_positions.position_in_base_frame.y;
1567 const double dz_base = mo.position_in_base_frame.z - mo_old_positions.position_in_base_frame.z;
1568 const double dx_sensor = mo.position.x - x_old;
1569 const double dy_sensor = mo.position.y - y_old;
1570 const double dz_sensor = mo.position.z - z_old;
1634 const double dt = mo.header.stamp.toSec() - bank_stamp[bank_index_put];
1636 mo.velocity.x = dx_sensor / dt;
1637 mo.velocity.y = dy_sensor / dt;
1638 mo.velocity.z = dz_sensor / dt;
1639 mo.velocity_in_map_frame.x = dx_map / dt;
1640 mo.velocity_in_map_frame.y = dy_map / dt;
1641 mo.velocity_in_map_frame.z = dz_map / dt;
1642 mo.velocity_in_fixed_frame.x = dx_fixed / dt;
1643 mo.velocity_in_fixed_frame.y = dy_fixed / dt;
1644 mo.velocity_in_fixed_frame.z = dz_fixed / dt;
1645 mo.velocity_in_base_frame.x = dx_base / dt;
1646 mo.velocity_in_base_frame.y = dy_base / dt;
1647 mo.velocity_in_base_frame.z = dz_base / dt;
1650 mo.speed =
sqrt(mo.velocity.x * mo.velocity.x +
1651 mo.velocity.y * mo.velocity.y +
1652 mo.velocity.z * mo.velocity.z);
1653 mo.speed_in_map_frame =
sqrt(mo.velocity_in_map_frame.x * mo.velocity_in_map_frame.x +
1654 mo.velocity_in_map_frame.y * mo.velocity_in_map_frame.y +
1655 mo.velocity_in_map_frame.z * mo.velocity_in_map_frame.z);
1656 mo.speed_in_fixed_frame =
sqrt(mo.velocity_in_fixed_frame.x * mo.velocity_in_fixed_frame.x +
1657 mo.velocity_in_fixed_frame.y * mo.velocity_in_fixed_frame.y +
1658 mo.velocity_in_fixed_frame.z * mo.velocity_in_fixed_frame.z);
1659 mo.speed_in_base_frame =
sqrt(mo.velocity_in_base_frame.x * mo.velocity_in_base_frame.x +
1660 mo.velocity_in_base_frame.y * mo.velocity_in_base_frame.y +
1661 mo.velocity_in_base_frame.z * mo.velocity_in_base_frame.z);
1666 mo.velocity_normalized.x = mo.velocity.x / mo.speed;
1667 mo.velocity_normalized.y = mo.velocity.y / mo.speed;
1668 mo.velocity_normalized.z = mo.velocity.z / mo.speed;
1672 mo.velocity_normalized.x = 0.0;
1673 mo.velocity_normalized.y = 0.0;
1674 mo.velocity_normalized.z = 0.0;
1676 if (0 < mo.speed_in_map_frame)
1678 mo.velocity_normalized_in_map_frame.x = mo.velocity_in_map_frame.x / mo.speed_in_map_frame;
1679 mo.velocity_normalized_in_map_frame.y = mo.velocity_in_map_frame.y / mo.speed_in_map_frame;
1680 mo.velocity_normalized_in_map_frame.z = mo.velocity_in_map_frame.z / mo.speed_in_map_frame;
1684 mo.velocity_normalized_in_map_frame.x = 0.0;
1685 mo.velocity_normalized_in_map_frame.y = 0.0;
1686 mo.velocity_normalized_in_map_frame.z = 0.0;
1688 if (0 < mo.speed_in_fixed_frame)
1690 mo.velocity_normalized_in_fixed_frame.x = mo.velocity_in_fixed_frame.x / mo.speed_in_fixed_frame;
1691 mo.velocity_normalized_in_fixed_frame.y = mo.velocity_in_fixed_frame.y / mo.speed_in_fixed_frame;
1692 mo.velocity_normalized_in_fixed_frame.z = mo.velocity_in_fixed_frame.z / mo.speed_in_fixed_frame;
1696 mo.velocity_normalized_in_fixed_frame.x = 0.0;
1697 mo.velocity_normalized_in_fixed_frame.y = 0.0;
1698 mo.velocity_normalized_in_fixed_frame.z = 0.0;
1700 if (0 < mo.speed_in_base_frame)
1702 mo.velocity_normalized_in_base_frame.x = mo.velocity_in_base_frame.x / mo.speed_in_base_frame;
1703 mo.velocity_normalized_in_base_frame.y = mo.velocity_in_base_frame.y / mo.speed_in_base_frame;
1704 mo.velocity_normalized_in_base_frame.z = mo.velocity_in_base_frame.z / mo.speed_in_base_frame;
1708 mo.velocity_normalized_in_base_frame.x = 0.0;
1709 mo.velocity_normalized_in_base_frame.y = 0.0;
1710 mo.velocity_normalized_in_base_frame.z = 0.0;
1714 if (bank_argument.object_threshold_min_speed <= mo.speed ||
1715 bank_argument.object_threshold_min_speed <= mo.speed_in_map_frame ||
1716 bank_argument.object_threshold_min_speed <= mo.speed_in_fixed_frame ||
1717 bank_argument.object_threshold_min_speed <= mo.speed_in_base_frame)
1721 <<
" (sensor) x=" << std::setw(12) << std::left << mo.position.x \
1722 <<
" y=" << std::setw(12) << std::left << mo.position.y \
1723 <<
" z=" << std::setw(12) << std::left << mo.position.z \
1725 <<
" vx=" << std::setw(12) << std::left << mo.velocity.x \
1726 <<
" vy=" << std::setw(12) << std::left << mo.velocity.y \
1727 <<
" vz=" << std::setw(12) << std::left << mo.velocity.z \
1728 <<
" speed=" << mo.speed \
1730 <<
" (map) x=" << std::setw(12) << std::left << mo.position_in_map_frame.x \
1731 <<
" y=" << std::setw(12) << std::left << mo.position_in_map_frame.y \
1732 <<
" z=" << std::setw(12) << std::left << mo.position_in_map_frame.z \
1734 <<
" vx=" << std::setw(12) << std::left << mo.velocity_in_map_frame.x \
1735 <<
" vy=" << std::setw(12) << std::left << mo.velocity_in_map_frame.y \
1736 <<
" vz=" << std::setw(12) << std::left << mo.velocity_in_map_frame.z \
1737 <<
" speed=" << mo.speed_in_map_frame \
1739 <<
" (fixed) x=" << std::setw(12) << std::left << mo.position_in_fixed_frame.x \
1740 <<
" y=" << std::setw(12) << std::left << mo.position_in_fixed_frame.y \
1741 <<
" z=" << std::setw(12) << std::left << mo.position_in_fixed_frame.z \
1743 <<
" vx=" << std::setw(12) << std::left << mo.velocity_in_fixed_frame.x \
1744 <<
" vy=" << std::setw(12) << std::left << mo.velocity_in_fixed_frame.y \
1745 <<
" vz=" << std::setw(12) << std::left << mo.velocity_in_fixed_frame.z \
1746 <<
" speed=" << mo.speed_in_fixed_frame \
1748 <<
" (base) x=" << std::setw(12) << std::left << mo.position_in_base_frame.x \
1749 <<
" y=" << std::setw(12) << std::left << mo.position_in_base_frame.y \
1750 <<
" z=" << std::setw(12) << std::left << mo.position_in_base_frame.z \
1752 <<
" vx=" << std::setw(12) << std::left << mo.velocity_in_base_frame.x \
1753 <<
" vy=" << std::setw(12) << std::left << mo.velocity_in_base_frame.y \
1754 <<
" vz=" << std::setw(12) << std::left << mo.velocity_in_base_frame.z \
1755 <<
" speed=" << mo.speed_in_base_frame \
1759 mo.confidence = calculateConfidence(mo,
1762 object_seen_width_old);
1765 mo.confidence = (mo.confidence < 0.0 ? 0.0 : mo.confidence);
1766 mo.confidence = (mo.confidence < 1.0 ? mo.confidence : 1.0);
1769 if (bank_argument.object_threshold_min_confidence <= mo.confidence)
1772 if (bank_argument.publish_ema)
1775 if (index_min <= index_max)
1778 for (
unsigned int k=index_min; k<=index_max; ++k)
1780 msg_ema.intensities[k] = 300.0f;
1787 for (
unsigned int k=index_min; k<bank_argument.points_per_scan; ++k)
1789 msg_ema.intensities[k] = 300.0f;
1791 for (
unsigned int k=0; k<index_max; ++k)
1793 msg_ema.intensities[k] = 300.0f;
1799 moa.objects.push_back(mo);
1800 moa_old_positions.objects.push_back(mo_old_positions);
1806 i = index_at_angle_end + 1;
1807 nr_object_points = 0;
1815 if (bank_argument.publish_objects && 0 < moa.objects.size())
1820 pub_objects.publish(moa);
1827 if (bank_argument.publish_ema)
1830 memcpy(msg_ema.ranges.data(), &bank_ranges_ema[bank_index_newest][0], bank_ranges_bytes);
1831 msg_ema.header.seq = moa_seq;
1832 msg_ema.header.stamp = now;
1835 pub_ema.publish(msg_ema);
1839 if (bank_argument.publish_objects_closest_point_markers)
1841 msg_objects_closest_point_markers.header.stamp = now;
1842 msg_objects_closest_point_markers.header.seq = moa_seq;
1844 if (bank_argument.publish_objects_velocity_arrows)
1846 msg_objects_velocity_arrow.header.stamp = now;
1847 msg_objects_velocity_arrow.header.seq = moa_seq;
1849 if (bank_argument.publish_objects_delta_position_lines)
1851 msg_objects_delta_position_line.header.stamp = now;
1852 msg_objects_delta_position_line.header.seq = moa_seq;
1854 if (bank_argument.publish_objects_width_lines)
1856 msg_objects_width_line.header.stamp = now;
1857 msg_objects_width_line.header.seq = moa_seq;
1862 MovingObject * mo_old_positions;
1863 const unsigned int nr_moving_objects_found = moa.objects.size();
1864 for (
unsigned int i=0; i<nr_moving_objects_found; ++i)
1866 mo = &moa.objects[i];
1867 mo_old_positions = &moa_old_positions.objects[i];
1870 if (bank_argument.publish_objects_closest_point_markers)
1873 const unsigned int distance_min_index =
1874 round((mo->angle_for_closest_distance - bank_argument.angle_min) / bank_argument.angle_increment);
1875 msg_objects_closest_point_markers.ranges[distance_min_index] = mo->closest_distance;
1876 msg_objects_closest_point_markers.intensities[distance_min_index] = 1000;
1880 if (bank_argument.publish_objects_velocity_arrows)
1882 msg_objects_velocity_arrow.id = i;
1883 if (bank_argument.velocity_arrows_use_sensor_frame)
1886 msg_objects_velocity_arrow.points[0].x = mo->position.x;
1887 msg_objects_velocity_arrow.points[0].y = mo->position.y;
1888 msg_objects_velocity_arrow.points[0].z = mo->position.z;
1890 msg_objects_velocity_arrow.points[1].x = mo->position.x + mo->velocity.x;
1891 msg_objects_velocity_arrow.points[1].y = mo->position.y + mo->velocity.y;
1892 msg_objects_velocity_arrow.points[1].z = mo->position.z + mo->velocity.z;
1894 else if (bank_argument.velocity_arrows_use_base_frame)
1897 msg_objects_velocity_arrow.points[0].x = mo->position_in_base_frame.x;
1898 msg_objects_velocity_arrow.points[0].y = mo->position_in_base_frame.y;
1899 msg_objects_velocity_arrow.points[0].z = mo->position_in_base_frame.z;
1901 msg_objects_velocity_arrow.points[1].x = mo->position_in_base_frame.x + mo->velocity_in_base_frame.x;
1902 msg_objects_velocity_arrow.points[1].y = mo->position_in_base_frame.y + mo->velocity_in_base_frame.y;
1903 msg_objects_velocity_arrow.points[1].z = mo->position_in_base_frame.z + mo->velocity_in_base_frame.z;
1905 else if (bank_argument.velocity_arrows_use_fixed_frame)
1908 msg_objects_velocity_arrow.points[0].x = mo->position_in_fixed_frame.x;
1909 msg_objects_velocity_arrow.points[0].y = mo->position_in_fixed_frame.y;
1910 msg_objects_velocity_arrow.points[0].z = mo->position_in_fixed_frame.z;
1912 msg_objects_velocity_arrow.points[1].x = mo->position_in_fixed_frame.x + mo->velocity_in_fixed_frame.x;
1913 msg_objects_velocity_arrow.points[1].y = mo->position_in_fixed_frame.y + mo->velocity_in_fixed_frame.y;
1914 msg_objects_velocity_arrow.points[1].z = mo->position_in_fixed_frame.z + mo->velocity_in_fixed_frame.z;
1919 msg_objects_velocity_arrow.points[0].x = mo->position_in_map_frame.x;
1920 msg_objects_velocity_arrow.points[0].y = mo->position_in_map_frame.y;
1921 msg_objects_velocity_arrow.points[0].z = mo->position_in_map_frame.z;
1923 msg_objects_velocity_arrow.points[1].x = mo->position_in_map_frame.x + mo->velocity_in_map_frame.x;
1924 msg_objects_velocity_arrow.points[1].y = mo->position_in_map_frame.y + mo->velocity_in_map_frame.y;
1925 msg_objects_velocity_arrow.points[1].z = mo->position_in_map_frame.z + mo->velocity_in_map_frame.z;
1929 if (bank_argument.velocity_arrows_use_full_gray_scale && bank_argument.object_threshold_min_confidence < 1)
1931 const double adapted_confidence = (mo->confidence - bank_argument.object_threshold_min_confidence) /
1932 (1 - bank_argument.object_threshold_min_confidence);
1933 msg_objects_velocity_arrow.color.r = adapted_confidence;
1934 msg_objects_velocity_arrow.color.g = adapted_confidence;
1935 msg_objects_velocity_arrow.color.b = adapted_confidence;
1939 msg_objects_velocity_arrow.color.r = mo->confidence;
1940 msg_objects_velocity_arrow.color.g = mo->confidence;
1941 msg_objects_velocity_arrow.color.b = mo->confidence;
1945 msg_objects_velocity_arrows.markers.push_back(msg_objects_velocity_arrow);
1949 if (bank_argument.publish_objects_delta_position_lines)
1951 msg_objects_delta_position_line.id = i;
1954 msg_objects_delta_position_line.points[0].x = mo_old_positions->position.x;
1955 msg_objects_delta_position_line.points[0].y = mo_old_positions->position.y;
1956 msg_objects_delta_position_line.points[0].z = mo_old_positions->position.z;
1957 msg_objects_delta_position_line.points[1].x = mo->position.x;
1958 msg_objects_delta_position_line.points[1].y = mo->position.y;
1959 msg_objects_delta_position_line.points[1].z = mo->position.z;
1962 msg_objects_delta_position_lines.markers.push_back(msg_objects_delta_position_line);
1966 if (bank_argument.publish_objects_width_lines)
1968 msg_objects_width_line.id = i;
1971 if (!bank_argument.sensor_frame_has_z_axis_forward)
1974 msg_objects_width_line.points[0].x = mo->distance_at_angle_begin * cosf(mo->angle_begin);
1975 msg_objects_width_line.points[0].y = mo->distance_at_angle_begin * sinf(mo->angle_begin);
1976 msg_objects_width_line.points[0].z = 0.0;
1978 msg_objects_width_line.points[1].x = mo->distance_at_angle_end * cosf(mo->angle_end);
1979 msg_objects_width_line.points[1].y = mo->distance_at_angle_end * sinf(mo->angle_end);
1980 msg_objects_width_line.points[1].z = 0.0;
1985 msg_objects_width_line.points[0].x = -mo->distance_at_angle_begin * sinf(mo->angle_begin);
1986 msg_objects_width_line.points[0].y = 0.0;
1987 msg_objects_width_line.points[0].z = mo->distance_at_angle_begin * cosf(mo->angle_begin);
1989 msg_objects_width_line.points[1].x = -mo->distance_at_angle_end * sinf(mo->angle_end);
1990 msg_objects_width_line.points[1].y = 0.0;
1991 msg_objects_width_line.points[1].z = mo->distance_at_angle_end * cosf(mo->angle_end);
1995 msg_objects_width_lines.markers.push_back(msg_objects_width_line);
2000 if (bank_argument.publish_objects_closest_point_markers)
2002 pub_objects_closest_point_markers.publish(msg_objects_closest_point_markers);
2006 if (bank_argument.publish_objects_velocity_arrows)
2008 pub_objects_velocity_arrows.publish(msg_objects_velocity_arrows);
2012 if (bank_argument.publish_objects_delta_position_lines)
2014 pub_objects_delta_position_lines.publish(msg_objects_delta_position_lines);
2018 if (bank_argument.publish_objects_width_lines)
2020 pub_objects_width_lines.publish(msg_objects_width_lines);
2024 if (bank_argument.publish_objects_closest_point_markers)
2026 for (
unsigned int i=0; i<nr_moving_objects_found; ++i)
2028 mo = &moa.objects[i];
2029 const unsigned int distance_min_index =
2030 round((mo->angle_for_closest_distance - bank_argument.angle_min) / bank_argument.angle_increment);
2031 msg_objects_closest_point_markers.ranges[distance_min_index] = msg_objects_closest_point_markers.range_max + 10.0;
2032 msg_objects_closest_point_markers.intensities[distance_min_index] = 0.0;
2035 if (bank_argument.publish_objects_velocity_arrows)
2037 msg_objects_velocity_arrows.markers.clear();
2039 if (bank_argument.publish_objects_delta_position_lines)
2041 msg_objects_delta_position_lines.markers.clear();
2043 if (bank_argument.publish_objects_width_lines)
2045 msg_objects_width_lines.markers.clear();
2047 if (bank_argument.publish_ema)
2049 bzero(msg_ema.intensities.data(), bank_ranges_bytes);
2057 const unsigned int half_way = nr_bytes/2;
2058 for (
unsigned int i=0; i<half_way; ++i)
2060 const byte_t tmp_byte = bytes[i];
2061 bytes[i] = bytes[nr_bytes - i - 1];
2062 bytes[nr_bytes - i - 1] = tmp_byte;
2072 PC2_message_x_offset = -1;
2073 PC2_message_x_bytes = -1;
2074 PC2_message_y_offset = -1;
2075 PC2_message_y_bytes = -1;
2076 PC2_message_z_offset = -1;
2077 PC2_message_z_bytes = -1;
2078 const bool must_reverse_bytes = (msg->is_bigendian != !machine_is_little_endian);
2079 const unsigned int fields = msg->fields.size();
2083 for (
unsigned int i=0; i<fields; ++i)
2087 msg->fields[i].name.c_str()) == 0)
2090 memcpy(&tmp_byte4[0], &msg->fields[i].offset, 4);
2091 if (must_reverse_bytes)
2093 reverseBytes(tmp_byte4, 4);
2095 memcpy(&PC2_message_x_offset, tmp_byte4, 4);
2098 tmp_byte = msg->fields[i].datatype;
2099 if (tmp_byte == sensor_msgs::PointField::INT8 ||
2100 tmp_byte == sensor_msgs::PointField::UINT8)
2102 PC2_message_x_bytes = 1;
2104 else if (tmp_byte == sensor_msgs::PointField::INT16 ||
2105 tmp_byte == sensor_msgs::PointField::UINT16)
2107 PC2_message_x_bytes = 2;
2109 else if (tmp_byte == sensor_msgs::PointField::INT32 ||
2110 tmp_byte == sensor_msgs::PointField::UINT32 ||
2111 tmp_byte == sensor_msgs::PointField::FLOAT32)
2113 PC2_message_x_bytes = 4;
2115 else if (tmp_byte == sensor_msgs::PointField::FLOAT64)
2117 PC2_message_x_bytes = 8;
2121 ROS_ERROR(
"Cannot determine number of bytes for X coordinate");
2127 msg->fields[i].name.c_str()) == 0)
2130 memcpy(&tmp_byte4[0], &msg->fields[i].offset, 4);
2131 if (must_reverse_bytes)
2133 reverseBytes(tmp_byte4, 4);
2135 memcpy(&PC2_message_y_offset, tmp_byte4, 4);
2138 tmp_byte = msg->fields[i].datatype;
2139 if (tmp_byte == sensor_msgs::PointField::INT8 ||
2140 tmp_byte == sensor_msgs::PointField::UINT8)
2142 PC2_message_y_bytes = 1;
2144 else if (tmp_byte == sensor_msgs::PointField::INT16 ||
2145 tmp_byte == sensor_msgs::PointField::UINT16)
2147 PC2_message_y_bytes = 2;
2149 else if (tmp_byte == sensor_msgs::PointField::INT32 ||
2150 tmp_byte == sensor_msgs::PointField::UINT32 ||
2151 tmp_byte == sensor_msgs::PointField::FLOAT32)
2153 PC2_message_y_bytes = 4;
2155 else if (tmp_byte == sensor_msgs::PointField::FLOAT64)
2157 PC2_message_y_bytes = 8;
2161 ROS_ERROR(
"Cannot determine number of bytes for Y coordinate");
2167 msg->fields[i].name.c_str()) == 0)
2170 memcpy(&tmp_byte4[0], &msg->fields[i].offset, 4);
2171 if (must_reverse_bytes)
2173 reverseBytes(tmp_byte4, 4);
2175 memcpy(&PC2_message_z_offset, tmp_byte4, 4);
2178 tmp_byte = msg->fields[i].datatype;
2179 if (tmp_byte == sensor_msgs::PointField::INT8 ||
2180 tmp_byte == sensor_msgs::PointField::UINT8)
2182 PC2_message_z_bytes = 1;
2184 else if (tmp_byte == sensor_msgs::PointField::INT16 ||
2185 tmp_byte == sensor_msgs::PointField::UINT16)
2187 PC2_message_z_bytes = 2;
2189 else if (tmp_byte == sensor_msgs::PointField::INT32 ||
2190 tmp_byte == sensor_msgs::PointField::UINT32 ||
2191 tmp_byte == sensor_msgs::PointField::FLOAT32)
2193 PC2_message_z_bytes = 4;
2195 else if (tmp_byte == sensor_msgs::PointField::FLOAT64)
2197 PC2_message_z_bytes = 8;
2201 ROS_ERROR(
"Cannot determine number of bytes for Z coordinate");
2207 if (0 <= PC2_message_x_offset &&
2208 0 <= PC2_message_x_bytes &&
2209 0 <= PC2_message_y_offset &&
2210 0 <= PC2_message_y_bytes &&
2211 0 <= PC2_message_z_offset &&
2212 0 <= PC2_message_z_bytes)
2218 ROS_ERROR(
"Could not determine offsets and bytes");
2225 PC2_message_x_offset = -1;
2226 PC2_message_x_bytes = -1;
2227 PC2_message_y_offset = -1;
2228 PC2_message_y_bytes = -1;
2229 PC2_message_z_offset = -1;
2230 PC2_message_z_bytes = -1;
2231 const bool must_reverse_bytes = (msg->is_bigendian != !machine_is_little_endian);
2232 const unsigned int fields = msg->fields.size();
2236 for (
unsigned int i=0; i<fields; ++i)
2240 msg->fields[i].name.c_str()) == 0)
2243 memcpy(&tmp_byte4[0], &msg->fields[i].offset, 4);
2244 if (must_reverse_bytes)
2246 reverseBytes(tmp_byte4, 4);
2248 memcpy(&PC2_message_x_offset, tmp_byte4, 4);
2251 tmp_byte = msg->fields[i].datatype;
2252 if (tmp_byte == sensor_msgs::PointField::INT8 ||
2253 tmp_byte == sensor_msgs::PointField::UINT8)
2255 PC2_message_x_bytes = 1;
2257 else if (tmp_byte == sensor_msgs::PointField::INT16 ||
2258 tmp_byte == sensor_msgs::PointField::UINT16)
2260 PC2_message_x_bytes = 2;
2262 else if (tmp_byte == sensor_msgs::PointField::INT32 ||
2263 tmp_byte == sensor_msgs::PointField::UINT32 ||
2264 tmp_byte == sensor_msgs::PointField::FLOAT32)
2266 PC2_message_x_bytes = 4;
2268 else if (tmp_byte == sensor_msgs::PointField::FLOAT64)
2270 PC2_message_x_bytes = 8;
2274 ROS_ERROR(
"Cannot determine number of bytes for X coordinate");
2280 msg->fields[i].name.c_str()) == 0)
2283 memcpy(&tmp_byte4[0], &msg->fields[i].offset, 4);
2284 if (must_reverse_bytes)
2286 reverseBytes(tmp_byte4, 4);
2288 memcpy(&PC2_message_y_offset, tmp_byte4, 4);
2291 tmp_byte = msg->fields[i].datatype;
2292 if (tmp_byte == sensor_msgs::PointField::INT8 ||
2293 tmp_byte == sensor_msgs::PointField::UINT8)
2295 PC2_message_y_bytes = 1;
2297 else if (tmp_byte == sensor_msgs::PointField::INT16 ||
2298 tmp_byte == sensor_msgs::PointField::UINT16)
2300 PC2_message_y_bytes = 2;
2302 else if (tmp_byte == sensor_msgs::PointField::INT32 ||
2303 tmp_byte == sensor_msgs::PointField::UINT32 ||
2304 tmp_byte == sensor_msgs::PointField::FLOAT32)
2306 PC2_message_y_bytes = 4;
2308 else if (tmp_byte == sensor_msgs::PointField::FLOAT64)
2310 PC2_message_y_bytes = 8;
2314 ROS_ERROR(
"Cannot determine number of bytes for Y coordinate");
2320 msg->fields[i].name.c_str()) == 0)
2323 memcpy(&tmp_byte4[0], &msg->fields[i].offset, 4);
2324 if (must_reverse_bytes)
2326 reverseBytes(tmp_byte4, 4);
2328 memcpy(&PC2_message_z_offset, tmp_byte4, 4);
2331 tmp_byte = msg->fields[i].datatype;
2332 if (tmp_byte == sensor_msgs::PointField::INT8 ||
2333 tmp_byte == sensor_msgs::PointField::UINT8)
2335 PC2_message_z_bytes = 1;
2337 else if (tmp_byte == sensor_msgs::PointField::INT16 ||
2338 tmp_byte == sensor_msgs::PointField::UINT16)
2340 PC2_message_z_bytes = 2;
2342 else if (tmp_byte == sensor_msgs::PointField::INT32 ||
2343 tmp_byte == sensor_msgs::PointField::UINT32 ||
2344 tmp_byte == sensor_msgs::PointField::FLOAT32)
2346 PC2_message_z_bytes = 4;
2348 else if (tmp_byte == sensor_msgs::PointField::FLOAT64)
2350 PC2_message_z_bytes = 8;
2354 ROS_ERROR(
"Cannot determine number of bytes for Z coordinate");
2360 if (0 <= PC2_message_x_offset &&
2361 0 <= PC2_message_x_bytes &&
2362 0 <= PC2_message_y_offset &&
2363 0 <= PC2_message_y_bytes &&
2364 0 <= PC2_message_z_offset &&
2365 0 <= PC2_message_z_bytes)
2371 ROS_ERROR(
"Could not determine offsets and bytes");
2379 const bool must_reverse_bytes,
2384 uint8_t x_array[PC2_message_x_bytes];
2385 uint8_t y_array[PC2_message_y_bytes];
2386 uint8_t z_array[PC2_message_z_bytes];
2387 memcpy(x_array, start_of_point + PC2_message_x_offset, PC2_message_x_bytes);
2388 memcpy(y_array, start_of_point + PC2_message_y_offset, PC2_message_y_bytes);
2389 memcpy(z_array, start_of_point + PC2_message_z_offset, PC2_message_z_bytes);
2392 if (must_reverse_bytes)
2394 reverseBytes(x_array, PC2_message_x_bytes);
2395 reverseBytes(y_array, PC2_message_y_bytes);
2396 reverseBytes(z_array, PC2_message_z_bytes);
2401 if (PC2_message_x_bytes ==
sizeof(
float))
2404 memcpy(&xf, x_array, PC2_message_x_bytes);
2407 else if (PC2_message_x_bytes ==
sizeof(
double))
2409 memcpy(x, x_array, PC2_message_x_bytes);
2413 ROS_ERROR(
"Cannot determine how to read X coordinate for this point!");
2417 if (PC2_message_y_bytes ==
sizeof(
float))
2420 memcpy(&yf, y_array, PC2_message_y_bytes);
2423 else if (PC2_message_y_bytes ==
sizeof(
double))
2425 memcpy(y, y_array, PC2_message_y_bytes);
2429 ROS_ERROR(
"Cannot determine how to read Y coordinate for this point!");
2433 if (PC2_message_z_bytes ==
sizeof(
float))
2436 memcpy(&zf, z_array, PC2_message_z_bytes);
2439 else if (PC2_message_z_bytes ==
sizeof(
double))
2441 memcpy(z, z_array, PC2_message_z_bytes);
2445 ROS_ERROR(
"Cannot determine how to read Z coordinate for this point!");
2455 const double range = bank_argument.object_threshold_max_distance + 10.0;
2456 float * bank_put = bank_ranges_ema[bank_index_put];
2457 for (
unsigned int i=0; i<bank_argument.points_per_scan; ++i)
2459 bank_put[i] = range;
2471 const bool must_reverse_bytes = (msg->is_bigendian != !machine_is_little_endian);
2472 float * bank_put = bank_ranges_ema[bank_index_put];
2473 const double bank_view_angle = bank_argument.angle_max - bank_argument.angle_min;
2474 const double bank_view_angle_half = bank_view_angle / 2;
2475 const double voxel_leaf_size_half = bank_argument.PC2_voxel_leaf_size / 2;
2476 const double inverted_bank_resolution = bank_argument.points_per_scan / bank_view_angle;
2477 const int bank_index_max = bank_argument.points_per_scan - 1;
2478 const unsigned int rows = msg->height;
2479 const unsigned int bytes_per_row = msg->row_step;
2480 const unsigned int bytes_per_point = msg->point_step;
2483 unsigned int added_points_out = 0;
2484 for (
unsigned int i=0; i<rows; i++)
2487 const unsigned int row_offset = i * bytes_per_row;
2488 for (
unsigned int j=0; j<bytes_per_row; j+=bytes_per_point)
2491 const uint8_t * start_of_point = &msg->data[row_offset + j];
2493 readPoint(start_of_point,
2500 if (!bank_argument.sensor_frame_has_z_axis_forward)
2503 if (z < bank_argument.PC2_threshold_z_min ||
2504 bank_argument.PC2_threshold_z_max < z ||
2513 if (-y < bank_argument.PC2_threshold_z_min ||
2514 bank_argument.PC2_threshold_z_max < -y ||
2522 if (std::isnan(x) || std::isnan(y) || std::isnan(z))
2529 added_points_out = added_points_out + 1;
2532 const double range =
sqrt(x*x + y*y + z*z);
2533 double point_angle_min;
2534 double point_angle_max;
2535 if (!bank_argument.sensor_frame_has_z_axis_forward)
2538 point_angle_min =
atan((y - voxel_leaf_size_half) / x);
2539 point_angle_max =
atan((y + voxel_leaf_size_half) / x);
2544 point_angle_min =
atan((-x - voxel_leaf_size_half) / z);
2545 point_angle_max =
atan((-x + voxel_leaf_size_half) / z);
2549 const int bank_index_point_min =
2550 (0 > (point_angle_min + bank_view_angle_half) * inverted_bank_resolution ?
2552 (point_angle_min + bank_view_angle_half) * inverted_bank_resolution);
2553 const int bank_index_point_max =
2554 (bank_index_max < (point_angle_max + bank_view_angle_half) * inverted_bank_resolution ?
2556 (point_angle_max + bank_view_angle_half) * inverted_bank_resolution);
2558 ROS_DEBUG_STREAM(
"The point (" << x <<
"," << y <<
"," << z <<
") is added in the bank between indices " << \
2559 std::setw(4) << std::left << bank_index_point_min <<
" and " << bank_index_point_max << std::endl);
2563 for (
int p=bank_index_point_min; p<=bank_index_point_max; ++p)
2565 if (range < bank_put[p])
2567 bank_put[p] = range;
2573 return added_points_out;
2578 const bool must_reverse_bytes = (msg->is_bigendian != !machine_is_little_endian);
2579 float * bank_put = bank_ranges_ema[bank_index_put];
2580 const double bank_view_angle = bank_argument.angle_max - bank_argument.angle_min;
2581 const double bank_view_angle_half = bank_view_angle / 2;
2582 const double voxel_leaf_size_half = bank_argument.PC2_voxel_leaf_size / 2;
2583 const double inverted_bank_resolution = bank_argument.points_per_scan / bank_view_angle;
2584 const int bank_index_max = bank_argument.points_per_scan - 1;
2585 const unsigned int rows = msg->height;
2586 const unsigned int bytes_per_row = msg->row_step;
2587 const unsigned int bytes_per_point = msg->point_step;
2590 unsigned int added_points_out = 0;
2591 for (
unsigned int i=0; i<rows; i++)
2594 const unsigned int row_offset = i * bytes_per_row;
2595 for (
unsigned int j=0; j<bytes_per_row; j+=bytes_per_point)
2598 const uint8_t * start_of_point = &msg->data[row_offset + j];
2600 readPoint(start_of_point,
2607 if (!bank_argument.sensor_frame_has_z_axis_forward)
2610 if (z < bank_argument.PC2_threshold_z_min ||
2611 bank_argument.PC2_threshold_z_max < z ||
2620 if (-y < bank_argument.PC2_threshold_z_min ||
2621 bank_argument.PC2_threshold_z_max < -y ||
2629 if (std::isnan(x) || std::isnan(y) || std::isnan(z))
2636 added_points_out = added_points_out + 1;
2639 const double range =
sqrt(x*x + y*y + z*z);
2640 double point_angle_min;
2641 double point_angle_max;
2642 if (!bank_argument.sensor_frame_has_z_axis_forward)
2645 point_angle_min =
atan((y - voxel_leaf_size_half) / x);
2646 point_angle_max =
atan((y + voxel_leaf_size_half) / x);
2651 point_angle_min =
atan((-x - voxel_leaf_size_half) / z);
2652 point_angle_max =
atan((-x + voxel_leaf_size_half) / z);
2656 const int bank_index_point_min =
2657 (0 > (point_angle_min + bank_view_angle_half) * inverted_bank_resolution ?
2659 (point_angle_min + bank_view_angle_half) * inverted_bank_resolution);
2660 const int bank_index_point_max =
2661 (bank_index_max < (point_angle_max + bank_view_angle_half) * inverted_bank_resolution ?
2663 (point_angle_max + bank_view_angle_half) * inverted_bank_resolution);
2665 ROS_DEBUG_STREAM(
"The point (" << x <<
"," << y <<
"," << z <<
") is added in the bank between indices " << \
2666 std::setw(4) << std::left << bank_index_point_min <<
" and " << bank_index_point_max << std::endl);
2670 for (
int p=bank_index_point_min; p<=bank_index_point_max; ++p)
2672 if (range < bank_put[p])
2674 bank_put[p] = range;
2680 return added_points_out;
2689 const double alpha = bank_argument.ema_alpha;
2694 const double alpha_prev = 1.0 - alpha;
2695 float * bank_put = bank_ranges_ema[bank_index_put];
2696 float * bank_prev = bank_ranges_ema[bank_index_newest];
2698 for (
unsigned int i=0; i<bank_argument.points_per_scan; ++i)
2700 bank_put[i] = alpha * bank_put[i] +
2701 alpha_prev * bank_prev[i];
2710 float * bank_put = bank_ranges_ema[bank_index_put];
2711 std::ostringstream stream;
2712 stream <<
"Bank points (at put index):";
2713 for (
unsigned int i=0; i<bank_argument.points_per_scan; ++i)
2715 stream <<
" " << bank_put[i];
2717 stream << std::endl;
2718 std::string
string = stream.str();
2727 bank_index_newest = 0;
2734 bank_index_put = (bank_index_put + 1) % bank_argument.nr_scans_in_bank;
2735 bank_index_newest = (bank_index_newest + 1) % bank_argument.nr_scans_in_bank;
2742 if (!bank_is_initialized)
2746 ROS_WARN_STREAM(
"The sensor frame (" << msg->header.frame_id.c_str() <<
") seems to be a camera/optical frame. " 2747 "Perhaps sensor_frame_has_z_axis_forward should be set?");
2751 ROS_WARN_STREAM(
"Please note that setting sensor_frame_has_z_axis_forward will cause the ema and " 2752 "objects_closest_points messages to be shown incorrectly.");
2758 bank_argument.
angle_min = msg->angle_min;
2759 bank_argument.
angle_max = msg->angle_max;
2762 bank_argument.
scan_time = msg->scan_time;
2763 bank_argument.
range_min = msg->range_min;
2764 bank_argument.
range_max = msg->range_max;
2767 initBank(bank_argument);
2771 return addFirstMessage(msg);
2778 bank_stamp[0] = msg->header.stamp.toSec();
2782 float * bank_put = bank_ranges_ema[0];
2783 for (
unsigned int i=0; i<bank_argument.points_per_scan; ++i)
2785 if (msg->ranges[i] == std::numeric_limits<float>::infinity())
2787 bank_put[i] = bank_argument.range_max + 0.01;
2789 else if (msg->ranges[i] == -std::numeric_limits<float>::infinity())
2791 bank_put[i] = bank_argument.range_min - 0.01;
2794 else if (std::isnan(msg->ranges[i]))
2797 bank_put[i] = bank_argument.range_max + 0.01;
2802 bank_put[i] = msg->ranges[i];
2812 bank_is_filled =
false;
2823 bank_stamp[bank_index_put] = msg->header.stamp.toSec();
2826 const double alpha = bank_argument.ema_alpha;
2829 const double alpha_prev = 1.0 - bank_argument.ema_alpha;
2830 float * bank_put = bank_ranges_ema[bank_index_put];
2831 float * bank_newest = bank_ranges_ema[bank_index_newest];
2832 for (
unsigned int i=0; i<bank_argument.points_per_scan; ++i)
2834 if (msg->ranges[i] == std::numeric_limits<float>::infinity())
2836 bank_put[i] = bank_argument.range_max + 0.01;
2838 else if (msg->ranges[i] == -std::numeric_limits<float>::infinity())
2840 bank_put[i] = bank_argument.range_min - 0.01;
2842 else if (msg->ranges[i] != msg->ranges[i])
2845 bank_put[i] = bank_argument.range_max + 0.01;
2850 bank_put[i] = alpha * msg->ranges[i] + alpha_prev * bank_newest[i];
2860 if (!bank_is_filled && bank_index_put < bank_index_newest)
2862 bank_is_filled =
true;
2873 const bool discard_message_if_no_points_added)
2875 ROS_DEBUG(
"Init bank (%s)", msg->header.frame_id.c_str());
2877 if (!bank_is_initialized)
2881 ROS_WARN_STREAM(
"The sensor frame (" << msg->header.frame_id.c_str() <<
") seems to be a camera/optical frame. " 2882 "Perhaps sensor_frame_has_z_axis_forward should be set?");
2886 ROS_WARN_STREAM(
"Please note that setting sensor_frame_has_z_axis_forward will cause the ema and " 2887 "objects_closest_points messages to be shown incorrectly.");
2907 if (getOffsetsAndBytes(bank_argument, msg))
2909 ROS_ERROR(
"Cannot read offsets and bytes from message!");
2914 initBank(bank_argument);
2915 return addFirstMessage(msg, discard_message_if_no_points_added);
2921 const bool discard_message_if_no_points_added)
2924 bank_stamp[0] = msg->header.stamp.toSec();
2933 const unsigned int added_points = putPoints(msg);
2936 if (added_points == 0)
2938 ROS_WARN(
"Could not add any points from the PointCloud2 message");
2939 if (discard_message_if_no_points_added)
2947 ROS_DEBUG(
"%s", getStringPutPoints().c_str());
2951 bank_is_filled =
false;
2958 const bool discard_message_if_no_points_added)
2961 bank_stamp[bank_index_put] = msg->header.stamp.toSec();
2967 const unsigned int added_points = putPoints(msg);
2970 if (added_points == 0)
2972 ROS_WARN(
"Could not add any points from the PointCloud2 message");
2973 if (discard_message_if_no_points_added)
2979 ROS_DEBUG(
"%s", getStringPutPoints().c_str());
2986 if (bank_index_put < bank_index_newest)
2988 bank_is_filled =
true;
double object_threshold_max_distance
bool publish_objects_velocity_arrows
double object_threshold_min_speed
std::string PC2_message_y_coordinate_field_name
bool velocity_arrows_use_full_gray_scale
bool publish_objects_closest_point_markers
std::string topic_objects_closest_point_markers
std::string delta_position_line_ns
double object_threshold_bank_tracking_max_delta_distance
virtual long init(BankArgument bank_argument, const sensor_msgs::LaserScan *msg)
virtual long addMessage(const sensor_msgs::LaserScan *msg)
bool publish_objects_delta_position_lines
std::string getStringPutPoints()
void initBank(BankArgument bank_argument)
double PC2_voxel_leaf_size
void getOldIndices(const float range_min, const float range_max, const unsigned int object_width_in_points, const int current_level, const unsigned int levels_searched, const unsigned int index_mean, const unsigned int consecutive_failures_to_find_object, const unsigned int threshold_consecutive_failures_to_find_object, int *index_min_old, int *index_mean_old, int *index_max_old, float *range_sum_old, float *range_at_min_index_old, float *range_at_max_index_old)
Bank(tf2_ros::Buffer *buffer)
void findAndReportMovingObjects()
bool sensor_frame_has_z_axis_forward
ROSCPP_DECL const std::string & getName()
bool velocity_arrows_use_sensor_frame
virtual long addFirstMessage(const sensor_msgs::LaserScan *)
std::string width_line_ns
friend std::ostream & operator<<(std::ostream &os, const BankArgument &ba)
double object_threshold_edge_max_delta_range
std::string node_name_suffix
std::string topic_objects_width_lines
std::string velocity_arrow_ns
INLINE Rall1d< T, V, S > atan(const Rall1d< T, V, S > &x)
std::string PC2_message_x_coordinate_field_name
#define ROS_ASSERT_MSG(cond,...)
double PC2_threshold_z_max
int getOffsetsAndBytes(BankArgument bank_argument, const sensor_msgs::PointCloud2::ConstPtr msg)
std::string topic_objects_velocity_arrows
INLINE Rall1d< T, V, S > sqrt(const Rall1d< T, V, S > &arg)
double PC2_threshold_z_min
std::string topic_objects_delta_position_lines
#define ROS_WARN_STREAM(args)
#define ROS_DEBUG_STREAM(args)
bool velocity_arrows_use_fixed_frame
std::string PC2_message_z_coordinate_field_name
INLINE Rall1d< T, V, S > abs(const Rall1d< T, V, S > &x)
int object_threshold_max_delta_width_in_points
T & transform(const T &in, T &out, const std::string &target_frame, ros::Duration timeout=ros::Duration(0.0)) const
int object_threshold_min_nr_points
#define ROS_ERROR_STREAM(args)
bool sensor_is_360_degrees
bool publish_objects_width_lines
tf2_ros::Buffer * tf_buffer
bool velocity_arrows_use_base_frame
std::string topic_objects
void readPoint(const byte_t *start_of_point, const bool must_reverse_bytes, double *x, double *y, double *z)
void reverseBytes(byte_t *bytes, unsigned int nr_bytes)
unsigned int putPoints(const sensor_msgs::PointCloud2::ConstPtr msg)
double object_threshold_min_confidence