ros2_control
ros2_control copied to clipboard
How to define and load controller at runtime
Currently controllers and their parameters are defined in the controller.yaml
file we pass the controller manager at startup.
I would like to define and load a controller which is not defined in the controller.yaml
file.
What I tried was adding the settings for a new controller at runtime via the parameter server. This is possible up to the point where one wants to define the parameters for that controller. Apparently it is not possible to access the parameters the controller manager passes to a controller before that controller gets loaded.
To better illustrate the problem some excerpts from a controller.yaml file:
controller_manager:
ros__parameters:
update_rate: 500
joint_state_broadcaster: #This is currently possible to set at runtime
type: joint_state_broadcaster/JointStateBroadcaster
#This is not possible to access at runtime before the controller gets loaded
joint_state_broadcaster:
ros__parameters:
use_local_topics: true
I would guess if it was possible to access the parameters of a controller before it is loaded it would be really easy to support defining controllers at runtime as well as changing controllers at runtime (e.g. removing joints from a controller).
This is not ros2_control issue. It is how parameters are using in ROS 2. You cannot set parameters using the service interface for the node that does not exist. Loading yaml file is a different mechanism that works only at the moment when a node is created. Maybe there are option to add parameters into “staging” for non-existing nodes, but this questions is rather something for rclcpp
and rclpy
repositories (if not even DDS-implementation related).
Would loading and then setting parameters for the controller not work in your case? This might be the solution. It would be for sure a correct solution, in my oppinion.
Perhaps something controller_manager
could facilitate with a new service?
@destogl I think this might be a ros2_control issue as this feature request actually reads the controller.yaml
file at some point and passes it to the controller node. Wouldn't it be possible to make this stored file accessible via a service call ?
Perhaps to elaborate a bit why I would like to have this feature.
I have a system consisting of a large set of linear axes which can each either be controller in torque, velocity or position mode. Usually they are controlled in position mode, but for some actions we need to have some of them in position mode and some of them in torque mode. In the next step we want to swap these sets.
At the moment I solved this by defining a controller which has all axes in position mode, and then multiple controllers which have a subset of the axes for position and torque mode. This leads in the end to having a lot of controllers with the same parameters which only differ in the joints they controller. If I could change the joints a controller manages at runtime this would be way easier or as requested just define and manage new controllers at runtime.
Would loading and then setting parameters for the controller not work in your case? This might be the solution. It would be for sure a correct solution, in my oppinion.
As it is not possible to change the joints a controller manages after the controller is loaded I think this won't work.
Hello!
This exact issue has been solved with these two PRs: https://github.com/ros-controls/ros2_control/pull/1293 and https://github.com/ros-controls/ros2_control/pull/1502. Using these two, you should be able to define them in their individual config files and load them at run time!
Thank you!