Ros_control: How to access controller's output from hardware interface?

Dear Community,

I just finished the ros_control course (which was super exciting), however I am a little confused about how the ros_control interfaces access the controller’s output.

To give a minimal working example:

As in the tutorials my_robot_control.yaml might look like

rrbot:
  joint_state_controller:
    type: joint_state_controller/JointStateController
    publish_rate: 50  

  joint1_position_controller:
    type: effort_controllers/JointPositionController
    joint: joint1
    pid: {p: 100.0, i: 0.01, d: 10.0}
  joint2_position_controller:
    type: effort_controllers/JointPositionController
    joint: joint2
    pid: {p: 100.0, i: 0.01, d: 10.0}

while the ros_control interfaces in rrbot_hardware_interface.cpp are defined like

namespace rrbot_hardware_interface {

  bool RRBotHardwareInterface::init(ros::NodeHandle & /*root_nh*/ , ros::NodeHandle & robot_hw_nh) {
    [...]

    // Create ros_control interfaces
    for (size_t i = 0; i < num_joints; ++i) {
      // Create joint state interface for all joints
      joint_state_interface_.registerHandle(
        hardware_interface::JointStateHandle(
          joint_names_[i], & hw_position_states_[i], & hw_velocity_states_[i], & hw_effort_states_[i]));

      // Create joint position control interface
      position_command_interface_.registerHandle(
        hardware_interface::JointHandle(
          joint_state_interface_.getHandle(joint_names_[i]), & hw_position_commands_[i]));
    }
  }
}

My question is, how the JointHandle knows about the controller (i.e. JointPositionController). Do they have to be in the same namespace? Can I access the controller’s output with a JointHandle if the controller is outside its namespace?

Thank you so much for your help!

Hello @Doctor.No,

My understanding is that the JointHandle does NOT know about the controller. It is the controller that knows about the JointHandle. So basically the other way around.

But it doesn’t know directly, it needs an Hardware Interface, which knows about the JointHandle.

In the code above you can see that. It is the command interface that has the registerHandle() method. I think that it is this way how the hardware interface knows about the JointHandle.

In summary, my understanding is that the chain is like this: The controller knows about the hardware interface which in turn knows about the JointHandle.

I think however that a deep understanding of this matter definitely requires digging into the source code of ros_control to find out the exact relations. This is something haven’t done recently to be honest.

Cheers,

Roberto

1 Like

Thank you so much for your answer. At the end, I think the problem was not the different namespace, but more the fact that I assumed that the hardware interface would receive the controller’s output from gazebo. This is of course wrong, since in my understanding, the hardware interface populates the controller with it’s read function. So even if gazebo is running (with the ros_control plugin), it is NOT possible to directly access the controller’s output from gazebo.

My first idea is to subscribe in the read() function of the hardware_interface to the cmd_vel (the same that gazebo receives). In that way, I hope to be able to test the hardware_interface with the gazebo simulation.

Hi @Doctor.No,

in the context of using ros_control with Gazebo, there is no real ros_control hardware interface component, the hardware interface component is implemented as a Gazebo plugin. This plugin communicates with the Gazebo simulation to control the state of the simulated robot and receive feedback from the simulation. The plugin integrates with the Gazebo simulation through the Gazebo API. So basically, if I understand you correctly, want you really want to do is to test if the Gazebo plugin works correctly.

Cheers,

Roberto

1 Like

Thank you so much for your answer!

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.