gz_ros2_control icon indicating copy to clipboard operation
gz_ros2_control copied to clipboard

Feature Request: Support for external controller managers

Open methylDragon opened this issue 3 years ago • 8 comments

Context

Currently, the ROS 2 control plugin provisioned by this package starts a ROS2 Control controller manager as part of the plugin, and also does not seem to expose the plugin in the usual ROS 2 Control manner.

This means that if a user were to instantiate a controller manager independently outside of the one started by this plugin:

  1. The hardware interface can't be found
  2. (I'm speculating since I can't get past (1)) If it could be found, it would have already been claimed by this plugin's controller manager

For example, on trying to instantiate another controller manager:

[robot_controller_server-5] [INFO] [1661983405.401989605] [resource_manager]: Loading hardware 'GazeboABBMultiInterfaceHardware' 
[robot_controller_server-5] [ERROR] [1661983405.405588059] []: Caught exception in callback for transition 10
[robot_controller_server-5] [ERROR] [1661983405.405603913] []: Original error: According to the loaded plugin descriptions the class ign_ros2_control/IgnitionSystem with base class type hardware_interface::SystemInterface does not exist. Declared types are  abb_hardware_interface/ABBSystemPositionOnlyHardware fake_components/GenericSystem mock_components/GenericSystem ros2_control_demo_hardware/DiffBotSystemHardware test_hardware_components/TestSystemCommandModes test_hardware_components/TestTwoJointSystem test_system
[robot_controller_server-5] [WARN] [1661983405.405692816] []: Error occurred while doing error handling.

Feature Request

It would be great if:

  1. The plugin were exposed to external controller managers via the pluginlib exports
  2. A URDF/SDF arg or ROS parameter was exposed to allow a user to disable the automatic starting of a controller manager on the plugin

For (2), I'm not sure whether using the URDF/SDF tag or ROS parameter approach is more desirable

methylDragon avatar Aug 31 '22 21:08 methylDragon

The reason for this is fairly simple. One can't have a component that is a gazebo plugin and a ros2_control hw component (aka another plugin) at the same time normally.

The way to do it all under the same whiff, loading all of ros2_control (including the main loop and the CM) into the gazebo plugin which also has access to gazebo joint interfaces (since it is a gazebo plugin).

I'm happy to entertain other approaches of you can work out how they can be implemented.

bmagyar avatar Sep 02 '22 17:09 bmagyar

The reason for this is fairly simple. One can't have a component that is a gazebo plugin and a ros2_control hw component (aka another plugin) at the same time normally.

The way to do it all under the same whiff, loading all of ros2_control (including the main loop and the CM) into the gazebo plugin which also has access to gazebo joint interfaces (since it is a gazebo plugin).

I'm happy to entertain other approaches of you can work out how they can be implemented.

Thanks for the reply! I didn't realize having a library be usable as a plugin for multiple downstream applications wasn't possible :o

I'll have to think a little to see if I can think of an alternative approach, and it would be great to get some context for why it doesn't work.

Is the issue coming from plugin registration (the macros), the base classes (e.g. needing to inherit from separate base classes, e.g. with clashing method names), or something else (like the ABI that gets generated on compile not being accessible to two downstream applications at once?)

methylDragon avatar Sep 02 '22 18:09 methylDragon

Thanks for the reply! I didn't realize having a library be usable as a plugin for multiple downstream applications wasn't possible :o

I can't think of any use-case you would want to have this. (I doubt that I understand your question/comment)

I'll have to think a little to see if I can think of an alternative approach, and it would be great to get some context for why it doesn't work.

It would be great to get some context, what are you trying to do to know what the solution is.

Is the issue coming from plugin registration (the macros), the base classes (e.g. needing to inherit from separate base classes, e.g. with clashing method names), or something else (like the ABI that gets generated on compile not being accessible to two downstream applications at once?)

No, the issue (if I understand it correctly) is that if you use controller manager without Gazebo simulation, then controller manager is a stand-alone application and manages everything. If you are using it with Gazebo then the simulator is on top of it to triggers it for having synchronized simulation and for providing access to the simulated joints directly in the simulation.

destogl avatar Sep 03 '22 07:09 destogl

