static_map.cpp
Go to the documentation of this file.
1 #include "static_map.hpp"
2 
4 {
5 
6  StaticMap::StaticMap() : tfListener_(tfBuffer_)
7  {}
8 
10  config_(_config),
11  gridMap_({"static_map"}),
13  {
14  }
15 
17 
19  {
20  // Subscribers
21 
22  // Required
24 
25  // Optional
26  if (config_.markerSubTopic != "")
27  {
29  }
30 
31  if (config_.gridMapSubTopic != "")
32  {
34  }
35 
36 
37  // Publishers
38  occGridPub_ = nh_.advertise<nav_msgs::OccupancyGrid>(config_.occupancyOutputTopic, 1);
39  gridMapPub_ = nh_.advertise<grid_map_msgs::GridMap>(config_.gridmapOutputTopic, 1);
40 
41  initialized_ = true;
42  return 0;
43  }
44 
46  {
47  // Make the class has been initialized
48  if (!initialized_)
49  {
50  return 1;
51  }
52  else if (!recStaticMap_) // Don't publish unless a static map has been received
53  {
54  return 2;
55  }
56 
57  publishMap();
58 
59  return 0;
60  }
61 
62  void StaticMap::staticMapCb(const nav_msgs::OccupancyGrid &_occGrid)
63  {
64  // Only get the static map once
65  if (recStaticMap_)
66  {
67  return;
68  }
69 
70  // Update our gridmap to be the same as the received static map
72 
73  // Grid map seems to be using nans as obstacles, so we make all nans 100
74  gridMap_["static_map"] = (gridMap_["static_map"].array().isNaN()).select(100, gridMap_["static_map"]);
75 
76  // Logging information about the received gridmap
77  ROS_INFO("Static Map received!");
78 
81 
82  ROS_INFO("Map Size: %d, %d", size(0, 0), size(1, 0));
83  ROS_INFO("Resolution: %f", gridMap_.getResolution());
84  ROS_INFO("Position: %f, %f", pos(0), pos(1));
85 
86  recStaticMap_ = true;
87  }
88 
89  void StaticMap::mapMarkerCb(const visualization_msgs::Marker &_marker)
90  {
91  ROS_INFO("Recieved marker!");
92 
93  // TODO: If published in the ned frame we should switch the x and y before we look at it in utm_enu frame
94  // If we have a ned frame published then we might be okay.
95  if (!recStaticMap_)
96  {
97  ROS_WARN("Static map has not been received yet. Ignoring marker.");
98  return;
99  }
100 
101  // For now, assume the marker is in utm_enu and is operating on the static map
102  // Make sure the point is inside the map
103  grid_map::Position pos(_marker.pose.position.x, _marker.pose.position.y);
104  if (!gridMap_.isInside(pos))
105  {
106  ROS_WARN("Recieved Marker not inside of map.");
107  return;
108  }
109 
110  // ASSUMPTION: Obstacle is a circle/sphere
111  double radius = _marker.scale.x;
112  for (grid_map::CircleIterator it(gridMap_, pos, radius); !it.isPastEnd(); ++it)
113  {
114  gridMap_.at("static_map", *it) = 100;
115  }
116  }
117 
118  void StaticMap::gridMapCb(const grid_map_msgs::GridMap &_inMap)
119  {
120  ROS_DEBUG_THROTTLE(1,"Received grid map");
121  // TO BE IMPLEMENTED
122  // Update static map with obstacles from a grid map instance
123  grid_map::GridMap tempMap;
125 
126  // We need to determine the transform between the two maps
127  geometry_msgs::TransformStamped transform;
128  try
129  {
130  transform = tfBuffer_.lookupTransform(gridMap_.getFrameId(), tempMap.getFrameId(), ros::Time(0));
131  }
132  catch (const std::exception &e)
133  {
134  ROS_WARN("Unable to find transform: %s. Not including map in permanent obstacles.", e.what());
135  return;
136  }
137 
138  // FOR NOW WE ASSUME A PERMANENT LAYER
139  grid_map::Matrix &permanent = tempMap[config_.gridMapLayer];
140 
141  // Layer to add obstacles to
142  grid_map::Matrix &staticMap = gridMap_["static_map"];
143 
144  for (grid_map::GridMapIterator it(tempMap); !it.isPastEnd(); ++it)
145  {
146  const grid_map::Index index(*it);
147 
148  // We only care if the point is an actual obstacle
149  if (permanent(index(0), index(1)) != 100)
150  {
151  continue;
152  }
153 
154  grid_map::Position pos;
155  tempMap.getPosition(index, pos);
156 
157  // Convert the position into the gridMap_ frame
158  geometry_msgs::Pose poseIn;
159  poseIn.position.x = pos.x();
160  poseIn.position.y = pos.y();
161 
162  geometry_msgs::Pose poseOut;
163 
164  tf2::doTransform(poseIn, poseOut, transform);
165 
166  grid_map::Position gPos(poseOut.position.x, poseOut.position.y);
167 
168  // Remember, we found about this point holds an obstacle in tempMap
169  if (gridMap_.isInside(gPos))
170  {
171  // Is it faster to get the index and operate on the matrix, or just use the line below?
172  gridMap_.atPosition("static_map", gPos) = 100;
173  // grid_map::Index gIndex;
174  // gridMap_.getIndex(pos, gIndex);
175  // staticMap(gIndex(0), gIndex(1)) = 100; // Set a static obstacle cell
176  }
177  }
178  }
179 
181  {
182  // Occupancy grid publisher
183  nav_msgs::OccupancyGrid occGrid;
184  grid_map::GridMapRosConverter::toOccupancyGrid(gridMap_, "static_map", 0, 100, occGrid);
185 
186  occGridPub_.publish(occGrid);
187 
188  // Grid map message publisher
189  grid_map_msgs::GridMap gridMapMessage;
191  gridMapPub_.publish(gridMapMessage);
192  }
193 
194 } // namespace mitre_fast_layered_map
Eigen::Array2i Index
float & atPosition(const std::string &layer, const Position &position)
void publish(const boost::shared_ptr< M > &message) const
bool getPosition(const Index &index, Position &position) const
std::string gridMapLayer
Layer to retrieve permanent obstacles from.
Definition: static_map.hpp:38
#define ROS_DEBUG_THROTTLE(rate,...)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
StaticMapConfiguration config_
Definition: static_map.hpp:80
void gridMapCb(const grid_map_msgs::GridMap &)
Definition: static_map.cpp:118
Eigen::Array2i Size
const std::string & getFrameId() const
std::string gridMapSubTopic
in the grid map will be added to the static map instance.
Definition: static_map.hpp:36
Eigen::MatrixXf Matrix
void mapMarkerCb(const visualization_msgs::Marker &)
Definition: static_map.cpp:89
virtual geometry_msgs::TransformStamped lookupTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, const ros::Duration timeout) const
static void toMessage(const grid_map::GridMap &gridMap, grid_map_msgs::GridMap &message)
static bool fromOccupancyGrid(const nav_msgs::OccupancyGrid &occupancyGrid, const std::string &layer, grid_map::GridMap &gridMap)
void doTransform(const T &data_in, T &data_out, const geometry_msgs::TransformStamped &transform)
static void toOccupancyGrid(const grid_map::GridMap &gridMap, const std::string &layer, float dataMin, float dataMax, nav_msgs::OccupancyGrid &occupancyGrid)
tf2_ros::Buffer tfBuffer_
Holds transformations from tf tree.
Definition: static_map.hpp:72
#define ROS_WARN(...)
std::string staticMapSubTopic
Static map from map server to use as starting configuration.
Definition: static_map.hpp:34
static bool fromMessage(const grid_map_msgs::GridMap &message, grid_map::GridMap &gridMap, const std::vector< std::string > &layers, bool copyBasicLayers=true, bool copyAllNonBasicLayers=true)
double getResolution() const
bool isInside(const Position &position) const
Eigen::Vector2d Position
#define ROS_INFO(...)
std::string markerSubTopic
Topic users can post marker messages to to add obstacles.
Definition: static_map.hpp:35
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
tf2_ros::TransformListener tfListener_
Used in tfBuffer_.
Definition: static_map.hpp:73
float & at(const std::string &layer, const Index &index)
std::string occupancyOutputTopic
Topic for occupancy grid.
Definition: static_map.hpp:40
void staticMapCb(const nav_msgs::OccupancyGrid &)
Definition: static_map.cpp:62
Mapping solution for largely static obstacles. Despite the name, it can be modified, but all modifications are considered permanent unless explicitly removed. Not for use as a rapidly changing dynamic map. See the SensorMap for that capability.
std::string gridmapOutputTopic
Topic for grid map msgs output.
Definition: static_map.hpp:41
const Size & getSize() const


mitre_fast_layered_map
Author(s):
autogenerated on Thu Mar 11 2021 03:06:49