21
21
#include < vector>
22
22
23
23
#include " rcl_interfaces/srv/list_parameters.hpp"
24
+ #include " rcl_yaml_param_parser/parser.h"
24
25
#include " rclcpp/create_publisher.hpp"
25
26
#include " rcutils/logging_macros.h"
26
27
#include " rmw/qos_profiles.h"
27
28
28
29
using rclcpp::node_interfaces::NodeParameters;
29
30
30
31
NodeParameters::NodeParameters (
32
+ rclcpp::node_interfaces::NodeBaseInterface * node_base,
31
33
rclcpp::node_interfaces::NodeTopicsInterface * node_topics,
32
34
bool use_intra_process)
33
35
: node_topics_(node_topics)
@@ -44,6 +46,118 @@ NodeParameters::NodeParameters(
44
46
rmw_qos_profile_parameter_events,
45
47
use_intra_process,
46
48
allocator);
49
+
50
+ // Get the node's allocator
51
+ const rcl_node_t * node = node_base->get_rcl_node_handle ();
52
+ if (NULL == node) {
53
+ throw std::runtime_error (" Need valid node handle in NodeParameters" );
54
+ }
55
+ const rcl_node_options_t * options = rcl_node_get_options (node);
56
+ if (NULL == options) {
57
+ throw std::runtime_error (" Need valid node options NodeParameters" );
58
+ }
59
+
60
+ // TODO(sloretz) remove when circular dependency between rcl and rcl_yaml_param_parser is solved
61
+ // TODO(sloretz) Somehow need to get yaml parameters from RCL
62
+ const std::string yaml_path (" /tmp/sloretz-test-params.yaml" );
63
+ rcl_params_t * yaml_params = rcl_yaml_node_struct_init (options->allocator );
64
+ if (NULL == yaml_params) {
65
+ throw std::runtime_error (" Failed to initialize yaml params struct" );
66
+ }
67
+ if (!rcl_parse_yaml_file (yaml_path.c_str (), yaml_params, options->allocator )) {
68
+ throw std::runtime_error (" Failed to parse parameters " + yaml_path);
69
+ }
70
+
71
+ // Get namespace + node name
72
+ const std::string node_name = node_base->get_name ();
73
+ const std::string node_namespace = node_base->get_namespace ();
74
+ if (0u == node_namespace.size () || 0u == node_name.size ()) {
75
+ // Should never happen
76
+ throw std::runtime_error (" Node name and namespace were not set" );
77
+ }
78
+ std::string combined_name;
79
+ if (' /' == node_namespace.at (node_namespace.size ()-1 )) {
80
+ combined_name = node_namespace + node_name;
81
+ } else {
82
+ combined_name = node_namespace + ' /' + node_name;
83
+ }
84
+
85
+ // TODO(sloretz) should yaml param parser provide node names with a leading slash?
86
+ // Strip leading slash
87
+ combined_name.erase (combined_name.begin ());
88
+
89
+ // Convert c structs into a list of parameters to set
90
+ std::vector<rclcpp::parameter::ParameterVariant> parameters;
91
+ for (size_t n = 0 ; n < yaml_params->num_nodes ; ++n) {
92
+ if (combined_name != yaml_params->node_names [n]) {
93
+ continue ;
94
+ }
95
+ const rcl_node_params_t * const params_node = &(yaml_params->params [n]);
96
+ for (size_t p = 0 ; p < params_node->num_params ; ++p) {
97
+ const std::string param_name = params_node->parameter_names [p];
98
+ const rcl_variant_t * const param_value = &(params_node->parameter_values [p]);
99
+
100
+ if (param_value->bool_value ) {
101
+ parameters.emplace_back (param_name, *(param_value->bool_value ));
102
+ } else if (param_value->integer_value ) {
103
+ parameters.emplace_back (param_name, *(param_value->integer_value ));
104
+ } else if (param_value->double_value ) {
105
+ parameters.emplace_back (param_name, *(param_value->double_value ));
106
+ } else if (param_value->string_value ) {
107
+ parameters.emplace_back (param_name, std::string (param_value->string_value ));
108
+ } else if (param_value->byte_array_value ) {
109
+ const rcl_byte_array_t * const byte_array = param_value->byte_array_value ;
110
+ std::vector<uint8_t > bytes;
111
+ bytes.reserve (byte_array->size );
112
+ for (size_t v = 0 ; v < byte_array->size ; ++v) {
113
+ bytes.push_back (byte_array->values [v]);
114
+ }
115
+ parameters.emplace_back (param_name, bytes);
116
+ } else if (param_value->bool_array_value ) {
117
+ const rcl_bool_array_t * const bool_array = param_value->bool_array_value ;
118
+ std::vector<bool > bools;
119
+ bools.reserve (bool_array->size );
120
+ for (size_t v = 0 ; v < bool_array->size ; ++v) {
121
+ bools.push_back (bool_array->values [v]);
122
+ }
123
+ parameters.emplace_back (param_name, bools);
124
+ } else if (param_value->integer_array_value ) {
125
+ const rcl_int64_array_t * const int_array = param_value->integer_array_value ;
126
+ std::vector<int64_t > integers;
127
+ integers.reserve (int_array->size );
128
+ for (size_t v = 0 ; v < int_array->size ; ++v) {
129
+ integers.push_back (int_array->values [v]);
130
+ }
131
+ parameters.emplace_back (param_name, integers);
132
+ } else if (param_value->double_array_value ) {
133
+ const rcl_double_array_t * const double_array = param_value->double_array_value ;
134
+ std::vector<double > doubles;
135
+ doubles.reserve (double_array->size );
136
+ for (size_t v = 0 ; v < double_array->size ; ++v) {
137
+ doubles.push_back (double_array->values [v]);
138
+ }
139
+ parameters.emplace_back (param_name, doubles);
140
+ } else if (param_value->string_array_value ) {
141
+ const rcutils_string_array_t * const string_array = param_value->string_array_value ;
142
+ std::vector<std::string> strings;
143
+ strings.reserve (string_array->size );
144
+ for (size_t v = 0 ; v < string_array->size ; ++v) {
145
+ strings.emplace_back (string_array->data [v]);
146
+ }
147
+ parameters.emplace_back (param_name, strings);
148
+ } else {
149
+ rcl_yaml_node_struct_fini (yaml_params, options->allocator );
150
+ throw std::runtime_error (" Invalid parameter from parser" );
151
+ }
152
+ }
153
+ }
154
+ rcl_yaml_node_struct_fini (yaml_params, options->allocator );
155
+
156
+ // Set the parameters
157
+ rcl_interfaces::msg::SetParametersResult result = set_parameters_atomically (parameters);
158
+ if (!result.successful ) {
159
+ throw std::runtime_error (" Failed to set initial parameters" );
160
+ }
47
161
}
48
162
49
163
NodeParameters::~NodeParameters ()
0 commit comments