Hook to set new ROS parameters on launch of snap

Another ROS specific question. I would like to set some device specific parameters in my ROS snap programmed in C++. These parameters are normally set by loading a ROS parameter .yaml file. It would be nice if we can keep our C++ code as it is and just reload some of the parameters. This would be similar as using snapctl get/ set. However, the ROS parameter server only exists if the service is running and parameters are replaced on the next startup and never saved.

So I’m wondering about a good way to permanently set some parameters in C++ and I can think of these possibilities:

  • Use the install hook to create an empty .yaml config file and somehow load this file AFTER launching and loading the default parameters, i.e. only the parameters available in the new file are replaced. The rosparam server needs already be running. So command-chain can not be used.
  • Use the configuration hook and reload specific rosparams in the hook. However, same as above, this needs to be executed before every launch. Needs adaption of the hook for every new parameter.
  • Don’t use the rosparam server and use the configuration hook as standalone. Needs some modification in the code so that if the snap configuration parameters are set, these are used instead of the rosparam server. But I couldn’t find out how I can load the snap configuration parameters in my C++ code from the examples. So what is the idea with the snapctl get if I want to use the parameter’s value in my code and not just in a shell script?
  • Use environment variables instead (gets a little bit messy with many parameters).

@kyrofa, do you have any thoughts about keeping the advantage of ROS parameters (e.g. editing without recompiling) together with snap?

Edit:

I realized that setting parameters for the ROS parameter server without touching the existing launch files is not too easy to achieve. The loading of the new parameters needs to happen after loading the ones from the launch file, but before starting the node (because the parameters are often loaded in the constructor). Depending on how a user sets up his launch file (loading parameters at beginning or for specific nodes), this differs a lot.

Loading parameters from an external file is easy in general. But if you do this before initializing the nodes, the parameters are overwritten again. If you do this after initializing the nodes, the parameters in the classes are already loaded.

I found a “hacky” solution by using ‘override-build’ to add an additional rosparam load at specific places in the launch file, which then loads the params from a file in SNAP_DATA, which was created with an install hook. But since my ‘override-build’ searches for patterns in the launch file, this will not work if someone changes the files too much.

Would be interested if someone comes up with a nicer automated solution.