targets.cpp
Go to the documentation of this file.
1 #include "lib/targets.h"
2 
4 {
5  // read parameters
6  double loop_rate;
7  nh.param(this_node::getName() + "/loop_rate", loop_rate, 5.0);
8  Rate rate(loop_rate);
9  int queue_size;
10  nh.param(this_node::getName() + "/queue_size", queue_size, 10);
11  nh.param(this_node::getName() + "/fov", fov, 0.5);
12 
13  // uuid of this cps
14  cps = "";
15 
16  // read done targets from parameter server
17  vector<int> done;
18  nh.getParam(this_node::getNamespace() + "/targets_done", done);
19  for (int t : done) {
20  target_map.emplace(piecewise_construct, forward_as_tuple(t), forward_as_tuple(make_shared<target>(t, TARGET_DONE)));
21  }
22 
23  // publishers and subscribers
24  tracking_pub = nh.advertise<cpswarm_msgs::TargetTracking>("target_tracking", queue_size, true);
25  target_found_pub = nh.advertise<cpswarm_msgs::TargetPositionEvent>("target_found", queue_size);
26  target_update_pub = nh.advertise<cpswarm_msgs::TargetPositionEvent>("target_update", queue_size);
27  target_lost_pub = nh.advertise<cpswarm_msgs::TargetPositionEvent>("target_lost", queue_size);
28  target_done_pub = nh.advertise<cpswarm_msgs::TargetPositionEvent>("target_done", queue_size, true);
29 
30  Subscriber uuid_sub = nh.subscribe("bridge/uuid", queue_size, &targets::uuid_callback, this);
31 
32  // init uuid
33  while (ok() && cps == "") {
34  rate.sleep();
35  spinOnce();
36  }
37 }
38 
40 {
41  // read all potential targets from parameter file
42  vector<double> targets_x;
43  vector<double> targets_y;
44  nh.getParam(this_node::getName() + "/targets_x", targets_x);
45  nh.getParam(this_node::getName() + "/targets_y", targets_y);
46  if (targets_x.size() != targets_y.size()) {
47  ROS_FATAL("Invalid targets specified! Exiting...");
48  shutdown();
49  }
50  else if (targets_x.size() < 1)
51  ROS_INFO("There are no targets!");
52  for (int i = 0; i < targets_x.size(); ++i) {
53  ROS_DEBUG("Target %d at [%.2f, %.2f]", i, targets_x[i], targets_y[i]);
54  geometry_msgs::Pose new_target_pose;
55  new_target_pose.position.x = targets_x[i];
56  new_target_pose.position.y = targets_y[i];
57  new_target_pose.orientation.w = 1;
58  simulated_targets.emplace(piecewise_construct, forward_as_tuple(i), forward_as_tuple(make_shared<target>(i, TARGET_UNKNOWN, new_target_pose)));
59  }
60 }
61 
62 void targets::update (geometry_msgs::Pose pose)
63 {
64  // check if a target is lost
65  for (auto t : target_map) {
66  // update target and inform others in case target is lost
67  if (t.second->lost()) {
68  publish_event("target_lost", t.first);
69  }
70  }
71 
72  // check if a new target is found in simulation
73  for (auto t : simulated_targets) {
74  // target pose
75  geometry_msgs::Pose t_pose = t.second->get_pose();
76 
77  ROS_DEBUG("Target %d distance %.2f < %.2f", t.first, hypot(pose.position.x - t_pose.position.x, pose.position.y - t_pose.position.y), fov);
78 
79  // target is within camera fov
80  if (hypot(pose.position.x - t_pose.position.x, pose.position.y - t_pose.position.y) <= fov) {
81  // publish tracking information
82  cpswarm_msgs::TargetTracking track;
83  track.header.stamp = Time::now();
84  track.id = t.first;
85  track.tf = transform(pose, t_pose);
86  tracking_pub.publish(track);
87  }
88  }
89 }
90 
91 void targets::update (cpswarm_msgs::TargetPositionEvent msg, target_state_t state)
92 {
93  // determine target pose
94  geometry_msgs::Pose pose;
95  pose = msg.pose.pose;
96 
97  ROS_DEBUG("Target %d at [%.2f, %.2f]", msg.id, pose.position.x, pose.position.y);
98 
99  // existing target
100  if (target_map.count(msg.id) > 0) {
101  // get previous state of target
102  target_state_t prev_state = target_map[msg.id]->get_state();
103 
104  // update target
105  target_map[msg.id]->update(state, pose, msg.header.stamp);
106 
107  // publish event for certain state transitions
108  if (prev_state == TARGET_ASSIGNED && state == TARGET_DONE && msg.swarmio.node != "") // only if incoming event
109  publish_event("target_done", msg.id);
110  else if (prev_state == TARGET_ASSIGNED && state == TARGET_TRACKED)
111  publish_event("target_update", msg.id);
112  else if (prev_state == TARGET_TRACKED && state == TARGET_TRACKED)
113  publish_event("target_update", msg.id);
114  else if (prev_state == TARGET_KNOWN && state == TARGET_TRACKED)
115  publish_event("target_found", msg.id);
116  else if (prev_state == TARGET_LOST && state == TARGET_TRACKED)
117  publish_event("target_found", msg.id);
118  else
119  ROS_DEBUG("Not publishing event for target");
120  }
121 
122  // new target
123  else {
124  // add to target map
125  target_map.emplace(piecewise_construct, forward_as_tuple(msg.id), forward_as_tuple(make_shared<target>(msg.id, state, pose, msg.header.stamp)));
126 
127  // publish event if target has been found by this cps
128  if (state == TARGET_TRACKED) {
129  publish_event("target_found", msg.id);
130  }
131  }
132 }
133 
134 void targets::publish_event (string event, int id)
135 {
136  // create target position event
137  cpswarm_msgs::TargetPositionEvent target;
138  geometry_msgs::PoseStamped ps;
139  ps.pose = target_map[id]->get_pose();
140  ps.header.frame_id = "local_origin_ned";
141  target.pose = ps;
142  target.header.stamp = Time::now();
143  target.swarmio.name = event;
144  target.id = id;
145 
146  // publish target position event
147  if (event == "target_found")
148  target_found_pub.publish(target);
149 
150  else if (event == "target_update")
151  target_update_pub.publish(target);
152 
153  else if (event == "target_lost")
154  target_lost_pub.publish(target);
155 
156  else if (event == "target_done")
157  target_done_pub.publish(target);
158 
159  else
160  ROS_ERROR("Not publishing invalid event %s!", event.c_str());
161 }
162 
163 geometry_msgs::Transform targets::transform (geometry_msgs::Pose p1, geometry_msgs::Pose p2) const
164 {
165  // orientation of first point
166  tf2::Quaternion orientation1;
167  tf2::fromMsg(p1.orientation, orientation1);
168 
169  // relative coordinates of second point
170  double dx = p2.position.x - p1.position.x;
171  double dy = p2.position.y - p1.position.y;
172  double distance = hypot(dx, dy);
173  double direction = (M_PI / 2.0) - tf2::getYaw(orientation1) + atan2(dy, dx);
174 
175  // compute transform
176  geometry_msgs::Transform tf;
177 
178  // translation
179  tf.translation.x = -distance * cos(direction); // x is inverted in tracking camera tf
180  tf.translation.y = distance * sin(direction);
181 
182  // rotation
183  p1.orientation.w *= -1; // invert p1
184  tf2::fromMsg(p1.orientation, orientation1);
185  tf2::Quaternion orientation2;
186  tf2::fromMsg(p2.orientation, orientation2);
187  tf2::Quaternion rotation = orientation2 * orientation1;
188  tf.rotation = tf2::toMsg(rotation);
189 
190  return tf;
191 }
192 
193 void targets::uuid_callback (const swarmros::String::ConstPtr& msg)
194 {
195  cps = msg->value;
196 }
targets()
Constructor that initializes the private member variables.
Definition: targets.cpp:3
#define ROS_FATAL(...)
void publish_event(string event, int id)
Publish a target position event.
Definition: targets.cpp:134
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())
unordered_map< unsigned int, shared_ptr< target > > target_map
A map holding ID and target object of all known targets.
Definition: targets.h:104
double fov
Range of the target tracking camera in meter. It is used to simulate target detection. Targets within this distance are detected by the CPS.
Definition: targets.h:119
void uuid_callback(const swarmros::String::ConstPtr &msg)
Callback function to receive the UUID from the communication library.
Definition: targets.cpp:193
geometry_msgs::Transform transform(geometry_msgs::Pose p1, geometry_msgs::Pose p2) const
Compute the transformation between two poses.
Definition: targets.cpp:163
Publisher target_done_pub
Publisher for transmitting information about completed targets locally to other nodes and remotely to...
Definition: targets.h:99
Publisher target_lost_pub
Publisher for transmitting information about lost targets locally to other nodes and remotely to othe...
Definition: targets.h:94
unordered_map< unsigned int, shared_ptr< target > > simulated_targets
A map holding ID and target object of simulated targets, including the ones not yet found...
Definition: targets.h:109
void simulate()
Read simulated targets from parameter file.
Definition: targets.cpp:39
string cps
The UUID of the CPS that owns this class instance.
Definition: targets.h:114
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
void update(geometry_msgs::Pose pose)
Update the state of all targets. If no update has been received for a target within a fixed period...
Definition: targets.cpp:62
void fromMsg(const A &, B &b)
ROSCPP_DECL bool ok()
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
bool sleep()
double getYaw(const A &a)
geometry_msgs::Pose pose
Position of the target.
Definition: target.h:118
B toMsg(const A &a)
A target that is monitored by the CPSs.
Definition: target.h:25
NodeHandle nh
A node handle for the main ROS node.
Definition: targets.h:74
Publisher target_found_pub
Publisher for transmitting information about found targets locally to other nodes and remotely to oth...
Definition: targets.h:84
ROSCONSOLE_DECL void shutdown()
bool getParam(const std::string &key, std::string &s) const
Publisher tracking_pub
Publisher for transmitting target tracking information in simulation.
Definition: targets.h:79
target_state_t
An enumeration for the state of a target.
Definition: target.h:13
Publisher target_update_pub
Publisher for transmitting updated information about targets locally to other nodes and remotely to o...
Definition: targets.h:89
ROSCPP_DECL void spinOnce()
#define ROS_ERROR(...)
geometry_msgs::Pose pose
Current position of the CPS.
#define ROS_DEBUG(...)


target_monitor
Author(s): Micha Sende
autogenerated on Tue Jan 19 2021 03:30:07