worldmodel_geotiff_plugins.cpp
Go to the documentation of this file.
1 //=================================================================================================
2 // Copyright (c) 2012, Johannes Meyer, TU Darmstadt
3 // All rights reserved.
4 
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above copyright
10 // notice, this list of conditions and the following disclaimer in the
11 // documentation and/or other materials provided with the distribution.
12 // * Neither the name of the Flight Systems and Automatic Control group,
13 // TU Darmstadt, nor the names of its contributors may be used to
14 // endorse or promote products derived from this software without
15 // specific prior written permission.
16 
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //=================================================================================================
28 
31 
32 #include <ros/ros.h>
33 #include <hector_worldmodel_msgs/GetObjectModel.h>
34 
35 #include <pluginlib/class_loader.h>
36 #include <fstream>
37 
38 #include <boost/date_time/posix_time/posix_time.hpp>
39 #include <boost/date_time/gregorian/formatters.hpp>
40 
41 #include <boost/tokenizer.hpp>
42 
44 
45 using namespace hector_geotiff;
46 
48 {
49 public:
51  virtual ~MapWriterPlugin();
52 
53  virtual void initialize(const std::string& name);
54  virtual void draw(MapWriterInterface *interface) = 0;
55 
56 protected:
57 
60 
62  std::string name_;
64  std::string class_id_;
65 };
66 
68  : initialized_(false)
69 {}
70 
72 {}
73 
74 void MapWriterPlugin::initialize(const std::string& name)
75 {
76  ros::NodeHandle plugin_nh("~/" + name);
77  std::string service_name_;
78 
79  plugin_nh.param("service_name", service_name_, std::string("worldmodel/get_object_model"));
80  plugin_nh.param("draw_all_objects", draw_all_objects_, false);
81  plugin_nh.param("class_id", class_id_, std::string());
82 
83  service_client_ = nh_.serviceClient<hector_worldmodel_msgs::GetObjectModel>(service_name_);
84 
85  initialized_ = true;
86  this->name_ = name;
87  ROS_INFO_NAMED(name_, "Successfully initialized hector_geotiff MapWriter plugin %s.", name_.c_str());
88 }
89 
91 {
92 public:
93  virtual ~VictimMapWriter() {}
94 
95  void draw(MapWriterInterface *interface)
96  {
97  if (!initialized_) return;
98 
99  hector_worldmodel_msgs::GetObjectModel data;
100  if (!service_client_.call(data)) {
101  ROS_ERROR_NAMED(name_, "Cannot draw victims, service %s failed", service_client_.getService().c_str());
102  return;
103  }
104 
105  std::string team_name;
106  std::string country;
107  std::string mission_name;
108  nh_.getParamCached("/team", team_name);
109  nh_.getParamCached("/country", country);
110  nh_.getParamCached("/mission", mission_name);
111 
112  boost::posix_time::ptime now = ros::Time::now().toBoost();
113  boost::gregorian::date now_date(now.date());
114  boost::posix_time::time_duration now_time(now.time_of_day().hours(), now.time_of_day().minutes(), now.time_of_day().seconds(), 0);
115 
116  std::ofstream description_file((interface->getBasePathAndFileName() + "_victims.csv").c_str());
117  if (description_file.is_open()) {
118  description_file << "\"victims\"" << std::endl;
119  description_file << "\"1.0\"" << std::endl;
120  if (!team_name.empty()) description_file << "\"" << team_name << "\"" << std::endl;
121  if (!country.empty()) description_file << "\"" << country << "\"" << std::endl;
122  description_file << "\"" << now_date << "\"" << std::endl;
123  description_file << "\"" << now_time << "\"" << std::endl;
124  if (!mission_name.empty()) description_file << "\"" << mission_name << "\"" << std::endl;
125  description_file << std::endl;
126  description_file << "id,time,name,x,y,z" << std::endl;
127  }
128 
129  int counter = 0;
130  for(hector_worldmodel_msgs::ObjectModel::_objects_type::const_iterator it = data.response.model.objects.begin(); it != data.response.model.objects.end(); ++it) {
131  const hector_worldmodel_msgs::Object& object = *it;
132  if (!draw_all_objects_ && object.state.state != hector_worldmodel_msgs::ObjectState::CONFIRMED) continue;
133  if (!class_id_.empty() && object.info.class_id != class_id_) continue;
134 
135  Eigen::Vector2f coords;
136  coords.x() = object.pose.pose.position.x;
137  coords.y() = object.pose.pose.position.y;
138  interface->drawObjectOfInterest(coords, boost::lexical_cast<std::string>(++counter), MapWriterInterface::Color(240,10,10));
139 
140  if (description_file.is_open()) {
141  boost::posix_time::time_duration time_of_day(object.header.stamp.toBoost().time_of_day());
142  boost::posix_time::time_duration time(time_of_day.hours(), time_of_day.minutes(), time_of_day.seconds(), 0);
143  description_file << counter << "," << time << "," << object.info.object_id << "," << object.pose.pose.position.x << "," << object.pose.pose.position.y << "," << object.pose.pose.position.z << std::endl;
144  }
145  }
146  }
147 };
148 
150 {
151 public:
152  virtual ~QRCodeMapWriter() {}
153 
154  void draw(MapWriterInterface *interface)
155  {
156  if (!initialized_) return;
157 
158  hector_worldmodel_msgs::GetObjectModel data;
159  if (!service_client_.call(data)) {
160  ROS_ERROR_NAMED(name_, "Cannot draw victims, service %s failed", service_client_.getService().c_str());
161  return;
162  }
163 
164  std::string team_name;
165  std::string country;
166  std::string mission_name;
167  nh_.getParamCached("/team", team_name);
168  nh_.getParamCached("/country", country);
169  nh_.getParamCached("/mission", mission_name);
170 
171  boost::posix_time::ptime now = ros::Time::now().toBoost();
172  boost::gregorian::date now_date(now.date());
173  boost::posix_time::time_duration now_time(now.time_of_day().hours(), now.time_of_day().minutes(), now.time_of_day().seconds(), 0);
174 
175  std::ofstream description_file((interface->getBasePathAndFileName() + "_qr.csv").c_str());
176  if (description_file.is_open()) {
177  description_file << "\"qr codes\"" << std::endl;
178  description_file << "\"1.0\"" << std::endl;
179  if (!team_name.empty()) description_file << "\"" << team_name << "\"" << std::endl;
180  if (!country.empty()) description_file << "\"" << country << "\"" << std::endl;
181  description_file << "\"" << now_date << "\"" << std::endl;
182  description_file << "\"" << now_time << "\"" << std::endl;
183  if (!mission_name.empty()) description_file << "\"" << mission_name << "\"" << std::endl;
184  description_file << std::endl;
185  description_file << "id,time,text,x,y,z" << std::endl;
186  }
187 
188 // hector_worldmodel_msgs::Object test_obj;
189 // test_obj.state.state = hector_worldmodel_msgs::ObjectState::CONFIRMED;
190 
191 // test_obj.info.class_id = "qrcode";
192 // test_obj.info.name = "Y_25_arena_2.4mm_Yaounde";
193 // test_obj.info.object_id = "qrcode_0";
194 // data.response.model.objects.push_back(test_obj);
195 
196 // test_obj.info.class_id = "qrcode";
197 // test_obj.info.name = "Y_25_arena_6mm_yuccas";
198 // test_obj.info.object_id = "qrcode_1";
199 // data.response.model.objects.push_back(test_obj);
200 
201 // test_obj.info.class_id = "qrcode";
202 // test_obj.info.name = "Y_23_arena_6mm_yoked";
203 // test_obj.info.object_id = "qrcode_0";
204 // test_obj.pose.pose.position.x = 0.3;
205 // data.response.model.objects.push_back(test_obj);
206 
207 // test_obj.info.class_id = "qrcode";
208 // test_obj.info.name = "Y_28_arena_6mm_yukking";
209 // test_obj.info.object_id = "qrcode_0";
210 // test_obj.pose.pose.position.x = 0.3;
211 // data.response.model.objects.push_back(test_obj);
212 
213 // test_obj.info.class_id = "qrcode";
214 // test_obj.info.name = "Y_23_arena_6mm_yoked";
215 // test_obj.info.object_id = "qrcode_0";
216 // test_obj.pose.pose.position.x = 0.3;
217 // data.response.model.objects.push_back(test_obj);
218 
219 // test_obj.info.class_id = "qrcode";
220 // test_obj.info.name = "Y_13_arena_6mm_Yorkshire";
221 // test_obj.info.object_id = "qrcode_0";
222 // test_obj.pose.pose.position.x = 0.3;
223 // data.response.model.objects.push_back(test_obj);
224 
225 // test_obj.info.class_id = "qrcode";
226 // test_obj.info.name = "Y_11_arena_6mm_yakking";
227 // test_obj.info.object_id = "qrcode_0";
228 // test_obj.pose.pose.position.x = 0.3;
229 // data.response.model.objects.push_back(test_obj);
230 
231 // test_obj.info.class_id = "qrcode";
232 // test_obj.info.name = "VictYel_1_yelled";
233 // test_obj.info.object_id = "qrcode_0";
234 // test_obj.pose.pose.position.x = 0.3;
235 // data.response.model.objects.push_back(test_obj);
236 
237  int counter = 0;
238  for(hector_worldmodel_msgs::ObjectModel::_objects_type::const_iterator it = data.response.model.objects.begin(); it != data.response.model.objects.end(); ++it) {
239  const hector_worldmodel_msgs::Object& object = *it;
240  if (!class_id_.empty() && object.info.class_id != class_id_) continue;
241  if (!draw_all_objects_ && object.state.state != hector_worldmodel_msgs::ObjectState::CONFIRMED) continue;
242  if (object.state.state == hector_worldmodel_msgs::ObjectState::DISCARDED) continue;
243 
244  ++counter;
245 
246  // add only largest qr codes into geotiff
247  if (isLargest(object, data.response.model.objects)) {
248  Eigen::Vector2f coords;
249  coords.x() = object.pose.pose.position.x;
250  coords.y() = object.pose.pose.position.y;
251  interface->drawObjectOfInterest(coords, boost::lexical_cast<std::string>(counter), MapWriterInterface::Color(10,10,240));
252  }
253 
254  if (description_file.is_open()) {
255  boost::posix_time::time_duration time_of_day(object.header.stamp.toBoost().time_of_day());
256  boost::posix_time::time_duration time(time_of_day.hours(), time_of_day.minutes(), time_of_day.seconds(), 0);
257  description_file << counter << "," << time << "," << object.info.name << "," << object.pose.pose.position.x << "," << object.pose.pose.position.y << "," << object.pose.pose.position.z << std::endl;
258  }
259  }
260 
261  description_file.close();
262  }
263 
264 protected:
265  float getSizeFromName(const std::string& name)
266  {
267  try {
268  boost::tokenizer<boost::char_separator<char> > tokens(name, boost::char_separator<char>("_"));
269  boost::tokenizer<boost::char_separator<char> >::const_iterator it = tokens.begin();
270 
271  if (it == tokens.end())
272  return -1.0f;
273 
274  for (unsigned int i = 0; i < 3; i++) {
275  if (++it == tokens.end())
276  return -1.0f;
277  }
278 
279  return it->size() > 2 ? boost::lexical_cast<float>(it->substr(0, it->size()-2)) : -1.0f;
280  }
281  catch (boost::bad_lexical_cast&) {
282  return -1.0f;
283  }
284  }
285 
286  bool isLargest(const hector_worldmodel_msgs::Object& object, const std::vector<hector_worldmodel_msgs::Object>& objects )
287  {
288  // determine size of qr code
289  float size = getSizeFromName(object.info.name);
290 
291  if (size == -1.0f) // QR does not include size information
292  return true;
293 
294  // compare size of other qr codes
295  for (hector_worldmodel_msgs::ObjectModel::_objects_type::const_iterator it = objects.begin(); it != objects.end(); ++it) {
296  const hector_worldmodel_msgs::Object& object2 = *it;
297 
298  float dist_sqr = (object.pose.pose.position.x-object2.pose.pose.position.x) * (object.pose.pose.position.x-object2.pose.pose.position.x)
299  +(object.pose.pose.position.y-object2.pose.pose.position.y) * (object.pose.pose.position.y-object2.pose.pose.position.y);
300 
301  // check if both qrcodes are at same position+tolerance
302  if (dist_sqr < 0.75f) {
303  float size2 = getSizeFromName(object2.info.name);
304  if (size2 > size) {
305  return false;
306  }
307  }
308  }
309 
310  return true;
311  }
312 };
313 
314 } // namespace
315 
316 //register this planner as a MapWriterPluginInterface plugin
320 
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
virtual std::string getBasePathAndFileName() const =0
#define ROS_INFO_NAMED(name,...)
f
ROSCONSOLE_DECL void initialize()
bool getParamCached(const std::string &key, std::string &s) const
bool call(MReq &req, MRes &res)
std_msgs::Header * header(M &m)
bool isLargest(const hector_worldmodel_msgs::Object &object, const std::vector< hector_worldmodel_msgs::Object > &objects)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
virtual void drawObjectOfInterest(const Eigen::Vector2f &coords, const std::string &txt, const Color &color)=0
#define ROS_ERROR_NAMED(name,...)
static Time now()
std::string getService()
boost::posix_time::ptime toBoost() const
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)


hector_worldmodel_geotiff_plugins
Author(s): Johannes Meyer
autogenerated on Mon Jun 10 2019 13:35:15