Skip to content

Commit 408107c

Browse files
authored
Merge branch 'main' into main
Signed-off-by: Sakshay Mahna <sakshum19@gmail.com>
2 parents 74631ae + 7f561b0 commit 408107c

File tree

15 files changed

+284
-21
lines changed

15 files changed

+284
-21
lines changed

.circleci/config.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@ _commands:
3333
- restore_cache:
3434
name: Restore Cache << parameters.key >>
3535
keys:
36-
- "<< parameters.key >>-v33\
36+
- "<< parameters.key >>-v35\
3737
-{{ arch }}\
3838
-{{ .Branch }}\
3939
-{{ .Environment.CIRCLE_PR_NUMBER }}\
4040
-{{ checksum \"<< parameters.workspace >>/lockfile.txt\" }}"
41-
- "<< parameters.key >>-v33\
41+
42+
- "<< parameters.key >>-v35\
4243
-{{ arch }}\
4344
-main\
4445
-<no value>\
@@ -58,7 +59,8 @@ _commands:
5859
steps:
5960
- save_cache:
6061
name: Save Cache << parameters.key >>
61-
key: "<< parameters.key >>-v33\
62+
63+
key: "<< parameters.key >>-v35\
6264
-{{ arch }}\
6365
-{{ .Branch }}\
6466
-{{ .Environment.CIRCLE_PR_NUMBER }}\

.github/mergify.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ pull_request_rules:
2626
branches:
2727
- humble
2828

29+
- name: backport to kilted at reviewers discretion
30+
conditions:
31+
- base=main
32+
- "label=backport-kilted"
33+
actions:
34+
backport:
35+
branches:
36+
- kilted
37+
2938
- name: delete head branch after merge
3039
conditions:
3140
- merged

nav2_bringup/launch/tb3_loopback_simulation_launch.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ def generate_launch_description() -> LaunchDescription:
144144
'use_composition': use_composition,
145145
'use_respawn': use_respawn,
146146
'use_localization': 'False', # Don't use SLAM, AMCL
147+
'use_keepout_zones': 'False',
148+
'use_speed_zones': 'False',
147149
}.items(),
148150
)
149151

nav2_bringup/launch/tb3_simulation_launch.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,8 @@ def generate_launch_description() -> LaunchDescription:
195195
'autostart': autostart,
196196
'use_composition': use_composition,
197197
'use_respawn': use_respawn,
198+
'use_keepout_zones': 'False',
199+
'use_speed_zones': 'False',
198200
}.items(),
199201
)
200202
# The SDF file for the world is a xacro file because we wanted to

nav2_bringup/params/nav2_params.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ local_costmap:
229229
plugin: "nav2_costmap_2d::KeepoutFilter"
230230
enabled: KEEPOUT_ZONE_ENABLED
231231
filter_info_topic: "keepout_costmap_filter_info"
232+
override_lethal_cost: True
233+
lethal_override_cost: 200
232234
inflation_layer:
233235
plugin: "nav2_costmap_2d::InflationLayer"
234236
cost_scaling_factor: 3.0
@@ -281,6 +283,8 @@ global_costmap:
281283
plugin: "nav2_costmap_2d::KeepoutFilter"
282284
enabled: KEEPOUT_ZONE_ENABLED
283285
filter_info_topic: "keepout_costmap_filter_info"
286+
override_lethal_cost: True
287+
lethal_override_cost: 200
284288
speed_filter:
285289
plugin: "nav2_costmap_2d::SpeedFilter"
286290
enabled: SPEED_ZONE_ENABLED

nav2_controller/src/controller_server.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ ControllerServer::ControllerServer(const rclcpp::NodeOptions & options)
6868
// The costmap node is used in the implementation of the controller
6969
costmap_ros_ = std::make_shared<nav2_costmap_2d::Costmap2DROS>(
7070
"local_costmap", std::string{get_namespace()},
71-
get_parameter("use_sim_time").as_bool());
71+
get_parameter("use_sim_time").as_bool(), options);
7272
}
7373

7474
ControllerServer::~ControllerServer()

nav2_costmap_2d/include/nav2_costmap_2d/costmap_2d_ros.hpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ class Costmap2DROS : public nav2_util::LifecycleNode
9191
explicit Costmap2DROS(
9292
const std::string & name,
9393
const std::string & parent_namespace = "/",
94-
const bool & use_sim_time = false);
94+
const bool & use_sim_time = false,
95+
const rclcpp::NodeOptions & options = rclcpp::NodeOptions());
9596

