Macro for deriving ROS parameters code#65
Conversation
305e6b3 to
d89f40a
Compare
|
I think this is now close to be merged (or at least reviewed). As written above, I'll clean up commit history before merging and write useful commit messages. |
|
Hi, interesting. I haven't had a chance to look at it yet but I hope to find some time later this week. Would you mind expanding a little on the motivation (e.g. show how it reduces boiler plate or something) similar. Thanks! |
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`.
1362b91 to
0a355ec
Compare
|
I squashed most of the commits and added the following to the commit message of the first commit. Hopefully, this is what you're looking for. 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 After spawning the handler, e.g.: spawner.spawn_local(paramater_handler)?;changing a parameter with external ROS tools (e.g. The other direction also works: Changing a value in the 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 |
|
Thanks that description was what I wanted. It will be convenient to have and I think the code looks good and it really only touches the parameter handling, so I will just merge it to master. Hoping to get the windows support in also before I make a new release but don't hesitate to open an issue about that if it takes too long. Thanks! |
|
That was quick :-) I'm also working on support of |
This is an initial attempt to create a derive macro, which would make dealing with ROS parameters easier. Currently, it works for my simple use case, but it's far from perfect and there is several TODOs and FIXMEs in the code. I'm posting it here if @m-dahl or somebody else wants to comment on it. Please, don't look at individual commits (which are a mess), just the final diff should make sense. I'll clean up the commit history before eventual merge.
How to use this feature is best visible in the
parameters_derive.rsexample.Before merging this, I think the following should be clarified/fixed:
RosParams.Updating of parameters is currently hooked into the event stream. This should probably be changed to happen directly inset_params_futurehandler to report errors to the clients if the parameter was not defined or the value has incorrect type.allow_undeclared_parameters.Currently, parameters are "read only". It's possible to change the value of the parameter, but the value is not propagated outside of the node via.rcl_interfaces/srv/GetParametersas, which has wrapping semantics, i.e.255 as i8 == -1.