With this, declaring and handling node parameters becomes easy. One
just needs to define a structure(s) containing the parameters such as:
#[derive(RosParams, Default, Debug)]
struct Params {
par1: f64,
par2: i32,
str: String,
}
And then instantiate and register it with:
let params = Arc::new(Mutex::new(Params::default()));
let (paramater_handler, _) = node.make_derived_parameter_handler(params.clone())?;
This will add three parameters `par1`, `par2` and `str` to the node.
Their type will be `Double`, `Integer` and `String` respectively.
Other Rust types such as `f32` or differently sized integers, e.g.
`u16` are also supported and registered as appropriate ROS parameter
types.
After spawning the handler, e.g.:
spawner.spawn_local(paramater_handler)?;
changing a parameter with external ROS tools (e.g. `ros2 param set`)
will result in changing the appropriate field in the `Params`
structure. Type conversion is handled automatically. For example,
setting an `i8` field (represented as `Integer` ROS parameter) will
succeed if the value is in range -128 to 127 and fail with appropriate
error message for other values.
The other direction also works: Changing a value in the `Params`
structure will be visible outside of the Node via the `get_parameters`
service.
It is also possible to organize the parameters as several nested
structures with parameters. Then, parameter names of different nesting
levels will be separated by `.`. For example `nested.par3`. See the
full example in `parameters_derive.rs`.