9697
/**
9798
* @brief Common initialization for constructors
@@ -430,6 +431,27 @@ class Costmap2DROS : public nav2_util::LifecycleNode
430431
dynamicParametersCallback(std::vector<rclcpp::Parameter> parameters);
431432
};
432433

434+
// free functions
435+
436+
/**
437+
* @brief Given a specified argument name, replaces it with the specified
438+
* new value. If the argument is not in the existing list, a new argument
439+
* is created with the specified option.
440+
*/
441+
void replaceOrAddArgument(
442+
std::vector<std::string> & arguments, const std::string & option,
443+
const std::string & arg_name, const std::string & new_argument);
444+
445+
/**
446+
* @brief Given the node options of a parent node, expands of replaces
447+
* the fields for the node name, namespace and use_sim_time
448+
*/
449+
rclcpp::NodeOptions getChildNodeOptions(
450+
const std::string & name,
451+
const std::string & parent_namespace,
452+
const bool & use_sim_time,
453+
const rclcpp::NodeOptions & parent_options);
454+
433455
} // namespace nav2_costmap_2d
434456

435457
#endif // NAV2_COSTMAP_2D__COSTMAP_2D_ROS_HPP_

nav2_costmap_2d/include/nav2_costmap_2d/costmap_filters/keepout_filter.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@ class KeepoutFilter : public CostmapFilter
102102
nav_msgs::msg::OccupancyGrid::SharedPtr filter_mask_;
103103

104104
std::string global_frame_; // Frame of current layer (master_grid)
105+
106+
bool override_lethal_cost_{false}; // If true, lethal cost will be overridden
107+
unsigned char lethal_override_cost_{252}; // Value to override lethal cost with
108+
bool last_pose_lethal_{false}; // If true, last pose was lethal
109+
unsigned int lethal_state_update_min_x_{999999u}, lethal_state_update_min_y_{999999u};
110+
unsigned int lethal_state_update_max_x_{0u}, lethal_state_update_max_y_{0u};
105111
};
106112

107113
} // namespace nav2_costmap_2d

nav2_costmap_2d/plugins/costmap_filters/keepout_filter.cpp

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,15 @@ void KeepoutFilter::initializeFilter(
7474
std::bind(&KeepoutFilter::filterInfoCallback, this, std::placeholders::_1));
7575

7676
global_frame_ = layered_costmap_->getGlobalFrameID();
77+
78+
declareParameter("override_lethal_cost", rclcpp::ParameterValue(false));
79+
node->get_parameter(name_ + "." + "override_lethal_cost", override_lethal_cost_);
80+
declareParameter("lethal_override_cost", rclcpp::ParameterValue(MAX_NON_OBSTACLE));
81+
node->get_parameter(name_ + "." + "lethal_override_cost", lethal_override_cost_);
82+
83+
// clamp lethal_override_cost_ in case if higher than MAX_NON_OBSTACLE is given
84+
lethal_override_cost_ = \
85+
std::clamp<unsigned int>(lethal_override_cost_, FREE_SPACE, MAX_NON_OBSTACLE);
7786
}
7887

7988
void KeepoutFilter::filterInfoCallback(
@@ -149,7 +158,7 @@ void KeepoutFilter::maskCallback(
149158
void KeepoutFilter::process(
150159
nav2_costmap_2d::Costmap2D & master_grid,
151160
int min_i, int min_j, int max_i, int max_j,
152-
const geometry_msgs::msg::Pose2D & /*pose*/)
161+
const geometry_msgs::msg::Pose2D & pose)
153162
{
154163
std::lock_guard<CostmapFilter::mutex_t> guard(*getMutex());
155164

@@ -244,10 +253,47 @@ void KeepoutFilter::process(
244253
}
245254

246255
// unsigned<-signed conversions.
247-
unsigned const int mg_min_x_u = static_cast<unsigned int>(mg_min_x);
248-
unsigned const int mg_min_y_u = static_cast<unsigned int>(mg_min_y);
249-
unsigned const int mg_max_x_u = static_cast<unsigned int>(mg_max_x);
250-
unsigned const int mg_max_y_u = static_cast<unsigned int>(mg_max_y);
256+
unsigned int mg_min_x_u = static_cast<unsigned int>(mg_min_x);
257+
unsigned int mg_min_y_u = static_cast<unsigned int>(mg_min_y);
258+
unsigned int mg_max_x_u = static_cast<unsigned int>(mg_max_x);
259+
unsigned int mg_max_y_u = static_cast<unsigned int>(mg_max_y);
260+
261+
// Let's find the pose's cost if we are allowed to override the lethal cost
262+
bool is_pose_lethal = false;
263+
if (override_lethal_cost_) {
264+
geometry_msgs::msg::Pose2D mask_pose;
265+
if (transformPose(global_frame_, pose, filter_mask_->header.frame_id, mask_pose)) {
266+
unsigned int mask_robot_i, mask_robot_j;
267+
if (worldToMask(filter_mask_, mask_pose.x, mask_pose.y, mask_robot_i, mask_robot_j)) {
268+
auto data = getMaskCost(filter_mask_, mask_robot_i, mask_robot_j);
269+
is_pose_lethal = (data == INSCRIBED_INFLATED_OBSTACLE || data == LETHAL_OBSTACLE);
270+
if (is_pose_lethal) {
271+
RCLCPP_WARN_THROTTLE(
272+
logger_, *(clock_), 2000,
273+
"KeepoutFilter: Pose is in keepout zone, reducing cost override to navigate out.");
274+
}
275+
}
276+
}
277+
278+
// If in lethal space or just exited lethal space,
279+
// we need to update all possible spaces touched during this state
280+
if (is_pose_lethal || (last_pose_lethal_ && !is_pose_lethal)) {
281+
lethal_state_update_min_x_ = std::min(mg_min_x_u, lethal_state_update_min_x_);
282+
mg_min_x_u = lethal_state_update_min_x_;
283+
lethal_state_update_min_y_ = std::min(mg_min_y_u, lethal_state_update_min_y_);
284+
mg_min_y_u = lethal_state_update_min_y_;
285+
lethal_state_update_max_x_ = std::max(mg_max_x_u, lethal_state_update_max_x_);
286+
mg_max_x_u = lethal_state_update_max_x_;
287+
lethal_state_update_max_y_ = std::max(mg_max_y_u, lethal_state_update_max_y_);
288+
mg_max_y_u = lethal_state_update_max_y_;
289+
} else {
290+
// If out of lethal space, reset managed lethal state sizes
291+
lethal_state_update_min_x_ = master_grid.getSizeInCellsX();
292+
lethal_state_update_min_y_ = master_grid.getSizeInCellsY();
293+
lethal_state_update_max_x_ = 0u;
294+
lethal_state_update_max_y_ = 0u;
295+
}
296+
}
251297

252298
unsigned int i, j; // master_grid iterators
253299
unsigned int index; // corresponding index of master_grid
@@ -284,12 +330,19 @@ void KeepoutFilter::process(
284330
if (data == NO_INFORMATION) {
285331
continue;
286332
}
333+
287334
if (data > old_data || old_data == NO_INFORMATION) {
288-
master_array[index] = data;
335+
if (override_lethal_cost_ && is_pose_lethal) {
336+
master_array[index] = lethal_override_cost_;
337+
} else {
338+
master_array[index] = data;
339+
}
289340
}
290341
}
291342
}
292343
}
344+
345+
last_pose_lethal_ = is_pose_lethal;
293346
}
294347

