Skip to content
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

Parse parameter descriptors in yaml #533

Open
wants to merge 19 commits into
base: rolling
Choose a base branch
from

Conversation

bpwilcox
Copy link

This PR addresses the feature request in #481, namely parsing parameter descriptor keys in the yaml file. This feature will enable parameter descriptors to be added into nodes at run-time.

Overview of additions are:

  • New struct types to contain parameter descriptor information (in alignment with the ParameterDescriptor.msg)
    • rcl_param_descriptor_t, rcl_node_params_descriptor_t
    • descriptor keys are compared for assignment into struct
  • Added map level for MAP_PARAM_DESCRIPTORS_LVL to parse descriptors
    • new map level is triggered when the 'parameter__descriptors' key is parsed by the yaml event
    • some added API to handle descriptor keys/values
  • Independent allocation/access to parameters and parameter descriptors in the params_t struct
    • each node will have its list of parameters as well as descriptors
    • parameter descriptors may be added in yaml file without corresponding parameter or mixed

The proposed syntax for this PR is:

  node1:
    ros__parameters:
      foo: 42
      bar: 25.0
      param1: 10
      parameter__descriptors:
        param1:
          type: 2
          min_value: 5
          max_value: 100
          step: 5
          read_only: false
          description: "int parameter"
          additional_constraints: "only multiples of 5"
        param2:
          min_value: 1.0
          max_value: 10.0
          description: "double parameter"

I've made accompanying changes in rclcpp to extract the parameter descriptors struct into a ParameterDescriptor.msg which will override when calling declare_parameter (or if the overrides are automatically declared). I will submit that PR to the rclcpp repo soon, though this is a pre-requisite.

@bpwilcox bpwilcox force-pushed the parse_parameter_descriptors branch 2 times, most recently from feb60ac to f28d0cc Compare October 28, 2019 23:18
@wjwwood wjwwood added the enhancement New feature or request label Nov 14, 2019
@wjwwood wjwwood requested a review from hidmic November 15, 2019 23:08
Copy link
Contributor

@hidmic hidmic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First pass!

int64_t * min_value_int;
int64_t * max_value_int;
int64_t * step_int;
} rcl_param_descriptor_t;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wjwwood meta: not a comment for you @bpwilcox, but replicating rcl_interfaces/msg/ParameterDescriptor structure is not ideal. The same goes with rcl_interfaces/msg/Parameter, so I wonder if we should be re-using the message C representation instead (like we partially do in rcl_action already). Thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a related note, I understand pointers are used here to have indication of absence. At the same time, ROS 2 interfaces have no optional fields, so something, somewhere, will choose defaults. If we had all of that here, we could get rid of many heap allocations and simplify the code.

} namespace_tracker_t;

#define PARAMS_KEY "ros__parameters"
#define PARAMS_DESCRIPTORS_KEY "parameter__descriptors"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox meta: why not ros__parameter_descriptors for consistency?

Copy link
Author

@bpwilcox bpwilcox Nov 22, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given it is already scoped under ros__parameters level it seemed redundant, but I'm not opposed.

This does bring up my original approach to have the parameter__descriptors be at the same level as ros__parameters (i.e. no longer scoped), so the two would be uncoupled. It seemed like much more work at the time with not too significant benefits, but I'm open to discussing it.

@@ -826,6 +1136,77 @@ void rcl_yaml_node_struct_print(
}
}
}
printf("\n Node Name\t\t\t\tParameter Descriptors\n");
Copy link
Contributor

@hidmic hidmic Nov 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox nit: I guess it's fine to begin with, as it precludes the need to match parameter values with parameter descriptors, but it'd be nice to collapse both printed tables into one.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I didn't want to have to match values and descriptors.

parameter_idx++)
{
if (
(NULL != node_descriptors_st->parameter_names))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox nit: can't this line be collapsed with the one above?

break;
}

