49 #include <sensor_msgs/LaserScan.h> 50 #include <visualization_msgs/Marker.h> 51 #include <visualization_msgs/MarkerArray.h> 60 #include <find_moving_objects/MovingObject.h> 61 #include <find_moving_objects/MovingObjectArray.h> 65 #define MIN(X,Y) (X<Y?X:Y) 66 #define MAX(X,Y) (X>Y?X:Y) 68 #define WL(W) std::setw(W) << std::left 69 #define WR(W) std::setw(W) << std::right 92 void moaCallback(
const find_moving_objects::MovingObjectArray::ConstPtr & msg)
95 static std::vector<std::string> g_msg_buffer_moa_senders;
101 if (strcmp(msg->origin_node_name.c_str(), g_msg_buffer_moa_senders[sender_index].c_str()) == 0)
112 if (sender_index == g_nr_senders)
115 g_msg_buffer_moa_senders.push_back(msg->origin_node_name);
158 bool print_received_objects;
159 bool publish_objects;
160 bool publish_objects_closest_points_markers;
161 bool publish_objects_velocity_arrows;
162 bool velocity_arrows_use_full_gray_scale;
163 bool velocity_arrows_use_sensor_frame_param;
164 bool velocity_arrows_use_base_frame_param;
165 bool velocity_arrows_use_fixed_frame_param;
166 std::string topic_moving_objects_enhanced;
167 std::string topic_objects_closest_point_markers;
168 std::string topic_objects_velocity_arrows;
169 double threshold_min_confidence;
170 double threshold_max_delta_time_for_different_sources;
171 double threshold_max_delta_position;
172 double threshold_max_delta_velocity;
173 bool ignore_z_map_coordinate_for_position;
174 nh_priv.
param(
"verbose", verbose,
false);
175 nh_priv.
param(
"print_received_objects", print_received_objects,
false);
176 nh_priv.
param(
"publish_objects", publish_objects,
true);
177 nh_priv.
param(
"publish_objects_closest_points_markers", publish_objects_closest_points_markers,
true);
178 nh_priv.
param(
"publish_objects_velocity_arrows", publish_objects_velocity_arrows,
true);
179 nh_priv.
param(
"velocity_arrows_use_full_gray_scale", velocity_arrows_use_full_gray_scale,
false);
180 nh_priv.
param(
"velocity_arrows_use_sensor_frame", velocity_arrows_use_sensor_frame_param,
false);
181 nh_priv.
param(
"velocity_arrows_use_base_frame", velocity_arrows_use_base_frame_param,
false);
182 nh_priv.
param(
"velocity_arrows_use_fixed_frame", velocity_arrows_use_fixed_frame_param,
false);
183 nh_priv.
param(
"threshold_min_confidence", threshold_min_confidence, 0.0);
184 nh_priv.
param(
"threshold_max_delta_time_for_different_sources", threshold_max_delta_time_for_different_sources, 0.2);
185 nh_priv.
param(
"threshold_max_delta_position", threshold_max_delta_position, 0.1);
186 nh_priv.
param(
"threshold_max_delta_velocity", threshold_max_delta_velocity, 0.1);
187 nh_priv.
param(
"ignore_z_map_coordinate_for_position", ignore_z_map_coordinate_for_position,
true);
191 bool velocity_arrows_use_sensor_frame =
false;
192 bool velocity_arrows_use_base_frame =
false;
193 bool velocity_arrows_use_fixed_frame =
false;
194 if (velocity_arrows_use_sensor_frame_param)
195 velocity_arrows_use_sensor_frame =
true;
196 else if (velocity_arrows_use_base_frame_param)
197 velocity_arrows_use_base_frame =
true;
198 else if (velocity_arrows_use_fixed_frame_param)
199 velocity_arrows_use_fixed_frame =
true;
200 const double threshold_max_delta_position_line_squared = threshold_max_delta_position *
201 threshold_max_delta_position;
202 const double threshold_max_delta_velocity_squared = threshold_max_delta_velocity * threshold_max_delta_velocity;
206 find_moving_objects::MovingObjectArray::ConstPtr msg_sender;
207 find_moving_objects::MovingObjectArray::ConstPtr msg_other;
208 int sender_index = -1;
211 sensor_msgs::LaserScan msg_objects_closest_point_markers;
212 const unsigned int points = 720;
213 const double range_min = 0.0;
214 const double range_max = 100.0;
215 const double resolution =
TWO_PI / points;
216 const double inverted_resolution = points /
TWO_PI;
217 const double out_of_range = range_max + 10.0;
218 if (publish_objects_closest_points_markers)
220 msg_objects_closest_point_markers.header.seq = 0;
221 msg_objects_closest_point_markers.angle_min = -M_PI;
222 msg_objects_closest_point_markers.angle_max = M_PI;
223 msg_objects_closest_point_markers.angle_increment = resolution;
224 msg_objects_closest_point_markers.time_increment = 0.0;
225 msg_objects_closest_point_markers.scan_time = 0.0;
226 msg_objects_closest_point_markers.range_min = range_min;
227 msg_objects_closest_point_markers.range_max = range_max;
228 msg_objects_closest_point_markers.intensities.resize(points);
229 msg_objects_closest_point_markers.ranges.resize(points);
230 for (
unsigned int i=0; i<points; ++i)
232 msg_objects_closest_point_markers.ranges[i] = out_of_range;
233 msg_objects_closest_point_markers.intensities[i] = 0.0;
236 visualization_msgs::Marker msg_objects_velocity_arrow;
237 if (publish_objects_velocity_arrows)
239 msg_objects_velocity_arrow.ns =
"fused_velocity_arrow";
240 msg_objects_velocity_arrow.type = visualization_msgs::Marker::ARROW;
241 msg_objects_velocity_arrow.action = visualization_msgs::Marker::ADD;
248 msg_objects_velocity_arrow.pose.orientation.w = 1.0;
249 msg_objects_velocity_arrow.scale.x = 0.05;
250 msg_objects_velocity_arrow.scale.y = 0.1;
255 msg_objects_velocity_arrow.color.a = 1.0;
257 msg_objects_velocity_arrow.frame_locked =
true;
258 msg_objects_velocity_arrow.points.resize(2);
259 msg_objects_velocity_arrow.points[0].z = 0.0;
260 msg_objects_velocity_arrow.points[1].z = 0.0;
262 visualization_msgs::MarkerArray msg_objects_velocity_arrows;
263 unsigned int arrow_seq = 0;
269 unsigned int nr_senders = 0;
294 if (print_received_objects)
296 std::ostringstream stream;
297 stream <<
"Received moving objects from " << msg_sender->origin_node_name \
298 <<
" (sender " << sender_index+1 <<
"/" << nr_senders <<
"):" << std::endl \
299 << *msg_sender << std::endl;
300 std::string
string = stream.str();
306 const unsigned int nr_sender_objects = msg_sender->objects.size();
307 if (0 < nr_sender_objects)
310 find_moving_objects::MovingObjectArray moa;
319 const double sender_stamp = msg_sender->objects[0].header.stamp.toSec();
322 unsigned int nr_objects = 0;
323 for (
unsigned int j=0; j<nr_sender_objects; ++j)
326 const find_moving_objects::MovingObject * sender_mo = & (msg_sender->objects[j]);
329 unsigned int nr_matching_senders = 0;
330 double confidence_sum = 0.0;
333 for (
unsigned int i=0; i<nr_senders; ++i)
336 if (i != sender_index)
345 const unsigned int nr_other_objects = msg_other->objects.size();
348 if (0 < nr_other_objects)
351 const double other_stamp = msg_other->objects[0].header.stamp.toSec();
354 if (fabs(sender_stamp - other_stamp) < threshold_max_delta_time_for_different_sources)
357 for (
unsigned int k=0; k<nr_other_objects; ++k)
360 const find_moving_objects::MovingObject * other_mo = & (msg_other->objects[k]);
363 const double dx = sender_mo->position_in_map_frame.x - other_mo->position_in_map_frame.x;
364 const double dy = sender_mo->position_in_map_frame.y - other_mo->position_in_map_frame.y;
365 const double dz = ignore_z_map_coordinate_for_position ?
367 sender_mo->position_in_map_frame.z - other_mo->position_in_map_frame.z;
368 const double dp2 = dx*dx + dy*dy + dz*dz;
370 const double dvx = sender_mo->velocity_in_map_frame.x - other_mo->velocity_in_map_frame.x;
371 const double dvy = sender_mo->velocity_in_map_frame.y - other_mo->velocity_in_map_frame.y;
372 const double dvz = sender_mo->velocity_in_map_frame.z - other_mo->velocity_in_map_frame.z;
373 const double dv2 = dvx*dvx + dvy*dvy + dvz*dvz;
380 if (dp2 < threshold_max_delta_position_line_squared &&
381 dv2 < threshold_max_delta_velocity_squared)
385 nr_matching_senders++;
386 confidence_sum += other_mo->confidence;
395 ROS_DEBUG_STREAM(
"Increasing confidence of object based on " << nr_matching_senders <<
" matching senders");
398 double confidence = sender_mo->confidence;
399 if (0 < nr_matching_senders)
401 confidence += confidence_sum / nr_matching_senders;
404 confidence =
MIN(1.0, confidence);
405 confidence =
MAX(0.0, confidence);
409 if (threshold_min_confidence <= confidence)
411 moa.objects.push_back(*sender_mo);
413 moa.objects.back().confidence = confidence;
427 if (publish_objects_closest_points_markers)
430 msg_objects_closest_point_markers.header.seq++;
431 msg_objects_closest_point_markers.header.stamp = moa.objects[0].header.stamp;
434 msg_objects_closest_point_markers.header.frame_id = moa.objects[0].header.frame_id;
437 std::vector<int> indices;
438 unsigned int nr_indices = 0;
439 for (
unsigned int a=0; a<nr_objects; ++a)
442 double angle = moa.objects[a].angle_for_closest_distance;
445 if (angle < 0 ||
TWO_PI <= angle)
451 int index = angle * inverted_resolution;
454 indices.push_back(index);
458 msg_objects_closest_point_markers.ranges[index] = moa.objects[a].closest_distance;
462 g_pub_objects_closest_point_markers.
publish(msg_objects_closest_point_markers);
465 for (
unsigned k=0; k<nr_indices; ++k)
467 msg_objects_closest_point_markers.ranges[indices[k]] = out_of_range;
472 if (publish_objects_velocity_arrows)
474 msg_objects_velocity_arrow.header.seq = ++arrow_seq;
476 for (
unsigned int a=0; a<nr_objects; ++a)
478 msg_objects_velocity_arrow.header.stamp = moa.objects[a].header.stamp;
479 if (velocity_arrows_use_sensor_frame)
481 msg_objects_velocity_arrow.header.frame_id = moa.objects[a].header.frame_id;
482 msg_objects_velocity_arrow.points[0].x = moa.objects[a].position.x;
483 msg_objects_velocity_arrow.points[0].y = moa.objects[a].position.y;
484 msg_objects_velocity_arrow.points[1].x = moa.objects[a].position.x + moa.objects[a].velocity.x;
485 msg_objects_velocity_arrow.points[1].y = moa.objects[a].position.y + moa.objects[a].velocity.y;
487 else if (velocity_arrows_use_base_frame)
489 msg_objects_velocity_arrow.header.frame_id = moa.objects[a].base_frame;
490 msg_objects_velocity_arrow.points[0].x = moa.objects[a].position_in_base_frame.x;
491 msg_objects_velocity_arrow.points[0].y = moa.objects[a].position_in_base_frame.y;
492 msg_objects_velocity_arrow.points[1].x = moa.objects[a].position_in_base_frame.x +
493 moa.objects[a].velocity_in_base_frame.x;
494 msg_objects_velocity_arrow.points[1].y = moa.objects[a].position_in_base_frame.y +
495 moa.objects[a].velocity_in_base_frame.y;
497 else if (velocity_arrows_use_fixed_frame)
499 msg_objects_velocity_arrow.header.frame_id = moa.objects[a].fixed_frame;
500 msg_objects_velocity_arrow.points[0].x = moa.objects[a].position_in_fixed_frame.x;
501 msg_objects_velocity_arrow.points[0].y = moa.objects[a].position_in_fixed_frame.y;
502 msg_objects_velocity_arrow.points[1].x = moa.objects[a].position_in_fixed_frame.x +
503 moa.objects[a].velocity_in_fixed_frame.x;
504 msg_objects_velocity_arrow.points[1].y = moa.objects[a].position_in_fixed_frame.y +
505 moa.objects[a].velocity_in_fixed_frame.y;
509 msg_objects_velocity_arrow.header.frame_id = moa.objects[a].map_frame;
510 msg_objects_velocity_arrow.points[0].x = moa.objects[a].position_in_map_frame.x;
511 msg_objects_velocity_arrow.points[0].y = moa.objects[a].position_in_map_frame.y;
512 msg_objects_velocity_arrow.points[1].x = moa.objects[a].position_in_map_frame.x +
513 moa.objects[a].velocity_in_map_frame.x;
514 msg_objects_velocity_arrow.points[1].y = moa.objects[a].position_in_map_frame.y +
515 moa.objects[a].velocity_in_map_frame.y;
517 msg_objects_velocity_arrow.id = a;
520 float adapted_confidence = moa.objects[a].confidence;
521 if (velocity_arrows_use_full_gray_scale && threshold_min_confidence < 1)
523 adapted_confidence = (moa.objects[a].confidence - threshold_min_confidence) /
524 (1 - threshold_min_confidence);
526 msg_objects_velocity_arrow.color.r = adapted_confidence;
527 msg_objects_velocity_arrow.color.g = adapted_confidence;
528 msg_objects_velocity_arrow.color.b = adapted_confidence;
531 msg_objects_velocity_arrows.markers.push_back(msg_objects_velocity_arrow);
534 msg_objects_velocity_arrows.markers[a].ns.append(msg_sender->origin_node_name);
538 g_pub_objects_velocity_arrows.
publish(msg_objects_velocity_arrows);
541 msg_objects_velocity_arrows.markers.clear();
552 int main(
int argc,
char** argv)
563 std::string topic_moving_objects_enhanced;
564 std::string topic_objects_velocity_arrows;
565 std::string topic_objects_closest_points_markers;
566 int publish_buffer_size;
567 nh_priv.
param(
"topic_moving_objects_enhanced", topic_moving_objects_enhanced, std::string(
"moving_objects_enhanced"));
568 nh_priv.
param(
"topic_objects_velocity_arrows", topic_objects_velocity_arrows, std::string(
"objects_velocity_arrows"));
569 nh_priv.
param(
"topic_objects_closest_points_markers", topic_objects_closest_points_markers, std::string(
"objects_closest_points_markers"));
570 nh_priv.
param(
"publish_buffer_size", publish_buffer_size, 2);
571 g_pub_moaf = g_node->
advertise<find_moving_objects::MovingObjectArray>
572 (topic_moving_objects_enhanced,
573 publish_buffer_size);
574 g_pub_objects_velocity_arrows = g_node->
advertise<visualization_msgs::MarkerArray>
575 (topic_objects_velocity_arrows,
576 publish_buffer_size);
577 g_pub_objects_closest_point_markers = g_node->
advertise<sensor_msgs::LaserScan>
578 (topic_objects_closest_points_markers,
579 publish_buffer_size);
582 pthread_t moa_handler;
585 ROS_ERROR(
"Failed to create thread for handling MovingObjectArray messages");
592 nh_priv.
param(
"subscribe_topic", subscribe_topic, std::string(
"moving_objects"));
594 nh_priv.
param(
"subscribe_buffer_size", subscribe_buffer_size, 10);
596 subscribe_buffer_size,
void moaCallback(const find_moving_objects::MovingObjectArray::ConstPtr &msg)
void publish(const boost::shared_ptr< M > &message) const
TF2SIMD_FORCE_INLINE tf2Scalar angle(const Quaternion &q1, const Quaternion &q2)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
pthread_mutex_t g_mutex_moa
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
ROSCPP_DECL const std::string & getName()
int subscribe_buffer_size
ros::Publisher g_pub_objects_velocity_arrows
ROSCPP_DECL void spin(Spinner &spinner)
void * moaHandlerBody(void *arg)
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
ros::Publisher g_pub_moaf
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
int main(int argc, char **argv)
#define ROS_DEBUG_STREAM(args)
std::string subscribe_topic
ros::Publisher g_pub_objects_closest_point_markers
pthread_cond_t g_cond_moa
static bool waitForValid()
std::vector< find_moving_objects::MovingObjectArray::ConstPtr > g_msg_buffer_moa