Thanks for the reply! I didn't realize having a library be usable as a plugin for multiple downstream applications wasn't possible :o

I can't think of any use-case you would want to have this. (I doubt that I understand your question/comment)

I'll have to think a little to see if I can think of an alternative approach, and it would be great to get some context for why it doesn't work.

It would be great to get some context, what are you trying to do to know what the solution is.

Is the issue coming from plugin registration (the macros), the base classes (e.g. needing to inherit from separate base classes, e.g. with clashing method names), or something else (like the ABI that gets generated on compile not being accessible to two downstream applications at once?)

No, the issue (if I understand it correctly) is that if you use controller manager without Gazebo simulation, then controller manager is a stand-alone application and manages everything. If you are using it with Gazebo then the simulator is on top of it to triggers it for having synchronized simulation and for providing access to the simulated joints directly in the simulation.

I think the main reason why I'm looking for a way to have an external controller manager manage the gz_ros2_control hardware interfaces is so that external controller manager can be wrapped in a lifecycle node with lifecycle functionality.

In order for that to happen the gz_ros2_control hardware interface plugins need to be findable, and the internal controller manager needs to not claim the hardware.

methylDragon avatar Sep 20 '22 07:09 methylDragon

I think the main reason why I'm looking for a way to have an external controller manager manage the gz_ros2_control hardware interfaces is so that external controller manager can be wrapped in a lifecycle node with lifecycle functionality.

I would like to understand the idea here. We are thinking to make controller manager a lifecycle node, but this would be more of an internal work to simplify debugging, and probably rather disturbing in classical use-cases. What are you trying to do? Do you actually need controller manager having lifecycle or do you want to control the lifecycle of the hardware? The latter can be done immediately withe one line of configuration (see ref).

In order for that to happen the gz_ros2_control hardware interface plugins need to be findable, and the internal controller manager needs to not claim the hardware.

Having a Gazebo HW interface outside the Gazebo doesn't make any sense. Where should your data then go? How should then data you write to your hardware communicate with the simulator to do its job? In a case, you don't need actually as simulation, why don't you use MockHardware (see our latest presentations at control.ros.org).

destogl avatar Nov 27 '22 08:11 destogl

Hello everyone, I'm facing the same issue as @methylDragon , but I might some more use cases which would benefit from having a more flexible Gazebo/ros2_control integration

  • Ignition provides a plugin that records force/torque measurements and publishes them on a topic, simulating a force/torque sensor mounted on a robot. I'm working on creating a sensor plugin that implements the hardware_interface::SensorInterface to capture these measurements and write them to the state interfaces. This approach allows me to simulate various controllers in Ignition that require force measurements to calculate their control laws. The controllers can retrieve force measurements from the state interfaces using a ForceTorqueSensor provided by ROS 2, making the controllers agnostic to the specific type of sensor being used. Loading a SensorInterface derived class as a plugin of the Gazebo-managed controller_manager does not seem to be possible.

  • Additionally, I would like to control the robot in simulation using a haptic device, that clearly needs hardware resources other than IgnitionSystemInterface. For performance and control loop reliability, it would be nice if the haptic device hardware resources could be managed by the same controller manager as the simulated robot, in a way that, for example, controller chaining can be employed.

The way to do it all under the same whiff, loading all of ros2_control (including the main loop and the CM) into the gazebo plugin which also has access to gazebo joint interfaces (since it is a gazebo plugin).

In reference to your comment, @bmagyar , may I ask you to be more precise?

AlessioCoone avatar Sep 04 '24 16:09 AlessioCoone

I have another question, although it’s more out of personal curiosity. I noticed that if I load a controller manager not managed by Ignition, I can load any type of hardware that inherits from:

  • hardware_interface::SensorInterface;

  • hardware_interface::SystemInterface;

  • hardware_interface::ActuatorInterface.

However, if I try to load an ign_ros2_control/IgnitionSystem, it throws the error shown in the figure below, even though it also inherits from hardware_interface::SystemInterface. On the other hand, I noticed that I can load controllers that inherit either from both controller_interface::ControllerInterface or controller_interface::ChainableControllerInterface, as both are derived from controller_interface::ControllerInterfaceBase. Could you explain me why?

AlessioCoone avatar Sep 05 '24 15:09 AlessioCoone