largemap_to_map.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018, the neonavigation authors
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  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the copyright holder nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include <ros/ros.h>
31 #include <nav_msgs/OccupancyGrid.h>
34 
35 #include <string>
37 
39 {
40 private:
46 
47  nav_msgs::OccupancyGrid::ConstPtr large_map_;
50 
51  std::string robot_frame_;
52 
53  int width_;
54 
55 public:
57  : pnh_("~")
58  , nh_()
59  , tfl_(tfbuf_)
60  {
62  pnh_.param("robot_frame", robot_frame_, std::string("base_link"));
63 
64  pub_map_ = neonavigation_common::compat::advertise<nav_msgs::OccupancyGrid>(
65  nh_, "map_local",
66  pnh_, "map", 1, true);
67  sub_largemap_ = nh_.subscribe("map", 2, &LargeMapToMapNode::cbLargeMap, this);
68 
69  pnh_.param("width", width_, 30);
70 
71  double hz;
72  pnh_.param("hz", hz, 1.0);
73  timer_ = nh_.createTimer(ros::Duration(1.0 / hz), &LargeMapToMapNode::cbTimer, this);
74  }
75 
76 private:
77  void cbTimer(const ros::TimerEvent& event)
78  {
79  publishMap();
80  }
81  void cbLargeMap(const nav_msgs::OccupancyGrid::ConstPtr& msg)
82  {
83  large_map_ = msg;
84  }
85  void publishMap()
86  {
87  if (!large_map_)
88  return;
90  try
91  {
92  tf2::fromMsg(tfbuf_.lookupTransform(large_map_->header.frame_id, robot_frame_, ros::Time(0)), trans);
93  }
94  catch (tf2::TransformException& e)
95  {
96  return;
97  }
98 
99  nav_msgs::OccupancyGrid map;
100  map.header.frame_id = large_map_->header.frame_id;
101  map.header.stamp = ros::Time::now();
102  map.info = large_map_->info;
103  map.info.width = width_;
104  map.info.height = width_;
105 
106  const auto pos = trans.getOrigin();
107  const float x = static_cast<int>(pos.x() / map.info.resolution) * map.info.resolution;
108  const float y = static_cast<int>(pos.y() / map.info.resolution) * map.info.resolution;
109  map.info.origin.position.x = x - map.info.width * map.info.resolution * 0.5;
110  map.info.origin.position.y = y - map.info.height * map.info.resolution * 0.5;
111  map.info.origin.position.z = 0.0;
112  map.info.origin.orientation.w = 1.0;
113  map.data.resize(width_ * width_);
114 
115  const int gx =
116  lroundf((map.info.origin.position.x - large_map_->info.origin.position.x) / map.info.resolution);
117  const int gy =
118  lroundf((map.info.origin.position.y - large_map_->info.origin.position.y) / map.info.resolution);
119 
120  for (int y = gy; y < gy + width_; ++y)
121  {
122  for (int x = gx; x < gx + width_; ++x)
123  {
124  const size_t addr = (y - gy) * width_ + (x - gx);
125  const size_t addr_large = y * large_map_->info.width + x;
126  if (x < 0 || y < 0 ||
127  x >= static_cast<int>(large_map_->info.width) ||
128  y >= static_cast<int>(large_map_->info.height))
129  {
130  map.data[addr] = -1;
131  }
132  else
133  {
134  map.data[addr] = large_map_->data[addr_large];
135  }
136  }
137  }
138 
139  pub_map_.publish(map);
140  }
141 };
142 
143 int main(int argc, char** argv)
144 {
145  ros::init(argc, argv, "largemap_to_map");
146 
147  LargeMapToMapNode conv;
148  ros::spin();
149 
150  return 0;
151 }
tf2_ros::TransformListener tfl_
void cbTimer(const ros::TimerEvent &event)
void publish(const boost::shared_ptr< M > &message) const
void cbLargeMap(const nav_msgs::OccupancyGrid::ConstPtr &msg)
ros::Subscriber sub_largemap_
virtual geometry_msgs::TransformStamped lookupTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, const ros::Duration timeout) const
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
TFSIMD_FORCE_INLINE const tfScalar & y() const
nav_msgs::OccupancyGrid::ConstPtr large_map_
ROSCPP_DECL void spin(Spinner &spinner)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
void fromMsg(const A &, B &b)
TFSIMD_FORCE_INLINE const tfScalar & x() const
ros::NodeHandle nh_
tf2_ros::Buffer tfbuf_
std::string robot_frame_
int main(int argc, char **argv)
static Time now()
ros::NodeHandle pnh_
ros::Publisher pub_map_


costmap_cspace
Author(s): Atsushi Watanabe
autogenerated on Tue Jul 9 2019 04:59:48