* Fixed failing `ros2 param ...` on r2r nodes for Jazzy (#120)
Add `/set_parameters_atomically` service to `make_parameter_handler_internal` in `nodes.rs` to fix failing `ros2 param ...` on r2r nodes for Jazzy.
* Atomic behavior for `set_parameters_atomically` (#121).
---------
Co-authored-by: Desmond Germans <desmond@germansmedia.nl>
* Implement TryInto for ParameterValue
* Add `get_parameter` method.
* Consolidate 'ParameterNotSet' into 'ParamterWrongType' error
* Add support for optional parameters
* Add example for get_parameter.
This fixes undefined behaviour, as the
rcl_subscription_get_topic_name documentation
states that the topic is no longer valid when
the subscription dies
Adds a QosProfile parameter for `Node::create_client` and `Node::node.create_service`.
`QosProfile::default()` can be passed when updating existing code.
The previous commit made the order of parameters deterministic
(defined by so called insertion order), but the order still depends on
whether or not some parameters were set from the command line. Command
line parameters are inserted to the IndexMap at Node creation time,
while other RosParams-derived parameters later, during the call to
make_derived_parameter_handler().
This commit ensures that parameters processed by
make_derived_parameter_handler() are always inserted in the same
order, even if some of them were already inserted before due to CLI
arguments.
GUI tools for working with parameters (at least Foxglove Studio, rqt
and rig_reconfigure) show the parameters in the same order as returned
by the ListParameters service. r2r stores the parameters in a HashMap,
which iterates keys and values in arbitrary order. The result is that
the GUI tools show the parameters in different order after every node
invocation, which can be quite annoying.
To make the order deterministic, we change the parameter storage from
HashMap to IndexMap, which iterates the map in insertion order.
According to the indexmap documentation, IndexMap is a drop-in
replacement of HashMap so this change should not require code changes
in applications using r2r. At least r2r examples and my projects
needed no changes.
cfg(r2r__rosgraph_msgs__msg__Clock) attribute is not propagated to user
code so this macro can be used to intentionally fail compilation if
sim time is not supported.
The TimeSource subscribes to /clock topic and publishes the time to all
attached clocks (by default only clock used by create_timer is attached).
This module is feature gated because the clock is published in message
rosgraph_msgs::msg::Clock and rosgraph_msgs needs to be specified as
dependency by the end users.
Added feature flag sim-time because functions that are feature gated does
not make sense without TimeSource that is implemented in later commit
and needs the feature flag.
This adds Node::create_timer() method. The method is similar to
already existing Node::create_wall_timer(), but the timer is based on
ClockType::RosTime rather than on ClockType::SteadyTime.
The advantage of ClockType::RosTime is that one can drive the clock
from a different time source. This will be used in the next commits to
implement for clock source on the /clock topic.
This commit is preparation for next commit with timer using RosTime clock.
In the previous implementation the function rcl_timer_init is called
with zero initialized timer handle being stored on stack and after
initialization with rcl_timer_init the timer handle is moved by rust
inside Timer_ struct.
The problem occurs if the type of clock being passed to rcl_timer_init()
is RosTime because the function also registers callbacks in the clock
that would notify the timer about sudden time change (jump callback).
In RCL the jump callback is registered with rcl_clock_add_jump_callback()
and the argument callback.user_data is pointer to timer handle that in
our case references timer stored om stack. When returning from function
create_wall_timer() the pointer becomes dangling and therefore when the
callback is actually called (by function _rcl_timer_time_jump) it could
result in SIGSEGV or could access some variable that happens to be in
the same place as the timer_handle was on stack.
This is fixed by storing timer_handle inside pinned box to prevent
moving the handle.