@@ -44,6 +44,58 @@ PLUGINLIB_EXPORT_CLASS(clear_costmap_recovery::ClearCostmapRecovery, nav_core::R
44
44
using costmap_2d::NO_INFORMATION;
45
45
46
46
namespace clear_costmap_recovery {
47
+
48
+ /* *
49
+ * @brief return the names of the layers in the costmap, each prefixed with prefix
50
+ */
51
+ std::vector<std::string> getLayerNames (const costmap_2d::Costmap2DROS& costmap)
52
+ {
53
+ std::vector<std::string> names;
54
+ std::vector<boost::shared_ptr<costmap_2d::Layer> >* plugins = costmap.getLayeredCostmap ()->getPlugins ();
55
+ for (std::vector<boost::shared_ptr<costmap_2d::Layer> >::const_iterator pluginp = plugins->begin ();
56
+ pluginp != plugins->end ();
57
+ ++pluginp) {
58
+ names.push_back ((*pluginp)->getName ());
59
+ }
60
+ return names;
61
+ }
62
+
63
+ /* *
64
+ * @brief A layer is considered "matching" if the raw name (after the slash) is in the name_specs set
65
+ */
66
+ bool isMatchingLayerName (const std::string& layer_name, const std::set<std::string>& name_specs)
67
+ {
68
+ size_t slash = layer_name.rfind (' /' );
69
+ if (slash != std::string::npos)
70
+ {
71
+ // If no slash, use whole string
72
+ return name_specs.count (layer_name) != 0 ;
73
+ }
74
+ else
75
+ {
76
+ // Check the part after the slash
77
+ return name_specs.count (layer_name.substr (slash + 1 )) != 0 ;
78
+ }
79
+ }
80
+
81
+ /* *
82
+ * @brief Returns the subset of layer_names which match the name spec
83
+ */
84
+ std::vector<std::string> getLayerMatches (const std::vector<std::string>& layer_names,
85
+ const std::set<std::string>& name_specs)
86
+ {
87
+ std::vector<std::string> matches;
88
+ for (unsigned int i = 0 ; i < layer_names.size (); i++)
89
+ {
90
+ if (isMatchingLayerName (layer_names[i], name_specs))
91
+ {
92
+ matches.push_back (layer_names[i]);
93
+ }
94
+ }
95
+ return matches;
96
+ }
97
+
98
+
47
99
ClearCostmapRecovery::ClearCostmapRecovery (): global_costmap_(NULL ), local_costmap_(NULL ),
48
100
tf_ (NULL ), initialized_(false ) {}
49
101
@@ -68,13 +120,55 @@ void ClearCostmapRecovery::initialize(std::string name, tf2_ros::Buffer* tf,
68
120
affected_maps_ = " both" ;
69
121
}
70
122
71
- std::vector<std::string> clearable_layers_default, clearable_layers;
72
- clearable_layers_default.push_back ( std::string (" obstacles" ) );
73
- private_nh.param (" layer_names" , clearable_layers, clearable_layers_default);
123
+ // Get a list of layer names
124
+ std::vector<std::string> layer_names = getLayerNames (*global_costmap_);
125
+ std::vector<std::string> local_layer_names = getLayerNames (*local_costmap_);
126
+ layer_names.insert (layer_names.end (), local_layer_names.begin (), local_layer_names.end ());
127
+
128
+ std::vector<std::string> clearable_layers_vector;
129
+ if (private_nh.getParam (" layer_names" , clearable_layers_vector))
130
+ {
131
+ clearable_layers_ = std::set<std::string>(clearable_layers_vector.begin (), clearable_layers_vector.end ());
132
+ }
133
+ else
134
+ {
135
+ // If the parameter is not specified, try two different defaults
136
+ std::vector<std::string> possible_defaults {" obstacles" , " obstacle_layer" };
137
+ for (unsigned int i = 0 ; i < possible_defaults.size (); i++)
138
+ {
139
+ std::set<std::string> default_set;
140
+ default_set.insert (possible_defaults[i]);
141
+ if (getLayerMatches (layer_names, default_set).size () > 0 )
142
+ {
143
+ clearable_layers_ = default_set;
144
+ break ;
145
+ }
146
+ }
147
+ }
74
148
75
- for (unsigned i=0 ; i < clearable_layers.size (); i++) {
76
- ROS_INFO (" Recovery behavior will clear layer '%s'" , clearable_layers[i].c_str ());
77
- clearable_layers_.insert (clearable_layers[i]);
149
+ std::vector<std::string> clearable_layer_names = getLayerMatches (layer_names, clearable_layers_);
150
+ if (clearable_layer_names.empty ())
151
+ {
152
+ ROS_ERROR (" In recovery behavior %s, none of the layer names match the layer_names parameter." , name.c_str ());
153
+ ROS_ERROR (" Layer names:" );
154
+ for (unsigned int i = 0 ; i < layer_names.size (); i++)
155
+ {
156
+ ROS_ERROR (" \t %s" , layer_names[i].c_str ());
157
+ }
158
+ ROS_ERROR (" Value of %s:" , private_nh.resolveName (" layer_names" ).c_str ());
159
+ for (std::set<std::string>::const_iterator it = clearable_layers_.begin ();
160
+ it != clearable_layers_.end ();
161
+ ++it) {
162
+ ROS_ERROR (" \t %s" , it->c_str ());
163
+ }
164
+ }
165
+ else
166
+ {
167
+ ROS_INFO (" Recovery behavior %s will clear layers:" , name.c_str ());
168
+ for (unsigned int i = 0 ; i < clearable_layer_names.size (); i++)
169
+ {
170
+ ROS_INFO (" \t %s" , clearable_layer_names[i].c_str ());
171
+ }
78
172
}
79
173
80
174
initialized_ = true ;
@@ -136,13 +230,8 @@ void ClearCostmapRecovery::clear(costmap_2d::Costmap2DROS* costmap){
136
230
137
231
for (std::vector<boost::shared_ptr<costmap_2d::Layer> >::iterator pluginp = plugins->begin (); pluginp != plugins->end (); ++pluginp) {
138
232
boost::shared_ptr<costmap_2d::Layer> plugin = *pluginp;
139
- std::string name = plugin->getName ();
140
- int slash = name.rfind (' /' );
141
- if ( slash != std::string::npos ){
142
- name = name.substr (slash+1 );
143
- }
144
-
145
- if (clearable_layers_.count (name)!=0 ){
233
+ if (isMatchingLayerName (plugin->getName (), clearable_layers_))
234
+ {
146
235
boost::shared_ptr<costmap_2d::CostmapLayer> costmap;
147
236
costmap = boost::static_pointer_cast<costmap_2d::CostmapLayer>(plugin);
148
237
clearMap (costmap, x, y);
0 commit comments