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