38 #include <nav_msgs/OccupancyGrid.h> 71 pnh_.
param(
"robot_frame", robot_frame_, std::string(
"base_link"));
73 pub_map_ = neonavigation_common::compat::advertise<nav_msgs::OccupancyGrid>(
75 pnh_,
"map", 1,
true);
78 pnh_.param(
"width", width_, 30);
79 pnh_.param(
"round_local_map", round_local_map_,
false);
80 pnh_.param(
"simulate_occlusion", simulate_occlusion_,
false);
82 for (
size_t addr = 0; addr < static_cast<size_t>(width_ *
width_); ++addr)
84 const int ux = addr %
width_;
85 const int uy = addr /
width_;
86 const float x = ux - width_ / 2.0;
87 const float y = uy - width_ / 2.0;
88 const float l = std::sqrt(x * x + y * y);
89 for (
float r = 1.0; r < l - 1.0; r += 0.5)
91 const float x2 = x * r / l;
92 const float y2 = y * r / l;
93 const int ux2 = x2 + width_ / 2.0;
94 const int uy2 = y2 + width_ / 2.0;
95 const int addr2 = uy2 * width_ + ux2;
96 occlusion_table_[addr2].push_back(addr);
99 for (
auto& cell : occlusion_table_)
101 std::sort(cell.second.begin(), cell.second.end());
102 cell.second.erase(std::unique(cell.second.begin(), cell.second.end()), cell.second.end());
103 const auto self_it = std::find(cell.second.begin(), cell.second.end(), cell.first);
104 if (self_it != cell.second.end())
105 cell.second.erase(self_it);
109 pnh_.param(
"hz", hz, 1.0);
118 void cbLargeMap(
const nav_msgs::OccupancyGrid::ConstPtr& msg)
136 nav_msgs::OccupancyGrid map;
137 map.header.frame_id = large_map_->header.frame_id;
139 map.info = large_map_->info;
143 const auto pos = trans.getOrigin();
144 const float x =
static_cast<int>(pos.x() / map.info.resolution) * map.info.resolution;
145 const float y = static_cast<int>(pos.y() / map.info.resolution) * map.info.resolution;
146 map.info.origin.position.x = x - map.info.width * map.info.resolution * 0.5;
147 map.info.origin.position.y =
y - map.info.height * map.info.resolution * 0.5;
148 map.info.origin.position.z = 0.0;
149 map.info.origin.orientation.w = 1.0;
150 map.data.resize(width_ * width_);
153 std::lround((map.info.origin.position.x - large_map_->info.origin.position.x) / map.info.resolution);
155 std::lround((map.info.origin.position.y - large_map_->info.origin.position.y) / map.info.resolution);
156 const float half_width = width_ / 2.0;
160 for (
int x = gx; x < gx +
width_; ++x)
162 const int lx = x - gx;
163 const int ly =
y - gy;
164 const size_t addr = ly * width_ + lx;
165 const size_t addr_large =
y * large_map_->info.width + x;
166 if (round_local_map_ &&
167 std::pow(lx - half_width, 2) + std::pow(ly - half_width, 2) > std::pow(half_width, 2))
171 else if (x < 0 ||
y < 0 ||
172 x >= static_cast<int>(large_map_->info.width) ||
173 y >= static_cast<int>(large_map_->info.height))
179 map.data[addr] = large_map_->data[addr_large];
183 if (simulate_occlusion_)
185 for (
size_t addr = 0; addr < static_cast<size_t>(width_ *
width_); ++addr)
187 if (map.data[addr] == 100)
189 for (
auto a : occlusion_table_[addr])
201 int main(
int argc,
char** argv)
203 ros::init(argc, argv,
"largemap_to_map");
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 ¶m_name, T ¶m_val, const T &default_val) const
void fromMsg(const A &, B &b)
TFSIMD_FORCE_INLINE const tfScalar & x() const
int main(int argc, char **argv)
std::map< size_t, std::vector< size_t > > occlusion_table_