laserscan_to_map.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2017, 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>
32 #include <nav_msgs/OccupancyGrid.h>
34 #include <sensor_msgs/LaserScan.h>
38 
39 #include <limits>
40 #include <string>
41 
44 
46 {
47 private:
52 
53  nav_msgs::OccupancyGrid map;
59 
60  double z_min_, z_max_;
61  std::string global_frame_;
62  std::string robot_frame_;
63 
64  unsigned int width_;
65  unsigned int height_;
66  float origin_x_;
67  float origin_y_;
68 
70 
71 public:
73  : nh_()
74  , pnh_("~")
75  , tfl_(tfbuf_)
76  {
78  pnh_.param("z_min", z_min_, std::numeric_limits<double>::lowest());
79  pnh_.param("z_max", z_max_, std::numeric_limits<double>::max());
80  pnh_.param("global_frame", global_frame_, std::string("map"));
81  pnh_.param("robot_frame", robot_frame_, std::string("base_link"));
82 
83  double accum_duration;
84  pnh_.param("accum_duration", accum_duration, 1.0);
85  accum_.reset(ros::Duration(accum_duration));
86 
87  pub_map_ = neonavigation_common::compat::advertise<nav_msgs::OccupancyGrid>(
88  nh_, "map_local",
89  pnh_, "map", 1, true);
91 
92  int width_param;
93  pnh_.param("width", width_param, 30);
94  height_ = width_ = width_param;
95  map.header.frame_id = global_frame_;
96 
97  double resolution;
98  pnh_.param("resolution", resolution, 0.1);
99  map.info.resolution = resolution;
100  map.info.width = width_;
101  map.info.height = height_;
102  map.data.resize(map.info.width * map.info.height);
103 
104  double hz;
105  pnh_.param("hz", hz, 1.0);
106  publish_interval_ = ros::Duration(1.0 / hz);
107  }
108 
109 private:
110  void cbScan(const sensor_msgs::LaserScan::ConstPtr& scan)
111  {
112  sensor_msgs::PointCloud2 cloud;
113  sensor_msgs::PointCloud2 cloud_global;
114  projector_.projectLaser(*scan, cloud);
115  try
116  {
117  geometry_msgs::TransformStamped trans = tfbuf_.lookupTransform(
118  global_frame_, cloud.header.frame_id, cloud.header.stamp, ros::Duration(0.5));
119  tf2::doTransform(cloud, cloud_global, trans);
120  }
121  catch (tf2::TransformException& e)
122  {
123  ROS_WARN("%s", e.what());
124  }
126  cloud_global, cloud_global.header.stamp));
127 
128  ros::Time now = scan->header.stamp;
129  if (published_ + publish_interval_ > now)
130  return;
131  published_ = now;
132 
133  float robot_z;
134  try
135  {
138 
139  auto pos = trans.getOrigin();
140  float x = static_cast<int>(pos.x() / map.info.resolution) * map.info.resolution;
141  float y = static_cast<int>(pos.y() / map.info.resolution) * map.info.resolution;
142  map.info.origin.position.x = x - map.info.width * map.info.resolution * 0.5;
143  map.info.origin.position.y = y - map.info.height * map.info.resolution * 0.5;
144  map.info.origin.position.z = 0.0;
145  map.info.origin.orientation.w = 1.0;
146  origin_x_ = x - width_ * map.info.resolution * 0.5;
147  origin_y_ = y - height_ * map.info.resolution * 0.5;
148  robot_z = pos.z();
149  }
150  catch (tf2::TransformException& e)
151  {
152  ROS_WARN("%s", e.what());
153  return;
154  }
155  for (auto& cell : map.data)
156  cell = 0;
157 
158  for (auto& pc : accum_)
159  {
160  auto itr_x = sensor_msgs::PointCloud2ConstIterator<float>(pc, "x");
161  auto itr_y = sensor_msgs::PointCloud2ConstIterator<float>(pc, "y");
162  auto itr_z = sensor_msgs::PointCloud2ConstIterator<float>(pc, "z");
163  for (; itr_x != itr_x.end(); ++itr_x, ++itr_y)
164  {
165  if (*itr_z - robot_z < z_min_ || z_max_ < *itr_z - robot_z)
166  continue;
167  unsigned int x = int(
168  (*itr_x - map.info.origin.position.x) / map.info.resolution);
169  unsigned int y = int(
170  (*itr_y - map.info.origin.position.y) / map.info.resolution);
171  if (x >= map.info.width || y >= map.info.height)
172  continue;
173  map.data[x + y * map.info.width] = 100;
174  }
175  }
176 
178  }
179 };
180 
181 int main(int argc, char** argv)
182 {
183  ros::init(argc, argv, "laserscan_to_map");
184 
185  LaserscanToMapNode conv;
186  ros::spin();
187 
188  return 0;
189 }
LaserscanToMapNode::origin_y_
float origin_y_
Definition: laserscan_to_map.cpp:67
costmap_cspace::PointcloudAccumulator::reset
void reset(const ros::Duration &duration)
Definition: pointcloud_accumulator.h:64
costmap_cspace::PointcloudAccumulator::push
void push(const Points &points)
Definition: pointcloud_accumulator.h:75
point_cloud2_iterator.h
LaserscanToMapNode
Definition: laserscan_to_map.cpp:45
pointcloud_accumulator.h
ros::Publisher
LaserscanToMapNode::height_
unsigned int height_
Definition: laserscan_to_map.cpp:65
costmap_cspace::PointcloudAccumulator::Points
Definition: pointcloud_accumulator.h:43
ros::init
ROSCPP_DECL void init(const M_string &remappings, const std::string &name, uint32_t options=0)
LaserscanToMapNode::origin_x_
float origin_x_
Definition: laserscan_to_map.cpp:66
LaserscanToMapNode::publish_interval_
ros::Duration publish_interval_
Definition: laserscan_to_map.cpp:58
tf2::fromMsg
void fromMsg(const A &, B &b)
laser_geometry::LaserProjection
ros.h
LaserscanToMapNode::pub_map_
ros::Publisher pub_map_
Definition: laserscan_to_map.cpp:50
LaserscanToMapNode::pnh_
ros::NodeHandle pnh_
Definition: laserscan_to_map.cpp:49
tf2_sensor_msgs.h
LaserscanToMapNode::z_max_
double z_max_
Definition: laserscan_to_map.cpp:60
LaserscanToMapNode::tfbuf_
tf2_ros::Buffer tfbuf_
Definition: laserscan_to_map.cpp:54
tf2::Stamped
compatibility.h
LaserscanToMapNode::map
nav_msgs::OccupancyGrid map
Definition: laserscan_to_map.cpp:53
ros::Publisher::publish
void publish(const boost::shared_ptr< M > &message) const
sensor_msgs::PointCloud2ConstIterator
tf2_ros::TransformListener
LaserscanToMapNode::accum_
costmap_cspace::PointcloudAccumulator< sensor_msgs::PointCloud2 > accum_
Definition: laserscan_to_map.cpp:69
laser_geometry::LaserProjection::projectLaser
void projectLaser(const sensor_msgs::LaserScan &scan_in, sensor_msgs::PointCloud &cloud_out, double range_cutoff=-1.0, int channel_options=channel_option::Default)
laser_geometry.h
main
int main(int argc, char **argv)
Definition: laserscan_to_map.cpp:181
LaserscanToMapNode::z_min_
double z_min_
Definition: laserscan_to_map.cpp:60
LaserscanToMapNode::tfl_
tf2_ros::TransformListener tfl_
Definition: laserscan_to_map.cpp:55
LaserscanToMapNode::sub_scan_
ros::Subscriber sub_scan_
Definition: laserscan_to_map.cpp:51
ROS_WARN
#define ROS_WARN(...)
tf2_ros::Buffer
ros::NodeHandle::subscribe
Subscriber subscribe(const std::string &topic, uint32_t queue_size, const boost::function< void(C)> &callback, const VoidConstPtr &tracked_object=VoidConstPtr(), const TransportHints &transport_hints=TransportHints())
LaserscanToMapNode::projector_
laser_geometry::LaserProjection projector_
Definition: laserscan_to_map.cpp:56
LaserscanToMapNode::width_
unsigned int width_
Definition: laserscan_to_map.cpp:64
costmap_cspace::PointcloudAccumulator< sensor_msgs::PointCloud2 >
neonavigation_common::compat::checkCompatMode
void checkCompatMode()
transform_listener.h
LaserscanToMapNode::global_frame_
std::string global_frame_
Definition: laserscan_to_map.cpp:61
ros::Time
tf2::doTransform
void doTransform(const T &data_in, T &data_out, const geometry_msgs::TransformStamped &transform)
LaserscanToMapNode::cbScan
void cbScan(const sensor_msgs::LaserScan::ConstPtr &scan)
Definition: laserscan_to_map.cpp:110
LaserscanToMapNode::published_
ros::Time published_
Definition: laserscan_to_map.cpp:57
LaserscanToMapNode::robot_frame_
std::string robot_frame_
Definition: laserscan_to_map.cpp:62
ros::NodeHandle::param
T param(const std::string &param_name, const T &default_val) const
tf2_geometry_msgs.h
ros::spin
ROSCPP_DECL void spin()
tf2::TransformException
ros::Duration
LaserscanToMapNode::nh_
ros::NodeHandle nh_
Definition: laserscan_to_map.cpp:48
LaserscanToMapNode::LaserscanToMapNode
LaserscanToMapNode()
Definition: laserscan_to_map.cpp:72
tf2_ros::Buffer::lookupTransform
virtual geometry_msgs::TransformStamped lookupTransform(const std::string &target_frame, const ros::Time &target_time, const std::string &source_frame, const ros::Time &source_time, const std::string &fixed_frame, const ros::Duration timeout) const
ros::NodeHandle
ros::Subscriber


costmap_cspace
Author(s): Atsushi Watanabe
autogenerated on Fri May 16 2025 02:15:10