Nav2 Navigation Stack - rolling  main
ROS 2 Navigation Stack
semantic_scorer.cpp
1 // Copyright (c) 2025, Open Navigation LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <memory>
16 #include <string>
17 
18 #include "nav2_route/plugins/edge_cost_functions/semantic_scorer.hpp"
19 
20 namespace nav2_route
21 {
22 
24  const nav2::LifecycleNode::SharedPtr node,
25  const std::shared_ptr<tf2_ros::Buffer>/* tf_buffer */,
26  std::shared_ptr<nav2_costmap_2d::CostmapSubscriber>/* costmap_subscriber */,
27  const std::string & name)
28 {
29  RCLCPP_INFO(node->get_logger(), "Configuring semantic scorer.");
30  name_ = name;
31 
32  // Find the semantic data
33  nav2::declare_parameter_if_not_declared(
34  node, getName() + ".semantic_classes", rclcpp::ParameterValue(std::vector<std::string>{}));
35  std::vector<std::string> classes =
36  node->get_parameter(getName() + ".semantic_classes").as_string_array();
37  for (auto & cl : classes) {
38  nav2::declare_parameter_if_not_declared(
39  node, getName() + "." + cl, rclcpp::ParameterType::PARAMETER_DOUBLE);
40  const double cost = node->get_parameter(getName() + "." + cl).as_double();
41  semantic_info_[cl] = static_cast<float>(cost);
42  }
43 
44  // Find the key to look for semantic data for within the metadata. If set to empty string,
45  // will search instead for any key in the metadata.
46  nav2::declare_parameter_if_not_declared(
47  node, getName() + ".semantic_key", rclcpp::ParameterValue(std::string("class")));
48  key_ = node->get_parameter(getName() + ".semantic_key").as_string();
49 
50  // Find the proportional weight to apply, if multiple cost functions
51  nav2::declare_parameter_if_not_declared(
52  node, getName() + ".weight", rclcpp::ParameterValue(1.0));
53  weight_ = static_cast<float>(node->get_parameter(getName() + ".weight").as_double());
54 }
55 
56 void SemanticScorer::metadataKeyScorer(Metadata & mdata, float & score)
57 {
58  for (auto it = mdata.data.cbegin(); it != mdata.data.cend(); ++it) {
59  if (auto sem = semantic_info_.find(it->first); sem != semantic_info_.end()) {
60  score += sem->second;
61  }
62  }
63 }
64 
65 void SemanticScorer::metadataValueScorer(Metadata & mdata, float & score)
66 {
67  std::string cl;
68  cl = mdata.getValue<std::string>(key_, cl);
69  if (auto sem = semantic_info_.find(cl); sem != semantic_info_.end()) {
70  score += sem->second;
71  }
72 }
73 
75  const EdgePtr edge,
76  const RouteRequest & /* route_request */,
77  const EdgeType & /* edge_type */, float & cost)
78 {
79  float score = 0.0;
80  Metadata & node_mdata = edge->end->metadata;
81  Metadata & edge_mdata = edge->metadata;
82 
83  // If a particular key is known to have semantic info, use it, else search
84  // each metadata key field to see if it matches
85  if (key_.empty()) {
86  metadataKeyScorer(node_mdata, score);
87  metadataKeyScorer(edge_mdata, score);
88  } else {
89  metadataValueScorer(node_mdata, score);
90  metadataValueScorer(edge_mdata, score);
91  }
92 
93  cost = weight_ * score;
94  return true;
95 }
96 
98 {
99  return name_;
100 }
101 
102 } // namespace nav2_route
103 
104 #include "pluginlib/class_list_macros.hpp"
A plugin interface to score edges during graph search to modify the lowest cost path (e....
Scores an edge based on arbitrary graph semantic data such as set priority/danger levels or regional ...
void metadataValueScorer(Metadata &mdata, float &score)
Scores graph object based on metadata's semantic value at key.
void configure(const nav2::LifecycleNode::SharedPtr node, const std::shared_ptr< tf2_ros::Buffer > tf_buffer, std::shared_ptr< nav2_costmap_2d::CostmapSubscriber > costmap_subscriber, const std::string &name) override
Configure.
std::string getName() override
Get name of the plugin for parameter scope mapping.
void metadataKeyScorer(Metadata &mdata, float &score)
Scores graph object based on metadata's key values.
bool score(const EdgePtr edge, const RouteRequest &route_request, const EdgeType &edge_type, float &cost) override
Main scoring plugin API.
An object representing edges between nodes.
Definition: types.hpp:134
An object to store arbitrary metadata regarding nodes from the graph file.
Definition: types.hpp:35
An object to store salient features of the route request including its start and goal node ids,...
Definition: types.hpp:224