Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature]: Get available states and commands interfaces from controllers. #1725

Open
rafa-martin opened this issue Aug 27, 2024 · 2 comments

Comments

@rafa-martin
Copy link

Situation:

In industrial robotics, motor drivers typically come equipped with one or more digital inputs and outputs. These I/O interfaces can be automatically detected by a "smart" HardwareInterface, which can then expose them via command and state interfaces (for digital outputs) or via state interfaces alone (for digital inputs) automatically by itself, without any config from ROS side.

Current Arquitecture:

  • In the current system architecture, the robot's description is defined using ros2_control tags as shown below:
<ros2_control name="my_robot" type="system">
  <hardware>
    <plugin>my_base_hw/MyBaseHw</plugin>
    <param name="device">/dev/ttyUSB0</param>
  </hardware>
  <joint name="left_wheel_joint">
    <param name="id">0x01</param>
    <param name="encoder_resolution">2000</param>
    <param name="gearbox">2000</param>
  </joint>
  <joint name="right_wheel_joint">
    <param name="id">0x02</param>
    <param name="encoder_resolution">1000</param>
  </joint>
</ros2_control>
  • The number of I/O interfaces (e.g., digital_output_1, digital_output_2, etc.) depends on the specific driver model. The following interfaces are expose as example:
    • Command: left_wheel_joint/velocity, left_wheel_joint/digital_output_0, left_wheel_joint/digital_output_1, right_wheel_joint/velocity, right_wheel_joint/digital_output_0
    • States: left_wheel_joint/position, left_wheel_joint/velocity, left_wheel_joint/position, left_wheel_joint/digital_output_0, left_wheel_joint/digital_output_1, left_wheel_joint/digital_input_0, right_wheel_joint/position, right_wheel_joint/velocity, right_wheel_joint/position, right_wheel_joint/digital_output_0, right_wheel_joint/digital_input_0, right_wheel_joint/digital_input_1,
  • I expose I/O information via a topic, and to modify outputs, a service server is created. A controller is created like forward_controller.
controller_manager:
  ros__parameters:
    update_rate: 100
    robot_io_controller:
      type: robot_io_controller/RobotIOController

robot_io_controller:
  ros__parameters:
    wheel_names:
    - left_wheel_joint
    - right_wheel_joint
    digital_inputs:
    - 1
    - 2
    digital_outputs:
    - 2
    - 1

Problem:

  • Whenever there is a change in the driver, the number of inputs and outputs can change and must be updated in the controller’s YAML configuration. This process can be done manually or with an external script, but it introduces an unnecessary burden.
  • I want to remove or make optional: wheel_names, digital_inputs and digital_outputs.

Proposed Solutions:

  1. Regex-Based Interface Configuration: Allow command_interface_configuration() and state_interface_configuration() to accept regular expressions. This would enable the automatic matching of interfaces, rather than relying on raw strings.
  2. Dynamic Interface Listing: Enable command_interface_configuration() and state_interface_configuration() to retrieve and list available commands or provide a callable method that returns this information dynamically during their invocation.

I would like to help in the project.
Ideas are welcome.

@mateusmenezes95
Copy link
Contributor

I think that this will not solve your problem, but as I didn't see any mention in the issue description... Have you heard about the gpio tag?

@rafa-martin
Copy link
Author

Yes, I heard about it, but probably I not explained the goal well.

From the example you provided, it's clear that the controller must be configured with the number of GPIOs defined in the robot's YAML file prior to launching the node, as demonstrated here: config. This setup does not support dynamic addition or removal of GPIOs based on the interfaces exposed by the loaded hardware interfaces.

The goal is to have a way to take all state interfaces:

  • Option 1: Use a regex or a similar filter such as main_gpio/output_[0-9]+ to identify these interfaces.
  • Option 2: Fetch all existing state and command interfaces, then apply filters within the command_interface_configuration() or state_interface_configuration() functions.

The main challenge isn't about sharing GPIO data between a controller and a hardware_interface. Rather, it's about dynamically capturing all command_interfaces—which must already exist and are blocked when a controller accesses this shared resource. While it's currently possible for state_interfaces to be automatically captured by the controller_manager, enhancing this functionality with filtering capabilities would be ideal, wouldn't it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants