38 #include "nav2_costmap_2d/costmap_filters/binary_filter.hpp"
45 #include "nav2_costmap_2d/costmap_filters/filter_values.hpp"
46 #include "nav2_util/occ_grid_values.hpp"
47 #include "nav2_util/occ_grid_utils.hpp"
53 : filter_info_sub_(nullptr), mask_sub_(nullptr),
54 binary_state_pub_(nullptr), filter_mask_(nullptr), global_frame_(
""),
55 default_state_(false), binary_state_(default_state_)
60 const std::string & filter_info_topic)
62 std::lock_guard<CostmapFilter::mutex_t> guard(*
getMutex());
64 nav2::LifecycleNode::SharedPtr node = node_.lock();
66 throw std::runtime_error{
"Failed to lock node"};
70 default_state_ = node->declare_or_get_parameter(name_ +
"." +
"default_state",
false);
71 std::string binary_state_topic = node->declare_or_get_parameter(name_ +
"." +
72 "binary_state_topic", std::string(
"binary_state"));
73 flip_threshold_ = node->declare_or_get_parameter(name_ +
"." +
"flip_threshold", 50.0);
79 "BinaryFilter: Subscribing to \"%s\" topic for filter info...",
81 filter_info_sub_ = node->create_subscription<nav2_msgs::msg::CostmapFilterInfo>(
87 global_frame_ = layered_costmap_->getGlobalFrameID();
90 binary_state_pub_ = node->create_publisher<std_msgs::msg::Bool>(
92 binary_state_pub_->on_activate();
96 multiplier_ = MULTIPLIER_DEFAULT;
103 const nav2_msgs::msg::CostmapFilterInfo::ConstSharedPtr & msg)
105 std::lock_guard<CostmapFilter::mutex_t> guard(*
getMutex());
107 nav2::LifecycleNode::SharedPtr node = node_.lock();
109 throw std::runtime_error{
"Failed to lock node"};
119 "BinaryFilter: New costmap filter info arrived from %s topic. Updating old filter info.",
125 if (msg->type != BINARY_FILTER) {
126 RCLCPP_ERROR(logger_,
"BinaryFilter: Mode %i is not supported", msg->type);
132 multiplier_ = msg->multiplier;
139 "BinaryFilter: Subscribing to \"%s\" topic for filter mask...",
141 mask_sub_ = node->create_subscription<nav_msgs::msg::OccupancyGrid>(
148 const nav_msgs::msg::OccupancyGrid::ConstSharedPtr & msg)
150 std::lock_guard<CostmapFilter::mutex_t> guard(*
getMutex());
155 "BinaryFilter: Received filter mask from %s topic.",
mask_topic_.c_str());
159 "BinaryFilter: New filter mask arrived from %s topic. Updating old filter mask.",
161 filter_mask_.reset();
169 int ,
int ,
int ,
int ,
170 const geometry_msgs::msg::Pose & pose)
172 std::lock_guard<CostmapFilter::mutex_t> guard(*
getMutex());
176 RCLCPP_WARN_THROTTLE(
177 logger_, *(clock_), 2000,
178 "BinaryFilter: Filter mask was not received");
182 geometry_msgs::msg::Pose mask_pose;
185 if (!
transformPose(global_frame_, pose, filter_mask_->header.frame_id, mask_pose)) {
190 unsigned int mask_robot_i, mask_robot_j;
191 if (!nav2_util::worldToMap(
192 filter_mask_, mask_pose.position.x, mask_pose.position.y,
193 mask_robot_i, mask_robot_j))
198 "BinaryFilter: Robot is outside of filter mask. Resetting binary state to default.");
204 int8_t mask_data =
getMaskData(filter_mask_, mask_robot_i, mask_robot_j);
205 if (mask_data == nav2_util::OCC_GRID_UNKNOWN) {
208 RCLCPP_WARN_THROTTLE(
209 logger_, *(clock_), 2000,
210 "BinaryFilter: Filter mask [%i, %i] data is unknown. Do nothing.",
211 mask_robot_i, mask_robot_j);
216 if (base_ + mask_data * multiplier_ > flip_threshold_) {
217 if (binary_state_ == default_state_) {
221 if (binary_state_ != default_state_) {
229 std::lock_guard<CostmapFilter::mutex_t> guard(*
getMutex());
232 std::unique_ptr<std_msgs::msg::Bool> msg =
233 std::make_unique<std_msgs::msg::Bool>();
234 msg->data = binary_state_;
235 binary_state_pub_->publish(std::move(msg));
237 filter_info_sub_.reset();
239 if (binary_state_pub_) {
240 binary_state_pub_->on_deactivate();
241 binary_state_pub_.reset();
247 std::lock_guard<CostmapFilter::mutex_t> guard(*
getMutex());
257 binary_state_ = state;
259 RCLCPP_INFO(logger_,
"BinaryFilter: Switched on");
261 RCLCPP_INFO(logger_,
"BinaryFilter: Switched off");
265 std::unique_ptr<std_msgs::msg::Bool> msg =
266 std::make_unique<std_msgs::msg::Bool>();
268 binary_state_pub_->publish(std::move(msg));
273 #include "pluginlib/class_list_macros.hpp"
A QoS profile for latched, reliable topics with a history of 10 messages.
Reads in a speed restriction mask and enables a robot to dynamically adjust speed based on pose in ma...
void filterInfoCallback(const nav2_msgs::msg::CostmapFilterInfo::ConstSharedPtr &msg)
Callback for the filter information.
void changeState(const bool state)
Changes binary state of filter. Sends a message with new state.
void resetFilter() override
Reset the costmap filter / topic / info.
void process(nav2_costmap_2d::Costmap2D &master_grid, int min_i, int min_j, int max_i, int max_j, const geometry_msgs::msg::Pose &pose) override
Process the keepout layer at the current pose / bounds / grid.
BinaryFilter()
A constructor.
bool isActive()
If this filter is active.
void maskCallback(const nav_msgs::msg::OccupancyGrid::ConstSharedPtr &msg)
Callback for the filter mask.
void initializeFilter(const std::string &filter_info_topic) override
Initialize the filter and subscribe to the info topic.
A 2D costmap provides a mapping between points in the world and their associated "costs".
int8_t getMaskData(nav_msgs::msg::OccupancyGrid::ConstSharedPtr filter_mask, const unsigned int mx, const unsigned int my) const
Get the data of a cell in the filter mask.
bool transformPose(const std::string global_frame, const geometry_msgs::msg::Pose &global_pose, const std::string mask_frame, geometry_msgs::msg::Pose &mask_pose) const
: Transforms robot pose from current layer frame to mask frame
std::string filter_info_topic_
: Name of costmap filter info topic
std::string mask_topic_
: Name of filter mask topic
mutex_t * getMutex()
: returns pointer to a mutex
Abstract class for layered costmap plugin implementations.