Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Set parameters from YAML dictionary. #208

Closed
MarqRazz opened this issue Jul 3, 2024 · 3 comments · Fixed by #211
Closed

Set parameters from YAML dictionary. #208

MarqRazz opened this issue Jul 3, 2024 · 3 comments · Fixed by #211

Comments

@MarqRazz
Copy link
Contributor

MarqRazz commented Jul 3, 2024

I'm in the need of using generate_parameter_library to declare, set and update my parameters when launching/running my node but I also need the ability to control which values are loaded when testing.

When I test I create a ROS2 node, declare the ParamListener and then get my parameters but the problem is that nothing has set them so everything defaults. I would like the ability to get my parameters and then override them from a YAML dictionary

self.node = rclpy.create_node('my_test_node')
self.param_listener = my_params.ParamListener(self.node)
self.params = self.param_listener.get_params()

path_to_test_config = os.path.dirname(__file__) + '/config/test_parameters_from_file.yaml'                   
# Load the parameters specific to the test Node
with open(path_to_test_config, 'r') as file:
     my_manually_loaded_yaml_parameters = yaml.safe_load(file)['my_test_node']['ros__parameters'] 
     print(my_manually_loaded_yaml_parameters['load_pose_list_from_file']) # print a parameter from the dictionary

If I could update the parameters from a YAML file it would allow me to write test configs that I can use to check expected behavior.

self.node = rclpy.create_node('my_test_node')
self.param_listener = my_params.ParamListener(self.node)
path_to_test_config = os.path.dirname(__file__) + '/config/test_parameters_from_file.yaml'                   
# Update parameters from test config YAML file before fetching a copy.
with open(path_to_test_config, 'r') as file:
     my_manually_loaded_yaml_parameters = yaml.safe_load(file)['my_test_node']['ros__parameters'] 
     self.param_listener.update_internal_params(my_manually_loaded_yaml_parameters)
self.params = self.param_listener.get_params()

@pac48 does this sound hard to implement?

@pac48
Copy link
Collaborator

pac48 commented Jul 3, 2024

I think it is possible. Here is an issue where we discussed doing the opposite (going from the struct to a dictionary) #155 I think something similar could be done for the use case you presented. Ideally, this can be implemented without modifying the code generator.

@MarqRazz
Copy link
Contributor Author

MarqRazz commented Jul 3, 2024

I got things to set from a YAML config but it does not collapse the mapped dictionaries correctly so it fails to get the item as an object.

path_to_test_config = os.path.dirname(__file__) + '/config/test_parameters_from_file.yaml'                   
# Load the parameters specific to the test Node
with open(path_to_test_config, 'r') as file:
    configParams = yaml.safe_load(file)['my_test_node']['ros__parameters'] 

my_loaded_params = self.param_listener.get_params()
for p in configParams:      
    vars(my_loaded_params).update({p: configParams[p]})
    print(vars(my_loaded_params).get(p))
self.param_listener.update_internal_params(my_loaded_params)
self.params = self.param_listener.get_params()

The generate_parameter_library smash the parameter name down to
"some_namespace.my_map_name.frame_id", value="base_link"

and the Yaml dictionary is still a dictionary when loaded like I suggest.
{some_namespace: {'my_map_name' : {'frame_id': 'link_of_interest'}}}

If you have suggestions on where to put this I'm all ears!

@pac48
Copy link
Collaborator

pac48 commented Jul 15, 2024

@MarqRazz Can we schedule the meeting tomorrow at 11:30 instead of 11:00?

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
2 participants