295348
void KeepoutFilter::resetFilter()

nav2_costmap_2d/src/costmap_2d_ros.cpp

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,21 +71,48 @@ Costmap2DROS::Costmap2DROS(const rclcpp::NodeOptions & options)
7171
init();
7272
}
7373

74+
void replaceOrAddArgument(
75+
std::vector<std::string> & arguments, const std::string & option,
76+
const std::string & arg_name, const std::string & new_argument)
77+
{
78+
auto argument = std::find_if(arguments.begin(), arguments.end(),
79+
[arg_name](const std::string & value){return value.find(arg_name) != std::string::npos;});
80+
if (argument != arguments.end()) {
81+
*argument = new_argument;
82+
} else {
83+
arguments.push_back("--ros-args");
84+
arguments.push_back(option);
85+
arguments.push_back(new_argument);
86+
}
87+
}
88+
89+
rclcpp::NodeOptions getChildNodeOptions(
90+
const std::string & name,
91+
const std::string & parent_namespace,
92+
const bool & use_sim_time,
93+
const rclcpp::NodeOptions & parent_options)
94+
{
95+
std::vector<std::string> new_arguments = parent_options.arguments();
96+
replaceOrAddArgument(new_arguments, "-r", "__ns",
97+
"__ns:=" + nav2_util::add_namespaces(parent_namespace, name));
98+
replaceOrAddArgument(new_arguments, "-r", "__node", name + ":" + "__node:=" + name);
99+
replaceOrAddArgument(new_arguments, "-p", "use_sim_time",
100+
"use_sim_time:=" + std::string(use_sim_time ? "true" : "false"));
101+
return rclcpp::NodeOptions().arguments(new_arguments);
102+
}
103+
74104
Costmap2DROS::Costmap2DROS(
75105
const std::string & name,
76106
const std::string & parent_namespace,
77-
const bool & use_sim_time)
107+
const bool & use_sim_time,
108+
const rclcpp::NodeOptions & options)
78109
: nav2_util::LifecycleNode(name, "",
79110
// NodeOption arguments take precedence over the ones provided on the command line
80111
// use this to make sure the node is placed on the provided namespace
81112
// TODO(orduno) Pass a sub-node instead of creating a new node for better handling
82113
// of the namespaces
83-
rclcpp::NodeOptions().arguments({
84-
"--ros-args", "-r", std::string("__ns:=") +
85-
nav2_util::add_namespaces(parent_namespace, name),
86-
"--ros-args", "-r", name + ":" + std::string("__node:=") + name,
87-
"--ros-args", "-p", "use_sim_time:=" + std::string(use_sim_time ? "true" : "false"),
88-
})),
114+
getChildNodeOptions(name, parent_namespace, use_sim_time, options)
115+
),
89116
name_(name),
90117
default_plugins_{"static_layer", "obstacle_layer", "inflation_layer"},
91118
default_types_{

0 commit comments

Comments
 (0)