Skip to content

Commit 920dff0

Browse files
mini-1235Copilot
andauthored
Add option to override lethal cost in keepout zone (#5433)
* Add option to override lethal cost in keepout zone Signed-off-by: mini-1235 <[email protected]> * Linting Signed-off-by: mini-1235 <[email protected]> * Update nav2_costmap_2d/plugins/costmap_filters/keepout_filter.cpp Co-authored-by: Copilot <[email protected]> Signed-off-by: mini-1235 <[email protected]> * Base class call Signed-off-by: mini-1235 <[email protected]> --------- Signed-off-by: mini-1235 <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent b066a18 commit 920dff0

File tree

2 files changed

+67
-59
lines changed

2 files changed

+67
-59
lines changed

nav2_costmap_2d/include/nav2_costmap_2d/costmap_filters/keepout_filter.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,9 @@ class KeepoutFilter : public CostmapFilter
120120
bool override_lethal_cost_{false}; // If true, lethal cost will be overridden
121121
unsigned char lethal_override_cost_{252}; // Value to override lethal cost with
122122
bool last_pose_lethal_{false}; // If true, last pose was lethal
123-
unsigned int lethal_state_update_min_x_{999999u}, lethal_state_update_min_y_{999999u};
124-
unsigned int lethal_state_update_max_x_{0u}, lethal_state_update_max_y_{0u};
123+
bool is_pose_lethal_{false};
124+
double lethal_state_update_min_x_, lethal_state_update_min_y_;
125+
double lethal_state_update_max_x_, lethal_state_update_max_y_;
125126

126127
unsigned int x_{0};
127128
unsigned int y_{0};

nav2_costmap_2d/plugins/costmap_filters/keepout_filter.cpp

Lines changed: 64 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343

4444
#include "nav2_costmap_2d/costmap_filters/keepout_filter.hpp"
4545
#include "nav2_costmap_2d/costmap_filters/filter_values.hpp"
46+
#include "nav2_util/geometry_utils.hpp"
4647

4748
namespace nav2_costmap_2d
4849
{
@@ -84,6 +85,8 @@ void KeepoutFilter::initializeFilter(
8485
// clamp lethal_override_cost_ in case if higher than MAX_NON_OBSTACLE is given
8586
lethal_override_cost_ = \
8687
std::clamp<unsigned int>(lethal_override_cost_, FREE_SPACE, MAX_NON_OBSTACLE);
88+
lethal_state_update_max_x_ = lethal_state_update_max_y_ = std::numeric_limits<double>::lowest();
89+
lethal_state_update_min_x_ = lethal_state_update_min_y_ = std::numeric_limits<double>::max();
8790
}
8891

8992
void KeepoutFilter::filterInfoCallback(
@@ -171,27 +174,70 @@ void KeepoutFilter::updateBounds(
171174

172175
CostmapFilter::updateBounds(robot_x, robot_y, robot_yaw, min_x, min_y, max_x, max_y);
173176

174-
if(!has_updated_data_) {
175-
return;
176-
}
177+
// If new keepout zone received
178+
if(has_updated_data_) {
179+
double wx, wy;
180+
layered_costmap_->getCostmap()->mapToWorld(x_, y_, wx, wy);
181+
*min_x = std::min(wx, *min_x);
182+
*min_y = std::min(wy, *min_y);
177183

178-
double wx, wy;
184+
layered_costmap_->getCostmap()->mapToWorld(x_ + width_, y_ + height_, wx, wy);
185+
*max_x = std::max(wx, *max_x);
186+
*max_y = std::max(wy, *max_y);
179187

180-
layered_costmap_->getCostmap()->mapToWorld(x_, y_, wx, wy);
181-
*min_x = std::min(wx, *min_x);
182-
*min_y = std::min(wy, *min_y);
188+
has_updated_data_ = false;
189+
return;
190+
}
183191

184-
layered_costmap_->getCostmap()->mapToWorld(x_ + width_, y_ + height_, wx, wy);
185-
*max_x = std::max(wx, *max_x);
186-
*max_y = std::max(wy, *max_y);
192+
// Let's find the pose's cost if we are allowed to override the lethal cost
193+
is_pose_lethal_ = false;
194+
if (override_lethal_cost_) {
195+
geometry_msgs::msg::Pose pose;
196+
pose.position.x = robot_x;
197+
pose.position.y = robot_y;
198+
pose.position.z = 0.0;
199+
pose.orientation = nav2_util::geometry_utils::orientationAroundZAxis(robot_yaw);
200+
geometry_msgs::msg::Pose mask_pose;
201+
if (transformPose(global_frame_, pose, filter_mask_->header.frame_id, mask_pose)) {
202+
unsigned int mask_robot_i, mask_robot_j;
203+
if (worldToMask(filter_mask_, mask_pose.position.x, mask_pose.position.y, mask_robot_i,
204+
mask_robot_j))
205+
{
206+
auto data = getMaskCost(filter_mask_, mask_robot_i, mask_robot_j);
207+
is_pose_lethal_ = (data == INSCRIBED_INFLATED_OBSTACLE || data == LETHAL_OBSTACLE);
208+
if (is_pose_lethal_) {
209+
RCLCPP_WARN_THROTTLE(
210+
logger_, *(clock_), 2000,
211+
"KeepoutFilter: Pose is in keepout zone, reducing cost override to navigate out.");
212+
}
213+
}
214+
}
187215

188-
has_updated_data_ = false;
216+
// If in lethal space or just exited lethal space,
217+
// we need to update all possible spaces touched during this state
218+
if (is_pose_lethal_ || (last_pose_lethal_ && !is_pose_lethal_)) {
219+
lethal_state_update_min_x_ = std::min(*min_x, lethal_state_update_min_x_);
220+
*min_x = lethal_state_update_min_x_;
221+
lethal_state_update_min_y_ = std::min(*min_y, lethal_state_update_min_y_);
222+
*min_y = lethal_state_update_min_y_;
223+
lethal_state_update_max_x_ = std::max(*max_x, lethal_state_update_max_x_);
224+
*max_x = lethal_state_update_max_x_;
225+
lethal_state_update_max_y_ = std::max(*max_y, lethal_state_update_max_y_);
226+
*max_y = lethal_state_update_max_y_;
227+
} else {
228+
// If out of lethal space, reset managed lethal state sizes
229+
lethal_state_update_min_x_ = std::numeric_limits<double>::max();
230+
lethal_state_update_min_y_ = std::numeric_limits<double>::max();
231+
lethal_state_update_max_x_ = std::numeric_limits<double>::lowest();
232+
lethal_state_update_max_y_ = std::numeric_limits<double>::lowest();
233+
}
234+
}
189235
}
190236

191237
void KeepoutFilter::process(
192238
nav2_costmap_2d::Costmap2D & master_grid,
193239
int min_i, int min_j, int max_i, int max_j,
194-
const geometry_msgs::msg::Pose & pose)
240+
const geometry_msgs::msg::Pose & /*pose*/)
195241
{
196242
std::lock_guard<CostmapFilter::mutex_t> guard(*getMutex());
197243

@@ -286,49 +332,10 @@ void KeepoutFilter::process(
286332
}
287333

288334
// unsigned<-signed conversions.
289-
unsigned int mg_min_x_u = static_cast<unsigned int>(mg_min_x);
290-
unsigned int mg_min_y_u = static_cast<unsigned int>(mg_min_y);
291-
unsigned int mg_max_x_u = static_cast<unsigned int>(mg_max_x);
292-
unsigned int mg_max_y_u = static_cast<unsigned int>(mg_max_y);
293-
294-
// Let's find the pose's cost if we are allowed to override the lethal cost
295-
bool is_pose_lethal = false;
296-
if (override_lethal_cost_) {
297-
geometry_msgs::msg::Pose mask_pose;
298-
if (transformPose(global_frame_, pose, filter_mask_->header.frame_id, mask_pose)) {
299-
unsigned int mask_robot_i, mask_robot_j;
300-
if (worldToMask(filter_mask_, mask_pose.position.x, mask_pose.position.y, mask_robot_i,
301-
mask_robot_j))
302-
{
303-
auto data = getMaskCost(filter_mask_, mask_robot_i, mask_robot_j);
304-
is_pose_lethal = (data == INSCRIBED_INFLATED_OBSTACLE || data == LETHAL_OBSTACLE);
305-
if (is_pose_lethal) {
306-
RCLCPP_WARN_THROTTLE(
307-
logger_, *(clock_), 2000,
308-
"KeepoutFilter: Pose is in keepout zone, reducing cost override to navigate out.");
309-
}
310-
}
311-
}
312-
313-
// If in lethal space or just exited lethal space,
314-
// we need to update all possible spaces touched during this state
315-
if (is_pose_lethal || (last_pose_lethal_ && !is_pose_lethal)) {
316-
lethal_state_update_min_x_ = std::min(mg_min_x_u, lethal_state_update_min_x_);
317-
mg_min_x_u = lethal_state_update_min_x_;
318-
lethal_state_update_min_y_ = std::min(mg_min_y_u, lethal_state_update_min_y_);
319-
mg_min_y_u = lethal_state_update_min_y_;
320-
lethal_state_update_max_x_ = std::max(mg_max_x_u, lethal_state_update_max_x_);
321-
mg_max_x_u = lethal_state_update_max_x_;
322-
lethal_state_update_max_y_ = std::max(mg_max_y_u, lethal_state_update_max_y_);
323-
mg_max_y_u = lethal_state_update_max_y_;
324-
} else {
325-
// If out of lethal space, reset managed lethal state sizes
326-
lethal_state_update_min_x_ = master_grid.getSizeInCellsX();
327-
lethal_state_update_min_y_ = master_grid.getSizeInCellsY();
328-
lethal_state_update_max_x_ = 0u;
329-
lethal_state_update_max_y_ = 0u;
330-
}
331-
}
335+
const unsigned int mg_min_x_u = static_cast<unsigned int>(mg_min_x);
336+
const unsigned int mg_min_y_u = static_cast<unsigned int>(mg_min_y);
337+
const unsigned int mg_max_x_u = static_cast<unsigned int>(mg_max_x);
338+
const unsigned int mg_max_y_u = static_cast<unsigned int>(mg_max_y);
332339

333340
unsigned int i, j; // master_grid iterators
334341
unsigned int index; // corresponding index of master_grid
@@ -367,7 +374,7 @@ void KeepoutFilter::process(
367374
}
368375

369376
if (data > old_data || old_data == NO_INFORMATION) {
370-
if (override_lethal_cost_ && is_pose_lethal) {
377+
if (override_lethal_cost_ && is_pose_lethal_) {
371378
master_array[index] = lethal_override_cost_;
372379
} else {
373380
master_array[index] = data;
@@ -377,7 +384,7 @@ void KeepoutFilter::process(
377384
}
378385
}
379386

380-
last_pose_lethal_ = is_pose_lethal;
387+
last_pose_lethal_ = is_pose_lethal_;
381388
}
382389

383390
void KeepoutFilter::resetFilter()

0 commit comments

Comments
 (0)