-
Notifications
You must be signed in to change notification settings - Fork 472
[Draft]Add structured parameter support #2944
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: rolling
Are you sure you want to change the base?
Changes from all commits
892a2f0
6bec0a6
60b0637
dd0e66a
f36c794
c25ae28
a52fc85
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -26,6 +26,7 @@ | |||||||||||||||
#include "rcl_interfaces/msg/parameter_value.hpp" | ||||||||||||||||
#include "rclcpp/exceptions/exceptions.hpp" | ||||||||||||||||
#include "rclcpp/visibility_control.hpp" | ||||||||||||||||
#include "yaml-cpp/yaml.h" | ||||||||||||||||
|
||||||||||||||||
namespace rclcpp | ||||||||||||||||
{ | ||||||||||||||||
|
@@ -37,6 +38,7 @@ enum ParameterType : uint8_t | |||||||||||||||
PARAMETER_INTEGER = rcl_interfaces::msg::ParameterType::PARAMETER_INTEGER, | ||||||||||||||||
PARAMETER_DOUBLE = rcl_interfaces::msg::ParameterType::PARAMETER_DOUBLE, | ||||||||||||||||
PARAMETER_STRING = rcl_interfaces::msg::ParameterType::PARAMETER_STRING, | ||||||||||||||||
PARAMETER_YAML = rcl_interfaces::msg::ParameterType::PARAMETER_YAML, | ||||||||||||||||
PARAMETER_BYTE_ARRAY = rcl_interfaces::msg::ParameterType::PARAMETER_BYTE_ARRAY, | ||||||||||||||||
PARAMETER_BOOL_ARRAY = rcl_interfaces::msg::ParameterType::PARAMETER_BOOL_ARRAY, | ||||||||||||||||
PARAMETER_INTEGER_ARRAY = rcl_interfaces::msg::ParameterType::PARAMETER_INTEGER_ARRAY, | ||||||||||||||||
|
@@ -99,6 +101,9 @@ class ParameterValue | |||||||||||||||
/// Construct a parameter value with type PARAMETER_STRING. | ||||||||||||||||
RCLCPP_PUBLIC | ||||||||||||||||
explicit ParameterValue(const char * string_value); | ||||||||||||||||
/// Construct a parameter value with type PARAMETER_YAML | ||||||||||||||||
RCLCPP_PUBLIC | ||||||||||||||||
explicit ParameterValue(const YAML::Node & yaml_value); | ||||||||||||||||
/// Construct a parameter value with type PARAMETER_BYTE_ARRAY. | ||||||||||||||||
RCLCPP_PUBLIC | ||||||||||||||||
explicit ParameterValue(const std::vector<uint8_t> & byte_array_value); | ||||||||||||||||
|
@@ -121,6 +126,16 @@ class ParameterValue | |||||||||||||||
RCLCPP_PUBLIC | ||||||||||||||||
explicit ParameterValue(const std::vector<std::string> & string_array_value); | ||||||||||||||||
|
||||||||||||||||
|
||||||||||||||||
/// Generate a parameter value with type PARAMETER_YAML | ||||||||||||||||
Comment on lines
127
to
+130
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||
RCLCPP_PUBLIC | ||||||||||||||||
static ParameterValue YamlParameter(const std::string & yaml_string); | ||||||||||||||||
RCLCPP_PUBLIC | ||||||||||||||||
/// Generate a parameter value with type PARAMETER_YAML | ||||||||||||||||
static ParameterValue YamlParameter(const char * yaml_string); | ||||||||||||||||
/// Generate a parameter value with type PARAMETER_YAML | ||||||||||||||||
RCLCPP_PUBLIC | ||||||||||||||||
static ParameterValue YamlParameter(const YAML::Node & node); | ||||||||||||||||
/// Return an enum indicating the type of the set value. | ||||||||||||||||
RCLCPP_PUBLIC | ||||||||||||||||
ParameterType | ||||||||||||||||
|
@@ -187,6 +202,17 @@ class ParameterValue | |||||||||||||||
return value_.string_value; | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
template<ParameterType type> | ||||||||||||||||
constexpr | ||||||||||||||||
typename std::enable_if<type == ParameterType::PARAMETER_YAML, const YAML::Node>::type | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. include |
||||||||||||||||
get() const | ||||||||||||||||
{ | ||||||||||||||||
if (value_.type != rcl_interfaces::msg::ParameterType::PARAMETER_YAML) { | ||||||||||||||||
throw ParameterTypeException(ParameterType::PARAMETER_YAML, get_type()); | ||||||||||||||||
} | ||||||||||||||||
return YAML::Load(value_.yaml_value); | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
template<ParameterType type> | ||||||||||||||||
constexpr | ||||||||||||||||
typename std::enable_if< | ||||||||||||||||
|
@@ -282,6 +308,14 @@ class ParameterValue | |||||||||||||||
return get<ParameterType::PARAMETER_STRING>(); | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
template<typename type> | ||||||||||||||||
constexpr | ||||||||||||||||
typename std::enable_if<std::is_same<type, YAML::Node>::value, const YAML::Node>::type | ||||||||||||||||
get() const | ||||||||||||||||
{ | ||||||||||||||||
return get<ParameterType::PARAMETER_YAML>(); | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
template<typename type> | ||||||||||||||||
constexpr | ||||||||||||||||
typename std::enable_if< | ||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?> | ||
<package format="2"> | ||
<name>rclcpp</name> | ||
<version>30.1.0</version> | ||
<version>30.0.0</version> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't change this number manually. Restore |
||
<description>The ROS client library in C++.</description> | ||
|
||
<maintainer email="[email protected]">Ivan Paunovic</maintainer> | ||
|
@@ -46,6 +46,7 @@ | |
<depend>rosidl_dynamic_typesupport</depend> | ||
<depend>statistics_msgs</depend> | ||
<depend>tracetools</depend> | ||
<depend>yaml_cpp_vendor</depend> | ||
|
||
<test_depend>ament_cmake_gmock</test_depend> | ||
<test_depend>ament_cmake_google_benchmark</test_depend> | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -28,6 +28,7 @@ | |||||||||||||||
#include <string> | ||||||||||||||||
#include <utility> | ||||||||||||||||
#include <vector> | ||||||||||||||||
#include "yaml-cpp/yaml.h" | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. move above |
||||||||||||||||
|
||||||||||||||||
#include "rcl_interfaces/srv/list_parameters.hpp" | ||||||||||||||||
#include "rclcpp/create_publisher.hpp" | ||||||||||||||||
|
@@ -442,6 +443,131 @@ void __call_post_set_parameters_callbacks( | |||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
|
||||||||||||||||
Comment on lines
444
to
+446
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||
RCLCPP_LOCAL | ||||||||||||||||
/// Splits a parameter name into its component namespaces | ||||||||||||||||
std::vector<std::string> __split_parameter_name(const std::string & name) | ||||||||||||||||
{ | ||||||||||||||||
constexpr char delimiter = '.'; | ||||||||||||||||
std::vector<std::string> ret; | ||||||||||||||||
std::string out; | ||||||||||||||||
size_t position_found = -1; | ||||||||||||||||
std::string evaluation_string = name; | ||||||||||||||||
int counter = 0; | ||||||||||||||||
// Set an upper limit for the loop | ||||||||||||||||
// Anyone having more than 100 layers of namespacing should really evaluate their code - Rahul-K-A | ||||||||||||||||
while(counter++ < 100) | ||||||||||||||||
{ | ||||||||||||||||
position_found = evaluation_string.find(delimiter); | ||||||||||||||||
if (std::string::npos == position_found) | ||||||||||||||||
{ | ||||||||||||||||
break; | ||||||||||||||||
} | ||||||||||||||||
ret.push_back( evaluation_string.substr(0, position_found )); | ||||||||||||||||
evaluation_string = evaluation_string.substr(position_found + 1); | ||||||||||||||||
} | ||||||||||||||||
ret.push_back(evaluation_string); | ||||||||||||||||
return ret; | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
|
||||||||||||||||
RCLCPP_LOCAL | ||||||||||||||||
Comment on lines
+471
to
+474
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||
/// Pulled from Question 78243576 from Stack Overflow | ||||||||||||||||
void __traverse_node_and_change_value(YAML::Node & root, const std::vector<std::string>& path, rclcpp::ParameterValue value) | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lines < 100 characters |
||||||||||||||||
{ | ||||||||||||||||
YAML::Node traverse = root; | ||||||||||||||||
bool broken = false; | ||||||||||||||||
if (path.empty()) | ||||||||||||||||
{ | ||||||||||||||||
return; | ||||||||||||||||
} | ||||||||||||||||
// Skip first index because thats the name of the parameter itself and not a key | ||||||||||||||||
for (size_t i = 1; i < path.size() - 1; i++) | ||||||||||||||||
{ | ||||||||||||||||
if (traverse[path[i]]) | ||||||||||||||||
{ | ||||||||||||||||
traverse.reset(traverse[path[i]]); | ||||||||||||||||
} | ||||||||||||||||
else | ||||||||||||||||
{ | ||||||||||||||||
broken = true; | ||||||||||||||||
break; | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
if (broken) | ||||||||||||||||
{ | ||||||||||||||||
return; | ||||||||||||||||
} | ||||||||||||||||
// Set the value at the last level of nesting. Fugly switch case because we can't infer type - Rahul-K-A | ||||||||||||||||
switch (value.get_type()) { | ||||||||||||||||
case rclcpp::ParameterType::PARAMETER_BOOL: | ||||||||||||||||
traverse[path.back()] = value.get<rclcpp::ParameterType::PARAMETER_BOOL>(); | ||||||||||||||||
break; | ||||||||||||||||
case rclcpp::ParameterType::PARAMETER_INTEGER: | ||||||||||||||||
traverse[path.back()] = value.get<rclcpp::ParameterType::PARAMETER_INTEGER>(); | ||||||||||||||||
break; | ||||||||||||||||
case rclcpp::ParameterType::PARAMETER_DOUBLE: | ||||||||||||||||
traverse[path.back()] = value.get<rclcpp::ParameterType::PARAMETER_DOUBLE>(); | ||||||||||||||||
break; | ||||||||||||||||
case rclcpp::ParameterType::PARAMETER_STRING: | ||||||||||||||||
traverse[path.back()] = value.get<rclcpp::ParameterType::PARAMETER_STRING>(); | ||||||||||||||||
break; | ||||||||||||||||
case rclcpp::ParameterType::PARAMETER_BYTE_ARRAY: | ||||||||||||||||
traverse[path.back()] = value.get<rclcpp::ParameterType::PARAMETER_BYTE_ARRAY>(); | ||||||||||||||||
break; | ||||||||||||||||
case rclcpp::ParameterType::PARAMETER_BOOL_ARRAY: | ||||||||||||||||
traverse[path.back()] = value.get<rclcpp::ParameterType::PARAMETER_BOOL_ARRAY>(); | ||||||||||||||||
break; | ||||||||||||||||
case rclcpp::ParameterType::PARAMETER_INTEGER_ARRAY: | ||||||||||||||||
traverse[path.back()] = value.get<rclcpp::ParameterType::PARAMETER_INTEGER_ARRAY>(); | ||||||||||||||||
break; | ||||||||||||||||
case rclcpp::ParameterType::PARAMETER_DOUBLE_ARRAY: | ||||||||||||||||
traverse[path.back()] = value.get<rclcpp::ParameterType::PARAMETER_DOUBLE_ARRAY>(); | ||||||||||||||||
break; | ||||||||||||||||
case rclcpp::ParameterType::PARAMETER_STRING_ARRAY: | ||||||||||||||||
traverse[path.back()] = value.get<rclcpp::ParameterType::PARAMETER_STRING_ARRAY>(); | ||||||||||||||||
break; | ||||||||||||||||
default: | ||||||||||||||||
throw rclcpp::exceptions::UnimplementedError(); | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
RCLCPP_LOCAL | ||||||||||||||||
void __handle_changes_inside_yaml_parameters(const std::vector<rclcpp::Parameter>& parameters, std::map<std::string, | ||||||||||||||||
rclcpp::node_interfaces::ParameterInfo> & parameter_infos) | ||||||||||||||||
{ | ||||||||||||||||
for (const rclcpp::Parameter& parameter: parameters) | ||||||||||||||||
{ | ||||||||||||||||
std::vector<std::string> split_name = __split_parameter_name(parameter.get_name()); | ||||||||||||||||
|
||||||||||||||||
if (split_name.size() == 1 && split_name[0] == parameter.get_name()) | ||||||||||||||||
{ | ||||||||||||||||
continue; | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
// Find this yaml_param name inside parameter_infos | ||||||||||||||||
if (parameter_infos.find(split_name[0]) == parameter_infos.end()) | ||||||||||||||||
{ | ||||||||||||||||
continue; | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
if (parameter_infos[split_name[0]].descriptor.type != rclcpp::ParameterType::PARAMETER_YAML) | ||||||||||||||||
{ | ||||||||||||||||
continue; | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
// Load the value as a yaml | ||||||||||||||||
YAML::Node node = parameter_infos[split_name[0]].value.get<YAML::Node>(); | ||||||||||||||||
|
||||||||||||||||
// Set the value inside inside the yaml | ||||||||||||||||
__traverse_node_and_change_value(node, split_name, parameter.get_parameter_value()); | ||||||||||||||||
// Add the modified yaml param to the "parameters" vector so that it gets set | ||||||||||||||||
parameter_infos[split_name[0]].value = rclcpp::ParameterValue::YamlParameter(node); | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
|
||||||||||||||||
RCLCPP_LOCAL | ||||||||||||||||
rcl_interfaces::msg::SetParametersResult | ||||||||||||||||
__set_parameters_atomically_common( | ||||||||||||||||
|
@@ -471,6 +597,9 @@ __set_parameters_atomically_common( | |||||||||||||||
parameter_infos[name].descriptor.type = parameters[i].get_type(); | ||||||||||||||||
parameter_infos[name].value = parameters[i].get_parameter_value(); | ||||||||||||||||
} | ||||||||||||||||
// Handle cases where individual members of a yaml parameter have been changed | ||||||||||||||||
// We should probably not do this after the existing parameter namespacing feature is removed - Rahul-K-A | ||||||||||||||||
__handle_changes_inside_yaml_parameters(parameters, parameter_infos); | ||||||||||||||||
// Call the user post set parameter callback | ||||||||||||||||
__call_post_set_parameters_callbacks(parameters, post_set_callback_container); | ||||||||||||||||
} | ||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.