/// Add a parameter name into the node parameters
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox node parameter descriptors maybe?

} else if (0 == strncmp("type", ns_tracker->descriptor_key_ns, strlen("type"))) {
if (val_type == DATA_TYPE_INT64) {
param_descriptor->type = (uint8_t *)ret_val;
if (NULL == param_descriptor->type) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox here and everywhere else within this function, why do you check for ret_val nullity again? And why does the error message set reads as a memory allocation error?? Bad copy-paste?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not checking ret_val for nullity directly here, that is already done once when it is first assigned. Here I am following the same pattern as in the parse_value, where it checks the allocated descriptor struct field after being cast from ret_val. Am I misunderstanding the original code on that pattern?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I'm not following you, I don't see such pattern. But even if there was, you're not allocating memory here when you cast (as the log message below suggests). It's a C-like cast, it won't result in NULL if it isn't NULL already. Or I completely missed the point of this code.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realized my mistake, you're correct. The check was required when allocating the arrays in parse_value, which I am not doing here.

@@ -38,6 +38,7 @@ typedef enum yaml_map_lvl_e
MAP_UNINIT_LVL = 0U,
MAP_NODE_NAME_LVL = 1U,
MAP_PARAMS_LVL = 2U,
MAP_PARAMS_DESCRIPTORS_LVL = 3U
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox hmm, putting parameter descriptors within the ros__parameters and relying on users not using the parameter__descriptors key for their own purposes under the assumption that it's unlikely enough is not ideal. Consider either making this map a sibling of ros__parameters or supporting further nesting e.g.:

my_node:
    ros__parameters:
        param1: 1.0 
        param2:
            value: foo
            descriptor:
                read_only: true

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would think the further nesting could be more confusing to the user, just my opinion (it seems to conflate the yaml syntax rules for when it is a parameter vs a descriptor). I mentioned this in a another comment, but yes I can see parameter__descriptors as a sibling to ros__parameters,but as I did attempt that first, I think it is a bit more messy to write the code for doing so than simply using the key to trigger a new map level. If per your suggestion, we change the key to ros__parameter_descriptors, do you think it is unique enough for that assumption?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wary about the word enough there. I'd rather just preclude name collisions. But maybe others don't think alike. @ivanpauno @jacobperron @wjwwood thoughts?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a reason to nest parameter_descriptors under ros__parameters, and I would rather implement it as a sibling of ros__parameters, as @hidmic suggested. ros__parameter_descriptors is a good name for that sibling.
I also agree that the alternative of further nesting is confusing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer the extra nesting since it keeps the descriptors physically close to the parameters they are describing. As a sibling to ros__parameters, I think it requires more mental effort. My two cents.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, actually that option isn't bad either. But both the value and the descriptor should be optional (and at least one has to be specified).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a strong opinion. I see merit in both keeping it separate and having descriptors near the overrides.

Copy link
Author

@bpwilcox bpwilcox Dec 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In regards to the extra nesting, I am unsure what would be a preferable syntax. The one @hidmic presented as an example implies that there are two different ways to define an override, the original way, and the nested version, where the descriptor is attached and there's 2 new key words, value and descriptor. In my opinion, I think it obfuscates the parameter namespacing syntax by adding even more key words to check. For that reason, I'm still in favor of a separate map level (either sibling or scoped under ros__parameters) for the ros__parameter_descriptors where the rules for parsing are cleanly separated. In addition, I wouldn't want to require that both a parameter description and override have to exist, but a user can set either.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The one @hidmic presented as an example implies that there are two different ways to define an override, the original way, and the nested version,

That's correct.

In my opinion, I think it obfuscates the parameter namespacing syntax by adding even more key words to check.

That sounds a bit like an implementation detail i.e. something a user wouldn't (have to) care about.

In any case, I don't have a strong opinion in favor or against a sibling descriptor mapping or nested descriptors (and neither do others, or at least there's no general consensus), but I do think it should be one of those two collision free approaches and not the current one.


if (NULL == ns_tracker->parameter_ns) {
RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING(
"Parameter assignment at line %d unallowed in parameter__descriptors", line_num);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox here and elsewhere, isn't it the point of having a PARAMS_DESCRIPTORS_KEY macro to not use the string literal everywhere?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're referring to why I am using the ns_tracker->descriptor_key_ns in this function?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're referring to why I am using the ns_tracker->descriptor_key_ns in this function?

Not exactly, that I understand. What I meant to say is, let's try use PARAMS_DESCRIPTORS_KEY instead of parameter_descriptors where possible. For this particular line:

RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING(
      "Parameter assignment at line %d unallowed in " PARAMS_DESCRIPTORS_KEY, line_num);

Sorry for not being clear enough.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand now, thanks for clarifying

/// \brief node_params_descriptors_t stores all the parameter descriptors of a single node
typedef struct rcl_node_params_descriptors_s
{
char ** parameter_names; ///< Array of parameter names (keys)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox I don't follow why there's an array of parameter names here and a name on each descriptor.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parallelism? I think I had intended to parallel the structure of rcl_node_params and rcl_node_params_descriptors. It made the code more convenient to write, I believe, though I suppose we could remove one or the other.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I'm not entirely convinced it's worth the duplication. You can get away with just an rcl_param_descriptor_t array.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment still applies i.e. no need to have the parameter name in three (3) places.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the name field in rcl_param_descriptor_t instead since it made more sense following the parallel logic of the code with the parameter values.

@hidmic
Copy link
Contributor

hidmic commented Jan 7, 2020

@bpwilcox are you planning to circle back on this?

@bpwilcox
Copy link
Author

bpwilcox commented Jan 8, 2020

@hidmic Yes, I'd started some local changes before the new year but had been preoccupied since. Most notably, as suggested I'm intending to move the ros__parameters and ros__parameter_descriptors to be at sibling levels. With regards to removing parameter names from the descriptor type, I'm not sure if that is worthwhile as it breaks some of the intended code similarity I'd added intentionally before. I'll try to get an update in next week or so.

@hidmic
Copy link
Contributor

hidmic commented Feb 12, 2021

@bpwilcox do you still plan on submitting changes? Or shall I close this patch?

@bpwilcox
Copy link
Author

@bpwilcox do you still plan on submitting changes? Or shall I close this patch?

Yes, I believe I should have some more cycles to work on this in the near future.

@bpwilcox
Copy link
Author

@hidmic I've re-done this work and addressed feedback on a separate branch. It was easier and cleaner than trying to resolve all of the merge conflicts considering the many changes since I've last touched this PR. Would it be better to close this PR and open a new one, or to force push/reset that branch onto this one?

@bpwilcox bpwilcox force-pushed the parse_parameter_descriptors branch 2 times, most recently from ada671e to bf425d8 Compare March 29, 2021 23:31
@bpwilcox
Copy link
Author

@mjeronimo I reset this branch with commits from my revised branch. This way the previous PR comments can be referenced. Maybe we can get some re-reviews of this work while I push ahead in this next month on the rclcpp layer in ros2/rclcpp#909

Signed-off-by: Brian Wilcox <[email protected]>
…d parse key for descriptor map level

Signed-off-by: Brian Wilcox <[email protected]>
Signed-off-by: Brian Wilcox <[email protected]>
…ameters and descriptors under node name in yaml

Signed-off-by: Brian Wilcox <[email protected]>
Signed-off-by: Brian Wilcox <[email protected]>
@bpwilcox bpwilcox force-pushed the parse_parameter_descriptors branch 2 times, most recently from ea2051a to 27674f6 Compare June 29, 2021 16:02
@@ -786,13 +786,6 @@ rcutils_ret_t parse_key(
{
/// Till we get PARAMS_KEY or PARAMS_DESCRIPTORS_KEY, keep adding to node namespace
if (0 == strncmp(PARAMS_KEY, value, strlen(PARAMS_KEY))) {
if (0U == ns_tracker->num_node_ns) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the current unit tests, it was only testing the case of a node with a namespace. With no namespace, this error occurs when a yaml file includes both parameters (PARAMS_KEY) and descriptors (PARAM_DESCRIPTORS_KEY) under the same scope.

For example, this yaml would cause the error:

parameters_node:
  ros__parameters:
    param1: 30
    param3: "hello world"
  ros__parameter_descriptors:
    param1:
      type: 2
      min_value: 5
      max_value: 100
      step: 5
      read_only: false
      description: "int parameter"
      additional_constraints: "only multiples of 5"
    param2:
      min_value: 1.0
      max_value: 10.0
      description: "double parameter"

If these lines are removed, then this yaml becomes acceptable and the unit tests still pass. There will still be an error if trying to put a key without a node name (which is expected), but it is not caught here. I'm still trying to determine what should be the proper solution if anyone has some thoughts to add.

@hidmic hidmic self-requested a review August 9, 2021 13:17
Copy link
Contributor

@hidmic hidmic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First pass, mostly high-level comments.

Thanks for picking this up again @bpwilcox !

@@ -119,6 +119,17 @@ rcl_variant_t * rcl_yaml_node_struct_get(
const char * param_name,
rcl_params_t * params_st);

/// \brief Get the descriptor struct for a given parameter
/// \param[in] node_name is the name of the node to which the parameter belongs
/// \param[in] param_name is the name of the parameter whose value is to be retrieved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox this needs an update:

Suggested change
/// \param[in] param_name is the name of the parameter whose value is to be retrieved
/// \param[in] param_name is the name of the parameter whose descriptor is to be retrieved

/// \param[in] node_name is the name of the node to which the parameter belongs
/// \param[in] param_name is the name of the parameter whose value is to be retrieved
/// \param[inout] params_st points to the populated (or to be populated) parameter struct
/// \return parameter descriptor struct on success and NULL on failure
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox what if no descriptor was specified? what will this function do?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the parameter name or node name does not exist for the descriptor, then it will still return a descriptor (not NULL). I found that this is the same behavior as what happens with rcl_yaml_node_struct_get.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox it'd be best to document what the expected behavior is.

/// \brief node_params_descriptors_t stores all the parameter descriptors of a single node
typedef struct rcl_node_params_descriptors_s
{
char ** parameter_names; ///< Array of parameter names (keys)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment still applies i.e. no need to have the parameter name in three (3) places.

{
char ** parameter_names; ///< Array of parameter names (keys)
rcl_param_descriptor_t * parameter_descriptors; ///< Array of corresponding parameter descriptors
size_t num_params; ///< Number of parameters in the node
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox did you mean num_descriptors?

/// Finalize an rcl_param_descriptor_t
///
RCL_YAML_PARAM_PARSER_PUBLIC
void rcl_yaml_descriptor_fini(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox did you mean rcl_param_descriptor_fini? Same elsewhere. YAML is implied.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This parallels the function naming in yaml_variant.h so I just kept it. If we change the name to your suggestion, I'd recommend we do the same for the variant version. I don't know if this is a big concern, however.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox Hmm, I see. Though if we were to match rcl_variant_t APIs naming pattern it should be rcl_yaml_param_descriptor_fini().

rcl_param_descriptor_t * parameter_descriptors; ///< Array of corresponding parameter descriptors
size_t num_params; ///< Number of parameters in the node
size_t capacity_descriptors; ///< Capacity of parameters in the node
} rcl_node_params_descriptors_t;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox wouldn't adding an rcl_param_descriptor_t ** parameter_descriptors; field to the rcl_node_params_s struct simplify the code a bit? Using NULL to indicate when a descriptor is not available, precluding parameter descriptors without an associated parameter value.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was initially going to put the together as you recommend, however I do not think we would want the parameter descriptors to require association with a parameter value. In my view, it should be perfectly acceptable to have a yaml file with descriptors only and declared parameters in code may comply with these descriptions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox hmm, that's a strange use case. I'd expect the parameter file to specify both, or the descriptor to be specified in code. In what scenario would you want to externally change the parameter descriptor of a parameter declared in code?

int64_t * min_value_int;
int64_t * max_value_int;
int64_t * step_int;
} rcl_param_descriptor_t;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a related note, I understand pointers are used here to have indication of absence. At the same time, ROS 2 interfaces have no optional fields, so something, somewhere, will choose defaults. If we had all of that here, we could get rid of many heap allocations and simplify the code.

@hidmic
Copy link
Contributor

hidmic commented Sep 28, 2021

@bpwilcox friendly ping

@bpwilcox
Copy link
Author

Thanks for your feedback @hidmic I will be addressing your feedback soon!

@bpwilcox
Copy link
Author

Hey @hidmic Could you take another pass through this review since my latest commits?

@hidmic hidmic self-requested a review January 31, 2022 23:24
Copy link
Contributor

@hidmic hidmic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, another pass @bpwilcox. Sorry for the delay. Too much to do, and this PR's a lengthy one.

/// \param[in] node_name is the name of the node to which the parameter belongs
/// \param[in] param_name is the name of the parameter whose value is to be retrieved
/// \param[inout] params_st points to the populated (or to be populated) parameter struct
/// \return parameter descriptor struct on success and NULL on failure
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox it'd be best to document what the expected behavior is.

rcl_param_descriptor_t * parameter_descriptors; ///< Array of corresponding parameter descriptors
size_t num_params; ///< Number of parameters in the node
size_t capacity_descriptors; ///< Capacity of parameters in the node
} rcl_node_params_descriptors_t;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox hmm, that's a strange use case. I'd expect the parameter file to specify both, or the descriptor to be specified in code. In what scenario would you want to externally change the parameter descriptor of a parameter declared in code?


///
/// Create rcl_node_params_descriptors_t structure
///
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox here and elsewhere in this file, can we document return values and parameters?

/// Finalize an rcl_param_descriptor_t
///
RCL_YAML_PARAM_PARSER_PUBLIC
void rcl_yaml_descriptor_fini(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox Hmm, I see. Though if we were to match rcl_variant_t APIs naming pattern it should be rcl_yaml_param_descriptor_fini().

@@ -0,0 +1,84 @@
// Copyright 2020 Open Source Robotics Foundation, Inc.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox nit: here and elsewhere, dates probably need an update?

rcl_param_descriptor_t src_descriptor{}; \
rcl_param_descriptor_t dest_descriptor{}; \
rcutils_allocator_t allocator = rcutils_get_default_allocator(); \
src_descriptor.field = &tmp_field; \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox nit: you may also do:

Suggested change
src_descriptor.field = &tmp_field; \
auto tmp_field = field_value;
src_descriptor.field = &tmp_field; \

to not have to add a temporary lvalue for each literal rvalue you want to use for testing.

rcl_param_descriptor_t dest_descriptor{};
rcutils_allocator_t allocator = rcutils_get_default_allocator();

char * tmp_description = rcutils_strdup("param description", allocator);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox nit: following above's suggestion, you may be able to merge this test into the one before by directly passing rcutils_strdup() and setting up a scope exit block to finalize src_descriptor.

return RCUTILS_RET_ERROR;
}

char * dt = "dynamic_typing";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox nit: why make this one a variable, and a non const one of all things?

"Internal error adding node namespace at line %d", line_num);
break;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox nit: can we reduce code duplication? map_level bumps seem to be the only difference between the last two clauses.

@@ -801,13 +1083,19 @@ rcutils_ret_t parse_file_events(
yaml_event_delete(&event);
return RCUTILS_RET_ERROR;
}
if (0U == params_st->params[node_idx].num_params) {
if (0U == params_st->params[node_idx].num_params && map_level != 3U) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpwilcox meta: since ros__parameters and ros__parameter_descriptors are siblings, perhaps we should have another flag to signal which one we're processing as opposed to repurposing map_level

@Shubham2S
Copy link

Hi, I'm looking forward to use parameter descriptors in the YAML file. What is the status of this PR?

@fujitatomoya
Copy link
Collaborator

@bpwilcox are you planning to work on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants