Compare commits

...

2 Commits

Author SHA1 Message Date
Shane Loretz
041bb488f4 Add missing newline
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
2023-01-24 19:18:32 -08:00
Shane Loretz
0270775f65 Add rclcpp::list_parameter_override_prefixes
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
2023-01-24 19:07:44 -08:00
5 changed files with 216 additions and 0 deletions

View File

@@ -65,6 +65,7 @@ set(${PROJECT_NAME}_SRCS
src/rclcpp/guard_condition.cpp
src/rclcpp/init_options.cpp
src/rclcpp/intra_process_manager.cpp
src/rclcpp/list_parameter_override_prefixes.cpp
src/rclcpp/logger.cpp
src/rclcpp/logging_mutex.cpp
src/rclcpp/memory_strategies.cpp

View File

@@ -0,0 +1,67 @@
// Copyright 2023 Intrisnic.ai
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef RCLCPP__LIST_PARAMETER_OVERRIDE_PREFIXES_HPP_
#define RCLCPP__LIST_PARAMETER_OVERRIDE_PREFIXES_HPP_
#include <map>
#include <string>
#include <unordered_set>
#include <rclcpp/node_interfaces/node_interfaces.hpp>
#include <rclcpp/node_interfaces/node_parameters_interface.hpp>
#include <rclcpp/parameter_value.hpp>
namespace rclcpp
{
namespace detail
{
/** @brief Internal function for unit testing.
* @internal
*/
std::unordered_set<std::string>
list_parameter_override_prefixes(
const std::map<std::string, rclcpp::ParameterValue> & overrides,
std::string prefix);
} // namespace detail
/**
* @brief Get parameter overrides that have a given prefix
*
* Example:
* Say the given parameter overrides are foo, foo.baz, foo.bar.baz, and foobar.baz
* Given prefix "", this will return foo, and foobar
* Given prefix "foo", this will return foo.baz and foo.bar
* Given prefix "foo.bar", this will return foo.bar.baz
* Given prefix "foo.baz", this will return an empty list
*
* All overrides are searched and returned, so that this can be used to
* conditionally declare parameters.
* The returned names may or may not be valid parameters, but instead are
* prefixes of valid parameters.
* The prefix itself will never be in the returned output.
*
*
* @param[in] interfaces - The node interfaces used to get the parameter overrides
* @param[in] prefix - the parameter prefix
* @param[in] max_depth - how deep to return parameter override names, or 0 for
* unlimited depth.
*/
std::unordered_set<std::string>
list_parameter_override_prefixes(
node_interfaces::NodeInterfaces<node_interfaces::NodeParametersInterface> interfaces,
std::string prefix);
} // namespace rclcpp
#endif // RCLCPP__LIST_PARAMETER_OVERRIDE_PREFIXES_HPP_

View File

@@ -0,0 +1,66 @@
// Copyright 2023 Intrisnic.ai
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <rclcpp/list_parameter_override_prefixes.hpp>
#include <cassert>
#include <string>
#include <unordered_set>
namespace rclcpp
{
std::unordered_set<std::string>
list_parameter_override_prefixes(
node_interfaces::NodeInterfaces<node_interfaces::NodeParametersInterface> interfaces,
std::string prefix)
{
const std::map<std::string, rclcpp::ParameterValue> & overrides =
interfaces.get_node_parameters_interface()->get_parameter_overrides();
return detail::list_parameter_override_prefixes(overrides, prefix);
}
std::unordered_set<std::string>
detail::list_parameter_override_prefixes(
const std::map<std::string, rclcpp::ParameterValue> & overrides,
std::string prefix)
{
// TODO(sloretz) ROS 2 must have this in a header somewhere, right?
const char kParamSeparator = '.';
// Find all overrides starting with "prefix.", unless the prefix is empty.
// If the prefix is empty then look at all parameter overrides.
if (!prefix.empty() && prefix.back() != kParamSeparator) {
prefix += kParamSeparator;
}
std::unordered_set<std::string> output_names;
for (const auto & kv : overrides) {
const std::string & name = kv.first;
if (name.size() <= prefix.size()) {
// Too short, no point in checking
continue;
}
assert(prefix.size() < name.size());
// TODO(sloretz) use string::starts_with in c++20
if (name.rfind(prefix, 0) == 0) { // if name starts with prefix
// Truncate names to the next separator
size_t separator_pos = name.find(kParamSeparator, prefix.size());
// Insert truncated name
output_names.insert(name.substr(0, separator_pos));
}
}
return output_names;
}
} // namespace rclcpp

View File

@@ -766,3 +766,8 @@ function(test_subscription_content_filter_for_rmw_implementation)
endif()
endfunction()
call_for_each_rmw_implementation(test_subscription_content_filter_for_rmw_implementation)
ament_add_gtest(test_list_parameter_override_prefixes test_list_parameter_override_prefixes.cpp)
if(TARGET test_list_parameter_override_prefixes)
target_link_libraries(test_list_parameter_override_prefixes ${PROJECT_NAME})
endif()

View File

@@ -0,0 +1,77 @@
// Copyright 2023 Intrisnic.ai
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <gtest/gtest.h>
#include <map>
#include <string>
#include <rclcpp/list_parameter_override_prefixes.hpp>
TEST(parameter, list_parameter_override_prefixes)
{
const std::map<std::string, rclcpp::ParameterValue> overrides = {
{"foo", {}},
{"foo.baz", {}},
{"foo.bar", {}},
{"foo.bar.baz", {}},
{"foo.bar.baz.bing", {}},
{"foobar.baz", {}},
{"baz", {}}
};
{
auto matches = rclcpp::detail::list_parameter_override_prefixes(
overrides, "foo");
EXPECT_EQ(2u, matches.size());
EXPECT_NE(matches.end(), matches.find("foo.baz"));
EXPECT_NE(matches.end(), matches.find("foo.bar"));
}
{
auto matches = rclcpp::detail::list_parameter_override_prefixes(
overrides, "foo.bar");
EXPECT_EQ(1u, matches.size());
EXPECT_NE(matches.end(), matches.find("foo.bar.baz"));
}
{
auto matches = rclcpp::detail::list_parameter_override_prefixes(
overrides, "foo.bar.baz");
EXPECT_EQ(1u, matches.size());
EXPECT_NE(matches.end(), matches.find("foo.bar.baz.bing"));
}
{
auto matches = rclcpp::detail::list_parameter_override_prefixes(
overrides, "foo.baz");
EXPECT_EQ(0u, matches.size());
}
{
auto matches = rclcpp::detail::list_parameter_override_prefixes(
overrides, "foobar");
EXPECT_EQ(1u, matches.size());
EXPECT_NE(matches.end(), matches.find("foobar.baz"));
}
{
auto matches = rclcpp::detail::list_parameter_override_prefixes(
overrides, "dne");
EXPECT_EQ(0u, matches.size());
}
{
auto matches = rclcpp::detail::list_parameter_override_prefixes(
overrides, "");
EXPECT_EQ(3u, matches.size());
EXPECT_NE(matches.end(), matches.find("foo"));
EXPECT_NE(matches.end(), matches.find("foobar"));
EXPECT_NE(matches.end(), matches.find("baz"));
}
}