hector_map_server.cpp
Go to the documentation of this file.
1 //=================================================================================================
2 // Copyright (c) 2011, Stefan Kohlbrecher, 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 Simulation, Systems Optimization and Robotics
13 // group, 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 
29 #include <stdio.h>
30 #include <stdlib.h>
31 //#include <libgen.h>
32 //#include <fstream>
33 
34 #include "ros/ros.h"
35 #include "ros/console.h"
36 #include "nav_msgs/MapMetaData.h"
37 #include "nav_msgs/OccupancyGrid.h"
38 
39 #include <boost/thread.hpp>
40 
41 #include <tf/transform_listener.h>
42 
43 #include "nav_msgs/GetMap.h"
44 
47 
48 #include "hector_nav_msgs/GetDistanceToObstacle.h"
49 #include "hector_nav_msgs/GetSearchPosition.h"
50 
51 
53 {
54 public:
55  OccupancyGridContainer(std::string sub_topic, std::string prefix, ros::NodeHandle& nh, HectorDrawings* drawing_provider, tf::TransformListener* tf_)
56  : drawing_provider_(drawing_provider)
57  , tf_(tf_)
58  {
59 
60  std::string service_name = "map";
62 
63  ros::NodeHandle pnh("~");
64  std::string lookup_service_name = "get_distance_to_obstacle";
66 
67  std::string get_search_pos_service_name = "get_search_position";
69 
71  }
72 
74  {}
75 
76  bool mapServiceCallback(nav_msgs::GetMap::Request &req,
77  nav_msgs::GetMap::Response &res )
78  {
79  ROS_INFO("hector_map_server map service called");
80 
81  if (!map_ptr_){
82  ROS_INFO("map_server has no map yet, no map service available");
83  return false;
84  }
85 
86  res.map = *map_ptr_;
87 
88  return true;
89  }
90 
91  bool lookupServiceCallback(hector_nav_msgs::GetDistanceToObstacle::Request &req,
92  hector_nav_msgs::GetDistanceToObstacle::Response &res )
93  {
94  //ROS_INFO("hector_map_server lookup service called");
95 
96 
97  if (!map_ptr_){
98  ROS_INFO("map_server has no map yet, no lookup service available");
99  return false;
100  }
101 
102  tf::StampedTransform stamped_pose;
103 
104 
105 
106  try{
107  tf_->waitForTransform(map_ptr_->header.frame_id,req.point.header.frame_id, req.point.header.stamp, ros::Duration(1.0));
108  tf_->lookupTransform(map_ptr_->header.frame_id, req.point.header.frame_id, req.point.header.stamp, stamped_pose);
109 
110  tf::Point v2_tf;
111  tf::pointMsgToTF(req.point.point,v2_tf);
112 
113  tf::Vector3 v1 = stamped_pose * tf::Vector3(0.0, 0.0, 0.0);
114  tf::Vector3 v2 = stamped_pose * v2_tf;
115  tf::Vector3 diff = v2 - v1;
116  v2 = v1 + diff / tf::Vector3(diff.x(), diff.y(), 0.0).length() * 5.0f;
117 
118  Eigen::Vector2f start(v1.x(),v1.y());
119  Eigen::Vector2f end(v2.x(),v2.y());
120 
121  Eigen::Vector2f hit_world;
122  //float dist = dist_meas_.getDist(start,end, &hit_world);
123  float dist = dist_meas_.getDist(start,end,&hit_world);
124 
125  if (dist >=0.0f){
126  tf::Vector3 diff (v2-v1);
127 
128  float angle = diff.angle(tf::Vector3(diff.x(),diff.y(),0.0f));
129 
130  res.distance = dist/cos(angle);
131 
132  }else{
133  res.distance = -1.0f;
134  }
135 
136  //debug drawing
137  if (false){
138 
139  float cube_scale = map_ptr_->info.resolution;
140  drawing_provider_->setColor(1.0, 0.0, 0.0);
141  drawing_provider_->setScale(static_cast<double>(cube_scale));
142 
144 
145  drawing_provider_->setColor(0.0, 1.0, 0.0);
147 
148  if (dist >= 0.0f){
149  drawing_provider_->setColor(0.0, 0.0, 1.0);
150  drawing_provider_->drawPoint(hit_world);
151  }
152 
154  }
155 
156  return true;
157 
158  }
159  catch(tf::TransformException e)
160  {
161  ROS_ERROR("Transform failed in lookup distance service call: %s",e.what());
162  }
163 
164  return false;
165  }
166 
167  bool getSearchPosServiceCallback(hector_nav_msgs::GetSearchPosition::Request &req,
168  hector_nav_msgs::GetSearchPosition::Response &res )
169  {
170  if (!map_ptr_){
171  ROS_INFO("map_server has no map yet, no get best search pos service available");
172  return false;
173  }
174 
175  try{
176 
177  tf::Stamped<tf::Pose> ooi_pose, transformed_pose, search_position;
178  tf::poseStampedMsgToTF(req.ooi_pose, ooi_pose);
179 
180  tf_->waitForTransform(map_ptr_->header.frame_id, req.ooi_pose.header.frame_id, req.ooi_pose.header.stamp, ros::Duration(1.0));
181  tf_->transformPose(map_ptr_->header.frame_id, ooi_pose, transformed_pose);
182 
183  tf::Vector3 direction(-req.distance, 0.0, 0.0);
184  search_position = transformed_pose;
185  search_position.setOrigin(transformed_pose.getOrigin() + transformed_pose.getBasis() * direction);
186 
187  tf::poseStampedTFToMsg(search_position, res.search_pose);
188 
189  return true;
190 
191 // //tf::Point v2_tf;
192 // //tf::pointMsgToTF(req.point.point,v2_tf);
193 
194 // tf::Vector3 v1 = stamped_pose * tf::Vector3(0.0, 0.0, 0.0);
195 
196 // //warning: 3D!
197 // tf::Vector3 v2 = stamped_pose * tf::Vector3(-1.0, 0.0, 0.0);
198 
199 // tf::Vector3 dir = v2-v1;
200 
201 // Eigen::Vector2f dir_2d (dir.x(), dir.y());
202 
203 // dir_2d.normalize();
204 
205 // Eigen::Vector2f searchPos (Eigen::Vector2f(v1.x(),v1.y()) + (dir_2d*0.5f));
206 
207 // //copy original pose message but set translation
208 // res.search_pose.pose = ooi_pose.pose;
209 
210 // res.search_pose.pose.position.x = searchPos.x();
211 // res.search_pose.pose.position.y = searchPos.y();
212 
213  //return true;
214 
215 
216  //Eigen::Vector2f ooi_pos(v1.x(),v1.y());
217  //Eigen::Vector2f sample_point_pos(v2.x(),v2.y());
218 
219 
220  //float dist_from_target = dist_meas_.getDist(ooi_pos,sample_point_pos);
221  //float dist_from_sample_point = dist_meas_.getDist(sample_point_pos, ooi_pos);
222 
223 
224 
225 /*
226  if (dist >=0.0f){
227  tf::Vector3 diff (v2-v1);
228 
229  float angle = diff.angle(tf::Vector3(diff.x(),diff.y(),0.0f));
230 
231  res.distance = dist/cos(angle);
232 
233 
234  //debug drawing
235  if (true){
236 
237  float cube_scale = map_ptr_->info.resolution;
238  drawing_provider_->setColor(1.0, 0.0, 0.0);
239  drawing_provider_->setScale(static_cast<double>(cube_scale));
240 
241  drawing_provider_->drawPoint(start);
242  drawing_provider_->drawPoint(end);
243 
244  if (dist >= 0.0f){
245  drawing_provider_->setColor(0.0, 0.0, 1.0);
246  drawing_provider_->drawPoint(hit_world);
247  }
248 
249  drawing_provider_->sendAndResetData();
250  }
251 
252  }
253  */
254  //return true;
255 
256  } catch(tf::TransformException e){
257  ROS_ERROR("Transform failed in getSearchPosition service call: %s",e.what());
258  }
259 
260  return false;
261  }
262 
263  void mapCallback(const nav_msgs::OccupancyGridConstPtr& map)
264  {
265  map_ptr_ = map;
266 
268  }
269 
270  //Services
274 
275  //Subscriber
277 
279 
282 
283  //nav_msgs::MapMetaData meta_data_message_;
284  nav_msgs::GetMap::Response map_resp_;
285 
286  nav_msgs::OccupancyGridConstPtr map_ptr_;
287 };
288 
290 {
291  public:
294  {
295  std::string frame_id;
296 
297  hector_drawings_ = new HectorDrawings();
298  hector_drawings_->setNamespace("map_server");
299 
300  mapContainer = new OccupancyGridContainer("map", "" ,private_nh, hector_drawings_,&tf_);
301  }
302 
304  {
305  delete mapContainer;
306 
307 
308  delete hector_drawings_;
309  }
310 
311 
312 public:
314 private:
315 
318 };
319 
320 int main(int argc, char **argv)
321 {
322  ros::init(argc, argv, "hector_map_server");
323  ros::NodeHandle nh;
324 
325  HectorMapServer ms(nh);
326 
327  ros::spin();
328 
329  return 0;
330 }
331 
HectorDrawings * drawing_provider_
tf::TransformListener tf_
ros::ServiceServer dist_lookup_service_
static void pointMsgToTF(const geometry_msgs::Point &msg_v, Point &bt_v)
bool getSearchPosServiceCallback(hector_nav_msgs::GetSearchPosition::Request &req, hector_nav_msgs::GetSearchPosition::Response &res)
virtual void sendAndResetData()
HectorDrawings * hector_drawings_
ros::ServiceServer get_search_pos_service_
f
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
virtual void setScale(double scale)
HectorMapTools::DistanceMeasurementProvider dist_meas_
OccupancyGridContainer(std::string sub_topic, std::string prefix, ros::NodeHandle &nh, HectorDrawings *drawing_provider, tf::TransformListener *tf_)
static void poseStampedTFToMsg(const Stamped< Pose > &bt, geometry_msgs::PoseStamped &msg)
virtual void drawPoint(const Eigen::Vector2f &pointWorldFrame)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
bool lookupServiceCallback(hector_nav_msgs::GetDistanceToObstacle::Request &req, hector_nav_msgs::GetDistanceToObstacle::Response &res)
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
TFSIMD_FORCE_INLINE tfScalar angle(const Vector3 &v) const
nav_msgs::GetMap::Response map_resp_
TFSIMD_FORCE_INLINE tfScalar angle(const Quaternion &q1, const Quaternion &q2)
ROSCPP_DECL void spin(Spinner &spinner)
bool waitForTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, const ros::Duration &timeout, const ros::Duration &polling_sleep_duration=ros::Duration(0.01), std::string *error_msg=NULL) const
TFSIMD_FORCE_INLINE const tfScalar & x() const
int main(int argc, char **argv)
tf::TransformListener * tf_
HectorMapServer(ros::NodeHandle &private_nh)
void setMap(const nav_msgs::OccupancyGridConstPtr map)
ros::ServiceServer map_service_
#define ROS_INFO(...)
TFSIMD_FORCE_INLINE const tfScalar & y() const
bool mapServiceCallback(nav_msgs::GetMap::Request &req, nav_msgs::GetMap::Response &res)
void mapCallback(const nav_msgs::OccupancyGridConstPtr &map)
void lookupTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, StampedTransform &transform) const
nav_msgs::OccupancyGridConstPtr map_ptr_
void transformPose(const std::string &target_frame, const geometry_msgs::PoseStamped &stamped_in, geometry_msgs::PoseStamped &stamped_out) const
float getDist(const Eigen::Vector2f &begin_world, const Eigen::Vector2f &end_world, Eigen::Vector2f *hitCoords=0)
virtual void setColor(double r, double g, double b, double a=1.0)
OccupancyGridContainer * mapContainer
static void poseStampedMsgToTF(const geometry_msgs::PoseStamped &msg, Stamped< Pose > &bt)
#define ROS_ERROR(...)
TFSIMD_FORCE_INLINE tfScalar length() const


hector_map_server
Author(s): Stefan Kohlbrecher
autogenerated on Sun Nov 3 2019 03:18:41