37 #ifndef LASER_SCAN_SHADOWS_FILTER_H 38 #define LASER_SCAN_SHADOWS_FILTER_H 44 #include <sensor_msgs/LaserScan.h> 46 #include <laser_filters/ScanShadowsFilterConfig.h> 47 #include <dynamic_reconfigure/server.h> 65 std::shared_ptr<dynamic_reconfigure::Server<laser_filters::ScanShadowsFilterConfig>>
dyn_server_;
78 dyn_server_.reset(
new dynamic_reconfigure::Server<laser_filters::ScanShadowsFilterConfig>(own_mutex_, private_nh));
79 dynamic_reconfigure::Server<laser_filters::ScanShadowsFilterConfig>::CallbackType
f;
81 dyn_server_->setCallback(f);
85 ROS_ERROR(
"Error: ShadowsFilter was not given min_angle.\n");
90 ROS_ERROR(
"Error: ShadowsFilter was not given min_angle.\n");
95 ROS_ERROR(
"Error: ShadowsFilter was not given window.\n");
101 ROS_INFO(
"Error: ShadowsFilter was not given neighbors.\n");
103 remove_shadow_start_point_ =
false;
105 ROS_INFO(
"Remove shadow start point: %s", remove_shadow_start_point_ ?
"true" :
"false");
109 ROS_ERROR(
"min_angle must be 0 <= min_angle. Forcing min_angle = 0.\n");
114 ROS_ERROR(
"min_angle must be min_angle <= 90. Forcing min_angle = 90.\n");
119 ROS_ERROR(
"max_angle must be 90 <= max_angle. Forcing max_angle = 90.\n");
122 if (180 < min_angle_)
124 ROS_ERROR(
"max_angle must be max_angle <= 180. Forcing max_angle = 180.\n");
137 dyn_server_->updateConfig(param_config);
144 min_angle_ = config.min_angle;
145 max_angle_ = config.max_angle;
149 neighbors_ = config.neighbors;
150 window_ = config.window;
151 remove_shadow_start_point_ = config.remove_shadow_start_point;
167 bool update(
const sensor_msgs::LaserScan& scan_in, sensor_msgs::LaserScan& scan_out)
169 boost::recursive_mutex::scoped_lock lock(own_mutex_);
174 std::set<int> indices_to_delete;
176 for (
unsigned int i = 0; i < scan_in.ranges.size(); i++)
178 for (
int y = -window_; y < window_ + 1; y++)
181 if (j < 0 || j >= (
int)scan_in.ranges.size() || (int)i == j)
187 scan_in.ranges[i], scan_in.ranges[j], y * scan_in.angle_increment))
189 for (
int index = std::max<int>(i - neighbors_, 0); index <= std::min<int>(i +
neighbors_, (int)scan_in.ranges.size() - 1); index++)
191 if (scan_in.ranges[i] < scan_in.ranges[index])
193 indices_to_delete.insert(index);
196 if (remove_shadow_start_point_)
198 indices_to_delete.insert(i);
204 ROS_DEBUG(
"ScanShadowsFilter removing %d Points from scan with min angle: %.2f, max angle: %.2f, neighbors: %d, and window: %d",
206 for (std::set<int>::iterator it = indices_to_delete.begin(); it != indices_to_delete.end(); ++it)
208 scan_out.ranges[*it] = std::numeric_limits<float>::quiet_NaN();
217 #endif // LASER_SCAN_SHADOWS_FILTER_H ScanShadowDetector shadow_detector_
void configure(const float min_angle, const float max_angle)
boost::recursive_mutex own_mutex_
ScanShadowsFilterConfig param_config
void reconfigureCB(ScanShadowsFilterConfig &config, uint32_t level)
LaserScanMaskFilter removes points on directions defined in a mask from a laser scan.
const std::string & getName() const
bool remove_shadow_start_point_
static double from_degrees(double degrees)
bool update(const sensor_msgs::LaserScan &scan_in, sensor_msgs::LaserScan &scan_out)
Filter shadow points based on 3 global parameters: min_angle, max_angle and window. {min,max}_angle specify the allowed angle interval (in degrees) between the created lines (see getAngleWithViewPoint). Window specifies how many consecutive measurements to take into account for one point.
bool getParam(const std::string &name, std::string &value) const
bool isShadow(const float r1, const float r2, const float included_angle)
std::shared_ptr< dynamic_reconfigure::Server< laser_filters::ScanShadowsFilterConfig > > dyn_server_
virtual ~ScanShadowsFilter()